diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index f19b3a0..ce126fd 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1161,7 +1161,7 @@ static bool isStartOfStmtConditionClause(const Token &Tok) { } -/// Parse the condition of an 'if' or 'while'. +/// Parse the condition of an 'if', 'while', or 'guard'. /// /// condition: /// expr-basic @@ -1186,6 +1186,10 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition, SmallVector result; + // The body of "if" and "while" are delimited with braces, so they need to + // parse conditions as "expr basic" productions. Guard statements are + // followed by an "else" keyword, so they don't have this requirement. + bool useExprBasic = ParentKind != StmtKind::Guard; // This little helper function is used to consume a separator comma if // present, it returns false if it isn't there. It also gracefully handles @@ -1237,7 +1241,7 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition, // Parse the leading boolean condition if present. if (!isStartOfStmtConditionClause(Tok)) { - ParserResult CondExpr = parseExprBasic(ID); + ParserResult CondExpr = parseExprImpl(ID, useExprBasic); Status |= CondExpr; result.push_back(CondExpr.getPtrOrNull()); @@ -1270,7 +1274,7 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition, diag::expected_expr_conditional_letbinding_bool_conditions) .fixItReplace(CommaLoc, " &&"); do { - ParserResult CondExpr = parseExprBasic(ID); + ParserResult CondExpr = parseExprImpl(ID, useExprBasic); Status |= CondExpr; result.push_back(CondExpr.getPtrOrNull()); } while (consumeIf(tok::comma) && !isStartOfStmtConditionClause(Tok)); @@ -1390,7 +1394,7 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition, // Conditional bindings must have an initializer. if (consumeIf(tok::equal)) { ParserResult InitExpr - = parseExprBasic(diag::expected_expr_conditional_var); + = parseExprImpl(diag::expected_expr_conditional_var, useExprBasic); Status |= InitExpr; if (InitExpr.isNull() || InitExpr.hasCodeCompletion()) return Status; @@ -1465,7 +1469,7 @@ ParserStatus Parser::parseStmtCondition(StmtCondition &Condition, // remember it. if (hadIncorrectlyWrittenWhereClause || consumeIf(tok::kw_where)) { ParserResult WhereExpr - = parseExprBasic(diag::expected_expr_conditional_where); + = parseExprImpl(diag::expected_expr_conditional_where, useExprBasic); Status |= WhereExpr; if (WhereExpr.isNull() || WhereExpr.hasCodeCompletion()) return Status; diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift index 399e613..32a9f3f 100644 --- a/test/Parse/recovery.swift +++ b/test/Parse/recovery.swift @@ -682,5 +682,8 @@ func r23036383(arr : [Int]?) { let numbers = [1, 2] for _ in numbers.filter {$0 > 4} { // expected-error {{trailing closure requires parentheses for disambiguation in this context}} {{12-12=(}} {{35-35=)}} } + + guard let _ = arr?.map {$0+1} else { preconditionFailure() } + }