Skip to content

Commit b091e73

Browse files
authored
Merge pull request #14455 from rudkx/fix-sr6837-4.1
[4.1] Fix SR-6837 - allow function conversion for -swift-version 4 *only*
2 parents 4e7b4de + 519dfea commit b091e73

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,16 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11731173
if (auto *paren2 = dyn_cast<ParenType>(func2Input.getPointer())) {
11741174
if (!isa<ParenType>(func1Input.getPointer()))
11751175
func2Input = paren2->getUnderlyingType();
1176+
} else if (getASTContext().isSwiftVersionAtLeast(4)
1177+
&& !getASTContext().isSwiftVersionAtLeast(5)
1178+
&& !isa<ParenType>(func2Input.getPointer())) {
1179+
auto *simplified = locator.trySimplifyToExpr();
1180+
// We somehow let tuple unsplatting function conversions
1181+
// through in some cases in Swift 4, so let's let that
1182+
// continue to work, but only for Swift 4.
1183+
if (simplified && isa<DeclRefExpr>(simplified))
1184+
if (auto *paren1 = dyn_cast<ParenType>(func1Input.getPointer()))
1185+
func1Input = paren1->getUnderlyingType();
11761186
}
11771187
}
11781188
}

test/Compatibility/tuple_arguments.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,3 +1493,12 @@ do {
14931493
func bar() -> ((()) -> Void)? { return nil }
14941494
foo(bar()) // OK in Swift 3 mode
14951495
}
1496+
1497+
// https://bugs.swift.org/browse/SR-6837
1498+
do {
1499+
func takeFn(fn: (_ i: Int, _ j: Int?) -> ()) {}
1500+
func takePair(_ pair: (Int, Int?)) {}
1501+
takeFn(fn: takePair)
1502+
takeFn(fn: { (pair: (Int, Int?)) in } )
1503+
takeFn { (pair: (Int, Int?)) in }
1504+
}

test/Constraints/tuple_arguments.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,3 +1628,14 @@ do {
16281628
func bar() -> ((()) -> Void)? { return nil }
16291629
foo(bar()) // expected-error {{cannot convert value of type '((()) -> Void)?' to expected argument type '(() -> Void)?'}}
16301630
}
1631+
1632+
// https://bugs.swift.org/browse/SR-6837
1633+
do {
1634+
func takeFn(fn: (_ i: Int, _ j: Int?) -> ()) {}
1635+
func takePair(_ pair: (Int, Int?)) {}
1636+
takeFn(fn: takePair) // Allow for -swift-version 4, but not later
1637+
takeFn(fn: { (pair: (Int, Int?)) in } ) // Disallow for -swift-version 4 and later
1638+
// expected-error@-1 {{contextual closure type '(Int, Int?) -> ()' expects 2 arguments, but 1 was used in closure body}}
1639+
takeFn { (pair: (Int, Int?)) in } // Disallow for -swift-version 4 and later
1640+
// expected-error@-1 {{contextual closure type '(Int, Int?) -> ()' expects 2 arguments, but 1 was used in closure body}}
1641+
}

0 commit comments

Comments
 (0)