Help needed: immutable struct is a type modifier, and that's wrong and broken

Jacob Carlborg doob at me.com
Fri Mar 13 13:25:52 UTC 2020


On Friday, 13 March 2020 at 09:33:18 UTC, FeepingCreature wrote:
> See this bug: https://issues.dlang.org/show_bug.cgi?id=20670
>
> immutable struct S { }
>
> static if(is(S == immutable T, T)) {
>     static assert(is(S == T));
> }
>
> So what happens here is that the spec states that immutable 
> struct S is "the same as if every member had been marked 
> immutable." But that's not at all what the compiler actually 
> does: apparently, it just stores S with an immutable modifier.
>
> As the code shows, immutable modifiers can be stripped away. 
> This is of course bad, because it means that there's a type 
> "S", but there's also a type "mutable S" that can only be 
> created by template specialization or Unqual, and it can't be 
> assigned to S despite nominally being the exact same type.
>
> Help?
>
> (For now, I'll probably homebrew an Unqual that uses mixin to 
> figure out when a type has a "fake immutable modifier". But I 
> won't like it.)

import std;

immutable struct S { }

void main()
{
     Unqual!S s;
     Unqual!S s2;

     pragma(msg, typeof(s)); // will print S
     s = s2;
}

The above code will compile, but if you add a member to S, it 
fails:

Error: cannot modify struct instance `s` of type `S` because it 
contains `const` or `immutable` members

Even though it looks like it's possible to strip of the immutable 
qualifier it will actually not work in practice. If you don't 
have any members, it doesn't really matter. If you do have 
members, it will not compile.

--
/Jacob Carlborg


More information about the Digitalmars-d mailing list