import std.stdio; /* ATTEMPT TO USE NESTED "PURE" FUNCTIONS IN A TEMPLATE. All works fine unless you uncomment the third line in main. If you do, dmd 2.032 yeilds: pure.d(35): Error: pure nested function 'bar' cannot access mutable data 'fooState' pure.d(36): Error: pure nested function 'bar' cannot access mutable data 'y' pure.d(47): Error: template instance pure.fooPT!(char) error instantiating */ //"pure" inner function, with concrete types - ok pure string foo(string x, string y){ string fooState; string bar(string x){ fooState = "hello "; return x ~ y; } return fooState ~ bar(x); } //potentially pure (?) templated version not labled as pure - ok immutable(T)[] fooT(T)(immutable(T)[] x, immutable(T)[] y){ immutable(T)[] fooState; immutable(T)[] bar(immutable(T)[] x){ fooState = "hello "; return x ~ y; } return fooState ~ bar(x); } //attempt to make templated version pure - no dice pure immutable(T)[] fooPT(T)(immutable(T)[] x, immutable(T)[] y){ immutable(T)[] fooState; immutable(T)[] bar(immutable(T)[] x){ fooState = "hello "; return x ~ y; } return fooState ~ bar(x); } void main(){ writeln(foo("p", "c")); writeln(fooT("p", "c")); //writeln(fooPT("p", "c"));
This is happening because the nested template is being marked as pure. This happens in mtype.c, in TypeFunction::semantic, line 4038: the template function gets marked as pure/nothrow because it's taken from the parent scope. This is wrong, because pure/nothrow shouldn't be inherited by members. PATCH: In DeclarationExp::semantic(Scope *sc), pure (and nothrow) should not be passed on to members. Turn it off while running semantic on those functions. Index: expression.c =================================================================== --- expression.c (revision 196) +++ expression.c (working copy) \@@ -4505,8 +4505,12 @@ } if (!s->isVarDeclaration()) { + // 'pure nothrow' is not inherited by member declarations + int scopePureNothrow = sc->stc & (STCpure | STCnothrow); + sc->stc ^= scopePureNothrow; declaration->semantic(sc); s->parent = sc->parent; + sc->stc ^= scopePureNothrow; } if (!global.errors) {
Fixed DMD2.035.