Bug 23798 – Type inference should traverse trivial aliases
Status
RESOLVED
Resolution
DUPLICATE
Severity
enhancement
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2023-03-22T13:02:05Z
Last change time
2023-03-23T12:39:43Z
Assigned to
No Owner
Creator
FeepingCreature
Comments
Comment #0 by default_357-line — 2023-03-22T13:02:05Z
See also: https://forum.dlang.org/thread/[email protected]
In C++, you can infer instantiation through simple alias templates:
```
template <typename T, int M, int N>
struct Matrix {
};
template <typename T>
using Vector3 = Matrix<T, 3, 1>;
template<typename T>
void baz(Vector3<T> vector) {}
int main() {
baz(Vector3<int>());
}
```
There is nothing special about the parameter being `Vector3<int>`; this also works:
```
baz(Matrix<int, 3, 1>());
```
C++ tries to match `Vector3<T>` with `Matrix<T, int, int>`, notices that `Vector3<T>` is a trivial alias to `Matrix<T, 3, 1>`, and matches with that instead.
If you try to do the analogous thing in D:
```
struct Matrix(T, int M, int N) {}
alias Vector3(T) = Matrix!(T, 3, 1);
void foo(T = Vector3!U, U)(T arg) { }
void main() {
foo!(Vector3!int, int)(Vector3!int());
foo(Vector3!int());
}
```
The first call works, but the second fails to infer that `U` can be `int`. D here should notice that `Vector3(T)` is a trivial alias to another template instance and do a simple parameter substitution, treating `foo` as equivalent to `void foo(T = Matrix!(U, 3, 1), U)(T arg)`.
Comment #1 by default_357-line — 2023-03-22T13:03:39Z