D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3538 - Default value of alias template parameter is instantiated only once.
Summary: Default value of alias template parameter is instantiated only once.
Status: RESOLVED DUPLICATE of issue 22540
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Linux
: P2 critical
Assignee: No Owner
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2009-11-21 12:28 UTC by Eldar Insafutdinov
Modified: 2022-01-28 09:52 UTC (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Eldar Insafutdinov 2009-11-21 12:28:04 UTC
template Boo(T) {}
struct Foo(T, alias V = Boo!T) { pragma(msg, V.stringof); }
alias Foo!double B;
alias Foo!int A;

outputs

Boo!(double)                                                        
Boo!(double)

while it should

Boo!(double)                                                        
Boo!(int)


Although it's a blocker for a design that I intend to use, I don't mark it as such with hope that it'll get fixed, as it looks trivial to me.
Comment 1 Robert Clipsham 2010-04-23 12:50:46 UTC
This is caused as default arguments to templates are only instantiated once, which causes the Boo!T to always become whatever is instantiated first. The patch below fixes this:
--- template.c       2010-03-18 18:58:06.000000000 +0000
+++ template.c  2010-04-23 20:49:54.000000000 +0100
@@ -2993,6 +2993,17 @@
 
 Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc)
 {
+    Type *ta = isType(defaultAlias);
+    if (ta)
+    {
+       if (ta->ty == Tinstance)
+       {
+           // If the default arg is a template, instantiate for each type
+           Object *da = ta->syntaxCopy();
+           Object *o = aliasParameterSemantic(loc, sc, da);
+           return o;
+       }
+    }
     Object *o = aliasParameterSemantic(loc, sc, defaultAlias);
     return o;
 }
Comment 2 Walter Bright 2010-05-16 11:15:20 UTC
changelog 492
Comment 3 aneas 2016-02-01 13:07:41 UTC
This problem still exists, if the default expression is not a type, but an actual expression referring to a type:

template Tpl(T, alias S = "" ~ T.stringof) {
	pragma(msg, S);
}
class A { }
class B { }
alias TA = Tpl!A;
alias TB = Tpl!B;

I think a possible solution would be to always use a syntaxCopy() of defaultAlias. How would this affect performance?
Comment 4 RazvanN 2022-01-28 09:52:49 UTC

*** This issue has been marked as a duplicate of issue 22540 ***