@@ -3834,18 +3834,6 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
3834
3834
Result != TemplateDeductionResult::Success)
3835
3835
return Result;
3836
3836
3837
- // C++ [temp.deduct.call]p10: [DR1391]
3838
- // If deduction succeeds for all parameters that contain
3839
- // template-parameters that participate in template argument deduction,
3840
- // and all template arguments are explicitly specified, deduced, or
3841
- // obtained from default template arguments, remaining parameters are then
3842
- // compared with the corresponding arguments. For each remaining parameter
3843
- // P with a type that was non-dependent before substitution of any
3844
- // explicitly-specified template arguments, if the corresponding argument
3845
- // A cannot be implicitly converted to P, deduction fails.
3846
- if (CheckNonDependent ())
3847
- return TemplateDeductionResult::NonDependentConversionFailure;
3848
-
3849
3837
// Form the template argument list from the deduced template arguments.
3850
3838
TemplateArgumentList *SugaredDeducedArgumentList =
3851
3839
TemplateArgumentList::CreateCopy (Context, SugaredBuilder);
@@ -3875,6 +3863,76 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
3875
3863
FD = const_cast <FunctionDecl *>(FDFriend);
3876
3864
Owner = FD->getLexicalDeclContext ();
3877
3865
}
3866
+ #if 1
3867
+ // FIXME: We have to partially instantiate lambda's captures for constraint
3868
+ // evaluation.
3869
+ if (!isLambdaCallOperator (FD) && !isLambdaConversionOperator (FD) &&
3870
+ (!PartialOverloading ||
3871
+ (CanonicalBuilder.size () ==
3872
+ FunctionTemplate->getTemplateParameters ()->size ()))) {
3873
+ FunctionTemplateDecl *Template = FunctionTemplate->getCanonicalDecl ();
3874
+ FunctionDecl *FD = Template->getTemplatedDecl ();
3875
+ SmallVector<const Expr *, 3 > TemplateAC;
3876
+ Template->getAssociatedConstraints (TemplateAC);
3877
+ if (!TemplateAC.empty ()) {
3878
+
3879
+ // Enter the scope of this instantiation. We don't use
3880
+ // PushDeclContext because we don't have a scope.
3881
+ LocalInstantiationScope Scope (*this );
3882
+
3883
+ // Collect the list of template arguments relative to the 'primary'
3884
+ // template. We need the entire list, since the constraint is completely
3885
+ // uninstantiated at this point.
3886
+
3887
+ MultiLevelTemplateArgumentList MLTAL (FD, SugaredBuilder, /* Final=*/ false );
3888
+ getTemplateInstantiationArgs (nullptr , FD->getLexicalDeclContext (),
3889
+ /* Final=*/ false ,
3890
+ /* Innermost=*/ std::nullopt,
3891
+ /* RelativeToPrimary=*/ true ,
3892
+ /* Pattern=*/ nullptr ,
3893
+ /* ForConstraintInstantiation=*/ true ,
3894
+ /* SkipForSpecialization=*/ false ,
3895
+ /* Merged=*/ &MLTAL);
3896
+
3897
+ // if (SetupConstraintScope(FD, SugaredBuilder, MLTAL, Scope))
3898
+ // return TemplateDeductionResult::MiscellaneousDeductionFailure;
3899
+
3900
+ MultiLevelTemplateArgumentList JustTemplArgs (
3901
+ Template, CanonicalDeducedArgumentList->asArray (),
3902
+ /* Final=*/ false );
3903
+ if (addInstantiatedParametersToScope (nullptr , FD, Scope, JustTemplArgs))
3904
+ return TemplateDeductionResult::MiscellaneousDeductionFailure;
3905
+
3906
+ if (FunctionTemplateDecl *FromMemTempl =
3907
+ Template->getInstantiatedFromMemberTemplate ()) {
3908
+ while (FromMemTempl->getInstantiatedFromMemberTemplate ())
3909
+ FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate ();
3910
+ if (addInstantiatedParametersToScope (
3911
+ nullptr , FromMemTempl->getTemplatedDecl (), Scope, MLTAL))
3912
+ return TemplateDeductionResult::MiscellaneousDeductionFailure;
3913
+ }
3914
+
3915
+ Qualifiers ThisQuals;
3916
+ CXXRecordDecl *Record = nullptr ;
3917
+ if (auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
3918
+ ThisQuals = Method->getMethodQualifiers ();
3919
+ Record = Method->getParent ();
3920
+ }
3921
+ CXXThisScopeRAII ThisScope (*this , Record, ThisQuals, Record != nullptr );
3922
+ llvm::SmallVector<Expr *, 1 > Converted;
3923
+ if (CheckConstraintSatisfaction (Template, TemplateAC, MLTAL,
3924
+ Template->getSourceRange (),
3925
+ Info.AssociatedConstraintsSatisfaction ))
3926
+ return TemplateDeductionResult::MiscellaneousDeductionFailure;
3927
+ if (!Info.AssociatedConstraintsSatisfaction .IsSatisfied ) {
3928
+ Info.reset (TemplateArgumentList::CreateCopy (Context, SugaredBuilder),
3929
+ Info.takeCanonical ());
3930
+ return TemplateDeductionResult::ConstraintsNotSatisfied;
3931
+ }
3932
+ }
3933
+ }
3934
+ #endif
3935
+
3878
3936
MultiLevelTemplateArgumentList SubstArgs (
3879
3937
FunctionTemplate, CanonicalDeducedArgumentList->asArray (),
3880
3938
/* Final=*/ false );
@@ -3924,6 +3982,18 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
3924
3982
}
3925
3983
}
3926
3984
3985
+ // C++ [temp.deduct.call]p10: [DR1391]
3986
+ // If deduction succeeds for all parameters that contain
3987
+ // template-parameters that participate in template argument deduction,
3988
+ // and all template arguments are explicitly specified, deduced, or
3989
+ // obtained from default template arguments, remaining parameters are then
3990
+ // compared with the corresponding arguments. For each remaining parameter
3991
+ // P with a type that was non-dependent before substitution of any
3992
+ // explicitly-specified template arguments, if the corresponding argument
3993
+ // A cannot be implicitly converted to P, deduction fails.
3994
+ if (CheckNonDependent ())
3995
+ return TemplateDeductionResult::NonDependentConversionFailure;
3996
+
3927
3997
// We skipped the instantiation of the explicit-specifier during the
3928
3998
// substitution of `FD` before. So, we try to instantiate it back if
3929
3999
// `Specialization` is either a constructor or a conversion function.
0 commit comments