When the argument passed to `ASTContext::getUnconstrainedType` is an unconstrained `AutoType`, will return the argument unchanged. However, when called with a constrained `AutoType`, an unconstrained, non-dependent `AutoType` will be returned even if the argument was dependent. Consider the following: ``` template<typename T> concept C = sizeof(T) == sizeof(int); template<auto N> struct A; template<C auto N> struct A<N>; // error: class template partial specialization is not more specialized than the primary template ``` When comparing the template parameters for equivalence, `ASTContext::getUnconstrainedType` is used to remove the constraints per [temp.over.link] p6 sentence 2. For the template parameter `N` of the class template, it returns a dependent `AutoType`. For the template parameter `N` of the class template partial specialization, it returns a non-dependent `AutoType`. We subsequently compare the adjusted types and find they are not equivalent, thus we consider the partial specialization to not be more specialized than the primary template per [temp.func.order] p6.2.2. This patch changes `ASTContext::getUnconstrainedType` such that the dependence of a constrained `AutoType` will propagate to the returned unconstrained `AutoType`. This causes the above example to be correctly accepted, fixing #77377.
509 KiB
509 KiB