https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120320
--- Comment #2 from Patrick Palka <ppalka at gcc dot gnu.org> --- The problem is the CNF/DNF of the constraints in template<Matrix T1, Matrix T2> requires(DenseMatrix<T1> || DenseMatrix<T2> || SparseMatrix<T1> || SparseMatrix<T2>) struct storage_mul<T1, T2> template<SparseMatrix T1, DiagonalMatrix T2> struct storage_mul<T1, T2> template<DiagonalMatrix T1, SparseMatrix T2> struct storage_mul<T1, T2> are all huge, which makes determining which of these partial specializations is most constrained not feasible via the ordinary subsumption algorithm. Assuming the intent is to make the second and third partial specializations above preferred over the first one, a workaround is to make this preference more obvious, e.g. by adding potentially redundant constraints: @@ -1187,7 +1187,7 @@ struct storage_mul<T, S> Specialization for DenseMatrix * Matrix or Matrix * DenseMatrix or SparseMatrix * Matrix or Matrix * SparseMatrix. */ template<Matrix T1, Matrix T2> -requires(DenseMatrix<T1> || DenseMatrix<T2> || SparseMatrix<T1> || SparseMatrix<T2>) +requires(!DiagonalMatrix<T1>) && (!DiagonalMatrix<T2>) && (DenseMatrix<T1> || DenseMatrix<T2> || SparseMatrix<T1> || SparseMatrix<T2>) struct storage_mul<T1, T2> { storage_mul() = delete;