On Monday, 19 November 2018 at 14:04:29 UTC, Dennis wrote:
On Monday, 19 November 2018 at 13:34:50 UTC, Stanislav Blinov wrote:
Because it's not mutation, it's initialization.

Ohhhhh. That's an epiphany for me.

:)

When a ctor is `pure`, the compiler knows it doesn't mutate any state other than the object's, so it allows conversion to all three qualifiers.

I had trouble thinking of an example where impure constructors would break immutable, but now I get it:

```
int* gPtr;

struct S {
  int a;
  this(int a) {
    this.a = a;
    gPtr = &this.a;
  }
}

void main() {
  S s = 1;
  (*gPtr)++;
}
```
s can't be immutable because its field could be mutated, so the constructor needs to be pure (so gPtr can't be set) or immutable (so &this.a is an immutable(int)*).

Yep. Or the other way around (as I said earlier, it really makes sense when you have indirections inside the struct):

int* global;

struct S {
     const(int)* a;
     this(bool b) {
         if (b) a = global;
         else a = new int;
     }
}

You obviously can't instantiate an immutable S with that ctor, since const(int)* may point to mutable data. Nor can you make that ctor `pure`. However this is fine:

immutable(int*) global; // note it's an immutable(int*), not an immutable(int)*

struct S {
     const(int)* a;
     this(bool b) pure {
         if (b) a = global;
         else a = new int;
     }
}

Reply via email to