Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Issue 8504 - Template attribute inferrence doesn't work #1096

Merged
merged 2 commits into from

5 participants

Hara Kenji Don Clugston Martin Nowak Walter Bright Daniel Murphy
Hara Kenji
Collaborator

http://d.puremagic.com/issues/show_bug.cgi?id=8504

While template function body semantic, function type and its mangled name are not yet reflected the attribute inference. After semantic3 done, its type and mangled name will be fixed to actual ones.

This change is based on #544 (merged).

Don Clugston

LGTM. (BTW, we should really refactor func.semantic3 sometime. It's enormous).

Martin Nowak
Collaborator

Why is the second commit in here?

Martin Nowak
Collaborator

I see, setting the mod flag to MODwild was missing in #836 and thus running semantic on the function type triggers Bugzilla 7757 again.

Martin Nowak MartinNowak merged commit 6344a72 into from
Walter Bright

This pull breaks the following test case:

C:\cbx\mars\test>..\dmd -m32 -c mula mulb -lib
DMD v2.062 DEBUG

C:\cbx\mars\test>..\dmd -m32 multi mula.lib
DMD v2.062 DEBUG
OPTLINK (R) for Win32 Release 8.00.12
Copyright (C) Digital Mars 1989-2010 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
multi.obj(multi)
Error 42: Symbol Undefined _D4mulb8__T3defZ3memFZv

mula.d:

import std.c.stdio;

import mulb;

void abc()
{
printf("mulb.abc()\n");
foo();
bar();
}

mulb.d:

module mulb;

import std.c.stdio;

int j;

int foo()()
{
printf("foo()\n");
static int z = 7;
assert(z != 10);
return ++z;
}

void bar()
{
assert(j == 7);
foo();
printf("bar\n");
}

template def()
{
alias int defint;

static this()
{
    printf("def.static this()\n");
    j = 7;
}

void mem()
{
    printf("def().mem()\n");
}

}

def!().defint x;

multi.d:

import std.c.stdio;

import mula, mulb;

int main()
{
printf("main\n");
abc();
def!().mem();
return 0;
}

Walter Bright

I hate github's random stupid markup that always mucks up my postings.

Daniel Murphy
Collaborator

Might be worth reading this, and it does let you preview your comments if you're posting via the web interface.

Don Clugston

I cannot imagine why anyone would want markup in a discussion about code. As a default, I think it's insane. There doesn't seem to be any way to turn it off, either.

Hara Kenji
Collaborator
Walter Bright

Thanks, Kenji.

Walter Bright

Any hope of getting this fixed soon? Or should it just be reverted?

Hara Kenji
Collaborator

I opened #1543 to fix bug 9377, which requires an additional Phobos change D-Programming-Language/phobos#1096.

The root cause of bug 9377 is essentially same as bug 5933 & 7159, that is "compile should invoke function semantic3 correctly where it is required". So #1543 is also a superseded pull of #535.

Deleted user Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Deleted user Unknown 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.
1  src/delegatize.c
View
@@ -37,6 +37,7 @@ Expression *Expression::toDelegate(Scope *sc, Type *t)
Type *tw = t->semantic(loc, sc);
Type *tc = t->substWildTo(MODconst)->semantic(loc, sc);
TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd);
+ if (tw != tc) tf->mod = MODwild; // hack for bug7757
(tf = (TypeFunction *)tf->semantic(loc, sc))->next = tw; // hack for bug7757
FuncLiteralDeclaration *fld =
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
18 src/func.c
View
@@ -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)
10 src/mtype.c
View
@@ -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++)
1  src/mtype.h
View
@@ -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();
30 test/compilable/testInference.d
View
@@ -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;
2  test/runnable/funclit.d
View
@@ -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);
Something went wrong with that request. Please try again.