Skip to content

Commit 63f8a92

Browse files
authored
Merge pull request #14481 from rudkx/fix-sr6796-5.0
2 parents 328dad8 + 6c501cd commit 63f8a92

File tree

5 files changed

+1747
-8
lines changed

5 files changed

+1747
-8
lines changed

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6173,9 +6173,12 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
61736173
// func bar() -> ((()) -> Void)? { return nil }
61746174
// foo(bar) // This expression should compile in Swift 3 mode
61756175
// ```
6176-
if (tc.getLangOpts().isSwiftVersion3()) {
6177-
auto obj1 = fromType->getAnyOptionalObjectType();
6178-
auto obj2 = toType->getAnyOptionalObjectType();
6176+
//
6177+
// See also: https://bugs.swift.org/browse/SR-6796
6178+
if (cs.getASTContext().isSwiftVersionAtLeast(3) &&
6179+
!cs.getASTContext().isSwiftVersionAtLeast(5)) {
6180+
auto obj1 = fromType->getOptionalObjectType();
6181+
auto obj2 = toType->getOptionalObjectType();
61796182

61806183
if (obj1 && obj2) {
61816184
auto *fn1 = obj1->getAs<AnyFunctionType>();

lib/Sema/CSSimplify.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,35 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11901190
}
11911191
}
11921192

1193+
// https://bugs.swift.org/browse/SR-6796
1194+
// Add a super-narrow hack to allow:
1195+
// (()) -> T to be passed in place of () -> T
1196+
if (getASTContext().isSwiftVersionAtLeast(4) &&
1197+
!getASTContext().isSwiftVersionAtLeast(5)) {
1198+
SmallVector<LocatorPathElt, 4> path;
1199+
locator.getLocatorParts(path);
1200+
1201+
// Find the last path element, skipping GenericArgument elements
1202+
// so that we allow this exception in cases of optional types, and
1203+
// skipping OptionalPayload elements so that we allow this
1204+
// exception in cases of optional injection.
1205+
auto last = std::find_if(
1206+
path.rbegin(), path.rend(), [](LocatorPathElt &elt) -> bool {
1207+
return elt.getKind() != ConstraintLocator::GenericArgument &&
1208+
elt.getKind() != ConstraintLocator::OptionalPayload;
1209+
});
1210+
1211+
if (last != path.rend()) {
1212+
if (last->getKind() == ConstraintLocator::ApplyArgToParam) {
1213+
if (auto *paren1 = dyn_cast<ParenType>(func1Input.getPointer())) {
1214+
auto innerTy = paren1->getUnderlyingType();
1215+
if (func2Input->isVoid() && innerTy->isVoid())
1216+
func1Input = innerTy;
1217+
}
1218+
}
1219+
}
1220+
}
1221+
11931222
// Input types can be contravariant (or equal).
11941223
SmallVector<AnyFunctionType::Param, 4> func1Params;
11951224
SmallVector<AnyFunctionType::Param, 4> func2Params;

test/Compatibility/tuple_arguments.swift renamed to test/Compatibility/tuple_arguments_3.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// RUN: %target-typecheck-verify-swift -swift-version 3
22

33
// Tests for tuple argument behavior in Swift 3, which was broken.
4-
// The Swift 4 test is in test/Constraints/tuple_arguments.swift.
4+
// The Swift 4 test is in test/Compatibility/tuple_arguments_4.swift.
5+
// The test for the most recent version is in test/Constraints/tuple_arguments.swift.
56

67
// Key:
78
// - "Crashes in actual Swift 3" -- snippets which crashed in Swift 3.0.1.
@@ -1516,3 +1517,20 @@ do {
15161517
takeFn(fn: { (pair: (Int, Int?)) in } )
15171518
takeFn { (pair: (Int, Int?)) in }
15181519
}
1520+
1521+
// https://bugs.swift.org/browse/SR-6796
1522+
do {
1523+
func f(a: (() -> Void)? = nil) {}
1524+
func log<T>() -> ((T) -> Void)? { return nil }
1525+
1526+
f(a: log() as ((()) -> Void)?) // Allow ((()) -> Void)? to be passed in place of (() -> Void)?
1527+
1528+
func logNoOptional<T>() -> (T) -> Void { }
1529+
f(a: logNoOptional() as ((()) -> Void)) // Also allow the optional-injected form.
1530+
1531+
func g() {}
1532+
g(())
1533+
1534+
func h(_: ()) {}
1535+
h()
1536+
}

0 commit comments

Comments
 (0)