[PATCH] D146178: [Clang][Sema] Fix comparison of constraint expressions

Richard Smith - zygoloid via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 16 16:05:42 PDT 2023


rsmith added a comment.

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).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D146178



More information about the llvm-commits mailing list