Skip to content

Commit 4c50c00

Browse files
authored
Merge pull request swiftlang#34046 from xedin/nil-with-context
[CSGen] Check whether parent has a contextual type before diagnosing …
2 parents 2649749 + 90e6fd4 commit 4c50c00

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

lib/Sema/CSGen.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,8 +1020,35 @@ namespace {
10201020
// `_ = nil`, let's diagnose it here because solver can't
10211021
// attempt any types for it.
10221022
auto *parentExpr = CS.getParentExpr(expr);
1023-
while (parentExpr && isa<ParenExpr>(parentExpr))
1024-
parentExpr = CS.getParentExpr(parentExpr);
1023+
bool hasContextualType = bool(CS.getContextualType(expr));
1024+
1025+
while (parentExpr) {
1026+
if (!isa<IdentityExpr>(parentExpr))
1027+
break;
1028+
1029+
// If there is a parent, use it, otherwise we need
1030+
// to check whether the last parent node in the chain
1031+
// had a contextual type associated with it because
1032+
// in situations like:
1033+
//
1034+
// \code
1035+
// func foo() -> Int? {
1036+
// return (nil)
1037+
// }
1038+
// \endcode
1039+
//
1040+
// parentheses around `nil` are significant.
1041+
if (auto *nextParent = CS.getParentExpr(parentExpr)) {
1042+
parentExpr = nextParent;
1043+
} else {
1044+
hasContextualType |= bool(CS.getContextualType(parentExpr));
1045+
// Since current expression is an identity expr
1046+
// and there are no more parents, let's pretend
1047+
// that `nil` don't have a parent since parens
1048+
// are not semantically significant for further checks.
1049+
parentExpr = nullptr;
1050+
}
1051+
}
10251052

10261053
// In cases like `_ = nil?` AST would have `nil`
10271054
// wrapped in `BindOptionalExpr`.
@@ -1056,7 +1083,7 @@ namespace {
10561083
}
10571084
}
10581085

1059-
if (!parentExpr && !CS.getContextualType(expr)) {
1086+
if (!parentExpr && !hasContextualType) {
10601087
DE.diagnose(expr->getLoc(), diag::unresolved_nil_literal);
10611088
return Type();
10621089
}

test/Constraints/optional.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,12 @@ func sr_12309() {
450450
_ = (((nil))) // expected-error {{'nil' requires a contextual type}}
451451
_ = ((((((nil)))))) // expected-error {{'nil' requires a contextual type}}
452452
_ = (((((((((nil))))))))) // expected-error {{'nil' requires a contextual type}}
453+
454+
func test_with_contextual_type_one() -> Int? {
455+
return (nil) // Ok
456+
}
457+
458+
func test_with_contextual_type_many() -> Int? {
459+
return (((nil))) // Ok
460+
}
453461
}

0 commit comments

Comments
 (0)