Skip to content

Commit 2e4ea3b

Browse files
[Sema] Adjusments from review in SR-13239 and for variadic closure case
1 parent 5401ed3 commit 2e4ea3b

File tree

2 files changed

+48
-21
lines changed

2 files changed

+48
-21
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,7 +3709,7 @@ static bool diagnoseAmbiguity(
37093709
return diagnosed;
37103710
}
37113711

3712-
using Fix = std::pair<const Solution *, const ConstraintFix *>;
3712+
using FixInContext = std::pair<const Solution *, const ConstraintFix *>;
37133713

37143714
// Attempts to diagnose function call ambiguities of types inferred for a result
37153715
// generic parameter from contextual type and a closure argument that
@@ -3725,17 +3725,16 @@ using Fix = std::pair<const Solution *, const ConstraintFix *>;
37253725
// }
37263726
// Where generic argument `T` can be inferred both as `Int` from contextual
37273727
// 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) {
37323731

37333732
if (contextualFixes.empty())
37343733
return false;
37353734

37363735
auto contextualFix = contextualFixes.front();
37373736
if (!std::all_of(contextualFixes.begin() + 1, contextualFixes.end(),
3738-
[&contextualFix](Fix fix) {
3737+
[&contextualFix](FixInContext fix) {
37393738
return fix.second->getLocator() ==
37403739
contextualFix.second->getLocator();
37413740
}))
@@ -3763,16 +3762,22 @@ diagnoseContextualFunctionCallGenericAmbiguity(ConstraintSystem &cs,
37633762
return false;
37643763

37653764
auto typeParamResultInvolvesTypeVar =
3766-
[&applyFnType](unsigned paramIdx, TypeVariableType *typeVar) {
3765+
[&cs, &applyFnType](unsigned paramIdx, TypeVariableType *typeVar) {
3766+
assert(paramIdx < applyFnType->getNumParams());
37673767
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());
37763781
};
37773782

37783783
llvm::SmallVector<ClosureExpr *, 4> closureArguments;
@@ -3805,7 +3810,7 @@ diagnoseContextualFunctionCallGenericAmbiguity(ConstraintSystem &cs,
38053810
for (auto &fix : contextualFixes)
38063811
genericParamInferredTypes.insert(fix.first->getFixedType(resultTypeVar));
38073812

3808-
if (llvm::all_of(allFixes, [&](Fix fix) {
3813+
if (llvm::all_of(allFixes, [&](FixInContext fix) {
38093814
auto fixLocator = fix.second->getLocator();
38103815
if (fixLocator->isForContextualType())
38113816
return true;
@@ -3896,14 +3901,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
38963901
// d. Diagnose remaining (uniqued based on kind + locator) fixes
38973902
// iff they appear in all of the solutions.
38983903

3899-
llvm::SmallSetVector<Fix, 4> fixes;
3904+
llvm::SmallSetVector<FixInContext, 4> fixes;
39003905
for (auto &solution : solutions) {
39013906
for (auto *fix : solution.Fixes)
39023907
fixes.insert({&solution, fix});
39033908
}
39043909

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;
39073913

39083914
for (const auto &entry : fixes) {
39093915
const auto &solution = *entry.first;
@@ -3923,7 +3929,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
39233929
bool diagnosed = false;
39243930

39253931
// All of the fixes which have been considered already.
3926-
llvm::SmallSetVector<Fix, 4> consideredFixes;
3932+
llvm::SmallSetVector<FixInContext, 4> consideredFixes;
39273933

39283934
for (const auto &ambiguity : solutionDiff.overloads) {
39293935
auto fixes = fixesByCallee.find(ambiguity.locator);
@@ -3946,7 +3952,8 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
39463952
// overload choices.
39473953
fixes.set_subtract(consideredFixes);
39483954

3949-
llvm::MapVector<std::pair<FixKind, ConstraintLocator *>, SmallVector<Fix, 4>>
3955+
llvm::MapVector<std::pair<FixKind, ConstraintLocator *>,
3956+
SmallVector<FixInContext, 4>>
39503957
fixesByKind;
39513958

39523959
for (const auto &entry : fixes) {

test/expr/closure/closures.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,10 @@ func callitTuple<T>(_ : Int, _ f: () -> (T, Int)) -> T {
628628
f().0
629629
}
630630

631+
func callitVariadic<T>(_ fs: () -> T...) -> T {
632+
fs.first!()
633+
}
634+
631635
func testSR13239_Tuple() -> Int {
632636
// expected-error@+1{{conflicting inferred types from call result and closure argument to generic parameter 'T' ('()' vs. 'Int')}}
633637
callitTuple(1) {
@@ -669,3 +673,19 @@ func testSR13239_GenericArg() -> Int {
669673
print("hello") // expected-error {{cannot convert value of type '()' to closure result type 'Int'}}
670674
}
671675
}
676+
677+
func testSR13239_Variadic() -> Int {
678+
// expected-error@+1{{conflicting inferred types from call result and closure argument to generic parameter 'T' ('()' vs. 'Int')}}
679+
callitVariadic({
680+
print("hello")
681+
})
682+
}
683+
684+
func testSR13239_Variadic_Twos() -> Int {
685+
// expected-error@+1{{cannot convert return expression of type '()' to return type 'Int'}}
686+
callitVariadic({
687+
print("hello")
688+
}, {
689+
print("hello")
690+
})
691+
}

0 commit comments

Comments
 (0)