Skip to content

Commit 89d7969

Browse files
committed
[Parse] Skip attributes in isStartOfDecl().
Previously, '@' token was unconditionally considered as isStartOfDecl() Since canParseTypeTupleBody() fails at isStartOfDecl(), generics arguments containing attributes, e.g. Array<(@convention(block) () -> Int) -> Void> failed to be parsed.
1 parent 67f4ae0 commit 89d7969

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,31 @@ bool Parser::isStartOfDecl() {
17411741
if (Tok.is(tok::kw_try))
17421742
return peekToken().isAny(tok::kw_let, tok::kw_var);
17431743

1744+
// Look through attribute list, because it may be an *type* attribute list.
1745+
if (Tok.is(tok::at_sign)) {
1746+
BacktrackingScope backtrack(*this);
1747+
while (consumeIf(tok::at_sign)) {
1748+
// If not identifier or code complete token, consider '@' is a incomplete
1749+
// attribute.
1750+
if (Tok.isNot(tok::identifier, tok::code_complete))
1751+
continue;
1752+
consumeToken();
1753+
// Eat paren after attribute name; e.g. @foo(x)
1754+
if (consumeIf(tok::l_paren)) {
1755+
while (Tok.isNot(tok::r_brace, tok::eof, tok::pound_endif)) {
1756+
if (consumeIf(tok::r_paren)) break;
1757+
skipSingle();
1758+
}
1759+
}
1760+
}
1761+
// If this attribute is the last element in the block,
1762+
// consider it is a start of incomplete decl.
1763+
if (Tok.isAny(tok::r_brace, tok::eof, tok::pound_endif))
1764+
return true;
1765+
1766+
return isStartOfDecl();
1767+
}
1768+
17441769
// Otherwise, the only hard case left is the identifier case.
17451770
if (Tok.isNot(tok::identifier)) return true;
17461771

test/Parse/generic_disambiguation.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ A<[[A<B>]]>.c()
4343
A<(Int, UnicodeScalar)>.c()
4444
A<(a:Int, b:UnicodeScalar)>.c()
4545
A<Runcible & Fungible>.c()
46+
A<@convention(c) () -> Int32>.c()
47+
A<(@autoclosure @escaping () -> Int, Int) -> Void>.c()
4648

4749
A<B>(x: 0) // expected-warning{{unused}}
4850

0 commit comments

Comments
 (0)