You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (llvm#88963)
Consider the following snippet from the discussion of CWG2847 on the core reflector:
```
template<typename T>
concept C = sizeof(T) <= sizeof(long);
template<typename T>
struct A
{
template<typename U>
void f(U) requires C<U>; // #1, declares a function template
void g() requires C<T>; // rust-lang#2, declares a function
template<>
void f(char); // rust-lang#3, an explicit specialization of a function template that declares a function
};
template<>
template<typename U>
void A<short>::f(U) requires C<U>; // rust-lang#4, an explicit specialization of a function template that declares a function template
template<>
template<>
void A<int>::f(int); // rust-lang#5, an explicit specialization of a function template that declares a function
template<>
void A<long>::g(); // rust-lang#6, an explicit specialization of a function that declares a function
```
A number of problems exist:
- Clang rejects `rust-lang#4` because the trailing _requires-clause_ has `U`
substituted with the wrong template parameter depth when
`Sema::AreConstraintExpressionsEqual` is called to determine whether it
matches the trailing _requires-clause_ of the implicitly instantiated
function template.
- Clang rejects `rust-lang#5` because the function template specialization
instantiated from `A<int>::f` has a trailing _requires-clause_, but `rust-lang#5`
does not (nor can it have one as it isn't a templated function).
- Clang rejects `rust-lang#6` for the same reasons it rejects `rust-lang#5`.
This patch resolves these issues by making the following changes:
- To fix `rust-lang#4`, `Sema::AreConstraintExpressionsEqual` is passed
`FunctionTemplateDecl`s when comparing the trailing _requires-clauses_
of `rust-lang#4` and the function template instantiated from `#1`.
- To fix `rust-lang#5` and `rust-lang#6`, the trailing _requires-clauses_ are not compared
for explicit specializations that declare functions.
In addition to these changes, `CheckMemberSpecialization` now considers
constraint satisfaction/constraint partial ordering when determining
which member function is specialized by an explicit specialization of a
member function for an implicit instantiation of a class template (we
previously would select the first function that has the same type as the
explicit specialization). With constraints taken under consideration, we
match EDG's behavior for these declarations.
0 commit comments