Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix Issue 8504 - Template attribute inferrence doesn't work

  • Loading branch information...
commit f9d53eb403cbe29310cc501ad099acddb71cac75 1 parent 71604e8
@9rnsr 9rnsr authored
View
18 src/func.c
@@ -1197,7 +1197,7 @@ void FuncDeclaration::semantic3(Scope *sc)
{ // If no return type inferred yet, then infer a void
if (!type->nextOf())
{
- ((TypeFunction *)type)->next = Type::tvoid;
+ f->next = Type::tvoid;
//type = type->semantic(loc, sc); // Removed with 6902
}
else if (returns && f->next->ty != Tvoid)
@@ -1338,7 +1338,10 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->isnothrow && (global.errors != nothrowErrors) )
error("'%s' is nothrow yet may throw", toChars());
if (flags & FUNCFLAGnothrowInprocess)
+ {
+ if (type == f) f = f->copy();
f->isnothrow = !(blockexit & BEthrow);
+ }
int offend = blockexit & BEfallthru;
#endif
@@ -1683,19 +1686,28 @@ void FuncDeclaration::semantic3(Scope *sc)
if (flags & FUNCFLAGpurityInprocess)
{
flags &= ~FUNCFLAGpurityInprocess;
+ if (type == f) f = f->copy();
f->purity = PUREfwdref;
}
if (flags & FUNCFLAGsafetyInprocess)
{
flags &= ~FUNCFLAGsafetyInprocess;
+ if (type == f) f = f->copy();
f->trust = TRUSTsafe;
}
+ // reset deco to apply inference result to mangled name
+ if (f != type)
+ f->deco = NULL;
+
// Do semantic type AFTER pure/nothrow inference.
- if (inferRetType)
+ if (!f->deco)
{
- type = type->semantic(loc, sc);
+ sc = sc->push();
+ sc->linkage = linkage; // Bugzilla 8496
+ type = f->semantic(loc, sc);
+ sc = sc->pop();
}
if (global.gag && global.errors != nerrors)
View
10 src/mtype.c
@@ -5103,6 +5103,13 @@ const char *TypeFunction::kind()
return "function";
}
+TypeFunction *TypeFunction::copy()
+{
+ TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
+ memcpy(tf, this, sizeof(TypeFunction));
+ return tf;
+}
+
Type *TypeFunction::syntaxCopy()
{
Type *treturn = next ? next->syntaxCopy() : NULL;
@@ -5538,8 +5545,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
* This can produce redundant copies if inferring return type,
* as semantic() will get called again on this.
*/
- TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
- memcpy(tf, this, sizeof(TypeFunction));
+ TypeFunction *tf = copy();
if (parameters)
{ tf->parameters = (Parameters *)parameters->copy();
for (size_t i = 0; i < parameters->dim; i++)
View
1  src/mtype.h
@@ -652,6 +652,7 @@ struct TypeFunction : TypeNext
TypeFunction(Parameters *parameters, Type *treturn, int varargs, enum LINK linkage, StorageClass stc = 0);
const char *kind();
+ TypeFunction *copy();
Type *syntaxCopy();
Type *semantic(Loc loc, Scope *sc);
void purityLevel();
View
30 test/compilable/testInference.d
@@ -160,6 +160,36 @@ pure string escapeShellArguments()
}
/***************************************************/
+// 8504
+
+void foo8504()()
+{
+ static assert(typeof(foo8504!()).stringof == "void()");
+ static assert(typeof(foo8504!()).mangleof == "FZv");
+ static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FZv");
+}
+
+auto toDelegate8504a(F)(auto ref F fp) { return fp; }
+ F toDelegate8504b(F)(auto ref F fp) { return fp; }
+
+extern(C) void testC8504() {}
+
+void test8504()
+{
+ static assert(typeof(foo8504!()).stringof == "pure nothrow @safe void()");
+ static assert(typeof(foo8504!()).mangleof == "FNaNbNfZv");
+ static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FNaNbNfZv");
+
+ auto fp1 = toDelegate8504a(&testC8504);
+ auto fp2 = toDelegate8504b(&testC8504);
+ static assert(is(typeof(fp1) == typeof(fp2)));
+ static assert(typeof(fp1).stringof == "extern (C) void function()");
+ static assert(typeof(fp2).stringof == "extern (C) void function()");
+ static assert(typeof(fp1).mangleof == "PUZv");
+ static assert(typeof(fp2).mangleof == "PUZv");
+}
+
+/***************************************************/
// 8751
alias bool delegate(in int) pure Bar8751;
View
2  test/runnable/funclit.d
@@ -586,7 +586,7 @@ void test8198()
return f => x => f(n(f)(x));
}
- auto n = &zero!uint;
+ uint delegate(uint) delegate(uint delegate(uint)) n = &zero!uint;
foreach (i; 0..10)
{
assert(n(x => x + 1)(0) == i);
Please sign in to comment.
Something went wrong with that request. Please try again.