On Wed, 5 Mar 2025, Jason Merrill wrote:

> On 3/5/25 10:13 AM, Patrick Palka wrote:
> > On Tue, 4 Mar 2025, Jason Merrill wrote:
> > 
> > > On 3/4/25 2:49 PM, Patrick Palka wrote:
> > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
> > > > for trunk/14?
> > > > 
> > > > -- >8 --
> > > > 
> > > > In the three-parameter version of satisfy_declaration_constraints, when
> > > > 't' isn't the most general template, then 't' won't correspond with
> > > > 'args' after we augment the latter via add_outermost_template_args, and
> > > > so the instantiation context that we push via push_tinst_level isn't
> > > > quite correct: 'args' is a complete set of template arguments, but 't'
> > > > is not necessarily the most general template.  This manifests as
> > > > misleading diagnostic context lines when issuing a hard error (or a
> > > > constraint recursion error) that occurred during satisfaction, e.g. for
> > > > the below testcase without this patch we emit:
> > > >     In substitution of '... void A<int>::f<U>() [with U = int]'
> > > > and with this patch we emit:
> > > >     In substitution of '... void A<T>::f<U>() [with U = char; T = int]'.
> > > > 
> > > > This patch fixes this by always passing the most general template to
> > > > push_tinst_level.
> > > 
> > > That soungs good, but getting it by passing it back from
> > > get_normalized_constraints_from_decl seems confusing; I'd think we should
> > > calculate it in parallel to changing args to correspond to that template.
> > 
> > Hmm, won't that mean duplicating the template adjustment logic in
> > get_normalized_constraints_from_decl, which seems undesirable?  The
> > function has many callers, some of which are for satisfaction where
> > targs are involved, and the rest are for subsumption where no targs are
> > involved, so I don't see a clean way of refactoring the code to avoid
> > duplication of the template adjustment logic.  Right now the targ
> > adjustment logic is unfortunately duplicated across both overloads
> > of satisfy_declaration_constraints and it seems undesirable to add
> > more duplication.
> 
> Fair enough.  Incidentally, I wonder why the two-parm overload doesn't call
> the three-parm overload?
> 
> > Maybe one way to reduce the duplication would be to go the other way and
> > move the targ adjustment logic to get_normalized_constraints_from_decl
> > as well (so that it has two out-parameters, 'gen_d' and 'gen_args').
> > The proposed patch then would be an incremental step towards that.
> 
> That makes sense, passing back something suitable for
> add_outermost_template_args.

I tried combining the two overloads, and/or moving the targ adjustment
logic to get_normalized_constraints_from_decl, but I couldn't arrive at
a formulation that worked and I was happy with (i.e. didn't lead to more
code duplication than the original appproach).

In the meantime I noticed that this bug is more pervasive than I
thought, and leads to wrong diagnostic context lines printed even in the
case of ordinary satisfaction failure -- however the wrong diagnostic
lines are more annoying/noticable during a hard error or constraint
recursion where there's likely no other useful diagnostic lines that
might have the correct args printed.

So I adjusted the testcase in the original patch accordingly.  Could the
following go in for now?

I also attached a diff of the output of all our concepts testcases
currently, before/after this patch.  Each change seems like a clear
improvement/correction to me.

-- >8 --

Subject: [PATCH] c++: wrong targs in satisfaction diagnostic context line
 [PR99214]

In the three-parameter version of satisfy_declaration_constraints, when
't' isn't the most general template, then 't' won't correspond with
'args' after we augment the latter via add_outermost_template_args, and
so the instantiation context that we push via push_tinst_level isn't
quite correct: 'args' is a complete set of template arguments, but 't'
is not necessarily the most general template.  This manifests as
misleading diagnostic context lines when issuing a satisfaction failure
error, e.g.  the below testcase without this patch we emit:
  In substitution of '... void A<int>::f<U>() [with U = int]'
and with this patch we emit:
  In substitution of '... void A<T>::f<U>() [with U = char; T = int]'.

This patch fixes this by always passing the most general template to
push_tinst_level.

        PR c++/99214

gcc/cp/ChangeLog:

        * constraint.cc (get_normalized_constraints_from_decl): New
        optional out-parameter GEN_D.
        (satisfy_declaration_constraints): Use it to pass the most
        general version of T to push_tinst_level.

gcc/testsuite/ChangeLog:

        * g++.dg/concepts/diagnostic20.C: New test.
---
 gcc/cp/constraint.cc                         | 15 +++++++++++----
 gcc/testsuite/g++.dg/concepts/diagnostic20.C | 14 ++++++++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic20.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index a9caba8e2cc7..f688a99c5fd7 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -648,10 +648,13 @@ get_normalized_constraints_from_info (tree ci, tree 
in_decl, bool diag = false)
   return t;
 }
 
-/* Returns the normalized constraints for the declaration D.  */
+/* Returns the normalized constraints for the declaration D.
+   If GEN_D is non-NULL, sets *GEN_D to the most general version
+   of D that ultimately owns its constraints.  */
 
 static tree
-get_normalized_constraints_from_decl (tree d, bool diag = false)
+get_normalized_constraints_from_decl (tree d, bool diag = false,
+                                     tree *gen_d = nullptr)
 {
   tree tmpl;
   tree decl;
@@ -716,6 +719,8 @@ get_normalized_constraints_from_decl (tree d, bool diag = 
false)
     tmpl = most_general_template (tmpl);
 
   d = tmpl ? tmpl : decl;
+  if (gen_d)
+    *gen_d = d;
 
   /* If we're not diagnosing errors, use cached constraints, if any.  */
   if (!diag)
@@ -2730,9 +2735,11 @@ satisfy_declaration_constraints (tree t, tree args, 
sat_info info)
     return boolean_true_node;
 
   tree result = boolean_true_node;
-  if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
+  tree gen_t;
+  if (tree norm = get_normalized_constraints_from_decl (t, info.noisy (),
+                                                       &gen_t))
     {
-      if (!push_tinst_level (t, args))
+      if (!push_tinst_level (gen_t, args))
        return result;
       tree pattern = DECL_TEMPLATE_RESULT (t);
       push_to_top_level ();
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic20.C 
b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
new file mode 100644
index 000000000000..d88000b342c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic20.C
@@ -0,0 +1,14 @@
+// PR c++/99214
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct A {
+  template <class U> static void f() requires requires { T::fail; };
+};
+
+int main() {
+  A<int>::f<char>(); // { dg-error "no match" }
+}
+
+// This matches the context line "In substitution of '... [with U = char; T = 
int]'"
+// { dg-message "U = char; T = int" "" { target *-*-* } 0 }
-- 
2.49.0.221.g485f5f8636
diff --git a/output-old.log b/output-new.log
index 46783d7ee9fe..1dffaa8e2bb6 100644
--- a/output-old.log
+++ b/output-new.log
@@ -848,7 +848,7 @@
       |   ^
 ./cpp2a/concepts-lambda11.C:10:3: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda11.C:10:3: note: constraints not satisfied
-./cpp2a/concepts-lambda11.C: In substitution of ‘template<int M> foo<0>()::<lambda()> [with int M = 0]’:
+./cpp2a/concepts-lambda11.C: In substitution of ‘template<int N> template<int M> foo()::<lambda()> [with int M = 1; int N = 0]’:
 ./cpp2a/concepts-lambda11.C:10:40:   required from ‘auto foo() [with int N = 0]’
    10 |   [] <int M=1> () requires (N == M) { }(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
@@ -1047,7 +1047,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |                        ^~
 ./cpp2a/concepts-memfun-err.C:19:24: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-memfun-err.C:19:24: note: constraints not satisfied
-./cpp2a/concepts-memfun-err.C: In substitution of ‘template<class U>  requires  C<U> void S1<int>::h1(U) [with U = int]’:
+./cpp2a/concepts-memfun-err.C: In substitution of ‘template<class T> template<class U>  requires  C<U> void S1<T>::h1(U) [with U = int; T = int]’:
 ./cpp2a/concepts-memfun-err.C:34:8:   required from here
    34 |   si.h1(0); // { dg-error "matching" }
       |   ~~~~~^~~
@@ -1249,7 +1249,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |      ^~~~~~
 ./cpp2a/concepts-explicit-spec7.C:18:6: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-explicit-spec7.C:18:6: note: constraints not satisfied
-./cpp2a/concepts-explicit-spec7.C: In substitution of ‘template<int N> static void A<int>::f() requires  N == 42 [with int N = int]’:
+./cpp2a/concepts-explicit-spec7.C: In substitution of ‘template<class T> template<int N> static void A<T>::f() requires  N == 42 [with int N = 43; T = int]’:
 ./cpp2a/concepts-explicit-spec7.C:27:16:   required from here
    27 |   A<int>::f<43>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~^~
@@ -1266,7 +1266,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |      ^~~~~~
 ./cpp2a/concepts-explicit-spec7.C:23:6: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-explicit-spec7.C:23:6: note: constraints not satisfied
-./cpp2a/concepts-explicit-spec7.C: In substitution of ‘template<int N> static void A<int>::B<int>::g() requires  T(N) == 42 [with int N = int]’:
+./cpp2a/concepts-explicit-spec7.C: In substitution of ‘template<class T> template<class U> template<int N> static void A<T>::B<U>::g() requires  T(N) == 42 [with int N = 43; U = int; T = int]’:
 ./cpp2a/concepts-explicit-spec7.C:29:24:   required from here
    29 |   A<int>::B<int>::g<43>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~~~^~
@@ -1597,7 +1597,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./cpp2a/concepts-inherit-ctor4.C:8:19: note: constraints not satisfied
     8 |     template<C U> S1(U x) { }
       |                   ^~
-./cpp2a/concepts-inherit-ctor4.C: In substitution of ‘template<class U>  requires  C<U> S1<int>::S1(U) [with U = int]’:
+./cpp2a/concepts-inherit-ctor4.C: In substitution of ‘template<class T> template<class U>  requires  C<U> S1<T>::S1(U) [with U = int; T = int]’:
 ./cpp2a/concepts-inherit-ctor4.C:17:14:   required from here
    17 |   S2<int> s(0); // { dg-error "no matching function" }
       |              ^
@@ -1672,7 +1672,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |                                                    ^
 ./cpp2a/concepts-fn1.C:96:52: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-fn1.C:96:52: note: constraints not satisfied
-./cpp2a/concepts-fn1.C: In substitution of ‘template<class U>  requires  Classes<T, U> void S<X>::h(U) [with U = X]’:
+./cpp2a/concepts-fn1.C: In substitution of ‘template<class T> template<class U>  requires  Classes<T, U> void S<T>::h(U) [with U = int; T = X]’:
 ./cpp2a/concepts-fn1.C:106:7:   required from here
   106 |   s1.h(0); // { dg-error "no matching function" }
       |   ~~~~^~~
@@ -2575,7 +2575,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |               ^
 ./cpp2a/concepts-friend12.C:11:15: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-friend12.C:11:15: note: constraints not satisfied
-./cpp2a/concepts-friend12.C: In substitution of ‘template<class ... Us>  requires (C<Ts, Us> && ...) void f(A<int>, A<Us ...>) [with Us = {int}]’:
+./cpp2a/concepts-friend12.C: In substitution of ‘template<class ... Ts> template<class ... Us>  requires (C<Ts, Us> && ...) void f(A<Ts>, A<Us ...>) [with Us = {char}; Ts = {int}]’:
 ./cpp2a/concepts-friend12.C:20:4:   required from here
    20 |   f(x, z); // { dg-error "no match" }
       |   ~^~~~~~
@@ -2600,7 +2600,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^
 ./cpp2a/concepts-this1.C:10:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-this1.C:10:8: note: constraints not satisfied
-./cpp2a/concepts-this1.C: In substitution of ‘template<class U>  requires requires{((A<T, <template-parameter-1-2> >*)(void)0)->A<T, <template-parameter-1-2> >::val.x;} void A<C>::f(U) [with U = C]’:
+./cpp2a/concepts-this1.C: In substitution of ‘template<class T, class> template<class U>  requires requires{((A<T, <template-parameter-1-2> >*)(void)0)->A<T, <template-parameter-1-2> >::val.x;} void A<T, <template-parameter-1-2> >::f(U) [with U = int; T = C; <template-parameter-1-2> = void]’:
 ./cpp2a/concepts-this1.C:27:11:   required from here
    27 |   A<C>().f(0); // { dg-error "no match" }
       |   ~~~~~~~~^~~
@@ -2656,7 +2656,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./cpp2a/concepts-lambda12.C:9:12: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda12.C:9:12: note: constraints not satisfied
-./cpp2a/concepts-lambda12.C: In substitution of ‘template<class auto:1>  requires  different_than<auto:1, B> diff<int>(int)::<lambda(auto:1)> [with auto:1 = int]’:
+./cpp2a/concepts-lambda12.C: In substitution of ‘template<class B> template<class auto:1>  requires  different_than<auto:1, B> diff(B)::<lambda(auto:1)> [with auto:1 = int; B = int]’:
 ./cpp2a/concepts-lambda12.C:14:13:   required from here
    14 |     diff(42)(42); // { dg-error "no match" }
       |     ~~~~~~~~^~~~
@@ -2691,7 +2691,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
    15 | int y = A<int>::v<char>; // { dg-error "invalid" }
       |                 ^~~~~~~
 ./cpp2a/concepts-var-templ1b.C:15:17: note: constraints not satisfied
-./cpp2a/concepts-var-templ1b.C: In substitution of ‘template<class> int A<int>::v< <template-parameter-1-1> > [with <template-parameter-1-1> = int]’:
+./cpp2a/concepts-var-templ1b.C: In substitution of ‘template<class T> template<class>  requires  C< <template-parameter-2-1>, T> int A<T>::v< <template-parameter-2-1> > [with <template-parameter-2-1> = char; T = int]’:
 ./cpp2a/concepts-var-templ1b.C:15:17:   required from here
 ./cpp2a/concepts-var-templ1b.C:4:36:   required for the satisfaction of ‘C< <template-parameter-2-1>, T>’ [with <template-parameter-2-1> = char; T = int]
 ./cpp2a/concepts-var-templ1b.C:4:40: note:   ‘char’ is not the same as ‘int’
@@ -2840,7 +2840,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |     ^
 ./cpp2a/concepts-lambda2.C:32:5: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:32:5: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class R>  requires  IsNotTiny<R> Bar<long long int>::<lambda(R)> [with R = long long int]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class R>  requires  IsNotTiny<R> Bar<T>::<lambda(R)> [with R = char; T = long long int]’:
 ./cpp2a/concepts-lambda2.C:32:39:   required from ‘constexpr const auto Bar<long long int>::a’
    32 |     []<IsNotTiny R>(R t) { return t; }('a'); // { dg-error "no match" }
       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -2896,7 +2896,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |     ^
 ./cpp2a/concepts-lambda2.C:34:5: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:34:5: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class R>  requires  IsNotTiny<R> Bar<long long int>::<lambda(R)> [with R = long long int]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class R>  requires  IsNotTiny<R> Bar<T>::<lambda(R)> [with R = char; T = long long int]’:
 ./cpp2a/concepts-lambda2.C:34:39:   required from here
    34 |     []<IsNotTiny R>(R t) { return t; }('b'); // { dg-error "no match" }
       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -2937,7 +2937,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |   ^
 ./cpp2a/concepts-lambda2.C:44:3: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:44:3: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class R>  requires  IsNotTiny<R> <lambda(R)> [with R = char]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class S> template<class R>  requires  IsNotTiny<R> <lambda(R)> [with R = char; S = char]’:
 ./cpp2a/concepts-lambda2.C:44:37:   required from ‘char c<char>’
    44 |   []<IsNotTiny R>(R t) { return t; }('c'); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -3361,7 +3361,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^
 ./cpp2a/concepts-lambda2.C:22:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:22:8: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class S>  requires  IsNotTiny<S> auto Foo<int>::b() [with S = int]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class S>  requires  IsNotTiny<S> auto Foo<T>::b() [with S = char; T = int]’:
 ./cpp2a/concepts-lambda2.C:136:15:   required from here
   136 |   foo1.b<char>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~^~
@@ -3380,7 +3380,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./cpp2a/concepts-lambda2.C:24:12: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:24:12: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class auto:2>  requires  False<auto:2> Foo<int>::b<long long int>()::<lambda(auto:2)> [with auto:2 = int]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class S> template<class auto:2>  requires  False<auto:2> Foo<T>::b()::<lambda(auto:2)> [with auto:2 = int; S = long long int; T = int]’:
 ./cpp2a/concepts-lambda2.C:137:22:   required from here
   137 |   foo1.b<long long>()(5); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~^~~
@@ -3397,7 +3397,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^
 ./cpp2a/concepts-lambda2.C:22:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:22:8: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class S>  requires  IsNotTiny<S> auto Foo<double>::b() [with S = double]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class S>  requires  IsNotTiny<S> auto Foo<T>::b() [with S = char; T = double]’:
 ./cpp2a/concepts-lambda2.C:142:15:   required from here
   142 |   foo2.b<char>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~^~
@@ -3416,7 +3416,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./cpp2a/concepts-lambda2.C:24:12: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda2.C:24:12: note: constraints not satisfied
-./cpp2a/concepts-lambda2.C: In substitution of ‘template<class auto:2>  requires  False<auto:2> Foo<double>::b<long long int>()::<lambda(auto:2)> [with auto:2 = double]’:
+./cpp2a/concepts-lambda2.C: In substitution of ‘template<class T> template<class S> template<class auto:2>  requires  False<auto:2> Foo<T>::b()::<lambda(auto:2)> [with auto:2 = int; S = long long int; T = double]’:
 ./cpp2a/concepts-lambda2.C:143:22:   required from here
   143 |   foo2.b<long long>()(5); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~^~~
@@ -3523,7 +3523,7 @@ compilation terminated.
       |               ^~~~~~
 ./cpp2a/concepts-pr68093-1.C:7:15: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-pr68093-1.C:7:15: note: constraints not satisfied
-./cpp2a/concepts-pr68093-1.C: In substitution of ‘template<class t2>  requires  false void foobar(S<double>, t2) [with t2 = double]’:
+./cpp2a/concepts-pr68093-1.C: In substitution of ‘template<class t> template<class t2>  requires  false void foobar(S<t>, t2) [with t2 = int; t = double]’:
 ./cpp2a/concepts-pr68093-1.C:12:9:   required from here
    12 |   foobar(S<double>{}, int{}); // { dg-error "" }
       |   ~~~~~~^~~~~~~~~~~~~~~~~~~~
@@ -3613,7 +3613,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^
 ./cpp2a/concepts-uneval5.C:9:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-uneval5.C:9:8: note: constraints not satisfied
-./cpp2a/concepts-uneval5.C: In substitution of ‘template<int J> void A<0>::f(A<J>) requires  A<I>::f::d.i != A<I>::i [with int J = 0]’:
+./cpp2a/concepts-uneval5.C: In substitution of ‘template<int I> template<int J> void A<I>::f(A<J>) requires  A<I>::f::d.i != A<I>::i [with int J = 0; int I = 0]’:
 ./cpp2a/concepts-uneval5.C:10:9:   required from ‘void A<I>::f(A<J>) requires  A<I>::f::d.i != A<I>::i [with int J = 1; int I = 0]’
    10 |     f<I>(); // { dg-error "no match" }
       |     ~~~~^~
@@ -4096,7 +4096,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./cpp2a/concepts-inherit-ctor11.C:11:5: note: constraints not satisfied
    11 |     alphabet_tuple_base(component_type) {}
       |     ^~~~~~~~~~~~~~~~~~~
-./cpp2a/concepts-inherit-ctor11.C: In substitution of ‘template<class component_type>  requires  __is_same(component_type, component_types) alphabet_tuple_base<rna4>::alphabet_tuple_base(component_type) [with component_type = rna4]’:
+./cpp2a/concepts-inherit-ctor11.C: In substitution of ‘template<class component_types> template<class component_type>  requires  __is_same(component_type, component_types) alphabet_tuple_base<component_types>::alphabet_tuple_base(component_type) [with component_type = dna4; component_types = rna4]’:
 ./cpp2a/concepts-inherit-ctor11.C:20:31:   required from here
    20 | structured_rna<rna4> t2{dna4{}}; // { dg-error "no match" }
       |                               ^
@@ -4309,7 +4309,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^~
 ./cpp2a/concepts-fn3.C:24:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-fn3.C:24:8: note: constraints not satisfied
-./cpp2a/concepts-fn3.C: In substitution of ‘template<class ... auto:4>  requires (... && integral<auto:4>) void S<void>::f1(auto:4 ...) [with auto:4 = void]’:
+./cpp2a/concepts-fn3.C: In substitution of ‘template<class T> template<class ... auto:4>  requires (... && integral<auto:4>) void S<T>::f1(auto:4 ...) [with auto:4 = {int, int, unsigned int}; T = void]’:
 ./cpp2a/concepts-fn3.C:43:7:   required from here
    43 |   s.f1(1, 2, 3u); // { dg-error "no matching function" }
       |   ~~~~^~~~~~~~~~
@@ -4326,7 +4326,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^~
 ./cpp2a/concepts-fn3.C:25:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-fn3.C:25:8: note: constraints not satisfied
-./cpp2a/concepts-fn3.C: In substitution of ‘template<class ... auto:5>  requires (... && all_integral<auto:5>) void S<void>::f2(auto:5 ...) [with auto:5 = void]’:
+./cpp2a/concepts-fn3.C: In substitution of ‘template<class T> template<class ... auto:5>  requires (... && all_integral<auto:5>) void S<T>::f2(auto:5 ...) [with auto:5 = {int, int, unsigned int}; T = void]’:
 ./cpp2a/concepts-fn3.C:45:7:   required from here
    45 |   s.f2(1, 2, 3u); // { dg-error "no matching function" }
       |   ~~~~^~~~~~~~~~
@@ -4343,7 +4343,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^~
 ./cpp2a/concepts-fn3.C:28:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-fn3.C:28:8: note: constraints not satisfied
-./cpp2a/concepts-fn3.C: In substitution of ‘template<class U, class ... auto:6>  requires (type<U>) && true && ((... && integral<auto:6>)) void S<void>::f3(U, auto:6 ...) [with U = void; auto:6 = <missing>]’:
+./cpp2a/concepts-fn3.C: In substitution of ‘template<class T> template<class U, class ... auto:6>  requires (type<U>) && true && ((... && integral<auto:6>)) void S<T>::f3(U, auto:6 ...) [with U = int; auto:6 = {int, unsigned int}; T = void]’:
 ./cpp2a/concepts-fn3.C:47:7:   required from here
    47 |   s.f3(1, 2, 3u); // { dg-error "no matching function" }
       |   ~~~~^~~~~~~~~~
@@ -4562,7 +4562,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./cpp2a/concepts-lambda16.C:7:12: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda16.C:7:12: note: constraints not satisfied
-./cpp2a/concepts-lambda16.C: In substitution of ‘template<class V> A<int>::<lambda(U)>::<lambda(V)> [with V = int]’:
+./cpp2a/concepts-lambda16.C: In substitution of ‘template<class T> template<class U> template<class V> A<T>::<lambda(U)>::<lambda(V)> [with V = std::nullptr_t; U = int; T = int]’:
 ./cpp2a/concepts-lambda16.C:45:15:   required from here
    45 |   A<int>::a(0)(nullptr); // { dg-error "no match" }
       |   ~~~~~~~~~~~~^~~~~~~~~
@@ -4583,7 +4583,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./cpp2a/concepts-lambda16.C:12:12: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda16.C:12:12: note: constraints not satisfied
-./cpp2a/concepts-lambda16.C: In substitution of ‘template<class V> A<int>::<lambda(U)>::<lambda(V)> [with V = int]’:
+./cpp2a/concepts-lambda16.C: In substitution of ‘template<class T> template<class W> template<class U> template<class V> A<T>::<lambda(U)>::<lambda(V)> [with V = std::nullptr_t; U = int; W = int; T = int]’:
 ./cpp2a/concepts-lambda16.C:48:20:   required from here
    48 |   A<int>::b<int>(0)(nullptr); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~^~~~~~~~~
@@ -4603,7 +4603,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |              ^
 ./cpp2a/concepts-lambda16.C:17:14: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda16.C:17:14: note: constraints not satisfied
-./cpp2a/concepts-lambda16.C: In substitution of ‘template<class V> A<int>::f()::<lambda(U)>::<lambda(V)> [with V = int]’:
+./cpp2a/concepts-lambda16.C: In substitution of ‘template<class T> template<class U> template<class V> A<T>::f()::<lambda(U)>::<lambda(V)> [with V = std::nullptr_t; U = int; T = int]’:
 ./cpp2a/concepts-lambda16.C:51:17:   required from here
    51 |   A<int>::f()(0)(nullptr); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~^~~~~~~~~
@@ -4623,7 +4623,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |              ^
 ./cpp2a/concepts-lambda16.C:24:14: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda16.C:24:14: note: constraints not satisfied
-./cpp2a/concepts-lambda16.C: In substitution of ‘template<class V> A<int>::g<int>()::<lambda(U)>::<lambda(V)> [with V = int]’:
+./cpp2a/concepts-lambda16.C: In substitution of ‘template<class T> template<class W> template<class U> template<class V> A<T>::g()::<lambda(U)>::<lambda(V)> [with V = std::nullptr_t; U = int; W = int; T = int]’:
 ./cpp2a/concepts-lambda16.C:54:22:   required from here
    54 |   A<int>::g<int>()(0)(nullptr); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~~~~~^~~~~~~~~
@@ -4643,7 +4643,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |          ^
 ./cpp2a/concepts-lambda16.C:31:10: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-lambda16.C:31:10: note: constraints not satisfied
-./cpp2a/concepts-lambda16.C: In substitution of ‘template<class V> <lambda(U)>::<lambda(V)> [with V = int]’:
+./cpp2a/concepts-lambda16.C: In substitution of ‘template<class T> template<class U> template<class V> <lambda(U)>::<lambda(V)> [with V = std::nullptr_t; U = int; T = int]’:
 ./cpp2a/concepts-lambda16.C:57:12:   required from here
    57 |   a<int>(0)(nullptr); // { dg-error "no match" }
       |   ~~~~~~~~~^~~~~~~~~
@@ -4990,7 +4990,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^~
 ./cpp2a/concepts-requires18.C:36:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-requires18.C:36:8: note: constraints not satisfied
-./cpp2a/concepts-requires18.C: In substitution of ‘template<class U>  requires  c1<U> void data<char>::f1() [with U = char]’:
+./cpp2a/concepts-requires18.C: In substitution of ‘template<class T> template<class U>  requires  c1<U> void data<T>::f1() [with U = void; T = char]’:
 ./cpp2a/concepts-requires18.C:79:13:   required from here
    79 |   x.f1<void>(); // { dg-error "no matching function" }
       |   ~~~~~~~~~~^~
@@ -5008,7 +5008,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |        ^~
 ./cpp2a/concepts-requires18.C:40:8: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-requires18.C:40:8: note: constraints not satisfied
-./cpp2a/concepts-requires18.C: In substitution of ‘template<class U>  requires requires{requires(integer<U>) || (subst<U&>);} void data<char>::f2() [with U = char]’:
+./cpp2a/concepts-requires18.C: In substitution of ‘template<class T> template<class U>  requires requires{requires(integer<U>) || (subst<U&>);} void data<T>::f2() [with U = void; T = char]’:
 ./cpp2a/concepts-requires18.C:82:13:   required from here
    82 |   x.f2<void>(); // { dg-error "no matching function" }
       |   ~~~~~~~~~~^~
@@ -5466,7 +5466,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./cpp2a/concepts-conv3a.C:7:38:   required from ‘struct Error<int>’
     7 | struct Error { static constexpr auto value = T::value; }; // { dg-error "not a member" }
       |                                      ^~~~~
-./cpp2a/concepts-conv3a.C:12:63:   required by substitution of ‘template<class U> B<int>::operator U() requires  Error<T>::value [with U = int]’
+./cpp2a/concepts-conv3a.C:12:63:   required by substitution of ‘template<class T> template<class U> B<T>::operator U() requires  Error<T>::value [with U = const A; T = int]’
    12 | struct B { template <class U> operator U() requires Error<T>::value; };
       |                                                               ^~~~~
 ./cpp2a/concepts-conv3a.C:15:33:   required from here
@@ -5698,8 +5698,8 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./cpp2a/concepts-pr100589.C:9:14: error: invalid use of constrained ‘auto’ type
     9 | using type = false_concept auto() -> int; // { dg-error "invalid use of constrained 'auto' type" }
       |              ^~~~~~~~~~~~~
-./cpp2a/concepts-recursive-sat4.C: In substitution of ‘template<class T>  requires  C<T, Rep> void operator*(T, Int<int>) [with T = int]’:
-./cpp2a/concepts-recursive-sat4.C:5:64:   required by substitution of ‘template<class T>  requires  C<T, Rep> void operator*(Int<int>, T) [with T = int]’
+./cpp2a/concepts-recursive-sat4.C: In substitution of ‘template<class Rep> template<class T>  requires  C<T, Rep> void operator*(T, Int<Rep>) [with T = Int<int>; Rep = int]’:
+./cpp2a/concepts-recursive-sat4.C:5:64:   required by substitution of ‘template<class Rep> template<class T>  requires  C<T, Rep> void operator*(Int<Rep>, T) [with T = Int<int>; Rep = int]’
     5 | template <class T, class U> concept C = requires(T t, U u) { t * u; };
       |                                                              ~~^~~
 ./cpp2a/concepts-recursive-sat4.C:15:25:   required from here
@@ -6004,7 +6004,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |               ^
 ./cpp2a/concepts-return-req4.C:15:15: note: template argument deduction/substitution failed:
 ./cpp2a/concepts-return-req4.C:15:15: note: constraints not satisfied
-./cpp2a/concepts-return-req4.C: In substitution of ‘template<class ...>  requires requires{{1} -> decltype(auto) [requires ::is_same<<placeholder>, T>];} static void A<bool>::f() [with <template-parameter-1-1> = bool]’:
+./cpp2a/concepts-return-req4.C: In substitution of ‘template<class T> template<class ...>  requires requires{{1} -> decltype(auto) [requires ::is_same<<placeholder>, T>];} static void A<T>::f() [with <template-parameter-2-1> = {}; T = bool]’:
 ./cpp2a/concepts-return-req4.C:23:13:   required from here
    23 |   A<bool>::f(); // { dg-error "no match" }
       |   ~~~~~~~~~~^~

Reply via email to