Skip to content

Commit e8fe5c3

Browse files
authored
Merge pull request swiftlang#78906 from xedin/rdar-143475850-part-1
[CSBindings] Allow subtype inference from `Void?` for closure result …
2 parents 95f1dfb + 116d1af commit e8fe5c3

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,8 @@ bool TypeVarBindingProducer::computeNext() {
25842584
//
25852585
// Let's not perform $T? -> $T for closure result types to avoid having
25862586
// to re-discover solutions that differ only in location of optional
2587-
// injection.
2587+
// injection. `Void` is a special case because in $T_result position
2588+
// it has special semantics and enables T? -> Void conversions.
25882589
//
25892590
// The pattern with such type variables is:
25902591
//
@@ -2595,7 +2596,7 @@ bool TypeVarBindingProducer::computeNext() {
25952596
// expression is non-optional), if we allow both the solver would
25962597
// find two solutions that differ only in location of optional
25972598
// injection.
2598-
if (!TypeVar->getImpl().isClosureResultType()) {
2599+
if (!TypeVar->getImpl().isClosureResultType() || objTy->isVoid()) {
25992600
// If T is a type variable, only attempt this if both the
26002601
// type variable we are trying bindings for, and the type
26012602
// variable we will attempt to bind, both have the same

test/Constraints/closures.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,3 +1283,25 @@ do {
12831283
}
12841284
}
12851285
}
1286+
1287+
// Make sure that closure gets both Void? and Void attempted
1288+
// otherwise it won't be possible to type-check the second closure.
1289+
do {
1290+
struct Semaphore {
1291+
func signal() -> Int {}
1292+
}
1293+
1294+
func compute(_ completion: (Semaphore?) -> Void?) {}
1295+
1296+
func test() {
1297+
compute { $0?.signal() }
1298+
// expected-warning@-1 {{result of call to 'signal()' is unused}}
1299+
1300+
true
1301+
? compute({ $0?.signal() }) // expected-warning {{result of call to 'signal()' is unused}}
1302+
: compute({
1303+
let sem = $0!
1304+
sem.signal() // expected-warning {{result of call to 'signal()' is unused}}
1305+
})
1306+
}
1307+
}

0 commit comments

Comments
 (0)