Issue 3294 - forward reference to inferred return type of function call
Summary: forward reference to inferred return type of function call
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: patch, rejects-valid
Depends on:
Blocks: 4387 4388 4403 4404 4411
  Show dependency treegraph
 
Reported: 2009-09-03 13:26 UTC by Koroskin Denis
Modified: 2015-06-09 01:28 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 Koroskin Denis 2009-09-03 13:26:54 UTC
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 Rainer Schuetze 2010-05-11 13:23:29 UTC
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 David Simcha 2010-08-10 20:57:34 UTC
Fixed 2.048
Comment 3 Walter Bright 2010-08-10 21:19:36 UTC
Although the test case works now, the bug isn't fixed properly. I need to undo my fix and use Rainer's.
Comment 4 Walter Bright 2010-08-11 23:11:06 UTC
http://www.dsource.org/projects/dmd/changeset/616