Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

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

Merged
merged 2 commits into from about 1 year ago

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 January 22, 2013
Martin Nowak MartinNowak closed this January 22, 2013
Walter Bright
Owner

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
Owner

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
Owner

Thanks, Kenji.

Walter Bright
Owner

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

Showing 2 unique commits by 1 author.

Jan 22, 2013
fix Issue 8504 - Template attribute inferrence doesn't work f9d53eb
Need more hack for bug 7757 406ad56
This page is out of date. Refresh to see the latest.
1  src/delegatize.c
@@ -37,6 +37,7 @@ Expression *Expression::toDelegate(Scope *sc, Type *t)
37 37
     Type *tw = t->semantic(loc, sc);
38 38
     Type *tc = t->substWildTo(MODconst)->semantic(loc, sc);
39 39
     TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd);
  40
+    if (tw != tc) tf->mod = MODwild;                            // hack for bug7757
40 41
     (tf = (TypeFunction *)tf->semantic(loc, sc))->next = tw;    // hack for bug7757
41 42
     FuncLiteralDeclaration *fld =
42 43
         new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
18  src/func.c
@@ -1197,7 +1197,7 @@ void FuncDeclaration::semantic3(Scope *sc)
1197 1197
             {   // If no return type inferred yet, then infer a void
1198 1198
                 if (!type->nextOf())
1199 1199
                 {
1200  
-                    ((TypeFunction *)type)->next = Type::tvoid;
  1200
+                    f->next = Type::tvoid;
1201 1201
                     //type = type->semantic(loc, sc);   // Removed with 6902
1202 1202
                 }
1203 1203
                 else if (returns && f->next->ty != Tvoid)
@@ -1338,7 +1338,10 @@ void FuncDeclaration::semantic3(Scope *sc)
1338 1338
                 if (f->isnothrow && (global.errors != nothrowErrors) )
1339 1339
                     error("'%s' is nothrow yet may throw", toChars());
1340 1340
                 if (flags & FUNCFLAGnothrowInprocess)
  1341
+                {
  1342
+                    if (type == f) f = f->copy();
1341 1343
                     f->isnothrow = !(blockexit & BEthrow);
  1344
+                }
1342 1345
 
1343 1346
                 int offend = blockexit & BEfallthru;
1344 1347
 #endif
@@ -1683,19 +1686,28 @@ void FuncDeclaration::semantic3(Scope *sc)
1683 1686
     if (flags & FUNCFLAGpurityInprocess)
1684 1687
     {
1685 1688
         flags &= ~FUNCFLAGpurityInprocess;
  1689
+        if (type == f) f = f->copy();
1686 1690
         f->purity = PUREfwdref;
1687 1691
     }
1688 1692
 
1689 1693
     if (flags & FUNCFLAGsafetyInprocess)
1690 1694
     {
1691 1695
         flags &= ~FUNCFLAGsafetyInprocess;
  1696
+        if (type == f) f = f->copy();
1692 1697
         f->trust = TRUSTsafe;
1693 1698
     }
1694 1699
 
  1700
+    // reset deco to apply inference result to mangled name
  1701
+    if (f != type)
  1702
+        f->deco = NULL;
  1703
+
1695 1704
     // Do semantic type AFTER pure/nothrow inference.
1696  
-    if (inferRetType)
  1705
+    if (!f->deco)
1697 1706
     {
1698  
-        type = type->semantic(loc, sc);
  1707
+        sc = sc->push();
  1708
+        sc->linkage = linkage;  // Bugzilla 8496
  1709
+        type = f->semantic(loc, sc);
  1710
+        sc = sc->pop();
1699 1711
     }
1700 1712
 
1701 1713
     if (global.gag && global.errors != nerrors)
10  src/mtype.c
@@ -5103,6 +5103,13 @@ const char *TypeFunction::kind()
5103 5103
     return "function";
5104 5104
 }
5105 5105
 
  5106
+TypeFunction *TypeFunction::copy()
  5107
+{
  5108
+    TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
  5109
+    memcpy(tf, this, sizeof(TypeFunction));
  5110
+    return tf;
  5111
+}
  5112
+
5106 5113
 Type *TypeFunction::syntaxCopy()
5107 5114
 {
5108 5115
     Type *treturn = next ? next->syntaxCopy() : NULL;
@@ -5538,8 +5545,7 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
5538 5545
      * This can produce redundant copies if inferring return type,
5539 5546
      * as semantic() will get called again on this.
5540 5547
      */
5541  
-    TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction));
5542  
-    memcpy(tf, this, sizeof(TypeFunction));
  5548
+    TypeFunction *tf = copy();
5543 5549
     if (parameters)
5544 5550
     {   tf->parameters = (Parameters *)parameters->copy();
5545 5551
         for (size_t i = 0; i < parameters->dim; i++)
1  src/mtype.h
@@ -652,6 +652,7 @@ struct TypeFunction : TypeNext
652 652
 
653 653
     TypeFunction(Parameters *parameters, Type *treturn, int varargs, enum LINK linkage, StorageClass stc = 0);
654 654
     const char *kind();
  655
+    TypeFunction *copy();
655 656
     Type *syntaxCopy();
656 657
     Type *semantic(Loc loc, Scope *sc);
657 658
     void purityLevel();
30  test/compilable/testInference.d
@@ -160,6 +160,36 @@ pure string escapeShellArguments()
160 160
 }
161 161
 
162 162
 /***************************************************/
  163
+// 8504
  164
+
  165
+void foo8504()()
  166
+{
  167
+    static assert(typeof(foo8504!()).stringof == "void()");
  168
+    static assert(typeof(foo8504!()).mangleof == "FZv");
  169
+    static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FZv");
  170
+}
  171
+
  172
+auto toDelegate8504a(F)(auto ref F fp) { return fp; }
  173
+   F toDelegate8504b(F)(auto ref F fp) { return fp; }
  174
+
  175
+extern(C) void testC8504() {}
  176
+
  177
+void test8504()
  178
+{
  179
+    static assert(typeof(foo8504!()).stringof == "pure nothrow @safe void()");
  180
+    static assert(typeof(foo8504!()).mangleof == "FNaNbNfZv");
  181
+    static assert(foo8504!().mangleof == "_D13testInference12__T7foo8504Z7foo8504FNaNbNfZv");
  182
+
  183
+    auto fp1 = toDelegate8504a(&testC8504);
  184
+    auto fp2 = toDelegate8504b(&testC8504);
  185
+    static assert(is(typeof(fp1) == typeof(fp2)));
  186
+    static assert(typeof(fp1).stringof == "extern (C) void function()");
  187
+    static assert(typeof(fp2).stringof == "extern (C) void function()");
  188
+    static assert(typeof(fp1).mangleof == "PUZv");
  189
+    static assert(typeof(fp2).mangleof == "PUZv");
  190
+}
  191
+
  192
+/***************************************************/
163 193
 // 8751
164 194
 
165 195
 alias bool delegate(in int) pure Bar8751;
2  test/runnable/funclit.d
@@ -586,7 +586,7 @@ void test8198()
586 586
         return f => x => f(n(f)(x));
587 587
     }
588 588
 
589  
-    auto n = &zero!uint;
  589
+    uint delegate(uint) delegate(uint delegate(uint)) n = &zero!uint;
590 590
     foreach (i; 0..10)
591 591
     {
592 592
         assert(n(x => x + 1)(0) == i);
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.