Skip to content

Commit 1c729ca

Browse files
author
Nathan Hawes
committed
[Parse] Fix up a few places where we weren't propagating parse error status correctly.
We were always dropping the error status when returning from parseExprImpl. We were also incorrectly keeping error status after recovering by finding the right close token in parseList. This change fixes both, and also updates a few callers of parseList that assumed when they reported a failure parsing an element the list as a whole would get error status, which isn't true due to recovery.
1 parent a368434 commit 1c729ca

File tree

4 files changed

+44
-35
lines changed

4 files changed

+44
-35
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
18391839
PlatformAndVersions;
18401840

18411841
StringRef AttrName = "@_originalDefinedIn";
1842+
bool SuppressLaterDiags = false;
18421843
if (parseList(tok::r_paren, LeftLoc, RightLoc, false,
18431844
diag::originally_defined_in_missing_rparen,
18441845
SyntaxKind::Unknown, [&]() -> ParserStatus {
@@ -1854,6 +1855,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
18541855
if (!Tok.is(tok::identifier) || Tok.getText() != "module" ||
18551856
!peekToken().is(tok::colon)) {
18561857
diagnose(Tok, diag::originally_defined_in_need_original_module_name);
1858+
SuppressLaterDiags = true;
18571859
return makeParserError();
18581860
}
18591861
consumeToken(tok::identifier);
@@ -1870,6 +1872,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
18701872
if (OriginalModuleName.empty()) {
18711873
diagnose(ModuleNameLoc,
18721874
diag::originally_defined_in_need_nonempty_module_name);
1875+
SuppressLaterDiags = true;
18731876
return makeParserError();
18741877
}
18751878
return makeParserSuccess();
@@ -1885,6 +1888,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
18851888
if (!Plat.hasValue()) {
18861889
diagnose(Tok.getLoc(),
18871890
diag::originally_defined_in_unrecognized_platform);
1891+
SuppressLaterDiags = true;
18881892
return makeParserError();
18891893
} else {
18901894
consumeToken();
@@ -1895,6 +1899,7 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
18951899
SourceRange VersionRange;
18961900
if (parseVersionTuple(VerTuple, VersionRange,
18971901
Diagnostic(diag::attr_availability_expected_version, AttrName))) {
1902+
SuppressLaterDiags = true;
18981903
return makeParserError();
18991904
} else {
19001905
if (VerTuple.getSubminor().hasValue() ||
@@ -1911,10 +1916,11 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
19111916
}
19121917
}
19131918
diagnose(AtLoc, diag::originally_defined_in_need_platform_version);
1919+
SuppressLaterDiags = true;
19141920
return makeParserError();
19151921
}
19161922
}
1917-
}).isError()) {
1923+
}).isError() || SuppressLaterDiags) {
19181924
return false;
19191925
}
19201926
if (OriginalModuleName.empty()) {

lib/Parse/ParseExpr.cpp

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,8 @@ ParserResult<Expr> Parser::parseExprImpl(Diag<> Message,
6262
return makeParserResult(new (Context) UnresolvedPatternExpr(pattern.get()));
6363
}
6464

65-
auto expr = parseExprSequence(Message, isExprBasic,
65+
return parseExprSequence(Message, isExprBasic,
6666
/*forConditionalDirective*/false);
67-
if (expr.hasCodeCompletion())
68-
return expr;
69-
if (expr.isNull())
70-
return nullptr;
71-
72-
return makeParserResult(expr.get());
7367
}
7468

7569
/// parseExprIs
@@ -173,7 +167,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
173167

174168
SmallVector<Expr*, 8> SequencedExprs;
175169
SourceLoc startLoc = Tok.getLoc();
176-
bool HasCodeCompletion = false;
170+
ParserStatus SequenceStatus;
177171
bool PendingTernary = false;
178172

179173
while (true) {
@@ -183,20 +177,18 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
183177
// Parse a unary expression.
184178
ParserResult<Expr> Primary =
185179
parseExprSequenceElement(Message, isExprBasic);
180+
SequenceStatus |= Primary;
186181

187-
if (Primary.hasCodeCompletion()) {
188-
HasCodeCompletion = true;
189-
if (CodeCompletion)
182+
if (SequenceStatus.hasCodeCompletion() && CodeCompletion)
190183
CodeCompletion->setLeadingSequenceExprs(SequencedExprs);
191-
}
184+
192185
if (Primary.isNull()) {
193-
if (HasCodeCompletion) {
186+
if (SequenceStatus.hasCodeCompletion()) {
194187
SequencedExprs.push_back(new (Context) CodeCompletionExpr(PreviousLoc));
195188
break;
196189
}
197-
return Primary;
190+
return nullptr;
198191
}
199-
200192
SequencedExprs.push_back(Primary.get());
201193

202194
// We know we can make a syntax node for ternary expression.
@@ -205,6 +197,9 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
205197
PendingTernary = false;
206198
}
207199

200+
if (SequenceStatus.isError() && !SequenceStatus.hasCodeCompletion())
201+
break;
202+
208203
if (isForConditionalDirective && Tok.isAtStartOfLine())
209204
break;
210205

@@ -242,9 +237,8 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
242237
// Parse the middle expression of the ternary.
243238
ParserResult<Expr> middle =
244239
parseExprSequence(diag::expected_expr_after_if_question, isExprBasic);
240+
SequenceStatus |= middle;
245241
ParserStatus Status = middle;
246-
if (middle.hasCodeCompletion())
247-
HasCodeCompletion = true;
248242
if (middle.isNull())
249243
return nullptr;
250244

@@ -304,6 +298,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
304298

305299
// Store the expr itself as a placeholder RHS. The real RHS is the
306300
// type parameter stored in the node itself.
301+
SequenceStatus |= is;
307302
SequencedExprs.push_back(is.get());
308303
SequencedExprs.push_back(is.get());
309304

@@ -320,6 +315,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
320315

321316
// Store the expr itself as a placeholder RHS. The real RHS is the
322317
// type parameter stored in the node itself.
318+
SequenceStatus |= as;
323319
SequencedExprs.push_back(as.get());
324320
SequencedExprs.push_back(as.get());
325321

@@ -334,6 +330,7 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
334330
ParserResult<Expr> arrow = parseExprArrow();
335331
if (arrow.isNull() || arrow.hasCodeCompletion())
336332
return arrow;
333+
SequenceStatus |= arrow;
337334
SequencedExprs.push_back(arrow.get());
338335
break;
339336
}
@@ -356,19 +353,13 @@ ParserResult<Expr> Parser::parseExprSequence(Diag<> Message,
356353
assert(!SequencedExprs.empty());
357354

358355
// If we saw no operators, don't build a sequence.
359-
if (SequencedExprs.size() == 1) {
360-
auto Result = makeParserResult(SequencedExprs[0]);
361-
if (HasCodeCompletion)
362-
Result.setHasCodeCompletion();
363-
return Result;
364-
}
356+
if (SequencedExprs.size() == 1)
357+
return makeParserResult(SequenceStatus, SequencedExprs[0]);
365358

366359
ExprSequnceContext.createNodeInPlace(SyntaxKind::ExprList);
367360
ExprSequnceContext.setCreateSyntax(SyntaxKind::SequenceExpr);
368-
auto Result = makeParserResult(SequenceExpr::create(Context, SequencedExprs));
369-
if (HasCodeCompletion)
370-
Result.setHasCodeCompletion();
371-
return Result;
361+
return makeParserResult(SequenceStatus,
362+
SequenceExpr::create(Context, SequencedExprs));
372363
}
373364

374365
/// parseExprSequenceElement
@@ -568,9 +559,12 @@ ParserResult<Expr> Parser::parseExprKeyPath() {
568559

569560
// FIXME: diagnostics
570561
ParserResult<Expr> rootResult, pathResult;
562+
ParserStatus parseStatus;
563+
571564
if (!startsWithSymbol(Tok, '.')) {
572565
rootResult = parseExprPostfix(diag::expr_keypath_expected_expr,
573566
/*isBasic=*/true);
567+
parseStatus = rootResult;
574568

575569
if (rootResult.isParseError())
576570
return rootResult;
@@ -600,10 +594,11 @@ ParserResult<Expr> Parser::parseExprKeyPath() {
600594
pathResult = parseExprPostfixSuffix(inner, /*isExprBasic=*/true,
601595
/*periodHasKeyPathBehavior=*/false,
602596
unusedHasBindOptional);
597+
parseStatus |= pathResult;
603598
}
604599

605-
if (!rootResult.getPtrOrNull() && !pathResult.getPtrOrNull())
606-
return pathResult;
600+
if (rootResult.isNull() && pathResult.isNull())
601+
return nullptr;
607602

608603
auto keypath = new (Context) KeyPathExpr(
609604
backslashLoc, rootResult.getPtrOrNull(), pathResult.getPtrOrNull());
@@ -619,7 +614,6 @@ ParserResult<Expr> Parser::parseExprKeyPath() {
619614
return makeParserCodeCompletionResult(keypath);
620615
}
621616

622-
ParserStatus parseStatus = ParserStatus(rootResult) | ParserStatus(pathResult);
623617
return makeParserResult(parseStatus, keypath);
624618
}
625619

lib/Parse/Parser.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,14 @@ Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
11181118

11191119
if (Status.isError()) {
11201120
// If we've already got errors, don't emit missing RightK diagnostics.
1121-
RightLoc =
1122-
Tok.is(RightK) ? consumeToken() : getLocForMissingMatchingToken();
1121+
if (Tok.is(RightK)) {
1122+
RightLoc = consumeToken();
1123+
// Don't propagate the error because we have recovered.
1124+
if (!Status.hasCodeCompletion())
1125+
Status = makeParserSuccess();
1126+
} else {
1127+
RightLoc = getLocForMissingMatchingToken();
1128+
}
11231129
} else if (parseMatchingToken(RightK, RightLoc, ErrorDiag, LeftLoc)) {
11241130
Status.setIsParseError();
11251131
}

lib/ParseSIL/ParseSIL.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,18 +1594,21 @@ bool SILParser::parseSILBBArgsAtBranch(SmallVector<SILValue, 6> &Args,
15941594
SourceLoc LParenLoc = P.consumeToken(tok::l_paren);
15951595
SourceLoc RParenLoc;
15961596

1597+
bool HasError = false;
15971598
if (P.parseList(tok::r_paren, LParenLoc, RParenLoc,
15981599
/*AllowSepAfterLast=*/false,
15991600
diag::sil_basicblock_arg_rparen,
16001601
SyntaxKind::Unknown,
16011602
[&]() -> ParserStatus {
16021603
SILValue Arg;
16031604
SourceLoc ArgLoc;
1604-
if (parseTypedValueRef(Arg, ArgLoc, B))
1605+
if (parseTypedValueRef(Arg, ArgLoc, B)) {
1606+
HasError = true;
16051607
return makeParserError();
1608+
}
16061609
Args.push_back(Arg);
16071610
return makeParserSuccess();
1608-
}).isError())
1611+
}).isError() || HasError)
16091612
return true;
16101613
}
16111614
return false;

0 commit comments

Comments
 (0)