@@ -2743,6 +2743,7 @@ Expr *
2743
2743
buildAssociatedConstraints (Sema &SemaRef, FunctionTemplateDecl *F,
2744
2744
TypeAliasTemplateDecl *AliasTemplate,
2745
2745
ArrayRef<DeducedTemplateArgument> DeduceResults,
2746
+ unsigned UndeducedTemplateParameterStartIndex,
2746
2747
Expr *IsDeducible) {
2747
2748
Expr *RC = F->getTemplateParameters ()->getRequiresClause ();
2748
2749
if (!RC)
@@ -2803,8 +2804,22 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2803
2804
2804
2805
for (unsigned Index = 0 ; Index < DeduceResults.size (); ++Index) {
2805
2806
const auto &D = DeduceResults[Index];
2806
- if (D.isNull ())
2807
+ if (D.isNull ()) { // non-deduced template parameters of f
2808
+ auto TP = F->getTemplateParameters ()->getParam (Index);
2809
+ MultiLevelTemplateArgumentList Args;
2810
+ Args.setKind (TemplateSubstitutionKind::Rewrite);
2811
+ Args.addOuterTemplateArguments (TemplateArgsForBuildingRC);
2812
+ // Rebuild the template parameter with updated depth and index.
2813
+ NamedDecl *NewParam = transformTemplateParameter (
2814
+ SemaRef, F->getDeclContext (), TP, Args,
2815
+ /* NewIndex=*/ UndeducedTemplateParameterStartIndex++,
2816
+ getTemplateParameterDepth (TP) + AdjustDepth);
2817
+
2818
+ assert (TemplateArgsForBuildingRC[Index].isNull ());
2819
+ TemplateArgsForBuildingRC[Index] = Context.getCanonicalTemplateArgument (
2820
+ Context.getInjectedTemplateArg (NewParam));
2807
2821
continue ;
2822
+ }
2808
2823
TemplateArgumentLoc Input =
2809
2824
SemaRef.getTrivialTemplateArgumentLoc (D, QualType (), SourceLocation{});
2810
2825
TemplateArgumentLoc Output;
@@ -2820,9 +2835,11 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2820
2835
MultiLevelTemplateArgumentList ArgsForBuildingRC;
2821
2836
ArgsForBuildingRC.setKind (clang::TemplateSubstitutionKind::Rewrite);
2822
2837
ArgsForBuildingRC.addOuterTemplateArguments (TemplateArgsForBuildingRC);
2823
- // For 2), if the underlying F is instantiated from a member template, we need
2824
- // the entire template argument list, as the constraint AST in the
2825
- // require-clause of F remains completely uninstantiated.
2838
+ // For 2), if the underlying function template F is nested in a class template
2839
+ // (either instantiated from an explicitly-written deduction guide, or
2840
+ // synthesized from a constructor), we need the entire template argument list,
2841
+ // as the constraint AST in the require-clause of F remains completely
2842
+ // uninstantiated.
2826
2843
//
2827
2844
// For example:
2828
2845
// template <typename T> // depth 0
@@ -2845,7 +2862,8 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2845
2862
// We add the outer template arguments which is [int] to the multi-level arg
2846
2863
// list to ensure that the occurrence U in `C<U>` will be replaced with int
2847
2864
// during the substitution.
2848
- if (F->getInstantiatedFromMemberTemplate ()) {
2865
+ if (F->getLexicalDeclContext ()->getDeclKind () ==
2866
+ clang::Decl::ClassTemplateSpecialization) {
2849
2867
auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs (
2850
2868
F, F->getLexicalDeclContext (),
2851
2869
/* Final=*/ false , /* Innermost=*/ std::nullopt,
@@ -3063,6 +3081,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
3063
3081
Context.getInjectedTemplateArg (NewParam));
3064
3082
TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
3065
3083
}
3084
+ unsigned UndeducedTemplateParameterStartIndex = FPrimeTemplateParams.size ();
3066
3085
// ...followed by the template parameters of f that were not deduced
3067
3086
// (including their default template arguments)
3068
3087
for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
@@ -3132,7 +3151,8 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
3132
3151
Expr *IsDeducible = buildIsDeducibleConstraint (
3133
3152
SemaRef, AliasTemplate, FPrime->getReturnType (), FPrimeTemplateParams);
3134
3153
Expr *RequiresClause = buildAssociatedConstraints (
3135
- SemaRef, F, AliasTemplate, DeduceResults, IsDeducible);
3154
+ SemaRef, F, AliasTemplate, DeduceResults,
3155
+ UndeducedTemplateParameterStartIndex, IsDeducible);
3136
3156
3137
3157
auto *FPrimeTemplateParamList = TemplateParameterList::Create (
3138
3158
Context, AliasTemplate->getTemplateParameters ()->getTemplateLoc (),
0 commit comments