Skip to content

Redo hir::Stmt #57689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 19, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 12 additions & 21 deletions src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
@@ -99,30 +99,21 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}

fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
let hir_id = self.tcx.hir().node_to_hir_id(stmt.node.id());
match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
let exit = self.decl(&decl, pred);
self.add_ast_node(hir_id.local_id, &[exit])
}

hir::StmtKind::Expr(ref expr, _) |
hir::StmtKind::Semi(ref expr, _) => {
let exit = self.expr(&expr, pred);
self.add_ast_node(hir_id.local_id, &[exit])
}
}
}

fn decl(&mut self, decl: &hir::Decl, pred: CFGIndex) -> CFGIndex {
match decl.node {
hir::DeclKind::Local(ref local) => {
let hir_id = self.tcx.hir().node_to_hir_id(stmt.id);
let exit = match stmt.node {
hir::StmtKind::Local(ref local) => {
let init_exit = self.opt_expr(&local.init, pred);
self.pat(&local.pat, init_exit)
}

hir::DeclKind::Item(_) => pred,
}
hir::StmtKind::Item(_) => {
pred
}
hir::StmtKind::Expr(ref expr) |
hir::StmtKind::Semi(ref expr) => {
self.expr(&expr, pred)
}
};
self.add_ast_node(hir_id.local_id, &[exit])
}

fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
4 changes: 2 additions & 2 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
@@ -298,8 +298,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {

fn check_stmt_attributes(&self, stmt: &hir::Stmt) {
// When checking statements ignore expressions, they will be checked later
if let hir::StmtKind::Decl(_, _) = stmt.node {
for attr in stmt.node.attrs() {
if let hir::StmtKind::Local(ref l) = stmt.node {
for attr in l.attrs.iter() {
if attr.check_name("inline") {
self.check_inline(attr, &stmt.span, Target::Statement);
}
22 changes: 5 additions & 17 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
@@ -260,9 +260,6 @@ pub trait Visitor<'v> : Sized {
fn visit_pat(&mut self, p: &'v Pat) {
walk_pat(self, p)
}
fn visit_decl(&mut self, d: &'v Decl) {
walk_decl(self, d)
}
fn visit_anon_const(&mut self, c: &'v AnonConst) {
walk_anon_const(self, c)
}
@@ -953,26 +950,17 @@ pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
}

pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
visitor.visit_id(statement.id);
match statement.node {
StmtKind::Decl(ref declaration, id) => {
visitor.visit_id(id);
visitor.visit_decl(declaration)
}
StmtKind::Expr(ref expression, id) |
StmtKind::Semi(ref expression, id) => {
visitor.visit_id(id);
StmtKind::Local(ref local) => visitor.visit_local(local),
StmtKind::Item(ref item) => visitor.visit_nested_item(**item),
StmtKind::Expr(ref expression) |
StmtKind::Semi(ref expression) => {
visitor.visit_expr(expression)
}
}
}

pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
match declaration.node {
DeclKind::Local(ref local) => visitor.visit_local(local),
DeclKind::Item(item) => visitor.visit_nested_item(item),
}
}

pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
visitor.visit_id(constant.id);
visitor.visit_nested_body(constant.body);
78 changes: 35 additions & 43 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
@@ -1957,7 +1957,7 @@ impl<'a> LoweringContext<'a> {
)
}

fn lower_local(&mut self, l: &Local) -> (P<hir::Local>, SmallVec<[hir::ItemId; 1]>) {
fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[hir::ItemId; 1]>) {
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id);
let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
if self.sess.features_untracked().impl_trait_in_bindings {
@@ -1967,7 +1967,7 @@ impl<'a> LoweringContext<'a> {
}
}
let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
(P(hir::Local {
(hir::Local {
id: node_id,
hir_id,
ty: l.ty
@@ -1984,7 +1984,7 @@ impl<'a> LoweringContext<'a> {
span: l.span,
attrs: l.attrs.clone(),
source: hir::LocalSource::Normal,
}), ids)
}, ids)
}

fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
@@ -4331,10 +4331,11 @@ impl<'a> LoweringContext<'a> {
ThinVec::new(),
))
};
let match_stmt = respan(
head_sp,
hir::StmtKind::Expr(match_expr, self.next_id().node_id)
);
let match_stmt = hir::Stmt {
id: self.next_id().node_id,
node: hir::StmtKind::Expr(match_expr),
span: head_sp,
};

let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));

@@ -4357,10 +4358,11 @@ impl<'a> LoweringContext<'a> {

let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
let body_stmt = respan(
body.span,
hir::StmtKind::Expr(body_expr, self.next_id().node_id)
);
let body_stmt = hir::Stmt {
id: self.next_id().node_id,
node: hir::StmtKind::Expr(body_expr),
span: body.span,
};

let loop_block = P(self.block_all(
e.span,
@@ -4533,25 +4535,15 @@ impl<'a> LoweringContext<'a> {
let (l, item_ids) = self.lower_local(l);
let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
.into_iter()
.map(|item_id| Spanned {
node: hir::StmtKind::Decl(
P(Spanned {
node: hir::DeclKind::Item(item_id),
span: s.span,
}),
self.next_id().node_id,
),
.map(|item_id| hir::Stmt {
id: self.next_id().node_id,
node: hir::StmtKind::Item(P(item_id)),
span: s.span,
})
.collect();
ids.push(Spanned {
node: hir::StmtKind::Decl(
P(Spanned {
node: hir::DeclKind::Local(l),
span: s.span,
}),
self.lower_node_id(s.id).node_id,
),
ids.push(hir::Stmt {
id: self.lower_node_id(s.id).node_id,
node: hir::StmtKind::Local(P(l)),
span: s.span,
});
return ids;
@@ -4561,26 +4553,23 @@ impl<'a> LoweringContext<'a> {
let mut id = Some(s.id);
return self.lower_item_id(it)
.into_iter()
.map(|item_id| Spanned {
node: hir::StmtKind::Decl(
P(Spanned {
node: hir::DeclKind::Item(item_id),
span: s.span,
}),
id.take()
.map(|item_id| hir::Stmt {
id: id.take()
.map(|id| self.lower_node_id(id).node_id)
.unwrap_or_else(|| self.next_id().node_id),
),
node: hir::StmtKind::Item(P(item_id)),
span: s.span,
})
.collect();
}
StmtKind::Expr(ref e) => Spanned {
node: hir::StmtKind::Expr(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
StmtKind::Expr(ref e) => hir::Stmt {
id: self.lower_node_id(s.id).node_id,
node: hir::StmtKind::Expr(P(self.lower_expr(e))),
span: s.span,
},
StmtKind::Semi(ref e) => Spanned {
node: hir::StmtKind::Semi(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
StmtKind::Semi(ref e) => hir::Stmt {
id: self.lower_node_id(s.id).node_id,
node: hir::StmtKind::Semi(P(self.lower_expr(e))),
span: s.span,
},
StmtKind::Mac(..) => panic!("Shouldn't exist here"),
@@ -4795,7 +4784,7 @@ impl<'a> LoweringContext<'a> {
) -> hir::Stmt {
let LoweredNodeId { node_id, hir_id } = self.next_id();

let local = P(hir::Local {
let local = hir::Local {
pat,
ty: None,
init: ex,
@@ -4804,9 +4793,12 @@ impl<'a> LoweringContext<'a> {
span: sp,
attrs: ThinVec::new(),
source,
});
let decl = respan(sp, hir::DeclKind::Local(local));
respan(sp, hir::StmtKind::Decl(P(decl), self.next_id().node_id))
};
hir::Stmt {
id: self.next_id().node_id,
node: hir::StmtKind::Local(P(local)),
span: sp
}
}

fn stmt_let(
2 changes: 1 addition & 1 deletion src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
@@ -426,7 +426,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}

fn visit_stmt(&mut self, stmt: &'hir Stmt) {
let id = stmt.node.id();
let id = stmt.id;
self.insert(stmt.span, id, Node::Stmt(stmt));

self.with_parent(id, |this| {
70 changes: 20 additions & 50 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ use util::nodemap::{NodeMap, FxHashSet};
use mir::mono::Linkage;

use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
use syntax::source_map::{self, Spanned};
use syntax::source_map::Spanned;
use rustc_target::spec::abi::Abi;
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy};
@@ -1144,45 +1144,41 @@ impl UnOp {
}

/// A statement
pub type Stmt = Spanned<StmtKind>;
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct Stmt {
pub id: NodeId,
pub node: StmtKind,
pub span: Span,
}

impl fmt::Debug for StmtKind {
impl fmt::Debug for Stmt {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Sadness.
let spanned = source_map::dummy_spanned(self.clone());
write!(f,
"stmt({}: {})",
spanned.node.id(),
print::to_string(print::NO_ANN, |s| s.print_stmt(&spanned)))
write!(f, "stmt({}: {})", self.id,
print::to_string(print::NO_ANN, |s| s.print_stmt(self)))
}
}

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum StmtKind {
/// Could be an item or a local (let) binding:
Decl(P<Decl>, NodeId),
/// A local (let) binding:
Local(P<Local>),
/// An item binding:
Item(P<ItemId>),

/// Expr without trailing semi-colon (must have unit type):
Expr(P<Expr>, NodeId),
Expr(P<Expr>),

/// Expr with trailing semi-colon (may have any type):
Semi(P<Expr>, NodeId),
Semi(P<Expr>),
}

impl StmtKind {
pub fn attrs(&self) -> &[Attribute] {
match *self {
StmtKind::Decl(ref d, _) => d.node.attrs(),
StmtKind::Expr(ref e, _) |
StmtKind::Semi(ref e, _) => &e.attrs,
}
}

pub fn id(&self) -> NodeId {
match *self {
StmtKind::Decl(_, id) |
StmtKind::Expr(_, id) |
StmtKind::Semi(_, id) => id,
StmtKind::Local(ref l) => &l.attrs,
StmtKind::Item(_) => &[],
StmtKind::Expr(ref e) |
StmtKind::Semi(ref e) => &e.attrs,
}
}
}
@@ -1201,32 +1197,6 @@ pub struct Local {
pub source: LocalSource,
}

pub type Decl = Spanned<DeclKind>;

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum DeclKind {
/// A local (let) binding:
Local(P<Local>),
/// An item binding:
Item(ItemId),
}

impl DeclKind {
pub fn attrs(&self) -> &[Attribute] {
match *self {
DeclKind::Local(ref l) => &l.attrs,
DeclKind::Item(_) => &[]
}
}

pub fn is_local(&self) -> bool {
match *self {
DeclKind::Local(_) => true,
_ => false,
}
}
}

/// represents one arm of a 'match'
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Arm {
63 changes: 23 additions & 40 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
@@ -992,14 +992,29 @@ impl<'a> State<'a> {
pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
self.maybe_print_comment(st.span.lo())?;
match st.node {
hir::StmtKind::Decl(ref decl, _) => {
self.print_decl(&decl)?;
hir::StmtKind::Local(ref loc) => {
self.space_if_not_bol()?;
self.ibox(indent_unit)?;
self.word_nbsp("let")?;

self.ibox(indent_unit)?;
self.print_local_decl(&loc)?;
self.end()?;
if let Some(ref init) = loc.init {
self.nbsp()?;
self.word_space("=")?;
self.print_expr(&init)?;
}
self.end()?
}
hir::StmtKind::Item(ref item) => {
self.ann.nested(self, Nested::Item(**item))?
}
hir::StmtKind::Expr(ref expr, _) => {
hir::StmtKind::Expr(ref expr) => {
self.space_if_not_bol()?;
self.print_expr(&expr)?;
}
hir::StmtKind::Semi(ref expr, _) => {
hir::StmtKind::Semi(ref expr) => {
self.space_if_not_bol()?;
self.print_expr(&expr)?;
self.s.word(";")?;
@@ -1562,30 +1577,6 @@ impl<'a> State<'a> {
Ok(())
}

pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> {
self.maybe_print_comment(decl.span.lo())?;
match decl.node {
hir::DeclKind::Local(ref loc) => {
self.space_if_not_bol()?;
self.ibox(indent_unit)?;
self.word_nbsp("let")?;

self.ibox(indent_unit)?;
self.print_local_decl(&loc)?;
self.end()?;
if let Some(ref init) = loc.init {
self.nbsp()?;
self.word_space("=")?;
self.print_expr(&init)?;
}
self.end()
}
hir::DeclKind::Item(item) => {
self.ann.nested(self, Nested::Item(item))
}
}
}

pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
self.s.word(i.to_string())
}
@@ -2401,18 +2392,10 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
/// seen the semicolon, and thus don't need another.
fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
match *stmt {
hir::StmtKind::Decl(ref d, _) => {
match d.node {
hir::DeclKind::Local(_) => true,
hir::DeclKind::Item(_) => false,
}
}
hir::StmtKind::Expr(ref e, _) => {
expr_requires_semi_to_be_stmt(&e)
}
hir::StmtKind::Semi(..) => {
false
}
hir::StmtKind::Local(_) => true,
hir::StmtKind::Item(_) => false,
hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e),
hir::StmtKind::Semi(..) => false,
}
}

20 changes: 10 additions & 10 deletions src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
@@ -483,7 +483,12 @@ impl_stable_hash_for!(enum hir::UnOp {
UnNeg
});

impl_stable_hash_for_spanned!(hir::StmtKind);
impl_stable_hash_for!(struct hir::Stmt {
id,
node,
span,
});


impl_stable_hash_for!(struct hir::Local {
pat,
@@ -496,12 +501,6 @@ impl_stable_hash_for!(struct hir::Local {
source
});

impl_stable_hash_for_spanned!(hir::DeclKind);
impl_stable_hash_for!(enum hir::DeclKind {
Local(local),
Item(item_id)
});

impl_stable_hash_for!(struct hir::Arm {
attrs,
pats,
@@ -941,9 +940,10 @@ impl_stable_hash_for!(enum hir::ForeignItemKind {
});

impl_stable_hash_for!(enum hir::StmtKind {
Decl(decl, id),
Expr(expr, id),
Semi(expr, id)
Local(local),
Item(item_id),
Expr(expr),
Semi(expr)
});

impl_stable_hash_for!(struct hir::Arg {
5 changes: 0 additions & 5 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
@@ -941,11 +941,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
hir_visit::walk_arm(self, a);
}

fn visit_decl(&mut self, d: &'tcx hir::Decl) {
run_lints!(self, check_decl, d);
hir_visit::walk_decl(self, d);
}

fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam) {
run_lints!(self, check_generic_param, p);
hir_visit::walk_generic_param(self, p);
1 change: 0 additions & 1 deletion src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
@@ -191,7 +191,6 @@ macro_rules! late_lint_methods {
fn check_stmt(a: &$hir hir::Stmt);
fn check_arm(a: &$hir hir::Arm);
fn check_pat(a: &$hir hir::Pat);
fn check_decl(a: &$hir hir::Decl);
fn check_expr(a: &$hir hir::Expr);
fn check_expr_post(a: &$hir hir::Expr);
fn check_ty(a: &$hir hir::Ty);
20 changes: 8 additions & 12 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
@@ -589,21 +589,17 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {

fn walk_stmt(&mut self, stmt: &hir::Stmt) {
match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
match decl.node {
hir::DeclKind::Local(ref local) => {
self.walk_local(&local);
}
hir::StmtKind::Local(ref local) => {
self.walk_local(&local);
}

hir::DeclKind::Item(_) => {
// we don't visit nested items in this visitor,
// only the fn body we were given.
}
}
hir::StmtKind::Item(_) => {
// we don't visit nested items in this visitor,
// only the fn body we were given.
}

hir::StmtKind::Expr(ref expr, _) |
hir::StmtKind::Semi(ref expr, _) => {
hir::StmtKind::Expr(ref expr) |
hir::StmtKind::Semi(ref expr) => {
self.consume_expr(&expr);
}
}
53 changes: 19 additions & 34 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
@@ -956,46 +956,31 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode)
-> LiveNode {
match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
self.propagate_through_decl(&decl, succ)
}
hir::StmtKind::Local(ref local) => {
// Note: we mark the variable as defined regardless of whether
// there is an initializer. Initially I had thought to only mark
// the live variable as defined if it was initialized, and then we
// could check for uninit variables just by scanning what is live
// at the start of the function. But that doesn't work so well for
// immutable variables defined in a loop:
// loop { let x; x = 5; }
// because the "assignment" loops back around and generates an error.
//
// So now we just check that variables defined w/o an
// initializer are not live at the point of their
// initialization, which is mildly more complex than checking
// once at the func header but otherwise equivalent.

hir::StmtKind::Expr(ref expr, _) | hir::StmtKind::Semi(ref expr, _) => {
self.propagate_through_expr(&expr, succ)
let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
self.define_bindings_in_pat(&local.pat, succ)
}
}
}

fn propagate_through_decl(&mut self, decl: &hir::Decl, succ: LiveNode)
-> LiveNode {
match decl.node {
hir::DeclKind::Local(ref local) => {
self.propagate_through_local(&local, succ)
hir::StmtKind::Item(..) => succ,
hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
self.propagate_through_expr(&expr, succ)
}
hir::DeclKind::Item(_) => succ,
}
}

fn propagate_through_local(&mut self, local: &hir::Local, succ: LiveNode)
-> LiveNode {
// Note: we mark the variable as defined regardless of whether
// there is an initializer. Initially I had thought to only mark
// the live variable as defined if it was initialized, and then we
// could check for uninit variables just by scanning what is live
// at the start of the function. But that doesn't work so well for
// immutable variables defined in a loop:
// loop { let x; x = 5; }
// because the "assignment" loops back around and generates an error.
//
// So now we just check that variables defined w/o an
// initializer are not live at the point of their
// initialization, which is mildly more complex than checking
// once at the func header but otherwise equivalent.

let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
self.define_bindings_in_pat(&local.pat, succ)
}

fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode)
-> LiveNode {
exprs.iter().rev().fold(succ, |succ, expr| {
35 changes: 20 additions & 15 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
@@ -784,20 +784,25 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
// index information.)

for (i, statement) in blk.stmts.iter().enumerate() {
if let hir::StmtKind::Decl(..) = statement.node {
// Each StmtKind::Decl introduces a subscope for bindings
// introduced by the declaration; this subscope covers
// a suffix of the block . Each subscope in a block
// has the previous subscope in the block as a parent,
// except for the first such subscope, which has the
// block itself as a parent.
visitor.enter_scope(
Scope {
id: blk.hir_id.local_id,
data: ScopeData::Remainder(FirstStatementIndex::new(i))
}
);
visitor.cx.var_parent = visitor.cx.parent;
match statement.node {
hir::StmtKind::Local(..) |
hir::StmtKind::Item(..) => {
// Each declaration introduces a subscope for bindings
// introduced by the declaration; this subscope covers a
// suffix of the block. Each subscope in a block has the
// previous subscope in the block as a parent, except for
// the first such subscope, which has the block itself as a
// parent.
visitor.enter_scope(
Scope {
id: blk.hir_id.local_id,
data: ScopeData::Remainder(FirstStatementIndex::new(i))
}
);
visitor.cx.var_parent = visitor.cx.parent;
}
hir::StmtKind::Expr(..) |
hir::StmtKind::Semi(..) => {}
}
visitor.visit_stmt(statement)
}
@@ -835,7 +840,7 @@ fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, pat: &
}

fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, stmt: &'tcx hir::Stmt) {
let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.node.id()).local_id;
let stmt_id = visitor.tcx.hir().node_to_hir_id(stmt.id).local_id;
debug!("resolve_stmt(stmt.id={:?})", stmt_id);

// Every statement will clean up the temporaries created during
4 changes: 2 additions & 2 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ impl LintPass for UnusedResults {
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
let expr = match s.node {
hir::StmtKind::Semi(ref expr, _) => &**expr,
hir::StmtKind::Semi(ref expr) => &**expr,
_ => return,
};

@@ -205,7 +205,7 @@ impl LintPass for PathStatements {

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
if let hir::StmtKind::Semi(ref expr, _) = s.node {
if let hir::StmtKind::Semi(ref expr) = s.node {
if let hir::ExprKind::Path(_) = expr.node {
cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect");
}
88 changes: 42 additions & 46 deletions src/librustc_mir/hair/cx/block.rs
Original file line number Diff line number Diff line change
@@ -46,12 +46,12 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
-> Vec<StmtRef<'tcx>> {
let mut result = vec![];
for (index, stmt) in stmts.iter().enumerate() {
let hir_id = cx.tcx.hir().node_to_hir_id(stmt.node.id());
let hir_id = cx.tcx.hir().node_to_hir_id(stmt.id);
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.node.id()));
let stmt_span = StatementSpan(cx.tcx.hir().span(stmt.id));
match stmt.node {
hir::StmtKind::Expr(ref expr, _) |
hir::StmtKind::Semi(ref expr, _) => {
hir::StmtKind::Expr(ref expr) |
hir::StmtKind::Semi(ref expr) => {
result.push(StmtRef::Mirror(Box::new(Stmt {
kind: StmtKind::Expr {
scope: region::Scope {
@@ -64,52 +64,48 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
span: stmt_span,
})))
}
hir::StmtKind::Decl(ref decl, _) => {
match decl.node {
hir::DeclKind::Item(..) => {
// ignore for purposes of the MIR
}
hir::DeclKind::Local(ref local) => {
let remainder_scope = region::Scope {
id: block_id,
data: region::ScopeData::Remainder(
region::FirstStatementIndex::new(index)),
};

let mut pattern = cx.pattern_from_hir(&local.pat);
hir::StmtKind::Item(..) => {
// ignore for purposes of the MIR
}
hir::StmtKind::Local(ref local) => {
let remainder_scope = region::Scope {
id: block_id,
data: region::ScopeData::Remainder(
region::FirstStatementIndex::new(index)),
};

if let Some(ty) = &local.ty {
if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) {
debug!("mirror_stmts: user_ty={:?}", user_ty);
pattern = Pattern {
ty: pattern.ty,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: PatternTypeProjection::from_user_type(user_ty),
user_ty_span: ty.span,
subpattern: pattern,
variance: ty::Variance::Covariant,
})
};
}
}
let mut pattern = cx.pattern_from_hir(&local.pat);

result.push(StmtRef::Mirror(Box::new(Stmt {
kind: StmtKind::Let {
remainder_scope: remainder_scope,
init_scope: region::Scope {
id: hir_id.local_id,
data: region::ScopeData::Node
},
pattern,
initializer: local.init.to_ref(),
lint_level: cx.lint_level_of(local.id),
},
opt_destruction_scope: opt_dxn_ext,
span: stmt_span,
})));
if let Some(ty) = &local.ty {
if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) {
debug!("mirror_stmts: user_ty={:?}", user_ty);
pattern = Pattern {
ty: pattern.ty,
span: pattern.span,
kind: Box::new(PatternKind::AscribeUserType {
user_ty: PatternTypeProjection::from_user_type(user_ty),
user_ty_span: ty.span,
subpattern: pattern,
variance: ty::Variance::Covariant,
})
};
}
}

result.push(StmtRef::Mirror(Box::new(Stmt {
kind: StmtKind::Let {
remainder_scope: remainder_scope,
init_scope: region::Scope {
id: hir_id.local_id,
data: region::ScopeData::Node
},
pattern,
initializer: local.init.to_ref(),
lint_level: cx.lint_level_of(local.id),
},
opt_destruction_scope: opt_dxn_ext,
span: stmt_span,
})));
}
}
}
7 changes: 1 addition & 6 deletions src/librustc_passes/hir_stats.rs
Original file line number Diff line number Diff line change
@@ -144,7 +144,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
}

fn visit_stmt(&mut self, s: &'v hir::Stmt) {
self.record("Stmt", Id::Node(s.node.id()), s);
self.record("Stmt", Id::Node(s.id), s);
hir_visit::walk_stmt(self, s)
}

@@ -158,11 +158,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
hir_visit::walk_pat(self, p)
}

fn visit_decl(&mut self, d: &'v hir::Decl) {
self.record("Decl", Id::None, d);
hir_visit::walk_decl(self, d)
}

fn visit_expr(&mut self, ex: &'v hir::Expr) {
self.record("Expr", Id::Node(ex.id), ex);
hir_visit::walk_expr(self, ex)
30 changes: 13 additions & 17 deletions src/librustc_passes/rvalue_promotion.rs
Original file line number Diff line number Diff line change
@@ -220,26 +220,22 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {

fn check_stmt(&mut self, stmt: &'tcx hir::Stmt) -> Promotability {
match stmt.node {
hir::StmtKind::Decl(ref decl, _node_id) => {
match &decl.node {
hir::DeclKind::Local(local) => {
if self.remove_mut_rvalue_borrow(&local.pat) {
if let Some(init) = &local.init {
self.mut_rvalue_borrows.insert(init.id);
}
}

if let Some(ref expr) = local.init {
let _ = self.check_expr(&expr);
}
NotPromotable
hir::StmtKind::Local(ref local) => {
if self.remove_mut_rvalue_borrow(&local.pat) {
if let Some(init) = &local.init {
self.mut_rvalue_borrows.insert(init.id);
}
// Item statements are allowed
hir::DeclKind::Item(_) => Promotable
}

if let Some(ref expr) = local.init {
let _ = self.check_expr(&expr);
}
NotPromotable
}
hir::StmtKind::Expr(ref box_expr, _node_id) |
hir::StmtKind::Semi(ref box_expr, _node_id) => {
// Item statements are allowed
hir::StmtKind::Item(..) => Promotable,
hir::StmtKind::Expr(ref box_expr) |
hir::StmtKind::Semi(ref box_expr) => {
let _ = self.check_expr(box_expr);
NotPromotable
}
28 changes: 10 additions & 18 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -4840,15 +4840,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
// Don't do all the complex logic below for `DeclItem`.
match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
if let hir::DeclKind::Item(_) = decl.node {
return
}
}
hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
hir::StmtKind::Item(..) => return,
hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
}

self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement");
self.warn_if_unreachable(stmt.id, stmt.span, "statement");

// Hide the outer diverging and `has_errors` flags.
let old_diverges = self.diverges.get();
@@ -4857,20 +4853,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.has_errors.set(false);

match stmt.node {
hir::StmtKind::Decl(ref decl, _) => {
match decl.node {
hir::DeclKind::Local(ref l) => {
self.check_decl_local(&l);
}
// Ignore for now.
hir::DeclKind::Item(_) => ()
}
hir::StmtKind::Local(ref l) => {
self.check_decl_local(&l);
}
hir::StmtKind::Expr(ref expr, _) => {
// Ignore for now.
hir::StmtKind::Item(_) => {}
hir::StmtKind::Expr(ref expr) => {
// Check with expected type of `()`.
self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
}
hir::StmtKind::Semi(ref expr, _) => {
hir::StmtKind::Semi(ref expr) => {
self.check_expr(&expr);
}
}
@@ -5273,7 +5265,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None => return None,
};
let last_expr = match last_stmt.node {
hir::StmtKind::Semi(ref e, _) => e,
hir::StmtKind::Semi(ref e) => e,
_ => return None,
};
let last_expr_ty = self.node_ty(last_expr.hir_id);