Skip to content

Commit

Permalink
Auto merge of #66994 - Centril:stmt-polish, r=estebank
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Dec 21, 2019
2 parents 9ff30a7 + 621661f commit c64eecf
Show file tree
Hide file tree
Showing 47 changed files with 1,764 additions and 1,187 deletions.
7 changes: 3 additions & 4 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ use crate::util::nodemap::{DefIdMap, NodeMap};
use errors::Applicability;
use rustc_data_structures::fx::FxHashSet;
use rustc_index::vec::IndexVec;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::sync::Lrc;

use std::collections::BTreeMap;
Expand Down Expand Up @@ -1205,7 +1204,7 @@ impl<'a> LoweringContext<'a> {
id: ty.id,
kind: ExprKind::Path(qself.clone(), path.clone()),
span: ty.span,
attrs: ThinVec::new(),
attrs: AttrVec::new(),
};

let ct = self.with_new_scopes(|this| {
Expand Down Expand Up @@ -2751,7 +2750,7 @@ impl<'a> LoweringContext<'a> {
/// has no attributes and is not targeted by a `break`.
fn lower_block_expr(&mut self, b: &Block) -> hir::Expr {
let block = self.lower_block(b, false);
self.expr_block(block, ThinVec::new())
self.expr_block(block, AttrVec::new())
}

fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
Expand Down Expand Up @@ -3102,7 +3101,7 @@ impl<'a> LoweringContext<'a> {

fn stmt_let_pat(
&mut self,
attrs: ThinVec<Attribute>,
attrs: AttrVec,
span: Span,
init: Option<P<hir::Expr>>,
pat: P<hir::Pat>,
Expand Down
18 changes: 6 additions & 12 deletions src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,8 +1318,7 @@ impl LoweringContext<'_> {
&mut self,
span: Span,
expr: P<hir::Expr>,
attrs: ThinVec<Attribute>
) -> hir::Expr {
attrs: AttrVec) -> hir::Expr {
self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
}

Expand All @@ -1333,7 +1332,7 @@ impl LoweringContext<'_> {
self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new())
}

fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> P<hir::Expr> {
let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
P(self.expr(span, expr_break, attrs))
}
Expand Down Expand Up @@ -1404,7 +1403,7 @@ impl LoweringContext<'_> {
span: Span,
components: &[Symbol],
params: Option<P<hir::GenericArgs>>,
attrs: ThinVec<Attribute>,
attrs: AttrVec,
) -> hir::Expr {
let path = self.std_path(span, components, params, true);
self.expr(
Expand All @@ -1423,7 +1422,7 @@ impl LoweringContext<'_> {
span: Span,
ident: Ident,
binding: hir::HirId,
attrs: ThinVec<Attribute>,
attrs: AttrVec,
) -> hir::Expr {
let expr_path = hir::ExprKind::Path(hir::QPath::Resolved(
None,
Expand Down Expand Up @@ -1459,16 +1458,11 @@ impl LoweringContext<'_> {
self.expr_block(P(blk), ThinVec::new())
}

pub(super) fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr {
pub(super) fn expr_block(&mut self, b: P<hir::Block>, attrs: AttrVec) -> hir::Expr {
self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
}

pub(super) fn expr(
&mut self,
span: Span,
kind: hir::ExprKind,
attrs: ThinVec<Attribute>
) -> hir::Expr {
pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind, attrs: AttrVec) -> hir::Expr {
hir::Expr { hir_id: self.next_id(), kind, span, attrs }
}

Expand Down
13 changes: 6 additions & 7 deletions src/librustc/hir/lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::hir::def_id::DefId;
use crate::hir::def::{Res, DefKind};
use crate::util::nodemap::NodeMap;

use rustc_data_structures::thin_vec::ThinVec;
use rustc_target::spec::abi;

use std::collections::BTreeSet;
Expand Down Expand Up @@ -899,7 +898,7 @@ impl LoweringContext<'_> {

/// Construct `ExprKind::Err` for the given `span`.
fn expr_err(&mut self, span: Span) -> hir::Expr {
self.expr(span, hir::ExprKind::Err, ThinVec::new())
self.expr(span, hir::ExprKind::Err, AttrVec::new())
}

fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem {
Expand Down Expand Up @@ -1182,7 +1181,7 @@ impl LoweringContext<'_> {
//
// If this is the simple case, this parameter will end up being the same as the
// original parameter, but with a different pattern id.
let mut stmt_attrs = ThinVec::new();
let mut stmt_attrs = AttrVec::new();
stmt_attrs.extend(parameter.attrs.iter().cloned());
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
let new_parameter = hir::Param {
Expand Down Expand Up @@ -1226,7 +1225,7 @@ impl LoweringContext<'_> {
desugared_span, ident, hir::BindingAnnotation::Mutable);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
let move_stmt = this.stmt_let_pat(
ThinVec::new(),
AttrVec::new(),
desugared_span,
Some(P(move_expr)),
move_pat,
Expand Down Expand Up @@ -1271,7 +1270,7 @@ impl LoweringContext<'_> {
let user_body = this.expr_drop_temps(
desugared_span,
P(user_body),
ThinVec::new(),
AttrVec::new(),
);

// As noted above, create the final block like
Expand All @@ -1288,9 +1287,9 @@ impl LoweringContext<'_> {
statements.into(),
Some(P(user_body)),
);
this.expr_block(P(body), ThinVec::new())
this.expr_block(P(body), AttrVec::new())
});
(HirVec::from(parameters), this.expr(body_span, async_expr, ThinVec::new()))
(HirVec::from(parameters), this.expr(body_span, async_expr, AttrVec::new()))
})
}

Expand Down
7 changes: 3 additions & 4 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use errors::FatalError;
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use syntax::source_map::Spanned;
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
use syntax::ast::{AttrVec, Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy};
pub use syntax::ast::{IsAuto, ImplPolarity, BorrowKind};
use syntax::attr::{InlineAttr, OptimizeAttr};
Expand All @@ -29,7 +29,6 @@ use syntax::tokenstream::TokenStream;
use syntax::util::parser::ExprPrecedence;
use rustc_target::spec::abi::Abi;
use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_macros::HashStable;
use rustc_serialize::{self, Encoder, Encodable, Decoder, Decodable};
use std::collections::{BTreeSet, BTreeMap};
Expand Down Expand Up @@ -1274,7 +1273,7 @@ pub struct Local {
pub init: Option<P<Expr>>,
pub hir_id: HirId,
pub span: Span,
pub attrs: ThinVec<Attribute>,
pub attrs: AttrVec,
/// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
/// desugaring. Otherwise will be `Normal`.
pub source: LocalSource,
Expand Down Expand Up @@ -1459,7 +1458,7 @@ pub struct AnonConst {
pub struct Expr {
pub hir_id: HirId,
pub kind: ExprKind,
pub attrs: ThinVec<Attribute>,
pub attrs: AttrVec,
pub span: Span,
}

Expand Down
7 changes: 3 additions & 4 deletions src/librustc_interface/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use rustc_data_structures::jobserver;
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_errors::registry::Registry;
use rustc_metadata::dynamic_lib::DynamicLibrary;
Expand All @@ -24,7 +23,7 @@ use std::ops::DerefMut;
use smallvec::SmallVec;
use syntax::ptr::P;
use syntax::mut_visit::{*, MutVisitor, visit_clobber};
use syntax::ast::BlockCheckMode;
use syntax::ast::{AttrVec, BlockCheckMode};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
use syntax::symbol::{Symbol, sym};
Expand Down Expand Up @@ -741,7 +740,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
id: resolver.next_node_id(),
kind: ast::ExprKind::Block(P(b), None),
span: syntax_pos::DUMMY_SP,
attrs: ThinVec::new(),
attrs: AttrVec::new(),
});

ast::Stmt {
Expand All @@ -756,7 +755,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
kind: ast::ExprKind::Loop(P(empty_block), None),
id: self.resolver.next_node_id(),
span: syntax_pos::DUMMY_SP,
attrs: ThinVec::new(),
attrs: AttrVec::new(),
});

let loop_stmt = ast::Stmt {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_parse/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(slice_patterns)]

use syntax::ast;
use syntax::print::pprust;
Expand Down
23 changes: 7 additions & 16 deletions src/librustc_parse/parser/attr.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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
})
Expand All @@ -311,28 +313,17 @@ 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(),
}

let found = self.this_token_to_string();
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())
}
}
Loading

0 comments on commit c64eecf

Please sign in to comment.