-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CTAD: incorrect transformed require-clause for the alias deduction guide #90177
Comments
@llvm/issue-subscribers-c-20 Author: Haojian Wu (hokein)
Example:
clang rejects the above valid code with the following diagnostics:
It seems to be an issue in the transformed require-clause for the alias deduction guide. The require expression should be evaluated on the type |
@llvm/issue-subscribers-clang-frontend Author: Haojian Wu (hokein)
Example:
clang rejects the above valid code with the following diagnostics:
It seems to be an issue in the transformed require-clause for the alias deduction guide. The require expression should be evaluated on the type |
OK, I can confirm that the synthesized deduction guide (and its require-clause) for the alias is correct
Up to the function overload resolution point at https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaTemplateDeduction.cpp#L3769-L3772, everything appears to be in order. The instantiated deduction guide looks like:
The issue seems to be in the |
If you switch this seems to have landed after clang-18, do you know which change brought this in? |
I think this is caused by the recent changes to support CTAD for alias.
Turns out it was wrong, the depth of the Taking on a working case (normal CTAD):
The explicit deduction guide for
Note the difference in the occurrence of template parameter My understanding is that this subtle difference is intentional. When clang evaluates the constraint, it requires the entire template argument list (even the outer template is instantiated). @erichkeane can you confirm? |
I think your understanding is correct because in llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp Lines 3100 to 3104 in 55c6bda
|
Right, that is correct. Constraints should NOT be instantiated at all unless they are being evaluated, this is so that they can refer to changes in types that happen after instantiation (and are useful for using them in CRTP in particular). Thus, we don't substitute them at all if at all possible (and the AST always stores the uninstantiated version). As a by-product of this, we end up having to recollect the entire set of template argument lists when we check constraints. |
Thanks for the confirmation and clarification, @zyn0217, @erichkeane.
And in the implementation, we take a shortcut and reuse the require-clause of the primary (uninstantiated) template. In this example, the require-clause of the deduction guide Given the way constraints work in clang, the When we synthesize the alias deduction guide from the underlying deduction guide, we "replace" all occurrences of template parameters of the underlying deduction guide with the alias RHS template arguments. The RHS arguments come from the alias template in the instantiated One way to fix the require-clause depth issue is to use the alias template in the primary |
#90961) In the clang AST, constraint nodes are deliberately not instantiated unless they are actively being evaluated. Consequently, occurrences of template parameters in the require-clause expression have a subtle "depth" difference compared to normal occurrences in places, such as function parameters. When transforming the require-clause, we must take this distinction into account. The existing implementation overlooks this consideration. This patch is to rewrite the implementation of the require-clause transformation to address this issue. Fixes #90177
llvm#90961) In the clang AST, constraint nodes are deliberately not instantiated unless they are actively being evaluated. Consequently, occurrences of template parameters in the require-clause expression have a subtle "depth" difference compared to normal occurrences in places, such as function parameters. When transforming the require-clause, we must take this distinction into account. The existing implementation overlooks this consideration. This patch is to rewrite the implementation of the require-clause transformation to address this issue. Fixes llvm#90177
llvm#90961) In the clang AST, constraint nodes are deliberately not instantiated unless they are actively being evaluated. Consequently, occurrences of template parameters in the require-clause expression have a subtle "depth" difference compared to normal occurrences in places, such as function parameters. When transforming the require-clause, we must take this distinction into account. The existing implementation overlooks this consideration. This patch is to rewrite the implementation of the require-clause transformation to address this issue. Fixes llvm#90177
Example:
clang rejects the above valid code with the following diagnostics:
It seems to be an issue in the transformed require-clause for the alias deduction guide. The require expression should be evaluated on the type
Key1
, rather than the outer typeForward
.The text was updated successfully, but these errors were encountered: