On Wed, 9 Apr 2025, Patrick Palka wrote:

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

Oops, that was not a complete diff of all the concepts tests, here is a
more complete one.

> 
> -- >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 db26b86de4b2..14bf67ee0580 100644
--- a/output-old.log
+++ b/output-new.log
@@ -476,7 +476,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |          ^~
 ./concepts/generic-fn-err.C:29:10: note: template argument deduction/substitution failed:
 ./concepts/generic-fn-err.C:29:10: note: constraints not satisfied
-./concepts/generic-fn-err.C: In substitution of ‘template<class auto:6>  requires  C<auto:6> void S2<S>::f2(auto:6) [with auto:6 = S]’:
+./concepts/generic-fn-err.C: In substitution of ‘template<class T> template<class auto:6>  requires  C<auto:6> void S2<T>::f2(auto:6) [with auto:6 = int; T = S]’:
 ./concepts/generic-fn-err.C:45:8:   required from here
    45 |   s2.f2(0); // { dg-error "matching" }
       |   ~~~~~^~~
@@ -493,7 +493,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |          ^~
 ./concepts/generic-fn-err.C:32:10: note: template argument deduction/substitution failed:
 ./concepts/generic-fn-err.C:32:10: note: constraints not satisfied
-./concepts/generic-fn-err.C: In substitution of ‘template<class auto:8>  requires  C<auto:8> void S2<S>::h2(auto:8) [with auto:8 = S]’:
+./concepts/generic-fn-err.C: In substitution of ‘template<class T> template<class auto:8>  requires  C<auto:8> void S2<T>::h2(auto:8) [with auto:8 = int; T = S]’:
 ./concepts/generic-fn-err.C:46:8:   required from here
    46 |   s2.h2(0); // { dg-error "matching" }
       |   ~~~~~^~~
@@ -510,7 +510,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |            ^
 ./concepts/generic-fn-err.C:35:12: note: template argument deduction/substitution failed:
 ./concepts/generic-fn-err.C:35:12: note: constraints not satisfied
-./concepts/generic-fn-err.C: In substitution of ‘template<class U>  requires  C<U> void S2<S>::g(S, U) [with U = S]’:
+./concepts/generic-fn-err.C: In substitution of ‘template<class T> template<class U>  requires  C<U> void S2<T>::g(T, U) [with U = int; T = S]’:
 ./concepts/generic-fn-err.C:48:7:   required from here
    48 |   s2.g(s, 0); // { dg-error "matching" }
       |   ~~~~^~~~~~
@@ -578,7 +578,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./concepts/variadic2.C:12:15: note: candidate 2: ‘constexpr int f(Ts ...) [with Ts = {int}]’
    12 | constexpr int f(Ts...) { return 1; }     // #2
       |               ^
-./concepts/diagnostic20a.C: In substitution of ‘template<class U> static void A<int>::f() requires (<lambda>)() [with U = int]’:
+./concepts/diagnostic20a.C: In substitution of ‘template<class T> template<class U> static void A<T>::f() requires (<lambda>)() [with U = char; T = int]’:
 ./concepts/diagnostic20a.C:10:18:   required from here
    10 |   A<int>::f<char>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~^~
@@ -886,7 +886,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
 ./concepts/inherit-ctor3.C:10:7: note: constraints not satisfied
    10 |       S1(U x) { }
       |       ^~
-./concepts/inherit-ctor3.C: In substitution of ‘template<class U>  requires  C<U> S1<X>::S1(U) [with U = X]’:
+./concepts/inherit-ctor3.C: In substitution of ‘template<class T> template<class U>  requires  C<U> S1<T>::S1(U) [with U = int; T = X]’:
 ./concepts/inherit-ctor3.C:21:13:   required from here
    21 |   S2<X> s1(0); // { dg-error "no matching function" }
       |             ^
@@ -1019,7 +1019,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |                         ^
 ./concepts/placeholder4.C:17:25: note: template argument deduction/substitution failed:
 ./concepts/placeholder4.C:17:25: note: constraints not satisfied
-./concepts/placeholder4.C: In substitution of ‘template<int t, class c>  requires  C<c> static constexpr bool A<int>::f() [with int t = int; c = <missing>]’:
+./concepts/placeholder4.C: In substitution of ‘template<class T> template<T t, class c>  requires  C<c> static constexpr bool A<T>::f() [with T t = 1; c = double; T = int]’:
 ./concepts/placeholder4.C:20:34:   required from here
    20 | static_assert(A<int>::f<1,double>(), "");       // { dg-error "" }
       |               ~~~~~~~~~~~~~~~~~~~^~
@@ -1814,7 +1814,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |                                  ^
 ./concepts/diagnostic20.C:6:34: note: template argument deduction/substitution failed:
 ./concepts/diagnostic20.C:6:34: note: constraints not satisfied
-./concepts/diagnostic20.C: In substitution of ‘template<class U> static void A<int>::f() requires requires{T::fail;} [with U = int]’:
+./concepts/diagnostic20.C: In substitution of ‘template<class T> template<class U> static void A<T>::f() requires requires{T::fail;} [with U = char; T = int]’:
 ./concepts/diagnostic20.C:10:18:   required from here
    10 |   A<int>::f<char>(); // { dg-error "no match" }
       |   ~~~~~~~~~~~~~~~^~
@@ -2513,7 +2513,7 @@ cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more de
       |   ^
 ./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" }
       |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
@@ -2712,7 +2712,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" }
       |   ~~~~~^~~
@@ -2914,7 +2914,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" }
       |   ~~~~~~~~~~~~~^~
@@ -2931,7 +2931,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" }
       |   ~~~~~~~~~~~~~~~~~~~~~^~
@@ -3262,7 +3262,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" }
       |              ^
@@ -3337,7 +3337,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" }
       |   ~~~~^~~
@@ -4240,7 +4240,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" }
       |   ~^~~~~~
@@ -4265,7 +4265,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" }
       |   ~~~~~~~~^~~
@@ -4321,7 +4321,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" }
       |     ~~~~~~~~^~~~
@@ -4356,7 +4356,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’
@@ -4505,7 +4505,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" }
       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -4561,7 +4561,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" }
       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -4602,7 +4602,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" }
       |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
@@ -5026,7 +5026,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" }
       |   ~~~~~~~~~~~~^~
@@ -5045,7 +5045,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" }
       |   ~~~~~~~~~~~~~~~~~~~^~~
@@ -5062,7 +5062,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" }
       |   ~~~~~~~~~~~~^~
@@ -5081,7 +5081,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" }
       |   ~~~~~~~~~~~~~~~~~~~^~~
@@ -5188,7 +5188,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 "" }
       |   ~~~~~~^~~~~~~~~~~~~~~~~~~~
@@ -5278,7 +5278,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" }
       |     ~~~~^~
@@ -5761,7 +5761,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" }
       |                               ^
@@ -5974,7 +5974,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" }
       |   ~~~~^~~~~~~~~~
@@ -5991,7 +5991,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" }
       |   ~~~~^~~~~~~~~~
@@ -6008,7 +6008,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" }
       |   ~~~~^~~~~~~~~~
@@ -6227,7 +6227,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" }
       |   ~~~~~~~~~~~~^~~~~~~~~
@@ -6248,7 +6248,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" }
       |   ~~~~~~~~~~~~~~~~~^~~~~~~~~
@@ -6268,7 +6268,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" }
       |   ~~~~~~~~~~~~~~^~~~~~~~~
@@ -6288,7 +6288,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" }
       |   ~~~~~~~~~~~~~~~~~~~^~~~~~~~~
@@ -6308,7 +6308,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" }
       |   ~~~~~~~~~^~~~~~~~~
@@ -6655,7 +6655,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" }
       |   ~~~~~~~~~~^~
@@ -6673,7 +6673,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" }
       |   ~~~~~~~~~~^~
@@ -7131,7 +7131,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
@@ -7363,8 +7363,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
@@ -7669,7 +7669,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