Skip to content

Commit 566abca

Browse files
authored
Merge pull request swiftlang#36386 from ahoppen/pr/cancellable-backtracking-scope
[Parser] Distinguish between backtracking scopes that can be cancelled or not
2 parents 4c7059f + bfbd812 commit 566abca

File tree

7 files changed

+39
-21
lines changed

7 files changed

+39
-21
lines changed

include/swift/Parse/Parser.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,11 @@ class Parser {
463463
/// RAII object that, when it is destructed, restores the parser and lexer to
464464
/// their positions at the time the object was constructed. Will not jump
465465
/// forward in the token stream.
466-
class BacktrackingScope {
466+
/// Actual uses of the backtracking scope should choose either \c
467+
/// BacktrackingScope, which will always backtrack or \c
468+
/// CancellableBacktrackingScope which can be cancelled.
469+
class BacktrackingScopeImpl {
470+
protected:
467471
Parser &P;
468472
ParserPosition PP;
469473
DiagnosticTransaction DT;
@@ -501,16 +505,32 @@ class Parser {
501505
}
502506
} TempReceiver;
503507

504-
public:
505-
BacktrackingScope(Parser &P)
508+
BacktrackingScopeImpl(Parser &P)
506509
: P(P), PP(P.getParserPosition()), DT(P.Diags),
507510
TempReceiver(P.TokReceiver) {
508511
SynContext.emplace(P.SyntaxContext);
509-
SynContext->setBackTracking();
510512
}
511513

512-
~BacktrackingScope();
514+
public:
515+
~BacktrackingScopeImpl();
513516
bool willBacktrack() const { return Backtrack; }
517+
};
518+
519+
/// A backtracking scope that will always backtrack when destructed.
520+
class BacktrackingScope final : public BacktrackingScopeImpl {
521+
public:
522+
BacktrackingScope(Parser &P) : BacktrackingScopeImpl(P) {
523+
SynContext->disable();
524+
}
525+
};
526+
527+
/// A backtracking scope whose backtracking can be disabled by calling
528+
/// \c cancelBacktrack.
529+
class CancellableBacktrackingScope final : public BacktrackingScopeImpl {
530+
public:
531+
CancellableBacktrackingScope(Parser &P) : BacktrackingScopeImpl(P) {
532+
SynContext->setBackTracking();
533+
}
514534

515535
void cancelBacktrack();
516536
};

include/swift/SyntaxParse/SyntaxTreeCreator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ class SyntaxTreeCreator final : public SyntaxParseActions {
4848
/// tree.
4949
SyntaxParsingCache *SyntaxCache;
5050

51-
llvm::BumpPtrAllocator ScratchAlloc;
52-
5351
public:
5452
SyntaxTreeCreator(SourceManager &SM, unsigned bufferID,
5553
SyntaxParsingCache *syntaxCache,

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,7 +1120,7 @@ static Optional<AccessorKind> isAccessorLabel(const Token &token) {
11201120
/// or to `nullptr` if not. A missing base type is not considered an error.
11211121
static bool parseBaseTypeForQualifiedDeclName(Parser &P, TypeRepr *&baseType) {
11221122
baseType = nullptr;
1123-
Parser::BacktrackingScope backtrack(P);
1123+
Parser::CancellableBacktrackingScope backtrack(P);
11241124

11251125
// If base type cannot be parsed, return false (no error).
11261126
if (!P.canParseBaseTypeForQualifiedDeclName())
@@ -3028,7 +3028,7 @@ bool Parser::canParseTypeAttribute() {
30283028
/// \returns true on error, false on success
30293029
static bool parseDifferentiableTypeAttributeArgument(
30303030
Parser &P, TypeAttributes &Attributes, bool emitDiagnostics) {
3031-
Parser::BacktrackingScope backtrack(P);
3031+
Parser::CancellableBacktrackingScope backtrack(P);
30323032

30333033
// Match '( <identifier> )', and store the identifier token to `argument`.
30343034
if (!P.consumeIf(tok::l_paren))
@@ -3226,7 +3226,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, SourceLoc AtLoc,
32263226
SyntaxParsingContext TokListContext(SyntaxContext, SyntaxKind::TokenList);
32273227

32283228
if (Tok.is(tok::l_paren) && getEndOfPreviousLoc() == Tok.getLoc()) {
3229-
BacktrackingScope backtrack(*this);
3229+
CancellableBacktrackingScope backtrack(*this);
32303230
skipSingle();
32313231
// If we found '->', or 'throws' after paren, it's likely a parameter
32323232
// of function type.
@@ -5046,7 +5046,7 @@ bool Parser::canDelayMemberDeclParsing(bool &HasOperatorDeclarations,
50465046

50475047
// Skip until the matching right curly bracket; if we find a pound directive,
50485048
// we can't lazily parse.
5049-
BacktrackingScope BackTrack(*this);
5049+
CancellableBacktrackingScope BackTrack(*this);
50505050
bool HasPoundDirective;
50515051
bool HasNestedTypeDeclarations;
50525052
skipUntilMatchingRBrace(*this,
@@ -5975,7 +5975,7 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags,
59755975
};
59765976

59775977
// Prepare backtracking for implicit getter.
5978-
Optional<BacktrackingScope> backtrack;
5978+
Optional<CancellableBacktrackingScope> backtrack;
59795979
backtrack.emplace(*this);
59805980

59815981
bool Invalid = false;
@@ -7114,7 +7114,7 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
71147114
// For recovery, see if the user typed something resembling a switch
71157115
// "case" label.
71167116
{
7117-
BacktrackingScope backtrack(*this);
7117+
CancellableBacktrackingScope backtrack(*this);
71187118
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
71197119
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
71207120
parseMatchingPattern(/*isExprBasic*/false);

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2083,7 +2083,7 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
20832083

20842084
// Try to parse a compound name.
20852085
SyntaxParsingContext ArgsCtxt(P.SyntaxContext, SyntaxKind::DeclNameArguments);
2086-
Parser::BacktrackingScope backtrack(P);
2086+
Parser::CancellableBacktrackingScope backtrack(P);
20872087

20882088
lparenLoc = P.consumeToken(tok::l_paren);
20892089
while (P.Tok.isNot(tok::r_paren)) {

lib/Parse/ParsePattern.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,8 @@ ParserResult<Pattern> Parser::parseTypedPattern() {
968968
// Disable this tentative parse when in code-completion mode, otherwise
969969
// code-completion may enter the delayed-decl state twice.
970970
if (Tok.isFollowingLParen() && !L->isCodeCompletion()) {
971-
BacktrackingScope backtrack(*this);
972-
971+
CancellableBacktrackingScope backtrack(*this);
972+
973973
// Create a local context if needed so we can parse trailing closures.
974974
LocalContext dummyContext;
975975
Optional<ContextChange> contextChange;

lib/Parse/ParseType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ ParserResult<TypeRepr> Parser::parseTypeTupleBody() {
999999
// 'inout' here can be a obsoleted use of the marker in an argument list,
10001000
// consume it in backtracking context so we can determine it's really a
10011001
// deprecated use of it.
1002-
llvm::Optional<BacktrackingScope> Backtracking;
1002+
llvm::Optional<CancellableBacktrackingScope> Backtracking;
10031003
SourceLoc ObsoletedInOutLoc;
10041004
if (Tok.is(tok::kw_inout)) {
10051005
Backtracking.emplace(*this);

lib/Parse/Parser.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,14 @@ void Parser::performCodeCompletionSecondPassImpl(
214214
State->restoreCodeCompletionDelayedDeclState(info);
215215
}
216216

217-
swift::Parser::BacktrackingScope::~BacktrackingScope() {
217+
swift::Parser::BacktrackingScopeImpl::~BacktrackingScopeImpl() {
218218
if (Backtrack) {
219219
P.backtrackToPosition(PP);
220220
DT.abort();
221221
}
222222
}
223223

224-
void swift::Parser::BacktrackingScope::cancelBacktrack() {
224+
void swift::Parser::CancellableBacktrackingScope::cancelBacktrack() {
225225
if (!Backtrack)
226226
return;
227227

@@ -783,8 +783,8 @@ void Parser::skipListUntilDeclRBrace(SourceLoc startLoc, tok T1, tok T2) {
783783
if (possibleDeclStartsLine && !hasDelimiter) {
784784
break;
785785
}
786-
787-
Parser::BacktrackingScope backtrack(*this);
786+
787+
Parser::CancellableBacktrackingScope backtrack(*this);
788788
// Consume the let or var
789789
consumeToken();
790790

0 commit comments

Comments
 (0)