diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-04 10:13:29 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-20 22:53:40 +0100 |
| commit | 9b53c5be0607d0c1e9aee357a309491ee1e99c80 (patch) | |
| tree | c3374e7e6ceeb86012c2062dc86adb03754d928e | |
| parent | 66470d3217f27b5950c38a3af4a99e0ef12fa2c8 (diff) | |
| download | rust-9b53c5be0607d0c1e9aee357a309491ee1e99c80.tar.gz rust-9b53c5be0607d0c1e9aee357a309491ee1e99c80.zip | |
fix bug in parse_tuple_parens_expr + related refactoring
| -rw-r--r-- | src/librustc_parse/parser/attr.rs | 23 | ||||
| -rw-r--r-- | src/librustc_parse/parser/expr.rs | 32 | ||||
| -rw-r--r-- | src/librustc_parse/parser/mod.rs | 62 |
3 files changed, 49 insertions, 68 deletions
diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 00fd6b8a25b..51310fb88f6 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -1,4 +1,4 @@ -use super::{SeqSep, Parser, TokenType, PathStyle}; +use super::{Parser, TokenType, PathStyle}; use rustc_errors::PResult; use syntax::attr; use syntax::ast; @@ -301,8 +301,10 @@ impl<'a> Parser<'a> { crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> { Ok(if self.eat(&token::Eq) { ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?) - } else if self.eat(&token::OpenDelim(token::Paren)) { - ast::MetaItemKind::List(self.parse_meta_seq()?) + } else if self.check(&token::OpenDelim(token::Paren)) { + // Matches `meta_seq = ( COMMASEP(meta_item_inner) )`. + let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?; + ast::MetaItemKind::List(list) } else { ast::MetaItemKind::Word }) @@ -311,16 +313,12 @@ impl<'a> Parser<'a> { /// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`. fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> { match self.parse_unsuffixed_lit() { - Ok(lit) => { - return Ok(ast::NestedMetaItem::Literal(lit)) - } + Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)), Err(ref mut err) => err.cancel(), } match self.parse_meta_item() { - Ok(mi) => { - return Ok(ast::NestedMetaItem::MetaItem(mi)) - } + Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)), Err(ref mut err) => err.cancel(), } @@ -328,11 +326,4 @@ impl<'a> Parser<'a> { let msg = format!("expected unsuffixed literal or identifier, found `{}`", found); Err(self.diagnostic().struct_span_err(self.token.span, &msg)) } - - /// Matches `meta_seq = ( COMMASEP(meta_item_inner) )`. - fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> { - self.parse_seq_to_end(&token::CloseDelim(token::Paren), - SeqSep::trailing_allowed(token::Comma), - |p: &mut Parser<'a>| p.parse_meta_item_inner()) - } } diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 68af34a36bb..8c66804604f 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -919,17 +919,13 @@ impl<'a> Parser<'a> { fn parse_tuple_parens_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> { let lo = self.token.span; - let mut first = true; - let parse_leading_attr_expr = |p: &mut Self| { - if first { - // `(#![foo] a, b, ...)` is OK... - attrs.extend(p.parse_inner_attributes()?); - // ...but not `(a, #![foo] b, ...)`. - first = false; - } - p.parse_expr_catch_underscore() - }; - let (es, trailing_comma) = match self.parse_paren_comma_seq(parse_leading_attr_expr) { + self.expect(&token::OpenDelim(token::Paren))?; + attrs.extend(self.parse_inner_attributes()?); // `(#![foo] a, b, ...)` is OK. + let (es, trailing_comma) = match self.parse_seq_to_end( + &token::CloseDelim(token::Paren), + SeqSep::trailing_allowed(token::Comma), + |p| p.parse_expr_catch_underscore(), + ) { Ok(x) => x, Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))), }; @@ -950,7 +946,8 @@ impl<'a> Parser<'a> { attrs.extend(self.parse_inner_attributes()?); - let kind = if self.eat(&token::CloseDelim(token::Bracket)) { + let close = &token::CloseDelim(token::Bracket); + let kind = if self.eat(close) { // Empty vector ExprKind::Array(Vec::new()) } else { @@ -962,21 +959,18 @@ impl<'a> Parser<'a> { id: DUMMY_NODE_ID, value: self.parse_expr()?, }; - self.expect(&token::CloseDelim(token::Bracket))?; + self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(&token::Comma) { // Vector with two or more elements. - let remaining_exprs = self.parse_seq_to_end( - &token::CloseDelim(token::Bracket), - SeqSep::trailing_allowed(token::Comma), - |p| Ok(p.parse_expr()?) - )?; + let sep = SeqSep::trailing_allowed(token::Comma); + let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?; let mut exprs = vec![first_expr]; exprs.extend(remaining_exprs); ExprKind::Array(exprs) } else { // Vector with one element - self.expect(&token::CloseDelim(token::Bracket))?; + self.expect(close)?; ExprKind::Array(vec![first_expr]) } }; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 938c2d89857..255e789b58e 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -739,34 +739,6 @@ impl<'a> Parser<'a> { } } - /// Parses a sequence, including the closing delimiter. The function - /// `f` must consume tokens until reaching the next separator or - /// closing bracket. - fn parse_seq_to_end<T>( - &mut self, - ket: &TokenKind, - sep: SeqSep, - f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, Vec<T>> { - let (val, _, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; - if !recovered { - self.bump(); - } - Ok(val) - } - - /// Parses a sequence, not including the closing delimiter. The function - /// `f` must consume tokens until reaching the next separator or - /// closing bracket. - fn parse_seq_to_before_end<T>( - &mut self, - ket: &TokenKind, - sep: SeqSep, - f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool, bool)> { - self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f) - } - fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool { kets.iter().any(|k| { match expect { @@ -854,6 +826,34 @@ impl<'a> Parser<'a> { Ok((v, trailing, recovered)) } + /// Parses a sequence, not including the closing delimiter. The function + /// `f` must consume tokens until reaching the next separator or + /// closing bracket. + fn parse_seq_to_before_end<T>( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec<T>, bool, bool)> { + self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f) + } + + /// Parses a sequence, including the closing delimiter. The function + /// `f` must consume tokens until reaching the next separator or + /// closing bracket. + fn parse_seq_to_end<T>( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec<T>, bool /* trailing */)> { + let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; + if !recovered { + self.eat(ket); + } + Ok((val, trailing)) + } + /// Parses a sequence, including the closing delimiter. The function /// `f` must consume tokens until reaching the next separator or /// closing bracket. @@ -865,11 +865,7 @@ impl<'a> Parser<'a> { f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, ) -> PResult<'a, (Vec<T>, bool)> { self.expect(bra)?; - let (result, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; - if !recovered { - self.eat(ket); - } - Ok((result, trailing)) + self.parse_seq_to_end(ket, sep, f) } fn parse_delim_comma_seq<T>( |
