Bug 24611 – Cannot explicitly instantiate template function with `auto ref`

Status
NEW
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-06-16T11:27:26Z
Last change time
2024-12-13T19:35:44Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#20468 →

Comments

Comment #0 by qs.il.paperinik — 2024-06-16T11:27:26Z
```d void f(T)(auto ref T x) {} void main() { int x; f(x); // infers T = int, auto ref = ref f(0); // infers T = int, auto ref = Ø f!int(x); // same as first f!int(0); // same as second auto fp = &f!int; // Error: cannot explicitly instantiate template function with `auto ref` alias f_int = f!int; // Error: cannot explicitly instantiate template function with `auto ref` } ``` The spec nowhere says that one can’t explicitly instantiate function templates with `auto ref` parameters. I suggest we extend template type parameters and let them be bound not just to a type, but also, optionally, a `ref`. Any template type parameter is effectively a bool–type pair where the bool says if `ref` was given as an argument. Supplying `ref` only makes a difference when the type parameter is used as a function parameter type. In every other use, it is ignored. When a template type parameter is `ref` and used as a function parameter type, that parameter must be `auto ref`, otherwise it is an error. If it is an `auto ref` parameter, it becomes `ref`. Explicit instantiations of function templates with `auto ref` parameters become valid and if no `ref` is given for the template type argument, the `auto ref` becomes pass-by-value. As for IFTI, nothing changes. The `ref` as part of a template type argument will be inferred even if the corresponding type of the bool–type pair is given. (Unlike say in C++, where the information of being reference is part of the type.) Example: ```d void f(T)(auto ref T x) {} void main() { int x; f(x); // infers T = ref int, therefore auto ref = ref f(0); // infers T = int, therefore auto ref = Ø f!int(x); // same as first, T = ref int, ref inferred f!int(0); // same as second, no ref inferred as argument is rvalue // nothing really changed up until here auto fp1 = &f!int; // Okay, T = int, pass-by-value auto fp2 = &f!(ref int); // T = ref int, pass-by-reference alias f_int = f!int; // Okay, T = int, pass-by-value alias f_ref_int = f!(ref int); // T = ref int, pass-by-reference ```
Comment #1 by qs.il.paperinik — 2024-06-17T11:47:16Z
Grammar change needed for the suggested fix: ```diff TemplateArgument: Type + ref Type AssignExpression Symbol ```
Comment #2 by robert.schadek — 2024-12-13T19:35:44Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20468 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB