Thread overview |
---|
February 20, 2013 [Issue 9541] New: CTFE: wrong code with delegates, recursion | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=9541 Summary: CTFE: wrong code with delegates, recursion Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Keywords: CTFE, wrong-code Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: nilsbossung@googlemail.com --- Comment #0 from Nils <nilsbossung@googlemail.com> 2013-02-19 16:49:00 PST --- CTFE: wrong code with delegates, recursion Probably two symptoms of the same cause: A) infinite loop --- cat > test_a.d <<code void main() { assert(go() == 1); // passes enum e = go(); // infinite loop } int go() { int result; S().into((s) {result = s;}); return result; } struct S { void into(void delegate(int) sink) { put(sink, R(true)); } } struct R { bool set; void into(void delegate(int) sink) { if(set) put(sink, R(false)); else sink(1); } } // a lengthy way to write r.into(sink) void put(void delegate(int) sink, R r) { r.into((s) {sink(s);}); } code dmd test_a.d --- test_a.d(24): Error: delegate test_a.put.__lambda4!(int).__lambda4 CTFE recursion limit exceeded test_a.d(24): called from here: sink(s) test_a.d(24): 994 recursive calls to function __lambda4 test_a.d(19): called from here: sink(1) test_a.d(24): called from here: r.into(delegate void(int s) { sink(s); } ) test_a.d(18): called from here: put(sink, R(false)) test_a.d(24): called from here: r.into(delegate void(int s) { sink(s); } ) test_a.d(12): called from here: put(sink, R(true)) test_a.d(7): called from here: S().into(delegate void(int s) { result = s; } ) test_a.d(3): called from here: go() --- B) variable of enclosing scope doesn't get set --- cat > test_b.d <<code void main() { assert(go() == 1); // passes enum e = go(); } int go() { int result; R(true).into((s) {result = s;}); return result; } struct R { bool set; void into(void delegate(int) sink) { int result = -1; if(set) { R(false).into((s) { result = s; assert(result == 1); // passes }); assert(result == 1); // fails in CTFE sink(result); } else sink(1); } } code dmd test_b.d --- test_b.d(19): Error: assert(result == 1) failed test_b.d(7): called from here: R(true).into(delegate void(int s) { result = s; } ) test_b.d(3): called from here: go() --- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 21, 2013 [Issue 9541] CTFE: wrong code with delegates, recursion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=9541 --- Comment #1 from Nils <nilsbossung@googlemail.com> 2013-02-20 16:03:31 PST --- Yup, they both boil down to this: --- cat > test.d <<code enum e = (){ into(null, 42); return true; }(); void into(void delegate() sink, int set) { if(set == 42) into(() {assert(set != 13);}, 13); else sink(); } code dmd -c test.d --- test.d(6): Error: assert(set != 13) failed --- (output truncated) Apparently, the delegate sees the wrong variables. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
February 27, 2013 [Issue 9541] CTFE: wrong code with delegates, recursion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=9541 --- Comment #2 from Don <clugdbug@yahoo.com.au> 2013-02-27 00:45:20 PST --- A slight reduction, which removes the delegate literal with a nested function. ================== bool into(void delegate() sink, int set) { void xxx() { assert(set != 13); } if(set == 42) into(&xxx, 13); else sink(); return true; } static assert(into(null, 42)); ================== This may be quite difficult to fix, since it has exposed a design flaw in the current CTFE implementation. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation