www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template instantiation problems

reply berni44 <dlang d-ecke.de> writes:
I'm trying to understand issue 17441 [1]. I reduced it (including 
Phobos) to the following (and added some message to point out the 
problem):

test.d:
---
alias parentOf(alias sym) = __traits(parent, sym);

template packageName(alias T)
{
     pragma(msg, "IN: ", T.stringof);
     static if (__traits(compiles, parentOf!T))
         enum parent = packageName!(parentOf!T);
     else
         enum string parent = null;

     static if (T.stringof[0..8] == "package ")
         enum packageName = (parent? parent ~ '.' : "") ~ 
T.stringof[8 .. $];
     else
         enum packageName = parent;
}

void main()
{
     import mod0 = foo.baz;
     import mod1 = foo;

     pragma(msg, "mod0: ",mod0.stringof);
     pragma(msg, "mod1: ",mod1.stringof);

     pragma(msg, "A");
     enum a = packageName!mod0;
     pragma(msg, "B");
     enum b = packageName!mod1;
     pragma(msg, "C");

     static assert(a == "foo");
     static assert(b == "");      // Error: static assert:  "foo" 
== "" is false
}
---

foo/baz.d:
---
module foo.baz;
---

foo/package.d:
---
module foo;
---

When compiling with

$> dmd test.d

I get:

---
mod0: module baz
mod1: module foo
A
IN: module baz
IN: package foo
B
C
test.d(32): Error: static assert:  "foo" == "" is false
---

This clearly shows, that packageName is only instatiated once at 
top level although mod0 and mod1 are two different things (at 
least their stringof produces different results) and therefore 
should be instantiated twice.

Now I don't know if this is a bug in DMD or I should know 
something I do not know... Can you help me?

[1] https://issues.dlang.org/show_bug.cgi?id=17441
Jan 10 2020
parent reply ag0aep6g <anonymous example.com> writes:
On 10.01.20 18:27, berni44 wrote:
 This clearly shows, that packageName is only instatiated once at top 
 level although mod0 and mod1 are two different things (at least their 
 stringof produces different results) and therefore should be 
 instantiated twice.
 
 Now I don't know if this is a bug in DMD or I should know something I do 
 not know... Can you help me?
---- import m1 = foo.baz; import m2 = foo; alias p = __traits(parent, m1); pragma(msg, m1.stringof); /* "module baz", ok */ pragma(msg, m2.stringof); /* "module foo", ok */ pragma(msg, p.stringof); /* "package foo", ok */ enum e(alias thing) = thing.stringof; pragma(msg, e!m1); /* "module baz", ok */ pragma(msg, e!m2); /* "module foo", ok */ pragma(msg, e!p); /* "module foo", wat?? */ ---- If you switch the last two lines around, you get "package foo" twice. The compiler apparently thinks that m2 (module foo) and p (package foo) are the same thing when used as a template argument. So it reuses the previous result. There's a similar issue with values: https://issues.dlang.org/show_bug.cgi?id=14501
Jan 10 2020
parent Boris Carvajal <boris2.9 gmail.com> writes:
On Friday, 10 January 2020 at 18:31:59 UTC, ag0aep6g wrote:
 ----
 import m1 = foo.baz;
 import m2 = foo;
 alias p = __traits(parent, m1);

 pragma(msg, m1.stringof); /* "module baz", ok */
 pragma(msg, m2.stringof); /* "module foo", ok */
 pragma(msg, p.stringof); /* "package foo", ok */

 enum e(alias thing) = thing.stringof;

 pragma(msg, e!m1); /* "module baz", ok */
 pragma(msg, e!m2); /* "module foo", ok */
 pragma(msg, e!p); /* "module foo", wat?? */
 ----
Thanks for your test case. https://github.com/dlang/dmd/pull/10724
Jan 14 2020