Skip to content

Commit 308d104

Browse files
[Sema] [Diagnostics] Consider function result locator when get structural contextual type for function arg/param
1 parent 8576aae commit 308d104

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

lib/Sema/CSFix.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,21 @@ getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
403403
return std::make_tuple(contextualTypeElt->getPurpose(), exprType,
404404
contextualType);
405405
} else if (auto argApplyInfo = solution.getFunctionArgApplyInfo(locator)) {
406-
return std::make_tuple(CTP_CallArgument,
407-
argApplyInfo->getArgType(),
408-
argApplyInfo->getParamType());
406+
Type fromType = argApplyInfo->getArgType();
407+
Type toType = argApplyInfo->getParamType();
408+
// In case locator points to the function result we want the
409+
// argument and param function types result.
410+
if (locator->isLastElement<LocatorPathElt::FunctionResult>()) {
411+
auto fromFnType = fromType->getAs<FunctionType>();
412+
auto toFnType = toType->getAs<FunctionType>();
413+
if (fromFnType && toFnType) {
414+
auto &cs = solution.getConstraintSystem();
415+
return std::make_tuple(
416+
cs.getContextualTypePurpose(locator->getAnchor()),
417+
fromFnType->getResult(), toFnType->getResult());
418+
}
419+
}
420+
return std::make_tuple(CTP_CallArgument, fromType, toType);
409421
} else if (auto *coerceExpr = getAsExpr<CoerceExpr>(locator->getAnchor())) {
410422
return std::make_tuple(CTP_CoerceOperand,
411423
solution.getType(coerceExpr->getSubExpr()),

test/expr/closure/closures.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,3 +589,20 @@ class SR14120 {
589589
}
590590
}
591591
}
592+
593+
// SR-14678
594+
func call<T>(_ : Int, _ f: () -> (T, Int)) -> (T, Int) {
595+
f()
596+
}
597+
598+
func testSR14678() -> (Int, Int) {
599+
call(1) { // expected-error {{cannot convert return expression of type '((), Int)' to return type '(Int, Int)'}}
600+
(print("hello"), 0)
601+
}
602+
}
603+
604+
func testSR14678_Optional() -> (Int, Int)? {
605+
call(1) { // expected-error {{cannot convert return expression of type '((), Int)' to return type '(Int, Int)'}}
606+
(print("hello"), 0)
607+
}
608+
}

0 commit comments

Comments
 (0)