Skip to content

Commit 3879a47

Browse files
committed
[CSSyntacticElement] Remove an assert that is too strict
`return` statement withot an expression automatically gets an implicit `()` which is allowed to be converted to types like `()?` and `Any` or `Any?`. Let's remove a too strict assertion that expected a contextual type to always be `()?` even through in reality any type that `()` is convertible to is valid. Resolves: rdar://152553143
1 parent 3d6c240 commit 3879a47

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

lib/Sema/CSSyntacticElement.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,14 +2159,10 @@ class SyntacticElementSolutionApplication
21592159
if (resultType->isVoid())
21602160
return returnStmt;
21612161

2162-
// It's possible to infer e.g. `Void?` for cases where
2163-
// `return` doesn't have an expression. If contextual
2164-
// type is `Void` wrapped into N optional types, let's
2165-
// add an implicit `()` expression and let it be injected
2166-
// into optional required number of times.
2167-
2168-
assert(resultType->getOptionalObjectType() &&
2169-
resultType->lookThroughAllOptionalTypes()->isVoid());
2162+
// Constraint generation injects an implicit `()` expresion
2163+
// into return statements without one. This helps to match
2164+
// cases like `Void` and `Any` that could be wrapped into a
2165+
// number of optional types.
21702166

21712167
auto target = *cs.getTargetFor(returnStmt);
21722168
returnStmt->setResult(target.getAsExpr());

test/Constraints/closures.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,3 +1392,26 @@ func test_generic_closure_parameter_requirement_failure<Item: Idable>(
13921392
Container(data: { (input: TestInput) in payload(input.value) })
13931393
// expected-error@-1 {{generic struct 'TestInput' requires that 'Item.ID' conform to 'Collection'}}
13941394
}
1395+
1396+
// Since implicit result implies `()` it should be allowed to be converted to e.g. `Void` and `Any`
1397+
func test_implicit_result_conversions() {
1398+
func test_optional(_ x: Int) {
1399+
let _: Any? = {
1400+
switch x {
1401+
case 0:
1402+
return 1
1403+
default:
1404+
return
1405+
}
1406+
}()
1407+
}
1408+
1409+
func testAny(_: () -> Any) {}
1410+
1411+
testAny { } // Ok
1412+
testAny { return } // Ok
1413+
testAny {
1414+
_ = 42
1415+
return // Ok
1416+
}
1417+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// {"kind":"typecheck","signature":"(anonymous namespace)::SyntacticElementSolutionApplication::visitReturnStmt(swift::ReturnStmt*)"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
enum a func b(c : a) {
44
let:
55
()->Copyable = { c return

0 commit comments

Comments
 (0)