Skip to content

Commit 9b53c5b

Browse files
committed
fix bug in parse_tuple_parens_expr + related refactoring
1 parent 66470d3 commit 9b53c5b

File tree

3 files changed

+49
-68
lines changed

3 files changed

+49
-68
lines changed

src/librustc_parse/parser/attr.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{SeqSep, Parser, TokenType, PathStyle};
1+
use super::{Parser, TokenType, PathStyle};
22
use rustc_errors::PResult;
33
use syntax::attr;
44
use syntax::ast;
@@ -301,8 +301,10 @@ impl<'a> Parser<'a> {
301301
crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
302302
Ok(if self.eat(&token::Eq) {
303303
ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
304-
} else if self.eat(&token::OpenDelim(token::Paren)) {
305-
ast::MetaItemKind::List(self.parse_meta_seq()?)
304+
} else if self.check(&token::OpenDelim(token::Paren)) {
305+
// Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
306+
let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?;
307+
ast::MetaItemKind::List(list)
306308
} else {
307309
ast::MetaItemKind::Word
308310
})
@@ -311,28 +313,17 @@ impl<'a> Parser<'a> {
311313
/// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`.
312314
fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
313315
match self.parse_unsuffixed_lit() {
314-
Ok(lit) => {
315-
return Ok(ast::NestedMetaItem::Literal(lit))
316-
}
316+
Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)),
317317
Err(ref mut err) => err.cancel(),
318318
}
319319

320320
match self.parse_meta_item() {
321-
Ok(mi) => {
322-
return Ok(ast::NestedMetaItem::MetaItem(mi))
323-
}
321+
Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)),
324322
Err(ref mut err) => err.cancel(),
325323
}
326324

327325
let found = self.this_token_to_string();
328326
let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
329327
Err(self.diagnostic().struct_span_err(self.token.span, &msg))
330328
}
331-
332-
/// Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
333-
fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
334-
self.parse_seq_to_end(&token::CloseDelim(token::Paren),
335-
SeqSep::trailing_allowed(token::Comma),
336-
|p: &mut Parser<'a>| p.parse_meta_item_inner())
337-
}
338329
}

src/librustc_parse/parser/expr.rs

+13-19
Original file line numberDiff line numberDiff line change
@@ -919,17 +919,13 @@ impl<'a> Parser<'a> {
919919

920920
fn parse_tuple_parens_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
921921
let lo = self.token.span;
922-
let mut first = true;
923-
let parse_leading_attr_expr = |p: &mut Self| {
924-
if first {
925-
// `(#![foo] a, b, ...)` is OK...
926-
attrs.extend(p.parse_inner_attributes()?);
927-
// ...but not `(a, #![foo] b, ...)`.
928-
first = false;
929-
}
930-
p.parse_expr_catch_underscore()
931-
};
932-
let (es, trailing_comma) = match self.parse_paren_comma_seq(parse_leading_attr_expr) {
922+
self.expect(&token::OpenDelim(token::Paren))?;
923+
attrs.extend(self.parse_inner_attributes()?); // `(#![foo] a, b, ...)` is OK.
924+
let (es, trailing_comma) = match self.parse_seq_to_end(
925+
&token::CloseDelim(token::Paren),
926+
SeqSep::trailing_allowed(token::Comma),
927+
|p| p.parse_expr_catch_underscore(),
928+
) {
933929
Ok(x) => x,
934930
Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))),
935931
};
@@ -950,7 +946,8 @@ impl<'a> Parser<'a> {
950946

951947
attrs.extend(self.parse_inner_attributes()?);
952948

953-
let kind = if self.eat(&token::CloseDelim(token::Bracket)) {
949+
let close = &token::CloseDelim(token::Bracket);
950+
let kind = if self.eat(close) {
954951
// Empty vector
955952
ExprKind::Array(Vec::new())
956953
} else {
@@ -962,21 +959,18 @@ impl<'a> Parser<'a> {
962959
id: DUMMY_NODE_ID,
963960
value: self.parse_expr()?,
964961
};
965-
self.expect(&token::CloseDelim(token::Bracket))?;
962+
self.expect(close)?;
966963
ExprKind::Repeat(first_expr, count)
967964
} else if self.eat(&token::Comma) {
968965
// Vector with two or more elements.
969-
let remaining_exprs = self.parse_seq_to_end(
970-
&token::CloseDelim(token::Bracket),
971-
SeqSep::trailing_allowed(token::Comma),
972-
|p| Ok(p.parse_expr()?)
973-
)?;
966+
let sep = SeqSep::trailing_allowed(token::Comma);
967+
let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
974968
let mut exprs = vec![first_expr];
975969
exprs.extend(remaining_exprs);
976970
ExprKind::Array(exprs)
977971
} else {
978972
// Vector with one element
979-
self.expect(&token::CloseDelim(token::Bracket))?;
973+
self.expect(close)?;
980974
ExprKind::Array(vec![first_expr])
981975
}
982976
};

src/librustc_parse/parser/mod.rs

+29-33
Original file line numberDiff line numberDiff line change
@@ -739,34 +739,6 @@ impl<'a> Parser<'a> {
739739
}
740740
}
741741

742-
/// Parses a sequence, including the closing delimiter. The function
743-
/// `f` must consume tokens until reaching the next separator or
744-
/// closing bracket.
745-
fn parse_seq_to_end<T>(
746-
&mut self,
747-
ket: &TokenKind,
748-
sep: SeqSep,
749-
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
750-
) -> PResult<'a, Vec<T>> {
751-
let (val, _, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
752-
if !recovered {
753-
self.bump();
754-
}
755-
Ok(val)
756-
}
757-
758-
/// Parses a sequence, not including the closing delimiter. The function
759-
/// `f` must consume tokens until reaching the next separator or
760-
/// closing bracket.
761-
fn parse_seq_to_before_end<T>(
762-
&mut self,
763-
ket: &TokenKind,
764-
sep: SeqSep,
765-
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
766-
) -> PResult<'a, (Vec<T>, bool, bool)> {
767-
self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
768-
}
769-
770742
fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool {
771743
kets.iter().any(|k| {
772744
match expect {
@@ -854,6 +826,34 @@ impl<'a> Parser<'a> {
854826
Ok((v, trailing, recovered))
855827
}
856828

829+
/// Parses a sequence, not including the closing delimiter. The function
830+
/// `f` must consume tokens until reaching the next separator or
831+
/// closing bracket.
832+
fn parse_seq_to_before_end<T>(
833+
&mut self,
834+
ket: &TokenKind,
835+
sep: SeqSep,
836+
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
837+
) -> PResult<'a, (Vec<T>, bool, bool)> {
838+
self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
839+
}
840+
841+
/// Parses a sequence, including the closing delimiter. The function
842+
/// `f` must consume tokens until reaching the next separator or
843+
/// closing bracket.
844+
fn parse_seq_to_end<T>(
845+
&mut self,
846+
ket: &TokenKind,
847+
sep: SeqSep,
848+
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
849+
) -> PResult<'a, (Vec<T>, bool /* trailing */)> {
850+
let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
851+
if !recovered {
852+
self.eat(ket);
853+
}
854+
Ok((val, trailing))
855+
}
856+
857857
/// Parses a sequence, including the closing delimiter. The function
858858
/// `f` must consume tokens until reaching the next separator or
859859
/// closing bracket.
@@ -865,11 +865,7 @@ impl<'a> Parser<'a> {
865865
f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
866866
) -> PResult<'a, (Vec<T>, bool)> {
867867
self.expect(bra)?;
868-
let (result, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
869-
if !recovered {
870-
self.eat(ket);
871-
}
872-
Ok((result, trailing))
868+
self.parse_seq_to_end(ket, sep, f)
873869
}
874870

875871
fn parse_delim_comma_seq<T>(

0 commit comments

Comments
 (0)