From 59af1d08e75f14c8082f81b546a12b21b30e5d3b Mon Sep 17 00:00:00 2001 From: k-hara Date: Mon, 9 Sep 2013 18:49:19 +0900 Subject: [PATCH] Partial fix for Issue 10666 - Appender does not work with a RefCounted type Essentially this is neigher dmd nor phobos regression, but recent Appender change in 2.064a should not raise "cannot build closure" error. --- src/expression.c | 19 +++++++++++++------ test/fail_compilation/fail10666.d | 22 ++++++++++++++++++++++ test/runnable/funclit.d | 20 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 test/fail_compilation/fail10666.d diff --git a/src/expression.c b/src/expression.c index 9c12feeaf92d..415a8be72d6a 100644 --- a/src/expression.c +++ b/src/expression.c @@ -8383,10 +8383,10 @@ Expression *CallExp::semantic(Scope *sc) #endif if (e1->op == TOKcomma) - { /* Rewrite (a,b)(args) as (a,(b(args))) + { + /* Rewrite (a,b)(args) as (a,(b(args))) */ CommaExp *ce = (CommaExp *)e1; - e1 = ce->e2; e1->type = ce->type; ce->e2 = this; @@ -8395,15 +8395,15 @@ Expression *CallExp::semantic(Scope *sc) } if (e1->op == TOKdelegate) - { DelegateExp *de = (DelegateExp *)e1; - + { + DelegateExp *de = (DelegateExp *)e1; e1 = new DotVarExp(de->loc, de->e1, de->func); return semantic(sc); } if (e1->op == TOKfunction) - { FuncExp *fe = (FuncExp *)e1; - + { + FuncExp *fe = (FuncExp *)e1; arguments = arrayExpressionSemantic(arguments, sc); preFunctionParameters(loc, sc, arguments); e1 = fe->semantic(sc, arguments); @@ -9158,6 +9158,13 @@ Expression *CallExp::semantic(Scope *sc) } } + // Handle the case of a direct lambda call + if (f && f->isFuncLiteralDeclaration() && + sc->func && !sc->intypeof) + { + f->tookAddressOf = 0; + } + return this; } diff --git a/test/fail_compilation/fail10666.d b/test/fail_compilation/fail10666.d new file mode 100644 index 000000000000..2e1747d4d2b9 --- /dev/null +++ b/test/fail_compilation/fail10666.d @@ -0,0 +1,22 @@ +// REQUIRED_ARGS: -c +/* +TEST_OUTPUT: +--- +fail_compilation/fail10666.d(16): Error: variable fail10666.foo10666.s1 has scoped destruction, cannot build closure +--- +*/ + + +struct S10666 +{ + int val; + ~this() {} +} + +void foo10666(S10666 s1) +{ + auto f1 = (){ return () => s1.val; }(); // NG + + S10666 s2; + auto f2 = (){ return () => s2.val; }(); // (should be NG) +} diff --git a/test/runnable/funclit.d b/test/runnable/funclit.d index 25d4c3374101..1cbd17635a91 100644 --- a/test/runnable/funclit.d +++ b/test/runnable/funclit.d @@ -822,6 +822,26 @@ void test10288() @safe pure nothrow static assert(!__traits(compiles, baz10288(10))); } +/***************************************************/ +// 10666 + +struct S10666 +{ + int val; + ~this() {} +} + +void foo10666(S10666 s1) +{ + S10666 s2; + + /* Even if closureVars(s1 and s2) are accessed by directly called lambdas, + * they won't escape the scope of this function. + */ + auto x1 = (){ return s1.val; }(); // OK + auto x2 = (){ return s2.val; }(); // OK +} + /***************************************************/ int main()