D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3187 - Nested foreach over opApply doesn't work
Summary: Nested foreach over opApply doesn't work
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: diagnostic, patch, rejects-valid
: 2192 (view as issue list)
Depends on:
Blocks:
 
Reported: 2009-07-17 06:05 UTC by John Chapman
Modified: 2014-02-15 13:12 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description John Chapman 2009-07-17 06:05:12 UTC
Calling nested foreach statements on types that implement opApply causes an error. There appears to be a bug in the code generated by the compiler.

class Collection {
  int opApply(int delegate(ref Object) a) {
    return 0;
  }
}

Object testForeach(Collection level1, Collection level2) {
  foreach (first; level1) {
    foreach (second; level2)
      return second;
  }
  return null;
}

void main() {
  testForeach(new Collection, new Collection);
}

Error: cannot implicitly convert expression (second) of type object.Object to int

This is the code DMD generates for the testForeach method, with the problem line highlighted:

Object testForeach(Collection level1, Collection level2) {
   switch(level1.opApply(delegate (Object __applyArg0) {
     {
       Object first = __applyArg0;
       switch(level2.opApply(delegate (Object __applyArg0) {
         {
           Object second = __applyArg0;
           {
// ********* HERE'S THE PROBLEM *********
             __result = cast(Object) cast(int) second;
             return 2;
           }
         }
         return 0;
       } )) {
         default:
         break;
         case 2:
           __result = __result;
           return 2;
       }
     }
     return 0;
   } )) {
     default:
     break;
     case 2:
       return __result;
   }
   return cast(Object) null;
}

This problem occurs with both DMD 1.x and 2.x compilers.
Comment 1 Don 2010-08-06 00:05:14 UTC
I'm changing this from wrong-code to ICE, since it never reaches code generation.
Comment 2 Don 2011-02-15 18:56:15 UTC
(In reply to comment #1)
> I'm changing this from wrong-code to ICE, since it never reaches code
> generation.

Actually although the compiler fouls this up badly, it isn't an ICE. It's a rejects-valid with a really bad diagnostic.
Comment 5 yebblies 2012-02-03 05:25:24 UTC
*** Issue 2192 has been marked as a duplicate of this issue. ***