@@ -2779,6 +2779,7 @@ Expr *
2779
2779
buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2780
2780
TypeAliasTemplateDecl *AliasTemplate,
2781
2781
ArrayRef<DeducedTemplateArgument> DeduceResults,
2782
+ unsigned UndeducedTemplateParameterStartIndex,
2782
2783
Expr *IsDeducible) {
2783
2784
Expr *RC = F->getTemplateParameters()->getRequiresClause();
2784
2785
if (!RC)
@@ -2839,8 +2840,22 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2839
2840
2840
2841
for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
2841
2842
const auto &D = DeduceResults[Index];
2842
- if (D.isNull())
2843
+ if (D.isNull()) { // non-deduced template parameters of f
2844
+ auto TP = F->getTemplateParameters()->getParam(Index);
2845
+ MultiLevelTemplateArgumentList Args;
2846
+ Args.setKind(TemplateSubstitutionKind::Rewrite);
2847
+ Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
2848
+ // Rebuild the template parameter with updated depth and index.
2849
+ NamedDecl *NewParam = transformTemplateParameter(
2850
+ SemaRef, F->getDeclContext(), TP, Args,
2851
+ /*NewIndex=*/UndeducedTemplateParameterStartIndex++,
2852
+ getTemplateParameterDepth(TP) + AdjustDepth);
2853
+
2854
+ assert(TemplateArgsForBuildingRC[Index].isNull());
2855
+ TemplateArgsForBuildingRC[Index] = Context.getCanonicalTemplateArgument(
2856
+ Context.getInjectedTemplateArg(NewParam));
2843
2857
continue;
2858
+ }
2844
2859
TemplateArgumentLoc Input =
2845
2860
SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
2846
2861
TemplateArgumentLoc Output;
@@ -2856,9 +2871,11 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2856
2871
MultiLevelTemplateArgumentList ArgsForBuildingRC;
2857
2872
ArgsForBuildingRC.setKind(clang::TemplateSubstitutionKind::Rewrite);
2858
2873
ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC);
2859
- // For 2), if the underlying F is instantiated from a member template, we need
2860
- // the entire template argument list, as the constraint AST in the
2861
- // require-clause of F remains completely uninstantiated.
2874
+ // For 2), if the underlying function template F is nested in a class template
2875
+ // (either instantiated from an explicitly-written deduction guide, or
2876
+ // synthesized from a constructor), we need the entire template argument list,
2877
+ // as the constraint AST in the require-clause of F remains completely
2878
+ // uninstantiated.
2862
2879
//
2863
2880
// For example:
2864
2881
// template <typename T> // depth 0
@@ -2881,7 +2898,8 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
2881
2898
// We add the outer template arguments which is [int] to the multi-level arg
2882
2899
// list to ensure that the occurrence U in `C<U>` will be replaced with int
2883
2900
// during the substitution.
2884
- if (F->getInstantiatedFromMemberTemplate()) {
2901
+ if (F->getLexicalDeclContext()->getDeclKind() ==
2902
+ clang::Decl::ClassTemplateSpecialization) {
2885
2903
auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs(
2886
2904
F, F->getLexicalDeclContext(),
2887
2905
/*Final=*/false, /*Innermost=*/std::nullopt,
@@ -3099,6 +3117,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
3099
3117
Context.getInjectedTemplateArg(NewParam));
3100
3118
TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
3101
3119
}
3120
+ unsigned UndeducedTemplateParameterStartIndex = FPrimeTemplateParams.size();
3102
3121
// ...followed by the template parameters of f that were not deduced
3103
3122
// (including their default template arguments)
3104
3123
for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
@@ -3168,7 +3187,8 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
3168
3187
Expr *IsDeducible = buildIsDeducibleConstraint(
3169
3188
SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
3170
3189
Expr *RequiresClause = buildAssociatedConstraints(
3171
- SemaRef, F, AliasTemplate, DeduceResults, IsDeducible);
3190
+ SemaRef, F, AliasTemplate, DeduceResults,
3191
+ UndeducedTemplateParameterStartIndex, IsDeducible);
3172
3192
3173
3193
auto *FPrimeTemplateParamList = TemplateParameterList::Create(
3174
3194
Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
0 commit comments