mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Merge #10420
10420: Parse outer attributes on StructPatternEtCetera r=jonas-schievink a=XFFXFF Try to fix https://github.com/rust-analyzer/rust-analyzer/issues/8610 Related pr in ungrammer: https://github.com/rust-analyzer/ungrammar/pull/41 Co-authored-by: zhoufan <1247714429@qq.com>
This commit is contained in:
commit
94fa49c0a3
@ -818,7 +818,7 @@ impl ExprCollector<'_> {
|
||||
let ellipsis = p
|
||||
.record_pat_field_list()
|
||||
.expect("every struct should have a field list")
|
||||
.dotdot_token()
|
||||
.rest_pat()
|
||||
.is_some();
|
||||
|
||||
Pat::Record { path, args, ellipsis }
|
||||
|
@ -205,46 +205,64 @@ fn tuple_pat_fields(p: &mut Parser) {
|
||||
p.expect(T![')']);
|
||||
}
|
||||
|
||||
// test record_pat_field
|
||||
// fn foo() {
|
||||
// let S { 0: 1 } = ();
|
||||
// let S { x: 1 } = ();
|
||||
// let S { #[cfg(any())] x: 1 } = ();
|
||||
// }
|
||||
fn record_pat_field(p: &mut Parser) {
|
||||
match p.current() {
|
||||
IDENT | INT_NUMBER if p.nth(1) == T![:] => {
|
||||
name_ref_or_index(p);
|
||||
p.bump(T![:]);
|
||||
pattern(p);
|
||||
}
|
||||
T![.] => {
|
||||
if p.at(T![..]) {
|
||||
p.bump(T![..]);
|
||||
} else {
|
||||
ident_pat(p, false);
|
||||
}
|
||||
}
|
||||
T![box] => {
|
||||
// FIXME: not all box patterns should be allowed
|
||||
box_pat(p);
|
||||
}
|
||||
_ => {
|
||||
ident_pat(p, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test record_pat_field_list
|
||||
// fn foo() {
|
||||
// let S {} = ();
|
||||
// let S { f, ref mut g } = ();
|
||||
// let S { h: _, ..} = ();
|
||||
// let S { h: _, } = ();
|
||||
// let S { #[cfg(any())] .. } = ();
|
||||
// }
|
||||
fn record_pat_field_list(p: &mut Parser) {
|
||||
assert!(p.at(T!['{']));
|
||||
let m = p.start();
|
||||
p.bump(T!['{']);
|
||||
while !p.at(EOF) && !p.at(T!['}']) {
|
||||
let m = p.start();
|
||||
attributes::outer_attrs(p);
|
||||
|
||||
match p.current() {
|
||||
// A trailing `..` is *not* treated as a REST_PAT.
|
||||
T![.] if p.at(T![..]) => p.bump(T![..]),
|
||||
T!['{'] => error_block(p, "expected ident"),
|
||||
|
||||
T![.] if p.at(T![..]) => {
|
||||
p.bump(T![..]);
|
||||
m.complete(p, REST_PAT);
|
||||
}
|
||||
T!['{'] => {
|
||||
error_block(p, "expected ident");
|
||||
m.abandon(p);
|
||||
}
|
||||
_ => {
|
||||
let m = p.start();
|
||||
attributes::outer_attrs(p);
|
||||
match p.current() {
|
||||
// test record_pat_field
|
||||
// fn foo() {
|
||||
// let S { 0: 1 } = ();
|
||||
// let S { x: 1 } = ();
|
||||
// let S { #[cfg(any())] x: 1 } = ();
|
||||
// }
|
||||
IDENT | INT_NUMBER if p.nth(1) == T![:] => {
|
||||
name_ref_or_index(p);
|
||||
p.bump(T![:]);
|
||||
pattern(p);
|
||||
}
|
||||
T![box] => {
|
||||
// FIXME: not all box patterns should be allowed
|
||||
box_pat(p);
|
||||
}
|
||||
_ => {
|
||||
ident_pat(p, false);
|
||||
}
|
||||
}
|
||||
record_pat_field(p);
|
||||
m.complete(p, RECORD_PAT_FIELD);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ rayon = "1"
|
||||
expect-test = "1.1"
|
||||
proc-macro2 = "1.0.8"
|
||||
quote = "1.0.2"
|
||||
ungrammar = "=1.14.5"
|
||||
ungrammar = "=1.14.6"
|
||||
|
||||
test_utils = { path = "../test_utils" }
|
||||
sourcegen = { path = "../sourcegen" }
|
||||
|
@ -1290,6 +1290,7 @@ impl BoxPat {
|
||||
pub struct RestPat {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl ast::HasAttrs for RestPat {}
|
||||
impl RestPat {
|
||||
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
|
||||
}
|
||||
@ -1418,7 +1419,7 @@ pub struct RecordPatFieldList {
|
||||
impl RecordPatFieldList {
|
||||
pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
|
||||
pub fn fields(&self) -> AstChildren<RecordPatField> { support::children(&self.syntax) }
|
||||
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
|
||||
pub fn rest_pat(&self) -> Option<RestPat> { support::child(&self.syntax) }
|
||||
pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
|
||||
}
|
||||
|
||||
@ -3836,6 +3837,7 @@ impl AstNode for AnyHasAttrs {
|
||||
| MATCH_ARM_LIST
|
||||
| MATCH_ARM
|
||||
| IDENT_PAT
|
||||
| REST_PAT
|
||||
| RECORD_PAT_FIELD => true,
|
||||
_ => false,
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ SOURCE_FILE@0..103
|
||||
RECORD_PAT_FIELD_LIST@66..72
|
||||
L_CURLY@66..67 "{"
|
||||
WHITESPACE@67..68 " "
|
||||
DOT2@68..70 ".."
|
||||
REST_PAT@68..70
|
||||
DOT2@68..70 ".."
|
||||
WHITESPACE@70..71 " "
|
||||
R_CURLY@71..72 "}"
|
||||
WHITESPACE@72..73 " "
|
||||
|
@ -1,5 +1,5 @@
|
||||
SOURCE_FILE@0..119
|
||||
FN@0..118
|
||||
SOURCE_FILE@0..156
|
||||
FN@0..155
|
||||
FN_KW@0..2 "fn"
|
||||
WHITESPACE@2..3 " "
|
||||
NAME@3..6
|
||||
@ -8,8 +8,8 @@ SOURCE_FILE@0..119
|
||||
L_PAREN@6..7 "("
|
||||
R_PAREN@7..8 ")"
|
||||
WHITESPACE@8..9 " "
|
||||
BLOCK_EXPR@9..118
|
||||
STMT_LIST@9..118
|
||||
BLOCK_EXPR@9..155
|
||||
STMT_LIST@9..155
|
||||
L_CURLY@9..10 "{"
|
||||
WHITESPACE@10..15 "\n "
|
||||
LET_STMT@15..29
|
||||
@ -89,7 +89,8 @@ SOURCE_FILE@0..119
|
||||
UNDERSCORE@78..79 "_"
|
||||
COMMA@79..80 ","
|
||||
WHITESPACE@80..81 " "
|
||||
DOT2@81..83 ".."
|
||||
REST_PAT@81..83
|
||||
DOT2@81..83 ".."
|
||||
R_CURLY@83..84 "}"
|
||||
WHITESPACE@84..85 " "
|
||||
EQ@85..86 "="
|
||||
@ -128,6 +129,47 @@ SOURCE_FILE@0..119
|
||||
L_PAREN@113..114 "("
|
||||
R_PAREN@114..115 ")"
|
||||
SEMICOLON@115..116 ";"
|
||||
WHITESPACE@116..117 "\n"
|
||||
R_CURLY@117..118 "}"
|
||||
WHITESPACE@118..119 "\n"
|
||||
WHITESPACE@116..121 "\n "
|
||||
LET_STMT@121..153
|
||||
LET_KW@121..124 "let"
|
||||
WHITESPACE@124..125 " "
|
||||
RECORD_PAT@125..147
|
||||
PATH@125..126
|
||||
PATH_SEGMENT@125..126
|
||||
NAME_REF@125..126
|
||||
IDENT@125..126 "S"
|
||||
WHITESPACE@126..127 " "
|
||||
RECORD_PAT_FIELD_LIST@127..147
|
||||
L_CURLY@127..128 "{"
|
||||
WHITESPACE@128..129 " "
|
||||
REST_PAT@129..145
|
||||
ATTR@129..142
|
||||
POUND@129..130 "#"
|
||||
L_BRACK@130..131 "["
|
||||
META@131..141
|
||||
PATH@131..134
|
||||
PATH_SEGMENT@131..134
|
||||
NAME_REF@131..134
|
||||
IDENT@131..134 "cfg"
|
||||
TOKEN_TREE@134..141
|
||||
L_PAREN@134..135 "("
|
||||
IDENT@135..138 "any"
|
||||
TOKEN_TREE@138..140
|
||||
L_PAREN@138..139 "("
|
||||
R_PAREN@139..140 ")"
|
||||
R_PAREN@140..141 ")"
|
||||
R_BRACK@141..142 "]"
|
||||
WHITESPACE@142..143 " "
|
||||
DOT2@143..145 ".."
|
||||
WHITESPACE@145..146 " "
|
||||
R_CURLY@146..147 "}"
|
||||
WHITESPACE@147..148 " "
|
||||
EQ@148..149 "="
|
||||
WHITESPACE@149..150 " "
|
||||
TUPLE_EXPR@150..152
|
||||
L_PAREN@150..151 "("
|
||||
R_PAREN@151..152 ")"
|
||||
SEMICOLON@152..153 ";"
|
||||
WHITESPACE@153..154 "\n"
|
||||
R_CURLY@154..155 "}"
|
||||
WHITESPACE@155..156 "\n"
|
||||
|
@ -3,4 +3,5 @@ fn foo() {
|
||||
let S { f, ref mut g } = ();
|
||||
let S { h: _, ..} = ();
|
||||
let S { h: _, } = ();
|
||||
let S { #[cfg(any())] .. } = ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user