Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Merged
merged 2 commits into from

4 participants

@9rnsr
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

@9rnsr
Collaborator

Added fix for bug 7159.

@Trass3r

fails the tests.

@9rnsr 9rnsr closed this
@9rnsr 9rnsr reopened this
@9rnsr
Collaborator

Updated with more better way.

@andralex
Owner

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

@braddr braddr referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@WalterBright WalterBright merged commit 2ba68e1 into D-Programming-Language:master
@WalterBright

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

@9rnsr
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.

@9rnsr 9rnsr referenced this pull request from a commit in 9rnsr/dmd
@9rnsr 9rnsr Revert "Merge pull request #535 from 9rnsr/fix5933" to fix auto-teste…
…r breaking

This reverts commit 2ba68e1, reversing
changes made to e3daa5e.
fd4a975
@9rnsr
Collaborator

I opened reversion pull request: #1304

@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@AlexeyProkhin AlexeyProkhin referenced this pull request from a commit
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.
View
1  src/declaration.h
@@ -632,6 +632,7 @@ struct FuncDeclaration : Declaration
void semantic(Scope *sc);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
+ bool functionSemantic(Scope *sc);
// called from semantic3
void varArgs(Scope *sc, TypeFunction*, VarDeclaration *&, VarDeclaration *&);
VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad);
View
73 src/expression.c
@@ -2994,45 +2994,10 @@ Expression *DsymbolExp::semantic(Scope *sc)
}
f = s->isFuncDeclaration();
if (f)
- { f = f->toAliasFunc();
-
- if (!f->originalType && f->scope) // semantic not yet run
- {
- unsigned oldgag = global.gag;
- if (global.isSpeculativeGagging() && !f->isSpeculative())
- global.gag = 0;
- f->semantic(f->scope);
- global.gag = oldgag;
- }
-
- // if inferring return type, sematic3 needs to be run
- if (f->scope && (f->inferRetType && f->type && !f->type->nextOf() ||
- getFuncTemplateDecl(f)))
- {
- TemplateInstance *spec = f->isSpeculative();
- int olderrs = global.errors;
- // If it isn't speculative, we need to show errors
- unsigned oldgag = global.gag;
- if (global.gag && !spec)
- global.gag = 0;
- f->semantic3(f->scope);
- global.gag = oldgag;
- // Update the template instantiation with the number
- // of errors which occured.
- if (spec && global.errors != olderrs)
- spec->errors = global.errors - olderrs;
- }
-
- if (f->isUnitTestDeclaration())
- {
- error("cannot call unittest function %s", toChars());
- return new ErrorExp();
- }
- if (!f->type->deco)
- {
- error("forward reference to %s", toChars());
+ {
+ f = f->toAliasFunc();
+ if (!f->functionSemantic(sc))
return new ErrorExp();
- }
FuncDeclaration *fd = s->isFuncDeclaration();
fd->type = f->type;
return new VarExp(loc, fd, hasOverloads);
@@ -5025,8 +4990,12 @@ Expression *VarExp::semantic(Scope *sc)
#if LOGSEMANTIC
printf("VarExp::semantic(%s)\n", toChars());
#endif
-// if (var->sem == SemanticStart && var->scope) // if forward referenced
-// var->semantic(sc);
+ if (FuncDeclaration *f = var->isFuncDeclaration())
+ {
+ if (!f->functionSemantic(sc))
+ return new ErrorExp();
+ }
+
if (!type)
{ type = var->type;
#if 0
@@ -7121,16 +7090,26 @@ Expression *DotVarExp::semantic(Scope *sc)
e1 = e1->semantic(sc);
e1 = e1->addDtorHook(sc);
- type = var->type;
- if (!type && global.errors)
- { // var is goofed up, just return 0
- return new ErrorExp();
- }
- assert(type);
Type *t1 = e1->type;
- if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution
+ FuncDeclaration *f = var->isFuncDeclaration();
+ if (f) // for functions, do checks after overload resolution
{
+ if (!f->functionSemantic(sc))
+ return new ErrorExp();
+
+ type = f->type;
+ assert(type);
+ }
+ else
+ {
+ type = var->type;
+ if (!type && global.errors)
+ { // var is goofed up, just return 0
+ goto Lerr;
+ }
+ assert(type);
+
if (t1->ty == Tpointer)
t1 = t1->nextOf();
View
43 src/func.c
@@ -1681,6 +1681,49 @@ void FuncDeclaration::semantic3(Scope *sc)
//fflush(stdout);
}
+bool FuncDeclaration::functionSemantic(Scope *sc)
+{
+ if (!originalType && scope) // semantic not yet run
+ {
+ unsigned oldgag = global.gag;
+ if (global.isSpeculativeGagging() && !isSpeculative())
+ global.gag = 0;
+ semantic(scope);
+ global.gag = oldgag;
+ }
+
+ // if inferring return type, sematic3 needs to be run
+ if (scope && (inferRetType && type && !type->nextOf() ||
+ getFuncTemplateDecl(this)))
+ {
+ TemplateInstance *spec = isSpeculative();
+ int olderrs = global.errors;
+ // If it isn't speculative, we need to show errors
+ unsigned oldgag = global.gag;
+ if (global.gag && !spec)
+ global.gag = 0;
+ semantic3(scope);
+ global.gag = oldgag;
+ // Update the template instantiation with the number
+ // of errors which occured.
+ if (spec && global.errors != olderrs)
+ spec->errors = global.errors - olderrs;
+ }
+
+ if (isUnitTestDeclaration())
+ {
+ error("cannot call unittest function %s", toChars());
+ return false;
+ }
+ if (!type->deco)
+ {
+ error("forward reference to %s", toChars());
+ return false;
+ }
+
+ return true;
+}
+
void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
//printf("FuncDeclaration::toCBuffer() '%s'\n", toChars());
View
43 test/runnable/xtest46.d
@@ -4219,6 +4219,37 @@ void test5696()
}
/***************************************************/
+// 5933
+
+int dummyfunc();
+alias typeof(dummyfunc) FuncType;
+
+struct S5933a { auto x() { return 0; } }
+static assert(is(typeof(&S5933a.init.x) == int delegate()));
+
+struct S5933b { auto x() { return 0; } }
+static assert(is(typeof(S5933b.init.x) == FuncType));
+
+struct S5933c { auto x() { return 0; } }
+static assert(is(typeof(&S5933c.x) == int function()));
+
+struct S5933d { auto x() { return 0; } }
+static assert(is(typeof(S5933d.x) == FuncType));
+
+
+class C5933a { auto x() { return 0; } }
+static assert(is(typeof(&(new C5933b()).x) == int delegate()));
+
+class C5933b { auto x() { return 0; } }
+static assert(is(typeof((new C5933b()).x) == FuncType));
+
+class C5933c { auto x() { return 0; } }
+static assert(is(typeof(&C5933c.x) == int function()));
+
+class C5933d { auto x() { return 0; } }
+static assert(is(typeof(C5933d.x) == FuncType));
+
+/***************************************************/
// 6084
template TypeTuple6084(T...){ alias T TypeTuple6084; }
@@ -4831,6 +4862,18 @@ void test7150()
}
/***************************************************/
+// 7159
+
+class HomeController7159 {
+ void* foo() {
+ return cast(void*)&HomeController7159.displayDefault;
+ }
+ auto displayDefault() {
+ return 1;
+ }
+}
+
+/***************************************************/
// 7160
class HomeController {
Something went wrong with that request. Please try again.