When checking that a constrained partial specialization is more
constrained than the primary template, we pass only the innermost level
of generic template arguments to strictly_subsumes. This leads to us
doing a nonsensical substitution from normalize_concept_check if the
full set of template arguments has multiple levels, and it ultimately
causes strictly_subsumes to sometimes erroneously return false as in the
testcase below.
gcc/cp/ChangeLog:
* pt.c (process_partial_specialization): Pass the full set of
generic template arguments to strictly_subsumes.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-partial-spec8.C: New test.
if (comp_template_args (inner_args, INNERMOST_TEMPLATE_ARGS (main_args))
&& (!flag_concepts
|| !strictly_subsumes (current_template_constraints (),
- inner_args, maintmpl)))
+ main_args, maintmpl)))
{
if (!flag_concepts)
error ("partial specialization %q+D does not specialize "
--- /dev/null
+// { dg-do compile { target c++20 } }
+
+template<int M, int N>
+concept equal = M == N;
+
+template<int M>
+struct traits
+{
+ template<int N> requires equal<M, N>
+ struct foo {};
+
+ template<int N> requires equal<M, N> && (M >= 0) // { dg-bogus "not more constrained" }
+ struct foo<N> {};
+};