Issue 23798 - Type inference should traverse trivial aliases
Summary: Type inference should traverse trivial aliases
Status: RESOLVED DUPLICATE of issue 1807
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P1 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-03-22 13:02 UTC by FeepingCreature
Modified: 2023-03-23 12:39 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description FeepingCreature 2023-03-22 13:02:05 UTC
See also: https://forum.dlang.org/thread/wgvtwckvjyhnbpcuyyqy@forum.dlang.org

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 FeepingCreature 2023-03-22 13:03:39 UTC
Oops: Dupe of https://issues.dlang.org/show_bug.cgi?id=1807 , thanks jmh530

*** This issue has been marked as a duplicate of issue 1807 ***