Skip to content

Loading…

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

Merged
merged 2 commits into from

5 participants

@9rnsr
D Programming Language member

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-sociomantic

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

@MartinNowak
D Programming Language member

Why is the second commit in here?

@MartinNowak
D Programming Language member

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

@MartinNowak MartinNowak merged commit 6344a72 into D-Programming-Language:master

1 check passed

Details default Pass: 10
@WalterBright
D Programming Language member

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;
}

@WalterBright
D Programming Language member

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

@yebblies
D Programming Language member

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

@don-clugston-sociomantic

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.

@9rnsr
D Programming Language member
@WalterBright
D Programming Language member

Thanks, Kenji.

@WalterBright
D Programming Language member

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

@9rnsr
D Programming Language member

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.

@ghost Unknown referenced this pull request
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request
Commit has since been removed from the repository and is no longer available.
@mihails-strasuns-sociomantic mihails-strasuns-sociomantic added a commit to mihails-strasuns-sociomantic/dmd that referenced this pull request
@mihails-strasuns-sociomantic mihails-strasuns-sociomantic Backport semantic order fix for delegates
Issue uncovered by recent mangling fixes. Full D2 PR this change
originates from is D-Programming-Language#1096
but most stuff there is for pure/@safe and thus not applicable to
D2.
73903a4
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.
Showing with 56 additions and 6 deletions.
  1. +1 −0 src/delegatize.c
  2. +15 −3 src/func.c
  3. +8 −2 src/mtype.c
  4. +1 −0 src/mtype.h
  5. +30 −0 test/compilable/testInference.d
  6. +1 −1 test/runnable/funclit.d
View
1 src/delegatize.c
@@ -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);
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);
Something went wrong with that request. Please try again.