[clang] [Clang][NFCI] Prefer non-canonical template arguments for synthesized CTAD guides (PR #99840)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 22 01:34:50 PDT 2024
zyn0217 wrote:
Thanks for the prompt review.
> There is an ambiguous case that I'm a little concerned about: if the alias template parameter and the underlying template parameter have the same name, the synthesized deduction guide may end up with two template parameters with the same name. For instance, see [this example](https://godbolt.org/z/q1n7Edzcz). In such cases, we cannot distinguish between the `T1` parameters from the function signature `auto (T1, T1) -> X<T1, double>`.
Yeah, this is indeed an interesting case. I played it a bit and realized we would now dump a confusing diagnostic for it:
```cpp
template <class T, class U>
struct X {
X(T, U);
};
template <class T, class T1>
X(T, T1) -> X<T, double>;
template <class T1>
using AX = X<T1, double>;
AX s(1);
```
would result in
```
note: candidate function template not viable: requires 2 arguments, but 1 was provided
note: implicit deduction guide declared as 'template <class T1, class T1> requires __is_deducible(AX, X<type-parameter-0-0, double>) AX(type-parameter-0-0, type-parameter-0-1) -> X<type-parameter-0-0, double>'
```
The printed template parameter list is actually syntactically illegal simply because we merely dump the synthesized parameter list, which actually reuses the written parameter names. I think a solution would be, if we realize there's a name clash when building up a list, we make up and use a different parameter name. (This can be left as a follow-up because I feel we're less likely to run into this case.)
Regarding the disambiguation, we could already do that through an AST dump. For the case above, I ran an AST dump locally and got the following:
```
|-FunctionTemplateDecl 0x7f90695f3970 <line:9:1, line:10:24> col:1 implicit <deduction guide for AX>
| |-TemplateTypeParmDecl 0x7f90695f3068 <line:9:11, col:17> col:17 class depth 0 index 0 T1
| |-TypeTraitExpr 0x7f90695f3858 <line:10:1> 'bool' __is_deducible
| | |-DeducedTemplateSpecializationType 0x7f90695f2e60 'AX' dependent
| | | `-name: 'AX'
| | | `-TypeAliasTemplateDecl 0x7f90695f1d70 <line:9:1, line:10:24> col:1 AX
| | `-TemplateSpecializationType 0x7f90695f35a0 'X<T1, double>' dependent
| | |-name: 'X' qualified
| | | `-ClassTemplateDecl 0x7f90695ce158 <line:1:1, line:4:1> line:2:8 X
| | |-TemplateArgument type 'T1':'type-parameter-0-0'
| | | `-SubstTemplateTypeParmType 0x7f90695f32d0 'T1' sugar dependent class depth 0 index 0 T
| | | |-FunctionTemplate 0x7f90695f18d0 '<deduction guide for X>'
| | | `-TemplateTypeParmType 0x7f90695f30c0 'T1' dependent depth 0 index 0
| | | `-TemplateTypeParm 0x7f90695f3068 'T1'
| | `-TemplateArgument type 'double'
| | `-SubstTemplateTypeParmType 0x7f90695f3320 'double' sugar class depth 0 index 1 U
| | |-FunctionTemplate 0x7f90695f18d0 '<deduction guide for X>'
| | `-BuiltinType 0x7f906957d780 'double'
| `-CXXDeductionGuideDecl 0x7f90695f38a8 <line:9:1, line:10:24> col:1 implicit <deduction guide for AX> 'auto (X<T1, double>) -> X<T1, double>'
| `-ParmVarDecl 0x7f90695f3438 <line:2:8> col:8 'X<T1, double>'
```
Note that we can see the `T1`'s canonical type at the node of `TemplateArgument`.
https://github.com/llvm/llvm-project/pull/99840
More information about the cfe-commits
mailing list