Bug 3467 – Non-int integral template parameters not correctly propagated

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
All
OS
All
Creation time
2009-11-02T02:56:38Z
Last change time
2019-10-23T09:42:36Z
Keywords
patch, rejects-valid
Assigned to
No Owner
Creator
Simen Kjaeraas

Comments

Comment #0 by simen.kjaras — 2009-11-02T02:56:38Z
The below code snippet fails to compile on DMD 2.035: Error: cannot implicitly convert expression (baz.barof type foo!(n) to foo!(4) Now change uint to int, and everything works perfectly. This might have to do with literal types ( 4 is an int, not a uint, ulong, byte, or whatever ). struct foo( uint n ) { foo!( n ) bar( ) { typeof( return ) result; return result; } } void main( ) { foo!( 4 ) baz; baz = baz.bar;// FAIL }
Comment #1 by bearophile_hugs — 2010-09-25T16:29:51Z
The bug is present in dmd 2.049 still: struct Vec(size_t N) { void opBinary(string op:"~", size_t M)(Vec!M) {} } void main() { Vec!2 a1; Vec!3 a2; a1 ~ a2; // line 7, Error }
Comment #2 by k.hara.pg — 2011-10-14T01:49:12Z
*** Issue 6806 has been marked as a duplicate of this issue. ***
Comment #3 by k.hara.pg — 2011-10-14T01:51:11Z
From bug 6806, this is D1 & D2 issue. And D2 patch: https://github.com/D-Programming-Language/dmd/pull/449
Comment #4 by bugzilla — 2011-11-19T23:26:17Z
I believe this is not a bug. The type of a template is based on what its argument types are, not its parameter types. Hence, foo!3 is always a different type from: foo!3u even if foo is defined to take an int parameter.
Comment #5 by issues.dlang — 2011-11-19T23:39:12Z
Why? I understand instantiating a different template with different arguments when the type itself is the argument. But when you've typed the argument, it's essentially the same as passing an argument to a function, only it's a template argument instead of a function argument. In this case, the template says that it takes a uint. I would expect that it then would instatiated based on the _value_ of the argument, not its _type_. It already _has_ a type - uint. Making foo!3 and foo!3u be different is just plain confusing because they're being given the exact same value. What value is there in having foo!3 and foo!3u be different? What does it add? I don't understand how the _type_ of the argument could matter when the type is already defined by the template and it's the value that changes between instantiations.
Comment #6 by k.hara.pg — 2011-11-23T16:27:10Z
(In reply to comment #4) > I believe this is not a bug. The type of a template is based on what its > argument types are, not its parameter types. Hence, > > foo!3 > > is always a different type from: > > foo!3u > > even if foo is defined to take an int parameter. The issue is that the foo template with signed integer makes incorrect instantiation internally. There are two solutions: 1. Makes that instantiation invalid. 2. Promote signed integer template value parameter into unsigned. My patch implements #2, and I believe that is correct. Because non-suffix integer literal can implicitly convertible to unsigned. And, my patch doesn't break existing code around template overloading. Following code still valid. template Foo(int n){ enum Foo = 1; } template Foo(uint n){ enum Foo = 2; } static assert(Foo!10 == 1); static assert(Foo!10u == 2);
Comment #7 by k.hara.pg — 2011-11-28T16:59:59Z
*** Issue 3210 has been marked as a duplicate of this issue. ***
Comment #8 by k.hara.pg — 2011-12-01T13:51:15Z
Updated pull/449 to fix bug2550, they are almost same issues.
Comment #9 by code — 2011-12-10T05:23:02Z
(In reply to comment #6) > There are two solutions: > 1. Makes that instantiation invalid. > 2. Promote signed integer template value parameter into unsigned. > > My patch implements #2, and I believe that is correct. > Because non-suffix integer literal can implicitly convertible to unsigned. > > And, my patch doesn't break existing code around template overloading. I agree. For an integer _value_ (and this is what we are talking about here), distinguishing between 3 and 3u just makes no sense.
Comment #10 by bugzilla — 2011-12-10T16:38:45Z
Comment #11 by k.hara.pg — 2012-04-24T18:01:52Z
*** Issue 6246 has been marked as a duplicate of this issue. ***
Comment #12 by verylonglogin.reg — 2012-10-30T06:49:11Z
(In reply to comment #10) > https://github.com/D-Programming-Language/dmd/commit/f8ad107800a2c9bf116779a49abe9945daf9d05f > > Resolved for D2 only. So it's D1 issue now.
Comment #13 by github-bugzilla — 2014-03-01T12:24:43Z
Commit pushed to master at https://github.com/D-Programming-Language/dlang.org https://github.com/D-Programming-Language/dlang.org/commit/2a56f5cc3dea215946f6e0ae8ac2c8c9be32686b fix Issue 3467 - Non-int integral template parameters not correctly propagated
Comment #14 by kai — 2014-05-08T16:24:17Z
As a side effect, the name mangling is wrong. Lets change the type parameter from uint to ulong. Then the bar function of foo!( 4 ) baz is mangled as _D7bug346712__T3fooVii4Z3foo3barMFNaNbNiNfZS7bug346712__T3fooVii4Z3foo but bar function of foo!( 4L ) baz is mangled as _D7bug346712__T3fooVli4Z3foo3barMFNaNbNiNfZS7bug346712__T3fooVli4Z3foo In both cases, I would expect _D7bug346712__T3fooVmi4Z3foo3barMFNaNbNiNfZS7bug346712__T3fooVmi4Z3foo because the type parameter is ulong.
Comment #15 by code — 2014-05-08T16:31:27Z
@Kai: Note that this report is marked as D1 only now. You might want to open a new issue for the mangling problem.
Comment #16 by razvan.nitu1305 — 2019-10-23T09:42:36Z
D1 is no longer supported. Closing...