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