fix parsing of isolated as an argument label

With the introduction of `isolated` as
a type modifier for actor types, the
parsing of a parameter regressed such
that `isolated` was no longer accepted
as an ordinary argument label. This patch
fixes that and adds a little lookahead
utility to clean-up the code that
disambiguates the uses of `isolated`
as either a label or a type modifier.

Resolves rdar://80300022
This commit is contained in:
Kavon Farvardin
2021-07-15 17:42:26 -07:00
parent f460de4847
commit 5ffe8e0878
3 changed files with 89 additions and 11 deletions

View File

@@ -172,12 +172,15 @@ bool Parser::startsParameterName(bool isClosure) {
return true;
// "isolated" can be an argument label, but it's also a contextual keyword,
// so look ahead one more token see if we have a ':' that would indicate
// that this is an argument label.
BacktrackingScope backtrackScope(*this);
consumeToken();
consumeToken();
return Tok.is(tok::colon);
// so look ahead one more token (two total) see if we have a ':' that would
// indicate that this is an argument label.
return lookahead<bool>(2, [&](CancellableBacktrackingScope &) {
if (Tok.is(tok::colon))
return true; // isolated :
// isolated x :
return Tok.canBeArgumentLabel() && nextTok.is(tok::colon);
});
}
if (isOptionalToken(nextTok)
@@ -260,14 +263,30 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
Tok.isContextualKeyword("__shared") ||
Tok.isContextualKeyword("__owned") ||
Tok.isContextualKeyword("isolated")) {
if (Tok.isContextualKeyword("isolated")) {
// did we already find an 'isolated' type modifier?
if (param.IsolatedLoc.isValid()) {
diagnose(Tok, diag::parameter_specifier_repeated)
.fixItRemove(Tok.getLoc());
.fixItRemove(Tok.getLoc());
consumeToken();
} else {
param.IsolatedLoc = consumeToken();
continue;
}
// is this 'isolated' token the identifier of an argument label?
bool partOfArgumentLabel = lookahead<bool>(1, [&](CancellableBacktrackingScope &) {
if (Tok.is(tok::colon))
return true; // isolated :
// isolated x :
return Tok.canBeArgumentLabel() && peekToken().is(tok::colon);
});
if (partOfArgumentLabel)
break;
// consume 'isolated' as type modifier
param.IsolatedLoc = consumeToken();
continue;
}
@@ -304,7 +323,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
diagnose(Tok, diag::parameter_let_var_as_attr, Tok.getText())
.fixItReplace(Tok.getLoc(), "`" + Tok.getText().str() + "`");
}
if (startsParameterName(isClosure)) {
// identifier-or-none for the first name
param.FirstNameLoc = consumeArgumentLabel(param.FirstName,
@@ -433,7 +452,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
status.setIsParseError();
}
}
// '...'?
if (Tok.isEllipsis()) {
Tok.setKind(tok::ellipsis);