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