diff --git a/src/dmd/delegatize.d b/src/dmd/delegatize.d index 06029cbcd7ad..53a022147a72 100644 --- a/src/dmd/delegatize.d +++ b/src/dmd/delegatize.d @@ -86,6 +86,25 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd) alias visit = typeof(super).visit; FuncDeclaration fd; + private void setParent(Dsymbol s) + { + VarDeclaration vd = s.isVarDeclaration(); + FuncDeclaration pfd = s.parent ? s.parent.isFuncDeclaration() : null; + s.parent = fd; + if (!vd || !pfd) + return; + // move to fd's closure when applicable + foreach (i; 0 .. pfd.closureVars.dim) + { + if (vd == pfd.closureVars[i]) + { + pfd.closureVars.remove(i); + fd.closureVars.push(vd); + break; + } + } + } + public: extern (D) this(FuncDeclaration fd) { @@ -98,7 +117,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd) override void visit(DeclarationExp e) { - e.declaration.parent = fd; + setParent(e.declaration); e.declaration.accept(this); } @@ -107,7 +126,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd) if (e.lengthVar) { //printf("lengthVar\n"); - e.lengthVar.parent = fd; + setParent(e.lengthVar); e.lengthVar.accept(this); } } @@ -117,7 +136,7 @@ private void lambdaSetParent(Expression e, FuncDeclaration fd) if (e.lengthVar) { //printf("lengthVar\n"); - e.lengthVar.parent = fd; + setParent(e.lengthVar); e.lengthVar.accept(this); } } diff --git a/test/compilable/test20063.d b/test/compilable/test20063.d new file mode 100644 index 000000000000..9fa1db401216 --- /dev/null +++ b/test/compilable/test20063.d @@ -0,0 +1,14 @@ + +struct S +{ + void f(alias fun)() {} +} + +auto handleLazily(T)(lazy T expr) {} + +void main() +{ + class C {} + + S().f!(() => new C()).handleLazily; +}