@@ -3709,7 +3709,7 @@ static bool diagnoseAmbiguity(
3709
3709
return diagnosed;
3710
3710
}
3711
3711
3712
- using Fix = std::pair<const Solution *, const ConstraintFix *>;
3712
+ using FixInContext = std::pair<const Solution *, const ConstraintFix *>;
3713
3713
3714
3714
// Attempts to diagnose function call ambiguities of types inferred for a result
3715
3715
// generic parameter from contextual type and a closure argument that
@@ -3725,17 +3725,16 @@ using Fix = std::pair<const Solution *, const ConstraintFix *>;
3725
3725
// }
3726
3726
// Where generic argument `T` can be inferred both as `Int` from contextual
3727
3727
// result and `Void` from the closure argument result.
3728
- static bool
3729
- diagnoseContextualFunctionCallGenericAmbiguity (ConstraintSystem &cs,
3730
- ArrayRef<Fix> contextualFixes,
3731
- ArrayRef<Fix> allFixes) {
3728
+ static bool diagnoseContextualFunctionCallGenericAmbiguity (
3729
+ ConstraintSystem &cs, ArrayRef<FixInContext> contextualFixes,
3730
+ ArrayRef<FixInContext> allFixes) {
3732
3731
3733
3732
if (contextualFixes.empty ())
3734
3733
return false ;
3735
3734
3736
3735
auto contextualFix = contextualFixes.front ();
3737
3736
if (!std::all_of (contextualFixes.begin () + 1 , contextualFixes.end (),
3738
- [&contextualFix](Fix fix) {
3737
+ [&contextualFix](FixInContext fix) {
3739
3738
return fix.second ->getLocator () ==
3740
3739
contextualFix.second ->getLocator ();
3741
3740
}))
@@ -3763,16 +3762,22 @@ diagnoseContextualFunctionCallGenericAmbiguity(ConstraintSystem &cs,
3763
3762
return false ;
3764
3763
3765
3764
auto typeParamResultInvolvesTypeVar =
3766
- [&applyFnType](unsigned paramIdx, TypeVariableType *typeVar) {
3765
+ [&cs, &applyFnType](unsigned paramIdx, TypeVariableType *typeVar) {
3766
+ assert (paramIdx < applyFnType->getNumParams ());
3767
3767
auto param = applyFnType->getParams ()[paramIdx];
3768
- auto paramType = param.getParameterType ()->castTo <FunctionType>();
3769
-
3770
- bool contains = false ;
3771
- paramType->getResult ().visit ([&](Type ty) {
3772
- if (ty->isEqual (typeVar))
3773
- contains = true ;
3774
- });
3775
- return contains;
3768
+ if (param.isVariadic ()) {
3769
+ auto paramType = param.getParameterType ();
3770
+ // Variadic parameter is constructed as an ArraySliceType(which is
3771
+ // just sugared type for a bound generic) with the closure type as
3772
+ // element.
3773
+ auto baseType =
3774
+ paramType->getDesugaredType ()->castTo <BoundGenericType>();
3775
+ auto paramFnType =
3776
+ baseType->getGenericArgs ()[0 ]->castTo <FunctionType>();
3777
+ return cs.typeVarOccursInType (typeVar, paramFnType->getResult ());
3778
+ }
3779
+ auto paramFnType = param.getParameterType ()->castTo <FunctionType>();
3780
+ return cs.typeVarOccursInType (typeVar, paramFnType->getResult ());
3776
3781
};
3777
3782
3778
3783
llvm::SmallVector<ClosureExpr *, 4 > closureArguments;
@@ -3805,7 +3810,7 @@ diagnoseContextualFunctionCallGenericAmbiguity(ConstraintSystem &cs,
3805
3810
for (auto &fix : contextualFixes)
3806
3811
genericParamInferredTypes.insert (fix.first ->getFixedType (resultTypeVar));
3807
3812
3808
- if (llvm::all_of (allFixes, [&](Fix fix) {
3813
+ if (llvm::all_of (allFixes, [&](FixInContext fix) {
3809
3814
auto fixLocator = fix.second ->getLocator ();
3810
3815
if (fixLocator->isForContextualType ())
3811
3816
return true ;
@@ -3896,14 +3901,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
3896
3901
// d. Diagnose remaining (uniqued based on kind + locator) fixes
3897
3902
// iff they appear in all of the solutions.
3898
3903
3899
- llvm::SmallSetVector<Fix , 4 > fixes;
3904
+ llvm::SmallSetVector<FixInContext , 4 > fixes;
3900
3905
for (auto &solution : solutions) {
3901
3906
for (auto *fix : solution.Fixes )
3902
3907
fixes.insert ({&solution, fix});
3903
3908
}
3904
3909
3905
- llvm::MapVector<ConstraintLocator *, SmallVector<Fix, 4 >> fixesByCallee;
3906
- llvm::SmallVector<Fix, 4 > contextualFixes;
3910
+ llvm::MapVector<ConstraintLocator *, SmallVector<FixInContext, 4 >>
3911
+ fixesByCallee;
3912
+ llvm::SmallVector<FixInContext, 4 > contextualFixes;
3907
3913
3908
3914
for (const auto &entry : fixes) {
3909
3915
const auto &solution = *entry.first ;
@@ -3923,7 +3929,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
3923
3929
bool diagnosed = false ;
3924
3930
3925
3931
// All of the fixes which have been considered already.
3926
- llvm::SmallSetVector<Fix , 4 > consideredFixes;
3932
+ llvm::SmallSetVector<FixInContext , 4 > consideredFixes;
3927
3933
3928
3934
for (const auto &ambiguity : solutionDiff.overloads ) {
3929
3935
auto fixes = fixesByCallee.find (ambiguity.locator );
@@ -3946,7 +3952,8 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
3946
3952
// overload choices.
3947
3953
fixes.set_subtract (consideredFixes);
3948
3954
3949
- llvm::MapVector<std::pair<FixKind, ConstraintLocator *>, SmallVector<Fix, 4 >>
3955
+ llvm::MapVector<std::pair<FixKind, ConstraintLocator *>,
3956
+ SmallVector<FixInContext, 4 >>
3950
3957
fixesByKind;
3951
3958
3952
3959
for (const auto &entry : fixes) {
0 commit comments