module Test; struct SomeInfiniteRange { int front() { return 42; } enum empty = false; void popFront() {} } struct SomeContainer(T) { auto opSlice() { return SomeInfiniteRange(); } } class Test { void test() { foreach (int f; _foo[]) { // do nothing } } private SomeContainer!(int) _foo; } Test.d(23): Error: forward reference to inferred return type of function call this._foo.opSlice() Test.d(23): Error: foreach: int is not an aggregate type Note that the code compiles just fine if SomeContainer is a concrete struct (not a template)
This one is a similar to #2810, i.e. the type inferring of the function is missing. The patch is a bit more complicated, though, because the function declaration is not available were it is needed, so it has to be added as an argument to functionParameters(): Index: expression.c =================================================================== --- expression.c (revision 483) +++ expression.c (working copy) @@ -642,7 +642,7 @@ */ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, - Expressions *arguments) + Expressions *arguments, FuncDeclaration* fd) { //printf("functionParameters()\n"); assert(arguments); @@ -931,6 +931,11 @@ arguments->dim - nparams); arguments->insert(0, e); } + + // if inferring return type, semantic3 needs to be run + if(!tf->next && fd->inferRetType) + fd->semantic3(fd->scope); + Type *tret = tf->next; if (wildmatch) { /* Adjust function return type based on wildmatch @@ -3972,7 +3977,7 @@ if (!arguments) arguments = new Expressions(); - functionParameters(loc, sc, tf, arguments); + functionParameters(loc, sc, tf, arguments, f); type = type->addMod(tf->nextOf()->mod); } @@ -3997,7 +4002,7 @@ assert(allocator); tf = (TypeFunction *)f->type; - functionParameters(loc, sc, tf, newargs); + functionParameters(loc, sc, tf, newargs, f); } else { @@ -4029,7 +4034,7 @@ if (!arguments) arguments = new Expressions(); - functionParameters(loc, sc, tf, arguments); + functionParameters(loc, sc, tf, arguments, f); } else { @@ -4053,7 +4058,7 @@ assert(allocator); tf = (TypeFunction *)f->type; - functionParameters(loc, sc, tf, newargs); + functionParameters(loc, sc, tf, newargs, f); #if 0 e = new VarExp(loc, f); e = new CallExp(loc, e, newargs); @@ -7254,7 +7259,7 @@ if (!arguments) arguments = new Expressions(); - type = functionParameters(loc, sc, tf, arguments); + type = functionParameters(loc, sc, tf, arguments, f); if (!type) {
Fixed 2.048
Although the test case works now, the bug isn't fixed properly. I need to undo my fix and use Rainer's.
http://www.dsource.org/projects/dmd/changeset/616