Bug 13488 – implicit conversions to immutable broken

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-17T06:59:24Z
Last change time
2024-12-13T18:27:02Z
Assigned to
No Owner
Creator
Walter Bright
See also
https://issues.dlang.org/show_bug.cgi?id=1654
Moved to GitHub: dmd#18882 →

Comments

Comment #0 by bugzilla — 2014-09-17T06:59:24Z
I had this working earlier, but subsequent fixes broke it: struct T { const(int)* p = null; this(const(int)* q) pure { p = q; } } void foo() { int x; T p1 = T(&x); // ok // immutable(T) p2 = T(&x); // error immutable int y; immutable(T) p3 = T(&y); // line 14, should be ok immutable(T)* p4 = new T(&y); // line 15, should be ok } C:\cbx\mars>dmd -c foo DMD v2.066 DEBUG foo.d(14): Error: cannot implicitly convert expression ((T __ctmp2 = T; , __ctmp2).this(& y)) of type T to immutable(T) foo.d(15): Error: cannot implicitly convert expression (new T(& y)) of type T* to immutable(T)* The non-constructor version of it also fails: struct S { const(int)* p; } void bar() { int x; // immutable(S)* q1 = new S(&x); // Error, &x is not unique immutable(S)* q2 = new S(null); // Ok immutable y = 3; immutable(S)* q3 = new S(&y); // line 11, this should work immutable(S)* q4 = new S(new int); // Ok immutable(int)* i2; immutable(S)* q5 = new S(i2); // line 14, this should work pure int* foo(); immutable(S)* q6 = new S(foo()); // Ok } C:\cbx\mars>dmd -c foo2 DMD v2.066 DEBUG foo2.d(11): Error: cannot implicitly convert expression (new S(& y)) of type S* to immutable(S)* foo2.d(14): Error: cannot implicitly convert expression (new S(cast(const(int)*)i2)) of type S* to immutable(S)* It's critical that these get fixed.
Comment #1 by bugzilla — 2014-09-17T07:09:04Z
I take it back, this is an enhancement not a regression. Changing the const(int) to immutable(int) will cause the examples to work. But I'd still like the examples to work as is.
Comment #2 by k.hara.pg — 2014-09-17T11:07:04Z
There's > struct T { > const(int)* p = null; > this(const(int)* q) pure { > p = q; > } > } When we see only the signature (const(int*)) pure, the constructor cannot construct immutable object in general, because the parameter q may receive mutable object. If you want to restrict constructed object qualifier by using constructor argument qualifiers, you can use inout constructor. struct T { const(int)* p = null; this(inout(int)* q) inout// pure { p = q; } } void foo() { int x; T mt1 = T(&x); // ok T* mp1 = new T(&x); // ok //T mt2 = immutable T(&x); // NG //T* mp2 = new immutable T(&x); // NG immutable int y; //immutable(T) it1 = T(&y); // NG //immutable(T)* ip1 = new T(&y); // NG immutable(T) it2 = immutable T(&y); // ok immutable(T)* ip2 = new immutable T(&y); // ok }
Comment #3 by k.hara.pg — 2014-09-17T11:13:34Z
(In reply to Kenji Hara from comment #2) > There's Sorry, ignore this part.
Comment #4 by dfj1esp02 — 2014-09-17T13:44:02Z
Doesn't work: --- struct B { const(int)[] a; } immutable(B) b(immutable int[] a) pure { return B(a); } --- Error: cannot implicitly convert expression (B(cast(const(int)[])a)) of type B to immutable(B)
Comment #5 by k.hara.pg — 2014-09-17T14:10:50Z
(In reply to Sobirari Muhomori from comment #4) > Doesn't work: > --- > struct B > { > const(int)[] a; > } > > immutable(B) b(immutable int[] a) pure > { > return B(a); > } > --- > Error: cannot implicitly convert expression (B(cast(const(int)[])a)) of type > B to immutable(B) It's equivalent with: struct B { const(int)[] a; } void main() { immutable int[] a; immutable(B) b = B(a); // <-- B is not implicitly convertible to immutable(B) }
Comment #6 by dfj1esp02 — 2014-09-18T09:21:04Z
It feels like everything constructed in a strongly pure call can be implicitly casted to immutable. A call to pure constructor can be seen as a call to pure factory, so its result can be casted to immutable if the call is strongly pure. This works: --- int[] a() pure { return new int[2]; } void b() { immutable int[] c = a(); } ---
Comment #7 by robert.schadek — 2024-12-13T18:27:02Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18882 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB