Skip to content

Commit 706922d

Browse files
authored
Merge pull request #10027 from rudkx/thread-tuple-splat-through-eyes-of-function-parameters
Roll back a portion of SE-0110
2 parents 0cfc56e + 0ba4a31 commit 706922d

File tree

4 files changed

+61
-21
lines changed

4 files changed

+61
-21
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,11 +1054,28 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
10541054

10551055
increaseScore(ScoreKind::SK_FunctionConversion);
10561056

1057+
// Add a very narrow exception to SE-0110 by allowing functions that
1058+
// take multiple arguments to be passed as an argument in places
1059+
// that expect a function that takes a single tuple (of the same
1060+
// arity).
1061+
auto func1Input = func1->getInput();
1062+
auto func2Input = func2->getInput();
1063+
if (!getASTContext().isSwiftVersion3()) {
1064+
if (auto elt = locator.last()) {
1065+
if (elt->getKind() == ConstraintLocator::ApplyArgToParam) {
1066+
if (auto *paren2 = dyn_cast<ParenType>(func2Input.getPointer())) {
1067+
func2Input = paren2->getUnderlyingType();
1068+
if (auto *paren1 = dyn_cast<ParenType>(func1Input.getPointer()))
1069+
func1Input = paren1->getUnderlyingType();
1070+
}
1071+
}
1072+
}
1073+
}
1074+
10571075
// Input types can be contravariant (or equal).
1058-
SolutionKind result = matchTypes(func2->getInput(), func1->getInput(),
1059-
subKind, subflags,
1060-
locator.withPathElement(
1061-
ConstraintLocator::FunctionArgument));
1076+
SolutionKind result =
1077+
matchTypes(func2Input, func1Input, subKind, subflags,
1078+
locator.withPathElement(ConstraintLocator::FunctionArgument));
10621079
if (result == SolutionKind::Error)
10631080
return SolutionKind::Error;
10641081

test/Constraints/diagnostics_swift4.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,13 @@ func foo() -> R31898542<()> {
3939

4040
// rdar://problem/31973368 - Cannot convert value of type '(K, V) -> ()' to expected argument type '((key: _, value: _)) -> Void'
4141

42+
// SE-0110: We reverted to allowing this for the time being, but this
43+
// test is valuable in case we end up disallowing it again in the
44+
// future.
45+
4246
class R<K: Hashable, V> {
4347
func forEach(_ body: (K, V) -> ()) {
44-
var dict: [K:V] = [:]
45-
dict.forEach(body) // expected-error {{nested tuple parameter '(key: K, value: V)' of function '(((key: K, value: V)) throws -> Void) throws -> ()' does not support destructuring}}
48+
let dict: [K:V] = [:]
49+
dict.forEach(body)
4650
}
4751
}

test/Constraints/enum_cases.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ func bar_3<T, U>(_: (T) -> G_E<U>) {}
4141

4242
bar_1(E.foo) // Ok
4343
bar_1(E.bar) // Ok
44-
bar_1(E.two) // expected-error {{cannot convert value of type '(Int, Int) -> E' to expected argument type '(_) -> E'}}
44+
// SE-0110: We reverted to allowing this for the time being, but this
45+
// test is valuable in case we end up disallowing it again in the
46+
// future.
47+
bar_1(E.two) // Ok since we backed off on this aspect of SE-0110 for the moment.
4548
bar_1(E.tuple) // Ok - it's going to be ((x: Int, y: Int))
4649

4750
bar_2(G_E<String>.foo) // Ok

test/Constraints/tuple_arguments.swift

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,17 +1338,17 @@ do {
13381338
s.takesClosureTuple({ _ = $0 })
13391339
s.takesClosureTuple({ x in })
13401340
s.takesClosureTuple({ (x: (Double, Double)) in })
1341-
s.takesClosureTuple({ _ = $0; _ = $1 }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring with implicit parameters}}
1342-
s.takesClosureTuple({ (x, y) in }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring}} {{25-31=(arg)}} {{34-34=let (x, y) = arg; }}
1343-
s.takesClosureTuple({ (x: Double, y:Double) in }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring}} {{25-46=(arg: (Double, Double))}} {{49-49=let (x, y) = arg; }}
1341+
s.takesClosureTuple({ _ = $0; _ = $1 })
1342+
s.takesClosureTuple({ (x, y) in })
1343+
s.takesClosureTuple({ (x: Double, y:Double) in })
13441344

13451345
let sTwo = GenericConforms<(Double, Double)>()
13461346
sTwo.takesClosure({ _ = $0 })
13471347
sTwo.takesClosure({ x in })
13481348
sTwo.takesClosure({ (x: (Double, Double)) in })
1349-
sTwo.takesClosure({ _ = $0; _ = $1 }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring with implicit parameters}}
1350-
sTwo.takesClosure({ (x, y) in }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring}} {{23-29=(arg)}} {{32-32=let (x, y) = arg; }}
1351-
sTwo.takesClosure({ (x: Double, y: Double) in }) // expected-error {{closure tuple parameter '(Double, Double)' does not support destructuring}} {{23-45=(arg: (Double, Double))}} {{48-48=let (x, y) = arg; }}
1349+
sTwo.takesClosure({ _ = $0; _ = $1 })
1350+
sTwo.takesClosure({ (x, y) in })
1351+
sTwo.takesClosure({ (x: Double, y: Double) in })
13521352
}
13531353

13541354
do {
@@ -1461,7 +1461,6 @@ let pages3: MutableProperty<(data: DataSourcePage<Int>, totalCount: Int)> = Muta
14611461
// SR-4745
14621462
let sr4745 = [1, 2]
14631463
let _ = sr4745.enumerated().map { (count, element) in "\(count): \(element)" }
1464-
// expected-error@-1 {{closure tuple parameter '(offset: Int, element: Int)' does not support destructuring}} {{35-51=(arg) -> <#Result#>}} {{55-55=let (count, element) = arg; return }}
14651464

14661465
// SR-4738
14671466

@@ -1472,7 +1471,6 @@ let sr4738 = (1, (2, 3))
14721471
// rdar://problem/31892961
14731472
let r31892961_1 = [1: 1, 2: 2]
14741473
r31892961_1.forEach { (k, v) in print(k + v) }
1475-
// expected-error@-1 {{closure tuple parameter '(key: Int, value: Int)' does not support destructuring}} {{23-29=(arg)}} {{33-33=let (k, v) = arg; }}
14761474

14771475
let r31892961_2 = [1, 2, 3]
14781476
let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
@@ -1482,15 +1480,12 @@ let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
14821480
}
14831481

14841482
let r31892961_3 = (x: 1, y: 42)
1485-
[r31892961_3].map { (x: Int, y: Int) in x + y }
1486-
// expected-error@-1 {{closure tuple parameter '(x: Int, y: Int)' does not support destructuring}} {{21-37=(arg: (x: Int, y: Int)) -> <#Result#>}} {{41-41=let (x, y) = arg; return }}
1483+
_ = [r31892961_3].map { (x: Int, y: Int) in x + y }
14871484

1488-
[r31892961_3].map { (x, y: Int) in x + y }
1489-
// expected-error@-1 {{closure tuple parameter '(x: Int, y: Int)' does not support destructuring}} {{21-32=(arg: (x: Int, y: Int)) -> <#Result#>}} {{36-36=let (x, y) = arg; return }}
1485+
_ = [r31892961_3].map { (x, y: Int) in x + y }
14901486

14911487
let r31892961_4 = (1, 2)
1492-
[r31892961_4].map { x, y in x + y }
1493-
// expected-error@-1 {{closure tuple parameter '(Int, Int)' does not support destructuring}} {{21-25=(arg) -> <#Result#>}} {{29-29=let (x, y) = arg; return }}
1488+
_ = [r31892961_4].map { x, y in x + y }
14941489

14951490
let r31892961_5 = (x: 1, (y: 2, (w: 3, z: 4)))
14961491
[r31892961_5].map { (x: Int, (y: Int, (w: Int, z: Int))) in x + y }
@@ -1526,3 +1521,24 @@ rdar32301091_2 { _ in }
15261521
// expected-error@-1 {{contextual closure type '(Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} {{19-19=,_ }}
15271522
rdar32301091_2 { x in }
15281523
// expected-error@-1 {{contextual closure type '(Int, Int) -> ()' expects 2 arguments, but 1 was used in closure body}} {{19-19=,<#arg#> }}
1524+
1525+
func rdar32875953() {
1526+
let myDictionary = ["hi":1]
1527+
1528+
myDictionary.forEach {
1529+
print("\($0) -> \($1)")
1530+
}
1531+
1532+
myDictionary.forEach { key, value in
1533+
print("\(key) -> \(value)")
1534+
}
1535+
1536+
myDictionary.forEach { (key, value) in
1537+
print("\(key) -> \(value)")
1538+
}
1539+
1540+
let array1 = [1]
1541+
let array2 = [2]
1542+
1543+
_ = zip(array1, array2).map(+)
1544+
}

0 commit comments

Comments
 (0)