Skip to content

Commit 9b00e35

Browse files
committed
[Parser] refactor nested 'init' diagnostics. NFC
Add better comment. Replace a dyn_cast with cast per Jordan's observation.
1 parent ccc8791 commit 9b00e35

File tree

2 files changed

+27
-28
lines changed

2 files changed

+27
-28
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,12 +1733,14 @@ static bool isParenthesizedUnowned(Parser &P) {
17331733
}
17341734

17351735

1736-
17371736
bool Parser::isStartOfDecl() {
17381737
// If this is obviously not the start of a decl, then we're done.
17391738
if (!isKeywordPossibleDeclStart(Tok)) return false;
17401739

1741-
// 'init' invocation is not start of a declaration
1740+
// When 'init' appears inside another 'init', it's likely the user wants to
1741+
// invoke a initializer but forgets to prefix it with 'self.' or 'super.'
1742+
// Otherwise, expect 'init' to be the start of a declaration (and complain
1743+
// when the expectation is not fullfilled).
17421744
if (Tok.is(tok::kw_init)) {
17431745
return !isa<ConstructorDecl>(CurDeclContext);
17441746
}

lib/Parse/ParseStmt.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -408,34 +408,31 @@ ParserStatus Parser::parseBraceItems(SmallVectorImpl<ASTNode> &Entries,
408408
}
409409
}
410410
}
411-
} else {
411+
} else if (Tok.is(tok::kw_init) && isa<ConstructorDecl>(CurDeclContext)) {
412412
SourceLoc StartLoc = Tok.getLoc();
413-
if (Tok.is(tok::kw_init)) {
414-
if (auto CD = dyn_cast<ConstructorDecl>(CurDeclContext)) {
415-
// Hint at missing 'self.' or 'super.' then skip this statement.
416-
bool isConvenient = CD->isConvenienceInit();
417-
diagnose(StartLoc, diag::invalid_nested_init, isConvenient)
418-
.fixItInsert(StartLoc, isConvenient ? "self." : "super.");
419-
NeedParseErrorRecovery = true;
420-
}
421-
} else {
422-
ParserStatus ExprOrStmtStatus = parseExprOrStmt(Result);
423-
BraceItemsStatus |= ExprOrStmtStatus;
424-
if (ExprOrStmtStatus.isError())
425-
NeedParseErrorRecovery = true;
426-
diagnoseDiscardedClosure(*this, Result);
427-
if (ExprOrStmtStatus.isSuccess() && IsTopLevel) {
428-
// If this is a normal library, you can't have expressions or
429-
// statements outside at the top level.
430-
diagnose(StartLoc,
431-
Result.is<Stmt*>() ? diag::illegal_top_level_stmt
432-
: diag::illegal_top_level_expr);
433-
Result = ASTNode();
434-
}
435-
436-
if (!Result.isNull())
437-
Entries.push_back(Result);
413+
auto CD = cast<ConstructorDecl>(CurDeclContext);
414+
// Hint at missing 'self.' or 'super.' then skip this statement.
415+
bool isConvenient = CD->isConvenienceInit();
416+
diagnose(StartLoc, diag::invalid_nested_init, isConvenient)
417+
.fixItInsert(StartLoc, isConvenient ? "self." : "super.");
418+
NeedParseErrorRecovery = true;
419+
} else {
420+
ParserStatus ExprOrStmtStatus = parseExprOrStmt(Result);
421+
BraceItemsStatus |= ExprOrStmtStatus;
422+
if (ExprOrStmtStatus.isError())
423+
NeedParseErrorRecovery = true;
424+
diagnoseDiscardedClosure(*this, Result);
425+
if (ExprOrStmtStatus.isSuccess() && IsTopLevel) {
426+
// If this is a normal library, you can't have expressions or
427+
// statements outside at the top level.
428+
diagnose(Tok.getLoc(),
429+
Result.is<Stmt*>() ? diag::illegal_top_level_stmt
430+
: diag::illegal_top_level_expr);
431+
Result = ASTNode();
438432
}
433+
434+
if (!Result.isNull())
435+
Entries.push_back(Result);
439436
}
440437

441438
if (!NeedParseErrorRecovery && !PreviousHadSemi && Tok.is(tok::semi)) {

0 commit comments

Comments
 (0)