12fd01d75SYounan Zhang // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
2*bb60c066STimm Bäder // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -fexperimental-new-constant-interpreter
32fd01d75SYounan Zhang
42fd01d75SYounan Zhang template <typename Iterator> class normal_iterator {};
52fd01d75SYounan Zhang
62fd01d75SYounan Zhang template <typename From, typename To> struct is_convertible {};
72fd01d75SYounan Zhang
82fd01d75SYounan Zhang template <typename From, typename To>
92fd01d75SYounan Zhang inline constexpr bool is_convertible_v = is_convertible<From, To>::value; // expected-error {{no member named 'value' in 'is_convertible<bool, bool>'}}
102fd01d75SYounan Zhang
112fd01d75SYounan Zhang template <typename From, typename To>
122fd01d75SYounan Zhang concept convertible_to = is_convertible_v<From, To>; // #1
132fd01d75SYounan Zhang
142fd01d75SYounan Zhang template <typename IteratorL, typename IteratorR>
152fd01d75SYounan Zhang requires requires(IteratorL lhs, IteratorR rhs) { // #2
162fd01d75SYounan Zhang { lhs == rhs } -> convertible_to<bool>; // #3
172fd01d75SYounan Zhang }
compare(normal_iterator<IteratorL> lhs,normal_iterator<IteratorR> rhs)182fd01d75SYounan Zhang constexpr bool compare(normal_iterator<IteratorL> lhs, normal_iterator<IteratorR> rhs) { // #4
192fd01d75SYounan Zhang return false;
202fd01d75SYounan Zhang }
212fd01d75SYounan Zhang
222fd01d75SYounan Zhang class Object;
232fd01d75SYounan Zhang
function()242fd01d75SYounan Zhang void function() {
252fd01d75SYounan Zhang normal_iterator<Object *> begin, end;
262fd01d75SYounan Zhang compare(begin, end); // expected-error {{no matching function for call to 'compare'}} #5
272fd01d75SYounan Zhang }
282fd01d75SYounan Zhang
292fd01d75SYounan Zhang // expected-note@#1 {{in instantiation of variable template specialization 'is_convertible_v<bool, bool>' requested here}}
302fd01d75SYounan Zhang // expected-note@#1 {{substituting template arguments into constraint expression here}}
312fd01d75SYounan Zhang // expected-note@#3 {{checking the satisfaction of concept 'convertible_to<bool, bool>'}}
322fd01d75SYounan Zhang // expected-note@#2 {{substituting template arguments into constraint expression here}}
332fd01d75SYounan Zhang // expected-note@#5 {{checking constraint satisfaction for template 'compare<Object *, Object *>'}}
342fd01d75SYounan Zhang // expected-note@#5 {{in instantiation of function template specialization 'compare<Object *, Object *>' requested here}}
352fd01d75SYounan Zhang
362fd01d75SYounan Zhang // expected-note@#4 {{candidate template ignored: constraints not satisfied [with IteratorL = Object *, IteratorR = Object *]}}
372fd01d75SYounan Zhang // We don't know exactly the substituted type for `lhs == rhs`, thus a placeholder 'expr-type' is emitted.
382fd01d75SYounan Zhang // expected-note@#3 {{because 'convertible_to<expr-type, bool>' would be invalid}}
39