digitalmars.D.bugs - [Issue 9541] New: CTFE: wrong code with delegates, recursion
- d-bugmail puremagic.com (111/111) Feb 19 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9541
- d-bugmail puremagic.com (23/23) Feb 20 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9541
- d-bugmail puremagic.com (21/21) Feb 27 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9541
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 --- 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: -------
Feb 19 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9541 --- 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: -------
Feb 20 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9541 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: -------
Feb 27 2013