From 9b53c5be0607d0c1e9aee357a309491ee1e99c80 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 4 Dec 2019 10:13:29 +0100 Subject: [PATCH] fix bug in parse_tuple_parens_expr + related refactoring --- src/librustc_parse/parser/attr.rs | 23 ++++-------- src/librustc_parse/parser/expr.rs | 32 +++++++--------- 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 @@ pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { 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 @@ pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> { /// 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 @@ fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> { 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> { - 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 @@ fn parse_lit_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { fn parse_tuple_parens_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P> { 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 @@ fn parse_array_or_repeat_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P PResult<'a, P PResult<'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( - &mut self, - ket: &TokenKind, - sep: SeqSep, - f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, Vec> { - 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( - &mut self, - ket: &TokenKind, - sep: SeqSep, - f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec, 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 @@ fn parse_seq_to_before_tokens( 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( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, 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( + &mut self, + ket: &TokenKind, + sep: SeqSep, + f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, + ) -> PResult<'a, (Vec, 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 @@ fn parse_unspanned_seq( f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, ) -> PResult<'a, (Vec, 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( -- 2.44.0