diff options
| author | bors <bors@rust-lang.org> | 2019-12-21 11:05:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-12-21 11:05:03 +0000 |
| commit | c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06 (patch) | |
| tree | 073a8038727414aed13f54622fce43ca63990ca6 /src/librustc_parse/parser/mod.rs | |
| parent | 9ff30a7810c586819a78188c173a7b74adbb9730 (diff) | |
| parent | 621661f8a63f2118f3add5c3d686d9a2b6f62e5e (diff) | |
| download | rust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.tar.gz rust-c64eecf4d0907095928fb36fd3a1dd5fb2d9ff06.zip | |
Auto merge of #66994 - Centril:stmt-polish, r=estebank
refactor expr & stmt parsing + improve recovery
Summary of important changes (best read commit-by-commit, ignoring whitespace changes):
- `AttrVec` is introduces as an alias for `ThinVec<Attribute>`
- `parse_expr_bottom` and `parse_stmt` are thoroughly refactored.
- Extract diagnostics logic for `vec![...]` in a pattern context.
- Recovery is added for `do catch { ... }`
- Recovery is added for `'label: non_block_expr`
- Recovery is added for `var $local`, `auto $local`, and `mut $local`. Fixes #65257.
- Recovery is added for `e1 and e2` and `e1 or e2`.
- ~~`macro_legacy_warnings` is turned into an error (has been a warning for 3 years!)~~
- Fixes #63396 by forward-porting #64105 which now works thanks to added recovery.
- `ui-fulldeps/ast_stmt_expr_attr.rs` is turned into UI and pretty tests.
- Recovery is fixed for `#[attr] if expr {}`
r? @estebank
Diffstat (limited to 'src/librustc_parse/parser/mod.rs')
| -rw-r--r-- | src/librustc_parse/parser/mod.rs | 71 |
1 files changed, 33 insertions, 38 deletions
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index 07e99cfe012..255e789b58e 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -15,9 +15,8 @@ use crate::{Directory, DirectoryOwnership}; use crate::lexer::UnmatchedBrace; use rustc_errors::{PResult, Applicability, DiagnosticBuilder, FatalError}; -use rustc_data_structures::thin_vec::ThinVec; -use syntax::ast::{self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit}; -use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety}; +use syntax::ast::{self, DUMMY_NODE_ID, AttrVec, AttrStyle, CrateSugar, Extern, Ident, Unsafety}; +use syntax::ast::{StrLit, IsAsync, MacArgs, MacDelimiter, Mutability, Visibility, VisibilityKind}; use syntax::print::pprust; use syntax::ptr::P; use syntax::token::{self, Token, TokenKind, DelimToken}; @@ -740,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 { @@ -855,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. @@ -866,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>( @@ -1054,8 +1049,8 @@ impl<'a> Parser<'a> { fn parse_or_use_outer_attributes( &mut self, - already_parsed_attrs: Option<ThinVec<Attribute>>, - ) -> PResult<'a, ThinVec<Attribute>> { + already_parsed_attrs: Option<AttrVec>, + ) -> PResult<'a, AttrVec> { if let Some(attrs) = already_parsed_attrs { Ok(attrs) } else { |
