Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/hir_def/src/body/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,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 }
Expand Down
68 changes: 43 additions & 25 deletions crates/parser/src/grammar/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,46 +200,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);
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/syntax/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
4 changes: 3 additions & 1 deletion crates/syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,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![..]) }
}
Expand Down Expand Up @@ -1289,7 +1290,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!['}']) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -3687,6 +3688,7 @@ impl AstNode for AnyHasAttrs {
| MATCH_ARM_LIST
| MATCH_ARM
| IDENT_PAT
| REST_PAT
| RECORD_PAT_FIELD => true,
_ => false,
}
Expand Down
3 changes: 2 additions & 1 deletion crates/syntax/test_data/parser/inline/ok/0008_path_part.rast
Original file line number Diff line number Diff line change
Expand Up @@ -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 " "
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 "="
Expand Down Expand Up @@ -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"
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ fn foo() {
let S { f, ref mut g } = ();
let S { h: _, ..} = ();
let S { h: _, } = ();
let S { #[cfg(any())] .. } = ();
}