Change parsing of struct field patterns

This commit is contained in:
Marcus Klaas de Vries 2019-01-19 01:02:38 +01:00 committed by Aleksey Kladov
parent bcbfa2cc11
commit fa43ef30f4
5 changed files with 46 additions and 40 deletions

View file

@ -854,25 +854,25 @@ impl ExprCollector {
ast::PatKind::PlaceholderPat(_) => Pat::Wild, ast::PatKind::PlaceholderPat(_) => Pat::Wild,
ast::PatKind::StructPat(p) => { ast::PatKind::StructPat(p) => {
let path = p.path().and_then(Path::from_ast); let path = p.path().and_then(Path::from_ast);
let fields = p let field_pat_list = p
.field_pat_list() .field_pat_list()
.expect("every struct should have a field list") .expect("every struct should have a field list");
.pats() let mut fields: Vec<_> = field_pat_list
.map(|f| { .bind_pats()
let ast_pat = f.pat().expect("field pat always contains a pattern"); .map(|bind_pat| {
let ast_pat = ast::Pat::cast(bind_pat.syntax()).expect("bind pat is a pat");
let pat = self.collect_pat(ast_pat); let pat = self.collect_pat(ast_pat);
let name = f let name = bind_pat.name().expect("bind pat has a name").as_name();
.name()
.unwrap_or_else(|| {
ast::BindPat::cast(ast_pat.syntax())
.expect("field pat without label is a bind pat")
.name()
.expect("bind pat has a name")
})
.as_name();
FieldPat { name, pat } FieldPat { name, pat }
}) })
.collect(); .collect();
let iter = field_pat_list.field_pats().map(|f| {
let ast_pat = f.pat().expect("field pat always contains a pattern");
let pat = self.collect_pat(ast_pat);
let name = f.name().expect("field pats always have a name").as_name();
FieldPat { name, pat }
});
fields.extend(iter);
Pat::Struct { Pat::Struct {
path: path, path: path,

View file

@ -910,7 +910,11 @@ impl AstNode for FieldPatList {
impl FieldPatList { impl FieldPatList {
pub fn pats(&self) -> impl Iterator<Item = &FieldPat> { pub fn field_pats(&self) -> impl Iterator<Item = &FieldPat> {
super::children(self)
}
pub fn bind_pats(&self) -> impl Iterator<Item = &BindPat> {
super::children(self) super::children(self)
} }
} }

View file

@ -496,7 +496,12 @@ Grammar(
"PlaceholderPat": (), "PlaceholderPat": (),
"PathPat": ( options: [ "Path" ] ), "PathPat": ( options: [ "Path" ] ),
"StructPat": ( options: ["FieldPatList", "Path"] ), "StructPat": ( options: ["FieldPatList", "Path"] ),
"FieldPatList": ( collections: [["pats", "FieldPat"]] ), "FieldPatList": (
collections: [
["field_pats", "FieldPat"],
["bind_pats", "BindPat"],
]
),
"FieldPat": ( "FieldPat": (
traits: ["NameOwner"], traits: ["NameOwner"],
options: ["Pat"] options: ["Pat"]

View file

@ -128,7 +128,11 @@ fn field_pat_list(p: &mut Parser) {
while !p.at(EOF) && !p.at(R_CURLY) { while !p.at(EOF) && !p.at(R_CURLY) {
match p.current() { match p.current() {
DOTDOT => p.bump(), DOTDOT => p.bump(),
_ => field_pat(p), IDENT if p.nth(1) == COLON => field_pat(p),
L_CURLY => error_block(p, "expected ident"),
_ => {
bind_pat(p, false);
}
} }
if !p.at(R_CURLY) { if !p.at(R_CURLY) {
p.expect(COMMA); p.expect(COMMA);
@ -139,18 +143,13 @@ fn field_pat_list(p: &mut Parser) {
} }
fn field_pat(p: &mut Parser) { fn field_pat(p: &mut Parser) {
assert!(p.at(IDENT));
assert!(p.nth(1) == COLON);
let m = p.start(); let m = p.start();
match p.current() {
IDENT if p.nth(1) == COLON => {
name(p); name(p);
p.bump(); p.bump();
pattern(p); pattern(p);
}
L_CURLY => error_block(p, "expected ident"),
_ => {
bind_pat(p, false);
}
}
m.complete(p, FIELD_PAT); m.complete(p, FIELD_PAT);
} }

View file

@ -43,13 +43,11 @@ SOURCE_FILE@[0; 119)
FIELD_PAT_LIST@[40; 56) FIELD_PAT_LIST@[40; 56)
L_CURLY@[40; 41) L_CURLY@[40; 41)
WHITESPACE@[41; 42) WHITESPACE@[41; 42)
FIELD_PAT@[42; 43)
BIND_PAT@[42; 43) BIND_PAT@[42; 43)
NAME@[42; 43) NAME@[42; 43)
IDENT@[42; 43) "f" IDENT@[42; 43) "f"
COMMA@[43; 44) COMMA@[43; 44)
WHITESPACE@[44; 45) WHITESPACE@[44; 45)
FIELD_PAT@[45; 54)
BIND_PAT@[45; 54) BIND_PAT@[45; 54)
REF_KW@[45; 48) REF_KW@[45; 48)
WHITESPACE@[48; 49) WHITESPACE@[48; 49)