https://issues.dlang.org/show_bug.cgi?id=16056
--- Comment #6 from Eyal Lotem <eyal.lo...@gmail.com> --- (In reply to ag0aep6g from comment #5) > (In reply to Eyal Lotem from comment #4) > > immutable void delegate() pure > > > > vs. > > > > immutable void delegate() immutable pure > > When the delegate is part of an immutable struct instance, it has the former > type, too: > > ---- > struct S { void delegate() pure f; } > immutable s = S(); > pragma(msg, typeof(s.f)); /* immutable(void delegate() pure) */ > ---- > > I suppose your point is that it should be the latter type, with two > "immutable"s. > > Fair enough, but I don't think that distinction is worth having. D doesn't > have head const with pointers. Why should we make delegates a special case? > > So in my opinion, `immutable void delegate()` should imply an immutable > context pointer, making it the same type as `immutable void delegate() > immutable`. Just like `immutable(int*)` is the same as > `immutable(immutable(int)*)`. > > The compiler agrees (to some extent): > > ---- > alias A = immutable int* delegate(); > alias B = immutable int* delegate() immutable; > static assert(is(A == B)); /* passes */ > ---- > > But then there's this: > > ---- > void main() > { > int x = 1; > const void delegate() dg1 = { ++x; }; > const void delegate() const dg2 = { ++x; }; > } > ---- > > That compiles, but when you take the dg1 line away, then the dg2 line isn't > accepted anymore. And when you swap them around, both lines are rejected. > There's obviously something wrong here. I've filed a separate issue: > https://issues.dlang.org/show_bug.cgi?id=16058 I agree `immutable delegate ..` should imply the context is immutable too (i.e: no head-const ptrs). But possibly not the other way around. It makes sense to have a mutable delegate with an immutable context (like a mutable ptr to immutable data). --