Bug 2257 – Template value parameters behave like alias parameters
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2008-07-31T13:35:00Z
Last change time
2015-06-09T01:20:00Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
samukha
Comments
Comment #0 by samukha — 2008-07-31T13:35:35Z
import std.stdio;
template Foo(string s)
{
enum Foo = s; // changing enum to invariant fixes the issue.
}
void main()
{
string a = "str";
alias Foo!(a) b; // b is now an alias of a. Should be a compiler error
}
Comment #1 by samukha — 2008-10-13T00:32:13Z
"compiler error" in the example was meant to be "compile error"
Comment #2 by sandford — 2009-10-13T10:21:10Z
This issue causes major issues with Nd-array and Small Vector implementations, as the incorrect type signatures play havoc with other templated functions. Here is another test case illustrating the problem:
import std.stdio;
struct Matrix(T,size_t D) {
Matrix!(U,D) foo(U)(U v) { return Matrix!(U,D)(); }
}
void main() {
real r;
size_t d = 2;
Matrix!(float,2) m;
writeln(typeof( m.foo(r) ).stringof); //writes Matrix(float,D)
Matrix!(float,d) n;
writeln(typeof( n ).stringof); //writes Matrix(float,d)
}
Comment #3 by sandford — 2009-11-06T22:23:35Z
(In reply to comment #2)
> This issue causes major issues with Nd-array and Small Vector implementations,
> as the incorrect type signatures play havoc with other templated functions.
> Here is another test case illustrating the problem:
>
> import std.stdio;
> struct Matrix(T,size_t D) {
> Matrix!(U,D) foo(U)(U v) { return Matrix!(U,D)(); }
> }
>
> void main() {
> real r;
> size_t d = 2;
> Matrix!(float,2) m;
> writeln(typeof( m.foo(r) ).stringof); //writes Matrix(float,D)
> Matrix!(float,d) n;
> writeln(typeof( n ).stringof); //writes Matrix(float,d)
> }
A Mitigation for the above example:
Matrix!(U,D+0) foo(U)(U v) { return Matrix!(U,D)(); }
changes "Matrix(float,D)" to "writes Matrix(float,2u)"
However, the original template type is still distinct: Matrix(float,2)
Also, it appears that even though D is unsigned, the template type is signed.
Comment #4 by clugdbug — 2010-12-01T02:29:17Z
*** Issue 4289 has been marked as a duplicate of this issue. ***
Comment #5 by clugdbug — 2010-12-01T02:29:56Z
Bug 2550 has the same root cause, I think.
Comment #6 by yebblies — 2012-01-29T22:25:10Z
*** Issue 2733 has been marked as a duplicate of this issue. ***
Comment #7 by smjg — 2012-02-05T14:56:56Z
This might be related:
----------
struct DimensionedValue(Val, int Dim) {
Val value;
auto opMul(T)(T v) {
return DimensionedValue!(typeof(value * T.init), Dim)(value * v);
}
}
template isDimensionedValue(T : DimensionedValue!(V, D), V, int D) {
enum bool isDimensionedValue = true;
}
template isDimensionedValue(T) {
enum bool isDimensionedValue = false;
}
DimensionedValue!(int, 1) x;
//DimensionedValue!(double, 1) y;
pragma(msg, typeof(x * 2));
pragma(msg, isDimensionedValue!(typeof(x * 2)));
pragma(msg, typeof(x * 2.5));
pragma(msg, isDimensionedValue!(typeof(x * 2.5)));
----------
DimensionedValue!(int,1)
true
DimensionedValue!(double,Dim)
false
----------
Reinstating the declaration of y suppresses the bug. As does using Dim + 0 in opMul.
Is this another manifestation of the same bug, or does it warrant a separate bug report?
Comment #8 by andrej.mitrovich — 2013-02-04T17:55:12Z
Fixed since a long time ago, tested as far back as 2.053.