Fixes #21033 with accompanying test.
This commit is contained in:
@@ -3256,39 +3256,48 @@ impl<'a> Parser<'a> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bind_type = if self.eat_keyword(keywords::Mut) {
|
// Check if a colon exists one ahead. This means we're parsing a fieldname.
|
||||||
BindByValue(MutMutable)
|
let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
|
||||||
} else if self.eat_keyword(keywords::Ref) {
|
// Parsing a pattern of the form "fieldname: pat"
|
||||||
BindByRef(self.parse_mutability())
|
|
||||||
} else {
|
|
||||||
BindByValue(MutImmutable)
|
|
||||||
};
|
|
||||||
|
|
||||||
let fieldname = self.parse_ident();
|
let fieldname = self.parse_ident();
|
||||||
|
|
||||||
let (subpat, is_shorthand) = if self.check(&token::Colon) {
|
|
||||||
match bind_type {
|
|
||||||
BindByRef(..) | BindByValue(MutMutable) => {
|
|
||||||
let token_str = self.this_token_to_string();
|
|
||||||
self.fatal(&format!("unexpected `{}`",
|
|
||||||
token_str)[])
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.bump();
|
self.bump();
|
||||||
let pat = self.parse_pat();
|
let pat = self.parse_pat();
|
||||||
hi = pat.span.hi;
|
hi = pat.span.hi;
|
||||||
(pat, false)
|
(pat, fieldname, false)
|
||||||
} else {
|
} else {
|
||||||
|
// Parsing a pattern of the form "(box) (ref) (mut) fieldname"
|
||||||
|
let is_box = self.eat_keyword(keywords::Box);
|
||||||
|
let boxed_span_lo = self.span.lo;
|
||||||
|
let is_ref = self.eat_keyword(keywords::Ref);
|
||||||
|
let is_mut = self.eat_keyword(keywords::Mut);
|
||||||
|
let fieldname = self.parse_ident();
|
||||||
hi = self.last_span.hi;
|
hi = self.last_span.hi;
|
||||||
|
|
||||||
|
let bind_type = match (is_ref, is_mut) {
|
||||||
|
(true, true) => BindByRef(MutMutable),
|
||||||
|
(true, false) => BindByRef(MutImmutable),
|
||||||
|
(false, true) => BindByValue(MutMutable),
|
||||||
|
(false, false) => BindByValue(MutImmutable),
|
||||||
|
};
|
||||||
let fieldpath = codemap::Spanned{span:self.last_span, node:fieldname};
|
let fieldpath = codemap::Spanned{span:self.last_span, node:fieldname};
|
||||||
(P(ast::Pat {
|
let fieldpat = P(ast::Pat{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: PatIdent(bind_type, fieldpath, None),
|
node: PatIdent(bind_type, fieldpath, None),
|
||||||
span: self.last_span
|
span: mk_sp(boxed_span_lo, hi),
|
||||||
}), true)
|
});
|
||||||
|
|
||||||
|
let subpat = if is_box {
|
||||||
|
P(ast::Pat{
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
node: PatBox(fieldpat),
|
||||||
|
span: mk_sp(lo, hi),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
fieldpat
|
||||||
};
|
};
|
||||||
|
(subpat, fieldname, true)
|
||||||
|
};
|
||||||
|
|
||||||
fields.push(codemap::Spanned { span: mk_sp(lo, hi),
|
fields.push(codemap::Spanned { span: mk_sp(lo, hi),
|
||||||
node: ast::FieldPat { ident: fieldname,
|
node: ast::FieldPat { ident: fieldname,
|
||||||
pat: subpat,
|
pat: subpat,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
struct Foo { x: isize }
|
struct Foo { x: isize }
|
||||||
match (Foo { x: 10 }) {
|
match (Foo { x: 10 }) {
|
||||||
Foo { ref x: ref x } => {}, //~ ERROR unexpected `:`
|
Foo { ref x: ref x } => {}, //~ ERROR expected `,`, found `:`
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
52
src/test/run-pass/issue-21033.rs
Normal file
52
src/test/run-pass/issue-21033.rs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
|
enum E {
|
||||||
|
StructVar { boxed: Box<i32> }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
// Test matching each shorthand notation for field patterns.
|
||||||
|
let mut a = E::StructVar { boxed: box 3 };
|
||||||
|
match a {
|
||||||
|
E::StructVar { box boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { box ref boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { box mut boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { box ref mut boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { ref boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { ref mut boxed } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { mut boxed } => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test matching non shorthand notation. Recreate a since last test
|
||||||
|
// moved `boxed`
|
||||||
|
let mut a = E::StructVar { boxed: box 3 };
|
||||||
|
match a {
|
||||||
|
E::StructVar { boxed: box ref mut num } => { }
|
||||||
|
}
|
||||||
|
match a {
|
||||||
|
E::StructVar { boxed: ref mut num } => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user