https://issues.dlang.org/show_bug.cgi?id=9148
--- Comment #4 from [email protected] --- (In reply to Xinok from comment #3) > 'S.bar' is immutable, meaning it can only access immutable members of 'S', > so the error is correct. > ... > > Immutable functions can only read immutable members, so this error is > actually correct. > (Indeed. I already noted this.) > I think the trouble of member functions vs local functions may be a > technicality: The struct object is seen as a hidden argument passed to the > member function, whereas it's not seen this way with local functions. Because > > pure functions can take mutable arguments, it will work for member > functions. > But because the context pointer is not seen as an argument for > local > functions, it fails. But obviously it is a hidden argument. There are no distinctions to be made between local functions and member functions in this respect, and this is especially important since delegates can be formed from both and their types need to have a consistent interpretation. > > > > int delegate()pure s(){ > > int x; > > int foo()pure{ > > // return x++; // error > > return 2; > > } > > /+int bar()immutable pure{ // error > > return 2; > > }+/ > > return &foo; > > } > > Function 'bar' actually compiles fine for me, no errors. > ... This is a change in behaviour since the bug was reported. > > > > void main(){ > > S s; > > int delegate()pure dg = &s.foo; > > // int delegate()pure immutable dg2 = &s.bar; // error > > writeln(dg(), dg(), dg(), dg()); // 0123 > > immutable int delegate()pure dg3 = dg; // ok > > writeln(dg3(), dg3(), dg3(), dg3()); // 4567 > > // static assert(is(typeof(cast()dg3)==int delegate() immutable pure)); > > // error > > auto bar = &s.bar; > > pragma(msg, typeof(bar)); // "int delegate() immutable pure" > > } > > immutable int delegate()pure == immutable(int delegate()pure) != int > delegate() immutable pure > ... Sure. Why is this relevant? The first 'error' appears to be fine now. The line annotated 'ok' absolutely must fail. In case this is not obvious consider the following code, which compiles and runs fine now: class C{} C foo(immutable C delegate()@safe pure dg)pure @safe{ return dg(); } void main()@safe{ C c = new C(); struct S{ C c; C foo()pure{ return c; } } S s=S(c); immutable(C) d=foo(&s.foo); assert(c is d); } I.e. this 'ok' is a loophole that allows unsafe type coercion. The static assertion should pass. If top-level immutable is stripped using the cast(), this should not affect the qualification of the context pointer (because this way, it is @safe). This is analogous to immutable(int*) x; static assert(is(typeof(cast()x)==immutable(int)*)); > > Other than some confusion with member functions vs local functions, (This confusion is actually the main part of the bug report and all the other problems seem to be quite related to it.) > I'm not sure there's actually any bugs here. Some parser limitations appear to have been fixed since this issue was reported but there are still plenty bugs as demonstrated above. --
