Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Issue 5933 & 7159 - Resolve forward reference to auto-return member function #535

Merged
merged 2 commits into from over 1 year ago

4 participants

Hara Kenji Trass3r Andrei Alexandrescu Walter Bright
Hara Kenji
Collaborator

Issue 5933 - Cannot retrieve the return type of an auto-return member function

Bug 5933 is synonym of bug 2810, and the fixing way is also almost same.

Issue 7159 - Forward reference when casting auto return method

Hara Kenji
Collaborator

Added fix for bug 7159.

Trass3r

fails the tests.

Hara Kenji 9rnsr closed this February 28, 2012
Hara Kenji 9rnsr reopened this February 28, 2012
Hara Kenji
Collaborator

Updated with more better way.

Andrei Alexandrescu
Owner

LGTM - please let's merge this baby. Thanks!

Brad Roberts braddr referenced this pull request from a commit October 21, 2012
Commit has since been removed from the repository and is no longer available.
Walter Bright WalterBright merged commit 2ba68e1 into from November 19, 2012
Walter Bright WalterBright closed this November 19, 2012
Walter Bright

Does not compile test suite:

Testing generated/linux/debug/32/unittest/std/numeric
std/numeric.d(398): Error: template instance opUnary!("+") opUnary!("+") does not match template dec
laration opUnary(string op)() if (__traits(compiles,mixin(op ~ "(get!real)")) || op == "++" || op ==
"--")
std/numeric.d(398): Error: function expected before (), not max().opUnary!("+") of type void
std/numeric.d(404): Error: template instance opUnary!("+") opUnary!("+") does not match template dec
laration opUnary(string op)() if (__traits(compiles,mixin(op ~ "(get!real)")) || op == "++" || op ==
"--")
std/numeric.d(404): Error: function expected before (), not min_normal().opUnary!("+") of type void
std/numeric.d(487): Error: undefined identifier 'sign', did you mean 'template sgn(F)(F x)'?
std/numeric.d(489): Error: CommonType!(int, __error) is used as a type
std/numeric.d(490): Error: CommonType!(uint, __error) is used as a type
std/numeric.d(492): Error: template std.numeric.CustomFloat!(5u, 10u, cast(CustomFloatFlags)31, 511)
.CustomFloat.toNormalized does not match any function template declaration. Candidates are:
std/numeric.d(218): std.numeric.CustomFloat!(5u, 10u, cast(CustomFloatFlags)31, 511).CustomFl
oat.toNormalized(T, U)(ref T sig, ref U exp)
std/numeric.d(492): Error: template std.numeric.CustomFloat!(5u, 10u, cast(CustomFloatFlags)31, 511)
.CustomFloat.toNormalized(T, U)(ref T sig, ref U exp) cannot deduce template function from argument
types !()(error,error)
std/numeric.d(496): Error: result.get.T_exp is used as a type
std/numeric.d(496): Error: undefined identifier 'exponent'
std/numeric.d(497): Error: result.get.T_sig is used as a type
std/numeric.d(497): Error: undefined identifier 'significand'
std/numeric.d(537): Error: template instance std.numeric.CustomFloat!(5u, 10u, cast(CustomFloatFlags
)31, 511).CustomFloat.get!(real) error instantiating
std/numeric.d(153): instantiated from here: CustomFloat!(5u, 10u, cast(CustomFloatFlags)31, 5
11)
std/numeric.d(543): instantiated from here: CustomFloat!(5, 10)
std/numeric.d(543): Error: template instance std.numeric.CustomFloat!(5, 10) error instantiating
std/numeric.d(398): Error: template instance opUnary!("+") opUnary!("+") does not match template dec
laration opUnary(string op)() if (__traits(compiles,mixin(op ~ "(get!real)")) || op == "++" || op ==
"--")
std/numeric.d(398): Error: function expected before (), not max().opUnary!("+") of type void
std/numeric.d(404): Error: template instance opUnary!("+") opUnary!("+") does not match template dec
laration opUnary(string op)() if (__traits(compiles,mixin(op ~ "(get!real)")) || op == "++" || op ==
"--")
std/numeric.d(404): Error: function expected before (), not min_normal().opUnary!("+") of type void
std/numeric.d(488): Error: undefined identifier 'sign', did you mean 'template sgn(F)(F x)'?
std/numeric.d(489): Error: CommonType!(int, __error) is used as a type
make[2]: *** [generated/linux/debug/32/unittest/std/numeric] Error 1
make[1]: *** [unittest] Error 2

Hara Kenji
Collaborator

I'm sorry for keeping broken pull open. But, it has recently appeared by interacting other fixes.
I'm searching root problem, but it is impossible immediately.
We should simply revert this to fix auto-tester breaking.

P.S. @WalterBright, if you want to merge a pull request, please look its lastest auto-tester result before merging. If it is red, you might break trunk head with high probability.

Hara Kenji 9rnsr referenced this pull request from a commit in 9rnsr/dmd November 20, 2012
Revert "Merge pull request #535 from 9rnsr/fix5933" to fix auto-teste…
…r breaking

This reverts commit 2ba68e1, reversing
changes made to e3daa5e.
fd4a975
Hara Kenji
Collaborator

I opened reversion pull request: #1304

Hara Kenji 9rnsr referenced this pull request in D-Programming-Language/phobos January 23, 2013
Merged

Add workaround for bug 9382, which introduced by fixing bug 5933 #1096

Deleted user Unknown referenced this pull request from a commit December 24, 2013
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown referenced this pull request from a commit December 25, 2013
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown referenced this pull request from a commit December 25, 2013
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown referenced this pull request from a commit December 25, 2013
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
1  src/declaration.h
@@ -632,6 +632,7 @@ struct FuncDeclaration : Declaration
632 632
     void semantic(Scope *sc);
633 633
     void semantic2(Scope *sc);
634 634
     void semantic3(Scope *sc);
  635
+    bool functionSemantic(Scope *sc);
635 636
     // called from semantic3
636 637
     void varArgs(Scope *sc, TypeFunction*, VarDeclaration *&, VarDeclaration *&);
637 638
     VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad);
73  src/expression.c
@@ -2994,45 +2994,10 @@ Expression *DsymbolExp::semantic(Scope *sc)
2994 2994
     }
2995 2995
     f = s->isFuncDeclaration();
2996 2996
     if (f)
2997  
-    {   f = f->toAliasFunc();
2998  
-
2999  
-        if (!f->originalType && f->scope)       // semantic not yet run
3000  
-        {
3001  
-            unsigned oldgag = global.gag;
3002  
-            if (global.isSpeculativeGagging() && !f->isSpeculative())
3003  
-                global.gag = 0;
3004  
-            f->semantic(f->scope);
3005  
-            global.gag = oldgag;
3006  
-        }
3007  
-
3008  
-        // if inferring return type, sematic3 needs to be run
3009  
-        if (f->scope && (f->inferRetType && f->type && !f->type->nextOf() ||
3010  
-                         getFuncTemplateDecl(f)))
3011  
-        {
3012  
-            TemplateInstance *spec = f->isSpeculative();
3013  
-            int olderrs = global.errors;
3014  
-            // If it isn't speculative, we need to show errors
3015  
-            unsigned oldgag = global.gag;
3016  
-            if (global.gag && !spec)
3017  
-                global.gag = 0;
3018  
-            f->semantic3(f->scope);
3019  
-            global.gag = oldgag;
3020  
-            // Update the template instantiation with the number
3021  
-            // of errors which occured.
3022  
-            if (spec && global.errors != olderrs)
3023  
-                spec->errors = global.errors - olderrs;
3024  
-        }
3025  
-
3026  
-        if (f->isUnitTestDeclaration())
3027  
-        {
3028  
-            error("cannot call unittest function %s", toChars());
3029  
-            return new ErrorExp();
3030  
-        }
3031  
-        if (!f->type->deco)
3032  
-        {
3033  
-            error("forward reference to %s", toChars());
  2997
+    {
  2998
+        f = f->toAliasFunc();
  2999
+        if (!f->functionSemantic(sc))
3034 3000
             return new ErrorExp();
3035  
-        }
3036 3001
         FuncDeclaration *fd = s->isFuncDeclaration();
3037 3002
         fd->type = f->type;
3038 3003
         return new VarExp(loc, fd, hasOverloads);
@@ -5025,8 +4990,12 @@ Expression *VarExp::semantic(Scope *sc)
5025 4990
 #if LOGSEMANTIC
5026 4991
     printf("VarExp::semantic(%s)\n", toChars());
5027 4992
 #endif
5028  
-//    if (var->sem == SemanticStart && var->scope)      // if forward referenced
5029  
-//      var->semantic(sc);
  4993
+    if (FuncDeclaration *f = var->isFuncDeclaration())
  4994
+    {
  4995
+        if (!f->functionSemantic(sc))
  4996
+            return new ErrorExp();
  4997
+    }
  4998
+
5030 4999
     if (!type)
5031 5000
     {   type = var->type;
5032 5001
 #if 0
@@ -7121,16 +7090,26 @@ Expression *DotVarExp::semantic(Scope *sc)
7121 7090
 
7122 7091
         e1 = e1->semantic(sc);
7123 7092
         e1 = e1->addDtorHook(sc);
7124  
-        type = var->type;
7125  
-        if (!type && global.errors)
7126  
-        {   // var is goofed up, just return 0
7127  
-            return new ErrorExp();
7128  
-        }
7129  
-        assert(type);
7130 7093
 
7131 7094
         Type *t1 = e1->type;
7132  
-        if (!var->isFuncDeclaration())  // for functions, do checks after overload resolution
  7095
+        FuncDeclaration *f = var->isFuncDeclaration();
  7096
+        if (f)  // for functions, do checks after overload resolution
7133 7097
         {
  7098
+            if (!f->functionSemantic(sc))
  7099
+                return new ErrorExp();
  7100
+
  7101
+            type = f->type;
  7102
+            assert(type);
  7103
+        }
  7104
+        else
  7105
+        {
  7106
+            type = var->type;
  7107
+            if (!type && global.errors)
  7108
+            {   // var is goofed up, just return 0
  7109
+                goto Lerr;
  7110
+            }
  7111
+            assert(type);
  7112
+
7134 7113
             if (t1->ty == Tpointer)
7135 7114
                 t1 = t1->nextOf();
7136 7115
 
43  src/func.c
@@ -1681,6 +1681,49 @@ void FuncDeclaration::semantic3(Scope *sc)
1681 1681
     //fflush(stdout);
1682 1682
 }
1683 1683
 
  1684
+bool FuncDeclaration::functionSemantic(Scope *sc)
  1685
+{
  1686
+    if (!originalType && scope)     // semantic not yet run
  1687
+    {
  1688
+        unsigned oldgag = global.gag;
  1689
+        if (global.isSpeculativeGagging() && !isSpeculative())
  1690
+            global.gag = 0;
  1691
+        semantic(scope);
  1692
+        global.gag = oldgag;
  1693
+    }
  1694
+
  1695
+    // if inferring return type, sematic3 needs to be run
  1696
+    if (scope && (inferRetType && type && !type->nextOf() ||
  1697
+                  getFuncTemplateDecl(this)))
  1698
+    {
  1699
+        TemplateInstance *spec = isSpeculative();
  1700
+        int olderrs = global.errors;
  1701
+        // If it isn't speculative, we need to show errors
  1702
+        unsigned oldgag = global.gag;
  1703
+        if (global.gag && !spec)
  1704
+            global.gag = 0;
  1705
+        semantic3(scope);
  1706
+        global.gag = oldgag;
  1707
+        // Update the template instantiation with the number
  1708
+        // of errors which occured.
  1709
+        if (spec && global.errors != olderrs)
  1710
+            spec->errors = global.errors - olderrs;
  1711
+    }
  1712
+
  1713
+    if (isUnitTestDeclaration())
  1714
+    {
  1715
+        error("cannot call unittest function %s", toChars());
  1716
+        return false;
  1717
+    }
  1718
+    if (!type->deco)
  1719
+    {
  1720
+        error("forward reference to %s", toChars());
  1721
+        return false;
  1722
+    }
  1723
+
  1724
+    return true;
  1725
+}
  1726
+
1684 1727
 void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1685 1728
 {
1686 1729
     //printf("FuncDeclaration::toCBuffer() '%s'\n", toChars());
43  test/runnable/xtest46.d
@@ -4219,6 +4219,37 @@ void test5696()
4219 4219
 }
4220 4220
 
4221 4221
 /***************************************************/
  4222
+// 5933
  4223
+
  4224
+int dummyfunc();
  4225
+alias typeof(dummyfunc) FuncType;
  4226
+
  4227
+struct S5933a { auto x() { return 0; } }
  4228
+static assert(is(typeof(&S5933a.init.x) == int delegate()));
  4229
+
  4230
+struct S5933b { auto x() { return 0; } }
  4231
+static assert(is(typeof(S5933b.init.x) == FuncType));
  4232
+
  4233
+struct S5933c { auto x() { return 0; } }
  4234
+static assert(is(typeof(&S5933c.x) == int function()));
  4235
+
  4236
+struct S5933d { auto x() { return 0; } }
  4237
+static assert(is(typeof(S5933d.x) == FuncType));
  4238
+
  4239
+
  4240
+class C5933a { auto x() { return 0; } }
  4241
+static assert(is(typeof(&(new C5933b()).x) == int delegate()));
  4242
+
  4243
+class C5933b { auto x() { return 0; } }
  4244
+static assert(is(typeof((new C5933b()).x) == FuncType));
  4245
+
  4246
+class C5933c { auto x() { return 0; } }
  4247
+static assert(is(typeof(&C5933c.x) == int function()));
  4248
+
  4249
+class C5933d { auto x() { return 0; } }
  4250
+static assert(is(typeof(C5933d.x) == FuncType));
  4251
+
  4252
+/***************************************************/
4222 4253
 // 6084
4223 4254
 
4224 4255
 template TypeTuple6084(T...){ alias T TypeTuple6084; }
@@ -4831,6 +4862,18 @@ void test7150()
4831 4862
 }
4832 4863
 
4833 4864
 /***************************************************/
  4865
+// 7159
  4866
+
  4867
+class HomeController7159 {
  4868
+    void* foo() {
  4869
+        return cast(void*)&HomeController7159.displayDefault;
  4870
+    }
  4871
+    auto displayDefault() {
  4872
+        return 1;
  4873
+    }
  4874
+}
  4875
+
  4876
+/***************************************************/
4834 4877
 // 7160
4835 4878
 
4836 4879
 class HomeController {
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.