erichkeane added a comment.

In D146178#4200821 <https://reviews.llvm.org/D146178#4200821>, @rsmith wrote:

> The approach of attempting to adjust the depth here is not correct, and we 
> should rip this whole mechanism out and reimplement it.  Consider this 
> closely related testcase:
>
>   template<typename T, typename U>
>   concept Concept = true;
>   
>   template<typename T>
>   struct A
>   {
>     template<Concept<T> V>
>     void C(V&& t);
>   };
>   
>   template<>
>   template<Concept<int> V>
>   void A<int>::C(V&& t)
>   {}
>
> Clang rejects this because it's trying to compare `Concept<T>` from the 
> declaration against `Concept<int>` from the explicit specialization.
>
> The right way to fix that and the issue being addressed here is that, rather 
> than adjusting the depths, we should substitute the outer template arguments 
> from the scope specifier (`A<int>::`) into the constraint before performing 
> the comparison. (In the special case where none of the outer template 
> parameters are used by the inner template, that does effectively just adjust 
> the depths of any inner template parameters.)
>
> The relevant language rule was introduced by the resolution of CA104 in 
> P2103R0 
> <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2103r0.html#ca104> 
> (which Clang's status page incorrectly marks as complete in Clang 10). In 
> particular, see temp.constr.decl/4 
> <https://eel.is/c++draft/temp.constr.decl#4> for the rule that we should 
> implement, but don't:
>
>> When determining whether a given introduced constraint-expression `C1` of a 
>> declaration in an instantiated specialization of a templated class is 
>> equivalent ([temp.over.link]) to the corresponding constraint-expression 
>> `C2` of a declaration outside the class body, `C1` is instantiated. If the 
>> instantiation results in an invalid expression, the constraint-expressions 
>> are not equivalent.
>
> So, in this case, we're supposed to instantiate the constraint expression 
> `Concept<T>`, substituting the template arguments of `A` into it (in a SFINAE 
> context).

IIRC, the original motivation for this attempt was that we frequently compare 
template arguments, even in cases where that isn't permitted?  I had sent you a 
couple of emails when I was attempting this, but you'd not gotten a chance to 
respond.  I think I came up on this as the only way to do this without 
instantiating the constraint (which I recall you'd said was not the right way 
to compare constraints at one point?).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146178/new/

https://reviews.llvm.org/D146178

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to