www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - SumType!(A,B) != SumType!(B,A) - a bug?

reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
Here is the code:
```d
struct A {}
struct B { int[] i; }

immutable s1 = SumType!(A,B)(B.init);    // (1) compiles
immutable s2 = SumType!(B,A)(B.init);    // (2) compilation error
```

Compilation error for (2):
 onlineapp.d(9): Error: cannot implicitly convert expression 
 `SumType(Storage(B(null), ), cast(ubyte)0u).this(B(null))` of 
 type `SumType!(B, A)` to `immutable(SumType!(B, A))`
 onlineapp.d(9):        `s2 = SumType(Storage(B(null), ), 
 cast(ubyte)0u).this(B(null))` is the first assignment of `s2` 
 therefore it represents its initialization
 onlineapp.d(9):        `opAssign` methods are not used for 
 initialization, but for subsequent assignments
Questions: - Should (1) and (2) behave the same way? - Is there anything I can do with type `A` to make (1) fail to compile the same way as (2)?
Dec 26 2023
parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 26 December 2023 at 19:05:08 UTC, Andrey Zherikov 
wrote:
 Here is the code:
 ```d
 struct A {}
 struct B { int[] i; }

 immutable s1 = SumType!(A,B)(B.init);    // (1) compiles
 immutable s2 = SumType!(B,A)(B.init);    // (2) compilation 
 error
 ```
[...]
 Questions:
 - Should (1) and (2) behave the same way?
 - Is there anything I can do with type `A` to make (1) fail to 
 compile the same way as (2)?
Yes, they should both behave the same way--either the conversion from mutable to immutable is valid, or it isn't. I think this is probably a compiler bug, but it's hard to tell without a reduced example.
Dec 26 2023
next sibling parent reply Andrey Zherikov <andrey.zherikov gmail.com> writes:
On Tuesday, 26 December 2023 at 19:19:08 UTC, Paul Backus wrote:
 I think this is probably a compiler bug, but it's hard to tell 
 without a reduced example.
Output from dustmite: ```d void main() { import std; struct B { int[] i; } immutable s2 = SumType!B(B.init); // compilation error } ``` Error:
 source.reduced/main.d(6): Error: cannot implicitly convert 
 expression `SumType(Storage(B(null)), 
 cast(ubyte)0u).this(B(null))` of type `SumType!(B)` to 
 `immutable(SumType!(B))`
 source.reduced/main.d(6):        `s2 = 
 SumType(Storage(B(null)), cast(ubyte)0u).this(B(null))` is the 
 first assignment of `s2` therefore it represents its 
 initialization
 source.reduced/main.d(6):        `opAssign` methods are not 
 used for initialization, but for subsequent assignments
Dec 26 2023
parent Paul Backus <snarwin gmail.com> writes:
On Tuesday, 26 December 2023 at 19:30:14 UTC, Andrey Zherikov 
wrote:
 On Tuesday, 26 December 2023 at 19:19:08 UTC, Paul Backus wrote:
 I think this is probably a compiler bug, but it's hard to tell 
 without a reduced example.
Output from dustmite: ```d void main() { import std; struct B { int[] i; } immutable s2 = SumType!B(B.init); // compilation error } ```
Needs to include `std.sumtype` in the reduction to be useful. I recommend copying `sumtype.d` from Phobos to a new directory to create a self-contained example.
Dec 26 2023
prev sibling parent Nickolay Bukreyev <buknik95 ya.ru> writes:
On Tuesday, 26 December 2023 at 19:19:08 UTC, Paul Backus wrote:
 I think this is probably a compiler bug, but it's hard to tell 
 without a reduced example.
```d union A { int x; int[] arr; } union B { int[] arr; int x; } A createA() /+pure+/ { return A.init; } B createB() /+pure+/ { return B.init; } void main() { immutable a = createA(); // OK immutable b = createB(); // cannot implicitly convert expression `createB()` of type `B` to `immutable(B)` } ``` If we mark `createB` pure, it will compile successfully. This behaviour is described in the spec: `createB` becomes a [pure factory function](https://dlang.org/spec/function.html#pure-factory-functions). I believe DMD should issue an error for `A` as well.
Dec 29 2023