With certain configurations of templated classes/interfaces with refinements, a recursive template expansion is incorrectly reported. This only occurs if the classes are in a certain order.
To reproduce:
1) Create a D file and enter the following code:
void main() {}
class SuperClass {}
class TemplatedClass(T : SuperClass) {}
class A : SuperClass {
alias T = TemplatedClass!B;
}
class B : SuperClass {
alias T = TemplatedClass!C;
}
class C : SuperClass {}
2) Compile the code.
Actual result:
test.d(12): Error: class `test.TemplatedClass(T : SuperClass)` recursive template expansion
test.d(12): while looking for match for TemplatedClass!(C)
Expected result: no error
Build 2018-03-22 on Mac OS 10.12.6 on DMD64 D Compiler v2.079.0
On the other hand, the following two examples both work:
1) Changed specialisation to constraint:
void main() {}
class SuperClass {}
class TemplatedClass(T)
if (is(T : SuperClass)) {}
class A : SuperClass {
alias T = TemplatedClass!B;
}
class B : SuperClass {
alias T = TemplatedClass!C;
}
class C : SuperClass {}
2) Reordered:
void main() {}
class SuperClass {}
class TemplatedClass(T : SuperClass) {}
class B : SuperClass {
alias T = TemplatedClass!C;
}
class A : SuperClass {
alias T = TemplatedClass!B;
}
class C : SuperClass {}
Comment #1 by publicnator — 2018-03-22T07:10:19Z
It also should be noted that the aliases don't have to be aliases. Any reference to the class works (e.g. variable with type, method with parameter or return type, etc.).
Comment #2 by ibuclaw — 2022-12-27T18:01:45Z
*** Issue 19585 has been marked as a duplicate of this issue. ***
Comment #3 by ibuclaw — 2022-12-27T18:02:41Z
*** Issue 22813 has been marked as a duplicate of this issue. ***
Comment #4 by ibuclaw — 2022-12-27T18:03:55Z
Extra testcase:
---
struct A {
M2 stdin;
}
mixin template Handle(T, T invalid_value = T.init) {}
struct M1 { mixin Handle!(size_t); }
struct M2 { mixin Handle!(M1); }
Comment #5 by ibuclaw — 2022-12-27T18:04:10Z
Extra testcase
---
struct Template(int i) { }
uint f()
{
Template!(1) x;
return 0;
}
immutable constant = f();
alias X = Template!constant;