This merrily compiles:
class Zmienna {
int a;
this(int a) {
this.a = a;
}
}
immutable class Stala : Zmienna {
this(int a) {
super(a);
}
}
void main() {
auto st = new Stala(5);
Zmienna zm = st;
zm.a = 666;
// st.a = 666; // fails
assert (st.a == 666);
}
The above shows that an immutable class shouldn't be allowed to derive from mutable classes. Unfortunately it won't work because Object is not (and can't be) immutable. Not sure how to bite this one, perhaps make an opt out that says mutable parents with no fields are OK? Or an exception only for Object?
Comment #1 by schveiguy — 2010-01-21T05:43:28Z
The solution would be to make it illegal to have a mutable class reference to the base class.
In your example, this line should be an error:
Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna)
Comment #2 by tomeksowi — 2010-01-21T11:03:00Z
(In reply to comment #1)
> The solution would be to make it illegal to have a mutable class reference to
> the base class.
>
> In your example, this line should be an error:
>
> Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna)
Thanks, that makes sense.
*** Issue 5080 has been marked as a duplicate of this issue. ***
Comment #8 by code — 2012-03-04T05:19:41Z
*** Issue 7636 has been marked as a duplicate of this issue. ***
Comment #9 by smjg — 2012-03-25T07:52:59Z
(In reply to comment #1)
> The solution would be to make it illegal to have a mutable class reference to
> the base class.
No, because a Zmienna is perfectly allowed to be mutable. It's Stala that isn't.
> In your example, this line should be an error:
>
> Zmienna zm = st; // error, must use immutable(Zmienna) or const(Zmienna)
Correct, since because Stala is immutable, any object reference of type Stala is actually of type immutable(Stala).
The bug is that constancy is ignored when converting from a derived class to a base class, as this code shows (DMD 2.058, Win32):
----------
class Base { int x; }
class Derived : Base { int y; }
void main() {
Derived md;
const(Derived) cd;
immutable(Derived) id;
Base mb_md = md;
const(Base) cb_md = md;
immutable(Base) ib_md = md; // accepts-invalid
Base mb_cd = cd; // accepts-invalid
const(Base) cb_cd = cd;
immutable(Base) ib_cd = cd; // accepts-invalid
Base mb_id = id; // accepts-invalid
const(Base) cb_id = id;
immutable(Base) ib_id = id;
}
Comment #10 by schveiguy — 2012-03-26T03:11:50Z
(In reply to comment #9)
> (In reply to comment #1)
> > The solution would be to make it illegal to have a mutable class reference to
> > the base class.
>
> No, because a Zmienna is perfectly allowed to be mutable. It's Stala that
> isn't.
I think you misunderstand. I don't mean because Stala exists, Zmienna should be prevented from being mutable, even for cases where Stala is not involved. I mean, it should be illegal to have a mutable Stala reference point at a Zmienna.
Comment #11 by smjg — 2012-03-26T03:57:16Z
(In reply to comment #10)
> I think you misunderstand. I don't mean because Stala exists,
> Zmienna should be prevented from being mutable, even for cases
> where Stala is not involved. I mean, it should be illegal to have
> a mutable Stala reference point at a Zmienna.
I haven't misunderstood. There's no such thing as a mutable Stala reference. Because Stala is an immutable class, any reference to a Stala is automatically immutable. See for yourself:
-----
void main() {
Stala st = new Stala(5);
pragma(msg, typeof(st)); // immutable(Stala)
st = new Stala(4); // errors, because st is immutable
Zmienna zm = st; // accepts-invalid
}
-----
The bug is that DMD allows the implicit conversion of immutable(Stala) to Zmienna. It's just mb_id in my last example.
Comment #12 by schveiguy — 2012-03-26T04:13:21Z
(In reply to comment #11)
> (In reply to comment #10)
> > I think you misunderstand. I don't mean because Stala exists,
> > Zmienna should be prevented from being mutable, even for cases
> > where Stala is not involved. I mean, it should be illegal to have
> > a mutable Stala reference point at a Zmienna.
>
> I haven't misunderstood. There's no such thing as a mutable Stala reference.
Gahh! maybe it's the names in this one :)
I meant to say this instead of the last sentence above:
"I mean, it should be illegal to have a mutable Zmienna reference point at a Stala"
Sorry.
Comment #13 by schveiguy — 2012-04-16T05:30:03Z
*** Issue 7920 has been marked as a duplicate of this issue. ***
Comment #14 by schveiguy — 2012-04-19T04:52:11Z
*** Issue 7939 has been marked as a duplicate of this issue. ***
Comment #15 by github-bugzilla — 2012-07-18T00:08:12Z