Skip to content

Commit 36e0c7d

Browse files
authored
Merge pull request #64566 from hamishknight/patterns-and-rec
2 parents a2d2fef + 0883b4b commit 36e0c7d

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/Parse/ParseStmt.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,16 @@ Parser::parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
17281728
auto diagLoc = ThePattern.get()->getSemanticsProvidingPattern()->getStartLoc();
17291729
diagnose(diagLoc, diag::conditional_var_valid_identifiers_only)
17301730
.fixItInsert(diagLoc, "<#identifier#> = ");
1731+
1732+
// For better recovery, assume the expression pattern as the initializer,
1733+
// and synthesize an optional AnyPattern.
1734+
auto *semanticPattern = ThePattern.get()->getSemanticsProvidingPattern();
1735+
if (auto *EP = dyn_cast<ExprPattern>(semanticPattern)) {
1736+
Init = makeParserResult(EP->getSubExpr());
1737+
auto *AP = AnyPattern::createImplicit(Context);
1738+
ThePattern =
1739+
makeParserResult(OptionalSomePattern::createImplicit(Context, AP));
1740+
}
17311741
} else {
17321742
diagnose(Tok, diag::conditional_var_initializer_required);
17331743
}

test/stmt/if_while_var.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ if var nonOptional { nonOptional = nonOptionalStruct(); _ = nonOptional } // exp
4242
guard let nonOptional else { _ = nonOptional; fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalStruct'}}
4343
guard var nonOptional else { _ = nonOptional; fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalStruct'}}
4444

45-
if let nonOptional.property { } // expected-error{{unwrap condition requires a valid identifier}} expected-error{{pattern matching in a condition requires the 'case' keyword}}
46-
if var nonOptional.property { } // expected-error{{unwrap condition requires a valid identifier}} expected-error{{pattern matching in a condition requires the 'case' keyword}}
45+
if let nonOptional.property { }
46+
// expected-error@-1 {{unwrap condition requires a valid identifier}}
47+
// expected-error@-2 {{initializer for conditional binding must have Optional type, not 'Any'}}
48+
49+
if var nonOptional.property { }
50+
// expected-error@-1 {{unwrap condition requires a valid identifier}}
51+
// expected-error@-2 {{initializer for conditional binding must have Optional type, not 'Any'}}
4752

4853
guard let _ = nonOptionalStruct() else { fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalStruct'}}
4954
guard let _ = nonOptionalEnum() else { fatalError() } // expected-error{{initializer for conditional binding must have Optional type, not 'NonOptionalEnum'}}
@@ -65,7 +70,11 @@ class B {} // expected-note * {{did you mean 'B'?}}
6570
class D : B {}// expected-note * {{did you mean 'D'?}}
6671

6772
// TODO poor recovery in these cases
68-
if let {} // expected-error {{expected '{' after 'if' condition}} expected-error {{pattern matching in a condition requires the 'case' keyword}} expected-error {{unwrap condition requires a valid identifier}}
73+
if let {}
74+
// expected-error@-1 {{expected '{' after 'if' condition}}
75+
// expected-error@-2 {{unwrap condition requires a valid identifier}}
76+
// expected-error@-3 {{initializer for conditional binding must have Optional type, not '() -> ()'}}
77+
6978
if let x = { } // expected-error{{'{' after 'if'}} expected-error{{initializer for conditional binding must have Optional type, not '() -> ()'}}
7079
// expected-warning@-1{{value 'x' was defined but never used}}
7180

0 commit comments

Comments
 (0)