Bug 3294 – forward reference to inferred return type of function call

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-09-03T13:26:00Z
Last change time
2015-06-09T01:28:06Z
Keywords
patch, rejects-valid
Assigned to
nobody
Creator
2korden
Blocks
4387, 4388, 4403, 4404, 4411

Comments

Comment #0 by 2korden — 2009-09-03T13:26:54Z
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)
Comment #1 by r.sagitario — 2010-05-11T13:23:29Z
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) {
Comment #2 by dsimcha — 2010-08-10T20:57:34Z
Fixed 2.048
Comment #3 by bugzilla — 2010-08-10T21:19:36Z
Although the test case works now, the bug isn't fixed properly. I need to undo my fix and use Rainer's.
Comment #4 by bugzilla — 2010-08-11T23:11:06Z