fix bug in parse_tuple_parens_expr + related refactoring

This commit is contained in:
Mazdak Farrokhzad 2019-12-04 10:13:29 +01:00
parent 66470d3217
commit 9b53c5be06
3 changed files with 49 additions and 68 deletions

View File

@ -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())
}
}

View File

@ -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])
}
};

View File

@ -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>(