Bug 8726 – About immutable and const constructors

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Linux
Creation time
2012-09-25T23:31:00Z
Last change time
2013-11-24T05:20:46Z
Assigned to
nobody
Creator
freeslave93

Comments

Comment #0 by freeslave93 — 2012-09-25T23:31:52Z
Hello to all. Actually I posted this issue on D forums, but I was advised to ask there. I want to discuss immutable and const constructors. For a start let's write the simple class with two constructors: class A { int x; this() immutable { x = 42; } this() { x = 13; } } void main() { // } Well, dmd passes this code, but what if we want to create some object of class A? void main() { A a = new A; } hello.d|177|Error: constructor hello.A.this called with argument types:| hello.d|177|Error: cannot implicitly convert expression (new A) of type immutable(A) to hello.A| Class A has mutable constructor, but for some reason immutable one is called and then immutable object can not be converted to type A, which is mutable. Let's rewrite this line to this: immutable A a = new A; hello.d|173|Error: constructor hello.A.this called with argument types:| So what's the problem? Yes, both A's constructors really have empty argument lists, but... ah. Let's try another way: immutable A a = new immutable A; hello.d|173|Error: found 'A' when expecting '('| hello.d|173|Error: basic type expected, not ;| hello.d|173|Error: found ';' when expecting ')'| hello.d|174|Error: semicolon expected, not '}'| Again not. Looks like it's not correct statement at all. So I conclude there is no way to keep simultaneously both mutable and immutable constructors with same argument list. But as we saw above, compiler passes code if we don't create objects of class A, although such permission has no sense. Well, now let's rewrite our class using const specifier instead of immutable class A { int x; this() const { x = 42; } this() { x = 13; } } void main() { const A a = new A; assert(a.x == 42); } Project is built without errors or warning, but we get assertion failure in runtime. Error seems obvious: new A is constructed like mutable and only then assigned to object of class const A. Maybe the following code will be correct? const A a = new const A; hello.d|173|Error: found 'A' when expecting '('| hello.d|173|Error: basic type expected, not ;| hello.d|173|Error: found ';' when expecting ')'| hello.d|174|Error: semicolon expected, not 'assert'| But we get same errors as with immutable specifier. I think, there is some compiler defect or problem of language design.
Comment #1 by k.hara.pg — 2013-04-26T00:15:48Z
In 2.063, qualified constructor will be supported properly. This code would work in 2.063. class A { int x; this() immutable { x = 42; } this() { x = 13; } } class B { int x; this() const { x = 42; } this() { x = 13; } } void main() { A ma = new A; assert(ma.x == 13); //immutable A ia = new A; //--> Error: cannot implicitly convert expression (new A) // of type test.A to immutable(A) immutable A ia = new immutable A; assert(ia.x == 42); const B mb = new B; assert(mb.x == 13); const B cb = new const B; assert(cb.x == 42); //immutable B ib = new B; //--> Error: cannot implicitly convert expression (new B) // of type test.B to immutable(B) }
Comment #2 by yebblies — 2013-11-24T05:20:46Z
All of this now works.