Skip to content

Commit 90c5dfa

Browse files
[Parse] Track whether an let _: pattern is an async let pattern
1 parent d321725 commit 90c5dfa

File tree

6 files changed

+52
-10
lines changed

6 files changed

+52
-10
lines changed

include/swift/AST/Pattern.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,14 @@ class NamedPattern : public Pattern {
369369
/// bind a name to it. This is spelled "_".
370370
class AnyPattern : public Pattern {
371371
SourceLoc Loc;
372+
/// Flag representing if this is an "async let _: Type" pattern since
373+
/// `async let _` is a subPattern of a \c TypedPattern represented
374+
/// as \c AnyPattern
375+
bool IsAsyncLet;
372376

373377
public:
374-
explicit AnyPattern(SourceLoc Loc)
375-
: Pattern(PatternKind::Any), Loc(Loc) { }
378+
explicit AnyPattern(SourceLoc Loc, bool IsAsyncLet = false)
379+
: Pattern(PatternKind::Any), Loc(Loc), IsAsyncLet(IsAsyncLet) {}
376380

377381
static AnyPattern *createImplicit(ASTContext &Context) {
378382
auto *AP = new (Context) AnyPattern(SourceLoc());
@@ -383,6 +387,8 @@ class AnyPattern : public Pattern {
383387
SourceLoc getLoc() const { return Loc; }
384388
SourceRange getSourceRange() const { return Loc; }
385389

390+
bool isAsyncLet() const { return IsAsyncLet; }
391+
386392
static bool classof(const Pattern *P) {
387393
return P->getKind() == PatternKind::Any;
388394
}

include/swift/Parse/Parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ class Parser {
160160
IVOLP_InLet
161161
} InVarOrLetPattern = IVOLP_NotInVarOrLet;
162162

163+
/// Whether this context has an async attribute.
164+
bool InPatternWithAsyncAttribute = false;
165+
163166
bool InPoundLineEnvironment = false;
164167
bool InPoundIfEnvironment = false;
165168
/// Do not call \c addUnvalidatedDeclWithOpaqueResultType when in an inactive

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6959,6 +6959,11 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
69596959
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
69606960
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
69616961

6962+
// Track whether we are parsing an 'async let' pattern.
6963+
const auto hasAsyncAttr = Attributes.hasAttribute<AsyncAttr>();
6964+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute,
6965+
hasAsyncAttr);
6966+
69626967
auto patternRes = parseTypedPattern();
69636968
if (patternRes.hasCodeCompletion())
69646969
return makeResult(makeParserCodeCompletionStatus());
@@ -7643,7 +7648,11 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
76437648
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
76447649
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
76457650
parseMatchingPattern(/*isExprBasic*/false);
7646-
7651+
7652+
// Reset async attribute in parser context.
7653+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute,
7654+
false);
7655+
76477656
if (consumeIf(tok::colon)) {
76487657
backtrack.cancelBacktrack();
76497658
diagnose(CaseLoc, diag::case_outside_of_switch, "case");

lib/Parse/ParseExpr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2917,7 +2917,10 @@ ParserResult<Expr> Parser::parseExprClosure() {
29172917
// reset our state to not be in a pattern for any recursive pattern parses.
29182918
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
29192919
T(InVarOrLetPattern, IVOLP_NotInVarOrLet);
2920-
2920+
2921+
// Reset async attribute in parser context.
2922+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
2923+
29212924
// Parse the opening left brace.
29222925
SourceLoc leftBrace = consumeToken();
29232926

lib/Parse/ParsePattern.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,8 @@ ParserResult<Pattern> Parser::parsePattern() {
11191119
switch (Tok.getKind()) {
11201120
case tok::l_paren:
11211121
return parsePatternTuple();
1122-
1123-
case tok::kw__:
1122+
1123+
case tok::kw__: {
11241124
// Normally, '_' is invalid in type context for patterns, but they show up
11251125
// in interface files as the name for type members that are non-public.
11261126
// Treat them as an implicitly synthesized NamedPattern with a nameless
@@ -1134,8 +1134,12 @@ ParserResult<Pattern> Parser::parsePattern() {
11341134
return makeParserResult(NamedPattern::createImplicit(Context, VD));
11351135
}
11361136
PatternCtx.setCreateSyntax(SyntaxKind::WildcardPattern);
1137-
return makeParserResult(new (Context) AnyPattern(consumeToken(tok::kw__)));
1138-
1137+
1138+
const auto isAsyncLet =
1139+
InPatternWithAsyncAttribute && introducer == VarDecl::Introducer::Let;
1140+
return makeParserResult(
1141+
new (Context) AnyPattern(consumeToken(tok::kw__), isAsyncLet));
1142+
}
11391143
case tok::identifier: {
11401144
PatternCtx.setCreateSyntax(SyntaxKind::IdentifierPattern);
11411145
Identifier name;
@@ -1174,7 +1178,10 @@ ParserResult<Pattern> Parser::parsePattern() {
11741178
// In our recursive parse, remember that we're in a var/let pattern.
11751179
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
11761180
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
1177-
1181+
1182+
// Reset async attribute in parser context.
1183+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
1184+
11781185
ParserResult<Pattern> subPattern = parsePattern();
11791186
if (subPattern.hasCodeCompletion())
11801187
return makeParserCodeCompletionResult<Pattern>();
@@ -1384,6 +1391,9 @@ ParserResult<Pattern> Parser::parseMatchingPatternAsLetOrVar(bool isLet,
13841391
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
13851392
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
13861393

1394+
// Reset async attribute in parser context.
1395+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
1396+
13871397
ParserResult<Pattern> subPattern = parseMatchingPattern(isExprBasic);
13881398
if (subPattern.isNull())
13891399
return nullptr;

lib/Parse/ParseStmt.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,10 @@ Parser::parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
15621562
// In our recursive parse, remember that we're in a matching pattern.
15631563
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
15641564
T(InVarOrLetPattern, IVOLP_InMatchingPattern);
1565+
1566+
// Reset async attribute in parser context.
1567+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
1568+
15651569
ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
15661570
} else if (Tok.is(tok::kw_case)) {
15671571
ConditionCtxt.setCreateSyntax(SyntaxKind::Unknown);
@@ -1580,7 +1584,10 @@ Parser::parseStmtConditionElement(SmallVectorImpl<StmtConditionElement> &result,
15801584
// In our recursive parse, remember that we're in a var/let pattern.
15811585
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
15821586
T(InVarOrLetPattern, wasLet ? IVOLP_InLet : IVOLP_InVar);
1583-
1587+
1588+
// Reset async attribute in parser context.
1589+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
1590+
15841591
ThePattern = parseMatchingPattern(/*isExprBasic*/ true);
15851592

15861593
if (ThePattern.isNonNull()) {
@@ -2234,6 +2241,10 @@ ParserResult<Stmt> Parser::parseStmtForEach(LabeledStmtInfo LabelInfo) {
22342241
if (consumeIf(tok::kw_case)) {
22352242
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
22362243
T(InVarOrLetPattern, Parser::IVOLP_InMatchingPattern);
2244+
2245+
// Reset async attribute in parser context.
2246+
llvm::SaveAndRestore<bool> AsyncAttr(InPatternWithAsyncAttribute, false);
2247+
22372248
pattern = parseMatchingPattern(/*isExprBasic*/true);
22382249
pattern = parseOptionalPatternTypeAnnotation(pattern);
22392250
} else if (!IsCStyleFor || Tok.is(tok::kw_var)) {

0 commit comments

Comments
 (0)