Bug 2192 – Returning from inside foreach body delegate only returns from inner delegate

Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2008-07-04T01:42:00Z
Last change time
2015-06-09T05:12:01Z
Keywords
rejects-valid, wrong-code
Assigned to
nobody
Creator
bus_dbugzilla

Comments

Comment #0 by bus_dbugzilla — 2008-07-04T01:42:09Z
The following code generates a rather curious compiler error: BEGIN CODE class Foo { } Foo[char][char] jaggedArray; Foo Bar() { foreach(Foo[char] array; jaggedArray) { foreach(Foo f; array) { return null; // Error } } } END CODE Compiler output from both DMD 1.029 and DMD 1.031: testb1.d(10): Error: cannot implicitly convert expression (null) of type void* to int testb1.d(10): Error: cannot implicitly convert expression (cast(int)null) of type int to testb1.Foo Changes that DO NOT eliminate the error: - Changing "jaggedArray" to "Foo[char[]][char[]]" - Adding "return null;" to the end of the function - Changing "return null;" to "return f;" That last change (returning "f" instead of "null") generates the following error: testb1.d(10): Error: cannot implicitly convert expression (f) of type testb1.Foo to int testb1.d(10): Error: cannot implicitly convert expression (cast(int)f) of type int to testb1.Foo So, that means: The function Bar() is declared to return a Foo, and it tries to return a Foo. But the compiler tries to turn the Foo into an int...and then back into a Foo again. Changes that DO cause the code to compile: - Changing "jaggedArray" to any of the following: "Foo[][char]" "Foo[char][]" "int[char][char]" - Eliminating the inner foreach - Eliminating the outer foreach and iterating over "jaggedAray['a']" The following change also causes the code to compile: class Foo { int var; } Foo[char][char] jaggedArray; Foo Bar() { foreach(Foo[char] array; jaggedArray) { foreach(Foo f; array) { f.var = 5; } } return null; }
Comment #1 by bus_dbugzilla — 2008-07-04T02:22:30Z
Changing the function's return type to something else, like 'bool' also eliminates the problem. Making the return statement conditional (ex "if(f.var == 1) return null;") does NOT solve to problem. If you need to return f, the following workaround does work (although it will result in extra unnecessary iterations): Foo Bar() { Foo ret = null; foreach(Foo[char] array; jaggedArray) { foreach(Foo f; array) { if( /* whatever you need */ ) { if(ret == null) ret = f; break; } } } return ret; }
Comment #2 by bus_dbugzilla — 2008-07-04T02:25:22Z
Erm...that should be "is null" in the workaround, not "== null". Must be tired...
Comment #3 by kovrov+puremagic — 2009-07-09T07:55:32Z
Same error is issued on returning from nested foreach over opApply/delegates.
Comment #4 by yebblies — 2012-02-03T03:23:44Z
This is an issue with opApply foreach iteration, and is working as designed (however unexpected).
Comment #5 by k.hara.pg — 2012-02-03T04:48:55Z
I think the original issue titled "Returning element in an AA of AAs during nested foreach generates compiler error" is a dup of bug 3187, and today it works as expected. So, I can't understand why yebblies changed the title and switched the importance to an enhancement.
Comment #6 by yebblies — 2012-02-03T05:25:24Z
(In reply to comment #5) > I think the original issue titled "Returning element in an AA of AAs during > nested foreach generates compiler error" is a dup of bug 3187, and today it > works as expected. > > So, I can't understand why yebblies changed the title and switched the > importance to an enhancement. I had no idea that it worked, or that it had been fixed! My compiler's broken for the moment, so I can't test it, but I'll take your comment to mean this works and close it as a duplicate. *** This issue has been marked as a duplicate of issue 3187 ***