From f6624782d41dce401a4103240daa06011ed326a5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 29 Jul 2016 23:47:55 +0300 Subject: [PATCH] Parse numeric fields in struct expressions and patterns --- src/libsyntax/parse/parser.rs | 13 +++++++++++-- src/test/compile-fail/numeric-fields.rs | 20 ++++++++++++++++++++ src/test/run-pass/numeric-fields.rs | 23 +++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/numeric-fields.rs create mode 100644 src/test/run-pass/numeric-fields.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1b32632a06f4..4c279b2fe483 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2009,10 +2009,19 @@ impl<'a> Parser<'a> { } } + pub fn parse_field_name(&mut self) -> PResult<'a, Ident> { + if let token::Literal(token::Integer(name), None) = self.token { + self.bump(); + Ok(Ident::with_empty_ctxt(name)) + } else { + self.parse_ident() + } + } + /// Parse ident COLON expr pub fn parse_field(&mut self) -> PResult<'a, Field> { let lo = self.span.lo; - let i = self.parse_ident()?; + let i = self.parse_field_name()?; let hi = self.last_span.hi; self.expect(&token::Colon)?; let e = self.parse_expr()?; @@ -3508,7 +3517,7 @@ impl<'a> Parser<'a> { // Check if a colon exists one ahead. This means we're parsing a fieldname. let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) { // Parsing a pattern of the form "fieldname: pat" - let fieldname = self.parse_ident()?; + let fieldname = self.parse_field_name()?; self.bump(); let pat = self.parse_pat()?; hi = pat.span.hi; diff --git a/src/test/compile-fail/numeric-fields.rs b/src/test/compile-fail/numeric-fields.rs new file mode 100644 index 000000000000..480d2dcddddd --- /dev/null +++ b/src/test/compile-fail/numeric-fields.rs @@ -0,0 +1,20 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(relaxed_adts)] + +struct S(u8, u16); + +fn main() { + let s = S{0b1: 10, 0: 11}; //~ ERROR structure `S` has no field named `0b1` + match s { + S{0: a, 0x1: b, ..} => {} //~ ERROR does not have a field named `0x1` + } +} diff --git a/src/test/run-pass/numeric-fields.rs b/src/test/run-pass/numeric-fields.rs new file mode 100644 index 000000000000..25e5a2a0fd5b --- /dev/null +++ b/src/test/run-pass/numeric-fields.rs @@ -0,0 +1,23 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(relaxed_adts)] + +struct S(u8, u16); + +fn main() { + let s = S{1: 10, 0: 11}; + match s { + S{0: a, 1: b, ..} => { + assert_eq!(a, 11); + assert_eq!(b, 10); + } + } +}