Bug 4960 – dmd 2.049 rejects code containing templates with a uint as template parameter

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Linux
Creation time
2010-09-30T10:15:00Z
Last change time
2016-12-22T14:27:23Z
Assigned to
nobody
Creator
CaptainSifff

Attachments

IDFilenameSummaryContent-TypeSize
778ChargeChargeCorrelation_Paste.dthe failing piece of codetext/x-dsrc436

Comments

Comment #0 by CaptainSifff — 2010-09-30T10:15:22Z
Created attachment 778 the failing piece of code Hi there the following code is rejected by dmd 2.049 With the help of some helpful people in the D IRC channel I inserted the pragmas into the code to highlight that dmd seems to somehow mix these two identical types up. If compiled the output is: ../../dmd2/linux/bin/dmd -O ChargeChargeCorrelation_Paste.d C29ChargeChargeCorrelation_Paste18__T9MeanfieldVxk1Z1U C29ChargeChargeCorrelation_Paste17__T9MeanfieldVk1Z1U ChargeChargeCorrelation_Paste.d(23): Error: cannot implicitly convert expression (timeevolver) of type ChargeChargeCorrelation_Paste.main.Meanfield!(dimension).U to ChargeChargeCorrelation_Paste.Meanfield!(dim).U The first two lines coming from the pragmas. If the alias is put into the global namespace the example compiles.
Comment #1 by ah08010-d — 2010-09-30T10:24:52Z
I get similar behavior on windows. Here is a smaller bit of code that reproduces the issue (I think): ========== class U(uint dim) { } void chargecharge_entry(uint dim)( U!(dim) time ) { //pragma(msg, "param: " ~ typeof( time ).mangleof); } void main() { const uint dimension = 1; alias U!(dimension) TimeEvolver; //pragma(msg, "main: " ~ TimeEvolver.mangleof); chargecharge_entry!(dimension)( new TimeEvolver ); } ========== For me emits: test.d(41): Error: cannot implicitly convert expression (new U) of type test.main.U!(dimension).U to test.U!(dim).U
Comment #2 by bearophile_hugs — 2010-09-30T10:32:03Z
Also note the effect of this version of the same program: template MeanField(int dim) { class U { cdouble opCall() { return 0.0 + 0.0i; } } } void chargeChargeEntry(int dim)(MeanField!(dim).U time) { pragma(msg, MeanField!(dim).U.mangleof); } void main() { alias MeanField!(1).U TimeEvolver; TimeEvolver timeEvolver = new TimeEvolver; pragma(msg, TimeEvolver.mangleof); chargeChargeEntry!(1)(timeEvolver); } Or even this version: class U(int dim) { cdouble opCall() { return 0.0 + 0.0i; } } void chargeChargeEntry(int dim)(U!dim time) { pragma(msg, (U!dim).mangleof); } void main() { alias U!1 TimeEvolver; TimeEvolver timeEvolver = new TimeEvolver; pragma(msg, TimeEvolver.mangleof); chargeChargeEntry!(1)(timeEvolver); } See also bug 3467
Comment #3 by CaptainSifff — 2010-10-01T02:00:22Z
I agree, your issue sounds similar, but in contrast to your code where there might be a slight difference between the types because the template takes an uint and you instantiate it with an int literal, my example uses uints exclusively and the parameter dimension is typed as an uint. So, there should be no reason for ambiguity... I just tested your programs and they compiled with dmd 2.049... Whereas changing austins example to using int doesn't lead to an compiling program... Essentially I don't get what's going wrong now...
Comment #4 by andrej.mitrovich — 2012-12-20T13:05:57Z
As a workaround you can use an enum instead of a const uint.
Comment #5 by andrei — 2016-12-22T14:27:23Z
All examples given compile and run with 2.072.1.