Skip to content

Commit 0ee6b70

Browse files
committed
Parse outer attributes on StructPatternEtCetera
1 parent 237ea0d commit 0ee6b70

File tree

6 files changed

+103
-32
lines changed

6 files changed

+103
-32
lines changed

crates/hir_def/src/body/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ impl ExprCollector<'_> {
821821
let ellipsis = p
822822
.record_pat_field_list()
823823
.expect("every struct should have a field list")
824-
.dotdot_token()
824+
.rest_pat()
825825
.is_some();
826826

827827
Pat::Record { path, args, ellipsis }

crates/parser/src/grammar/patterns.rs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,43 @@ fn tuple_pat_fields(p: &mut Parser) {
200200
p.expect(T![')']);
201201
}
202202

203+
// test record_pat_field
204+
// fn foo() {
205+
// let S { 0: 1 } = ();
206+
// let S { x: 1 } = ();
207+
// let S { #[cfg(any())] x: 1 } = ();
208+
// }
209+
fn record_pat_field(p: &mut Parser) {
210+
match p.current() {
211+
IDENT | INT_NUMBER if p.nth(1) == T![:] => {
212+
name_ref_or_index(p);
213+
p.bump(T![:]);
214+
pattern(p);
215+
}
216+
T![.] => {
217+
if p.at(T![..]) {
218+
p.bump(T![..]);
219+
} else {
220+
ident_pat(p, false);
221+
}
222+
}
223+
T![box] => {
224+
// FIXME: not all box patterns should be allowed
225+
box_pat(p);
226+
}
227+
_ => {
228+
ident_pat(p, false);
229+
}
230+
}
231+
}
232+
203233
// test record_pat_field_list
204234
// fn foo() {
205235
// let S {} = ();
206236
// let S { f, ref mut g } = ();
207237
// let S { h: _, ..} = ();
208238
// let S { h: _, } = ();
239+
// let S { #[cfg(any())] .. } = ();
209240
// }
210241
fn record_pat_field_list(p: &mut Parser) {
211242
assert!(p.at(T!['{']));
@@ -214,32 +245,26 @@ fn record_pat_field_list(p: &mut Parser) {
214245
while !p.at(EOF) && !p.at(T!['}']) {
215246
match p.current() {
216247
// A trailing `..` is *not* treated as a REST_PAT.
217-
T![.] if p.at(T![..]) => p.bump(T![..]),
248+
T![.] if p.at(T![..]) => {
249+
rest_pat(p);
250+
}
218251
T!['{'] => error_block(p, "expected ident"),
252+
T![#] => {
253+
let m = p.start();
254+
attributes::outer_attrs(p);
255+
if p.at(T![..]) {
256+
p.bump(T![..]);
257+
m.complete(p, REST_PAT);
258+
} else {
259+
record_pat_field(p);
260+
m.complete(p, RECORD_PAT_FIELD);
261+
}
262+
}
219263

220264
_ => {
221265
let m = p.start();
222266
attributes::outer_attrs(p);
223-
match p.current() {
224-
// test record_pat_field
225-
// fn foo() {
226-
// let S { 0: 1 } = ();
227-
// let S { x: 1 } = ();
228-
// let S { #[cfg(any())] x: 1 } = ();
229-
// }
230-
IDENT | INT_NUMBER if p.nth(1) == T![:] => {
231-
name_ref_or_index(p);
232-
p.bump(T![:]);
233-
pattern(p);
234-
}
235-
T![box] => {
236-
// FIXME: not all box patterns should be allowed
237-
box_pat(p);
238-
}
239-
_ => {
240-
ident_pat(p, false);
241-
}
242-
}
267+
record_pat_field(p);
243268
m.complete(p, RECORD_PAT_FIELD);
244269
}
245270
}

crates/syntax/src/ast/generated/nodes.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ impl BoxPat {
11751175
pub struct RestPat {
11761176
pub(crate) syntax: SyntaxNode,
11771177
}
1178+
impl ast::HasAttrs for RestPat {}
11781179
impl RestPat {
11791180
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
11801181
}
@@ -1289,7 +1290,7 @@ pub struct RecordPatFieldList {
12891290
impl RecordPatFieldList {
12901291
pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
12911292
pub fn fields(&self) -> AstChildren<RecordPatField> { support::children(&self.syntax) }
1292-
pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
1293+
pub fn rest_pat(&self) -> Option<RestPat> { support::child(&self.syntax) }
12931294
pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
12941295
}
12951296
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3687,6 +3688,7 @@ impl AstNode for AnyHasAttrs {
36873688
| MATCH_ARM_LIST
36883689
| MATCH_ARM
36893690
| IDENT_PAT
3691+
| REST_PAT
36903692
| RECORD_PAT_FIELD => true,
36913693
_ => false,
36923694
}

crates/syntax/test_data/parser/inline/ok/0008_path_part.rast

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ [email protected]
6262
6363
6464
65-
65+
66+
6667
6768
6869

crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
SOURCE_FILE@0..119
2-
FN@0..118
1+
SOURCE_FILE@0..156
2+
FN@0..155
33
44
55
@@ -8,8 +8,8 @@ [email protected]
88
99
1010
11-
BLOCK_EXPR@9..118
12-
STMT_LIST@9..118
11+
BLOCK_EXPR@9..155
12+
STMT_LIST@9..155
1313
1414
1515
@@ -89,7 +89,8 @@ [email protected]
8989
9090
9191
92-
92+
93+
9394
9495
9596
@@ -128,6 +129,47 @@ [email protected]
128129
129130
130131
131-
132-
133-
132+
133+
134+
135+
136+
137+
138+
139+
140+
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
152+
153+
154+
155+
156+
157+
158+
159+
160+
161+
162+
163+
164+
165+
166+
167+
168+
169+
170+
171+
172+
173+
174+
175+

crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ fn foo() {
33
let S { f, ref mut g } = ();
44
let S { h: _, ..} = ();
55
let S { h: _, } = ();
6+
let S { #[cfg(any())] .. } = ();
67
}

0 commit comments

Comments
 (0)