Remove hir::StmtKind::Decl
.
It's a level of indirection that hurts far more than it helps. The code is simpler without it. (This commit cuts more than 120 lines of code.) In particular, this commit removes some unnecessary `Span`s within `DeclKind` that were always identical to those in the enclosing `Stmt`, and some unnecessary allocations via `P`.
This commit is contained in:
parent
b2ce5a9099
commit
afbd004d69
16 changed files with 152 additions and 274 deletions
|
@ -100,29 +100,20 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
|
|
||||||
fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
|
fn stmt(&mut self, stmt: &hir::Stmt, pred: CFGIndex) -> CFGIndex {
|
||||||
let hir_id = self.tcx.hir().node_to_hir_id(stmt.id);
|
let hir_id = self.tcx.hir().node_to_hir_id(stmt.id);
|
||||||
match stmt.node {
|
let exit = match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref local) => {
|
||||||
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 init_exit = self.opt_expr(&local.init, pred);
|
let init_exit = self.opt_expr(&local.init, pred);
|
||||||
self.pat(&local.pat, init_exit)
|
self.pat(&local.pat, init_exit)
|
||||||
}
|
}
|
||||||
|
hir::StmtKind::Item(_) => {
|
||||||
hir::DeclKind::Item(_) => pred,
|
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 {
|
fn pat(&mut self, pat: &hir::Pat, pred: CFGIndex) -> CFGIndex {
|
||||||
|
|
|
@ -298,8 +298,8 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn check_stmt_attributes(&self, stmt: &hir::Stmt) {
|
fn check_stmt_attributes(&self, stmt: &hir::Stmt) {
|
||||||
// When checking statements ignore expressions, they will be checked later
|
// When checking statements ignore expressions, they will be checked later
|
||||||
if let hir::StmtKind::Decl(..) = stmt.node {
|
if let hir::StmtKind::Local(ref l) = stmt.node {
|
||||||
for attr in stmt.node.attrs() {
|
for attr in l.attrs.iter() {
|
||||||
if attr.check_name("inline") {
|
if attr.check_name("inline") {
|
||||||
self.check_inline(attr, &stmt.span, Target::Statement);
|
self.check_inline(attr, &stmt.span, Target::Statement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,9 +260,6 @@ pub trait Visitor<'v> : Sized {
|
||||||
fn visit_pat(&mut self, p: &'v Pat) {
|
fn visit_pat(&mut self, p: &'v Pat) {
|
||||||
walk_pat(self, p)
|
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) {
|
fn visit_anon_const(&mut self, c: &'v AnonConst) {
|
||||||
walk_anon_const(self, c)
|
walk_anon_const(self, c)
|
||||||
}
|
}
|
||||||
|
@ -955,9 +952,8 @@ 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) {
|
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
|
||||||
visitor.visit_id(statement.id);
|
visitor.visit_id(statement.id);
|
||||||
match statement.node {
|
match statement.node {
|
||||||
StmtKind::Decl(ref declaration) => {
|
StmtKind::Local(ref local) => visitor.visit_local(local),
|
||||||
visitor.visit_decl(declaration)
|
StmtKind::Item(ref item) => visitor.visit_nested_item(**item),
|
||||||
}
|
|
||||||
StmtKind::Expr(ref expression) |
|
StmtKind::Expr(ref expression) |
|
||||||
StmtKind::Semi(ref expression) => {
|
StmtKind::Semi(ref expression) => {
|
||||||
visitor.visit_expr(expression)
|
visitor.visit_expr(expression)
|
||||||
|
@ -965,13 +961,6 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
|
||||||
visitor.visit_id(constant.id);
|
visitor.visit_id(constant.id);
|
||||||
visitor.visit_nested_body(constant.body);
|
visitor.visit_nested_body(constant.body);
|
||||||
|
|
|
@ -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 LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id);
|
||||||
let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
|
let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
|
||||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
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);
|
let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
|
||||||
(P(hir::Local {
|
(hir::Local {
|
||||||
id: node_id,
|
id: node_id,
|
||||||
hir_id,
|
hir_id,
|
||||||
ty: l.ty
|
ty: l.ty
|
||||||
|
@ -1984,7 +1984,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
span: l.span,
|
span: l.span,
|
||||||
attrs: l.attrs.clone(),
|
attrs: l.attrs.clone(),
|
||||||
source: hir::LocalSource::Normal,
|
source: hir::LocalSource::Normal,
|
||||||
}), ids)
|
}, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
|
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
|
||||||
|
@ -4537,23 +4537,13 @@ impl<'a> LoweringContext<'a> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item_id| hir::Stmt {
|
.map(|item_id| hir::Stmt {
|
||||||
id: self.next_id().node_id,
|
id: self.next_id().node_id,
|
||||||
node: hir::StmtKind::Decl(
|
node: hir::StmtKind::Item(P(item_id)),
|
||||||
P(Spanned {
|
|
||||||
node: hir::DeclKind::Item(item_id),
|
|
||||||
span: s.span,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
span: s.span,
|
span: s.span,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
ids.push(hir::Stmt {
|
ids.push(hir::Stmt {
|
||||||
id: self.lower_node_id(s.id).node_id,
|
id: self.lower_node_id(s.id).node_id,
|
||||||
node: hir::StmtKind::Decl(
|
node: hir::StmtKind::Local(P(l)),
|
||||||
P(Spanned {
|
|
||||||
node: hir::DeclKind::Local(l),
|
|
||||||
span: s.span,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
span: s.span,
|
span: s.span,
|
||||||
});
|
});
|
||||||
return ids;
|
return ids;
|
||||||
|
@ -4567,12 +4557,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
id: id.take()
|
id: id.take()
|
||||||
.map(|id| self.lower_node_id(id).node_id)
|
.map(|id| self.lower_node_id(id).node_id)
|
||||||
.unwrap_or_else(|| self.next_id().node_id),
|
.unwrap_or_else(|| self.next_id().node_id),
|
||||||
node: hir::StmtKind::Decl(
|
node: hir::StmtKind::Item(P(item_id)),
|
||||||
P(Spanned {
|
|
||||||
node: hir::DeclKind::Item(item_id),
|
|
||||||
span: s.span,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
span: s.span,
|
span: s.span,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -4799,7 +4784,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
) -> hir::Stmt {
|
) -> hir::Stmt {
|
||||||
let LoweredNodeId { node_id, hir_id } = self.next_id();
|
let LoweredNodeId { node_id, hir_id } = self.next_id();
|
||||||
|
|
||||||
let local = P(hir::Local {
|
let local = hir::Local {
|
||||||
pat,
|
pat,
|
||||||
ty: None,
|
ty: None,
|
||||||
init: ex,
|
init: ex,
|
||||||
|
@ -4808,11 +4793,10 @@ impl<'a> LoweringContext<'a> {
|
||||||
span: sp,
|
span: sp,
|
||||||
attrs: ThinVec::new(),
|
attrs: ThinVec::new(),
|
||||||
source,
|
source,
|
||||||
});
|
};
|
||||||
let decl = respan(sp, hir::DeclKind::Local(local));
|
|
||||||
hir::Stmt {
|
hir::Stmt {
|
||||||
id: self.next_id().node_id,
|
id: self.next_id().node_id,
|
||||||
node: hir::StmtKind::Decl(P(decl)),
|
node: hir::StmtKind::Local(P(local)),
|
||||||
span: sp
|
span: sp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1160,8 +1160,10 @@ impl fmt::Debug for Stmt {
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, RustcEncodable, RustcDecodable)]
|
||||||
pub enum StmtKind {
|
pub enum StmtKind {
|
||||||
/// Could be an item or a local (let) binding:
|
/// A local (let) binding:
|
||||||
Decl(P<Decl>),
|
Local(P<Local>),
|
||||||
|
/// An item binding:
|
||||||
|
Item(P<ItemId>),
|
||||||
|
|
||||||
/// Expr without trailing semi-colon (must have unit type):
|
/// Expr without trailing semi-colon (must have unit type):
|
||||||
Expr(P<Expr>),
|
Expr(P<Expr>),
|
||||||
|
@ -1173,7 +1175,8 @@ pub enum StmtKind {
|
||||||
impl StmtKind {
|
impl StmtKind {
|
||||||
pub fn attrs(&self) -> &[Attribute] {
|
pub fn attrs(&self) -> &[Attribute] {
|
||||||
match *self {
|
match *self {
|
||||||
StmtKind::Decl(ref d) => d.node.attrs(),
|
StmtKind::Local(ref l) => &l.attrs,
|
||||||
|
StmtKind::Item(_) => &[],
|
||||||
StmtKind::Expr(ref e) |
|
StmtKind::Expr(ref e) |
|
||||||
StmtKind::Semi(ref e) => &e.attrs,
|
StmtKind::Semi(ref e) => &e.attrs,
|
||||||
}
|
}
|
||||||
|
@ -1194,32 +1197,6 @@ pub struct Local {
|
||||||
pub source: LocalSource,
|
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'
|
/// represents one arm of a 'match'
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||||
pub struct Arm {
|
pub struct Arm {
|
||||||
|
|
|
@ -992,8 +992,23 @@ impl<'a> State<'a> {
|
||||||
pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
|
pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> {
|
||||||
self.maybe_print_comment(st.span.lo())?;
|
self.maybe_print_comment(st.span.lo())?;
|
||||||
match st.node {
|
match st.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref loc) => {
|
||||||
self.print_decl(&decl)?;
|
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.space_if_not_bol()?;
|
||||||
|
@ -1562,30 +1577,6 @@ impl<'a> State<'a> {
|
||||||
Ok(())
|
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<()> {
|
pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
|
||||||
self.s.word(i.to_string())
|
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.
|
/// seen the semicolon, and thus don't need another.
|
||||||
fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
|
fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
|
||||||
match *stmt {
|
match *stmt {
|
||||||
hir::StmtKind::Decl(ref d) => {
|
hir::StmtKind::Local(_) => true,
|
||||||
match d.node {
|
hir::StmtKind::Item(_) => false,
|
||||||
hir::DeclKind::Local(_) => true,
|
hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e),
|
||||||
hir::DeclKind::Item(_) => false,
|
hir::StmtKind::Semi(..) => false,
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::StmtKind::Expr(ref e) => {
|
|
||||||
expr_requires_semi_to_be_stmt(&e)
|
|
||||||
}
|
|
||||||
hir::StmtKind::Semi(..) => {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -501,12 +501,6 @@ impl_stable_hash_for!(struct hir::Local {
|
||||||
source
|
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 {
|
impl_stable_hash_for!(struct hir::Arm {
|
||||||
attrs,
|
attrs,
|
||||||
pats,
|
pats,
|
||||||
|
@ -946,7 +940,8 @@ impl_stable_hash_for!(enum hir::ForeignItemKind {
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(enum hir::StmtKind {
|
impl_stable_hash_for!(enum hir::StmtKind {
|
||||||
Decl(decl),
|
Local(local),
|
||||||
|
Item(item_id),
|
||||||
Expr(expr),
|
Expr(expr),
|
||||||
Semi(expr)
|
Semi(expr)
|
||||||
});
|
});
|
||||||
|
|
|
@ -941,11 +941,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
|
||||||
hir_visit::walk_arm(self, a);
|
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) {
|
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam) {
|
||||||
run_lints!(self, check_generic_param, p);
|
run_lints!(self, check_generic_param, p);
|
||||||
hir_visit::walk_generic_param(self, p);
|
hir_visit::walk_generic_param(self, p);
|
||||||
|
|
|
@ -191,7 +191,6 @@ macro_rules! late_lint_methods {
|
||||||
fn check_stmt(a: &$hir hir::Stmt);
|
fn check_stmt(a: &$hir hir::Stmt);
|
||||||
fn check_arm(a: &$hir hir::Arm);
|
fn check_arm(a: &$hir hir::Arm);
|
||||||
fn check_pat(a: &$hir hir::Pat);
|
fn check_pat(a: &$hir hir::Pat);
|
||||||
fn check_decl(a: &$hir hir::Decl);
|
|
||||||
fn check_expr(a: &$hir hir::Expr);
|
fn check_expr(a: &$hir hir::Expr);
|
||||||
fn check_expr_post(a: &$hir hir::Expr);
|
fn check_expr_post(a: &$hir hir::Expr);
|
||||||
fn check_ty(a: &$hir hir::Ty);
|
fn check_ty(a: &$hir hir::Ty);
|
||||||
|
|
|
@ -589,18 +589,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
fn walk_stmt(&mut self, stmt: &hir::Stmt) {
|
fn walk_stmt(&mut self, stmt: &hir::Stmt) {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref local) => {
|
||||||
match decl.node {
|
|
||||||
hir::DeclKind::Local(ref local) => {
|
|
||||||
self.walk_local(&local);
|
self.walk_local(&local);
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::DeclKind::Item(_) => {
|
hir::StmtKind::Item(_) => {
|
||||||
// we don't visit nested items in this visitor,
|
// we don't visit nested items in this visitor,
|
||||||
// only the fn body we were given.
|
// only the fn body we were given.
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::StmtKind::Expr(ref expr) |
|
hir::StmtKind::Expr(ref expr) |
|
||||||
hir::StmtKind::Semi(ref expr) => {
|
hir::StmtKind::Semi(ref expr) => {
|
||||||
|
|
|
@ -956,28 +956,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode)
|
fn propagate_through_stmt(&mut self, stmt: &hir::Stmt, succ: LiveNode)
|
||||||
-> LiveNode {
|
-> LiveNode {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref local) => {
|
||||||
self.propagate_through_decl(&decl, succ)
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
|
|
||||||
self.propagate_through_expr(&expr, 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::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
|
// Note: we mark the variable as defined regardless of whether
|
||||||
// there is an initializer. Initially I had thought to only mark
|
// there is an initializer. Initially I had thought to only mark
|
||||||
// the live variable as defined if it was initialized, and then we
|
// the live variable as defined if it was initialized, and then we
|
||||||
|
@ -995,6 +974,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
|
let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
|
||||||
self.define_bindings_in_pat(&local.pat, succ)
|
self.define_bindings_in_pat(&local.pat, succ)
|
||||||
}
|
}
|
||||||
|
hir::StmtKind::Item(..) => succ,
|
||||||
|
hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
|
||||||
|
self.propagate_through_expr(&expr, succ)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode)
|
fn propagate_through_exprs(&mut self, exprs: &[Expr], succ: LiveNode)
|
||||||
-> LiveNode {
|
-> LiveNode {
|
||||||
|
|
|
@ -784,13 +784,15 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
|
||||||
// index information.)
|
// index information.)
|
||||||
|
|
||||||
for (i, statement) in blk.stmts.iter().enumerate() {
|
for (i, statement) in blk.stmts.iter().enumerate() {
|
||||||
if let hir::StmtKind::Decl(..) = statement.node {
|
match statement.node {
|
||||||
// Each StmtKind::Decl introduces a subscope for bindings
|
hir::StmtKind::Local(..) |
|
||||||
// introduced by the declaration; this subscope covers
|
hir::StmtKind::Item(..) => {
|
||||||
// a suffix of the block . Each subscope in a block
|
// Each declaration introduces a subscope for bindings
|
||||||
// has the previous subscope in the block as a parent,
|
// introduced by the declaration; this subscope covers a
|
||||||
// except for the first such subscope, which has the
|
// suffix of the block. Each subscope in a block has the
|
||||||
// block itself as a parent.
|
// 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(
|
visitor.enter_scope(
|
||||||
Scope {
|
Scope {
|
||||||
id: blk.hir_id.local_id,
|
id: blk.hir_id.local_id,
|
||||||
|
@ -799,6 +801,9 @@ fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, blk:
|
||||||
);
|
);
|
||||||
visitor.cx.var_parent = visitor.cx.parent;
|
visitor.cx.var_parent = visitor.cx.parent;
|
||||||
}
|
}
|
||||||
|
hir::StmtKind::Expr(..) |
|
||||||
|
hir::StmtKind::Semi(..) => {}
|
||||||
|
}
|
||||||
visitor.visit_stmt(statement)
|
visitor.visit_stmt(statement)
|
||||||
}
|
}
|
||||||
walk_list!(visitor, visit_expr, &blk.expr);
|
walk_list!(visitor, visit_expr, &blk.expr);
|
||||||
|
|
|
@ -64,12 +64,10 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
span: stmt_span,
|
span: stmt_span,
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Item(..) => {
|
||||||
match decl.node {
|
|
||||||
hir::DeclKind::Item(..) => {
|
|
||||||
// ignore for purposes of the MIR
|
// ignore for purposes of the MIR
|
||||||
}
|
}
|
||||||
hir::DeclKind::Local(ref local) => {
|
hir::StmtKind::Local(ref local) => {
|
||||||
let remainder_scope = region::Scope {
|
let remainder_scope = region::Scope {
|
||||||
id: block_id,
|
id: block_id,
|
||||||
data: region::ScopeData::Remainder(
|
data: region::ScopeData::Remainder(
|
||||||
|
@ -111,8 +109,6 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,11 +158,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
hir_visit::walk_pat(self, p)
|
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) {
|
fn visit_expr(&mut self, ex: &'v hir::Expr) {
|
||||||
self.record("Expr", Id::Node(ex.id), ex);
|
self.record("Expr", Id::Node(ex.id), ex);
|
||||||
hir_visit::walk_expr(self, ex)
|
hir_visit::walk_expr(self, ex)
|
||||||
|
|
|
@ -220,9 +220,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn check_stmt(&mut self, stmt: &'tcx hir::Stmt) -> Promotability {
|
fn check_stmt(&mut self, stmt: &'tcx hir::Stmt) -> Promotability {
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref local) => {
|
||||||
match &decl.node {
|
|
||||||
hir::DeclKind::Local(local) => {
|
|
||||||
if self.remove_mut_rvalue_borrow(&local.pat) {
|
if self.remove_mut_rvalue_borrow(&local.pat) {
|
||||||
if let Some(init) = &local.init {
|
if let Some(init) = &local.init {
|
||||||
self.mut_rvalue_borrows.insert(init.id);
|
self.mut_rvalue_borrows.insert(init.id);
|
||||||
|
@ -235,9 +233,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||||
NotPromotable
|
NotPromotable
|
||||||
}
|
}
|
||||||
// Item statements are allowed
|
// Item statements are allowed
|
||||||
hir::DeclKind::Item(_) => Promotable
|
hir::StmtKind::Item(..) => Promotable,
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::StmtKind::Expr(ref box_expr) |
|
hir::StmtKind::Expr(ref box_expr) |
|
||||||
hir::StmtKind::Semi(ref box_expr) => {
|
hir::StmtKind::Semi(ref box_expr) => {
|
||||||
let _ = self.check_expr(box_expr);
|
let _ = self.check_expr(box_expr);
|
||||||
|
|
|
@ -4840,12 +4840,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
|
pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) {
|
||||||
// Don't do all the complex logic below for `DeclItem`.
|
// Don't do all the complex logic below for `DeclItem`.
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Item(..) => return,
|
||||||
if let hir::DeclKind::Item(_) = decl.node {
|
hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.warn_if_unreachable(stmt.id, stmt.span, "statement");
|
self.warn_if_unreachable(stmt.id, stmt.span, "statement");
|
||||||
|
@ -4857,15 +4853,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.has_errors.set(false);
|
self.has_errors.set(false);
|
||||||
|
|
||||||
match stmt.node {
|
match stmt.node {
|
||||||
hir::StmtKind::Decl(ref decl) => {
|
hir::StmtKind::Local(ref l) => {
|
||||||
match decl.node {
|
|
||||||
hir::DeclKind::Local(ref l) => {
|
|
||||||
self.check_decl_local(&l);
|
self.check_decl_local(&l);
|
||||||
}
|
}
|
||||||
// Ignore for now.
|
// Ignore for now.
|
||||||
hir::DeclKind::Item(_) => ()
|
hir::StmtKind::Item(_) => {}
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::StmtKind::Expr(ref expr) => {
|
hir::StmtKind::Expr(ref expr) => {
|
||||||
// Check with expected type of `()`.
|
// Check with expected type of `()`.
|
||||||
self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
|
self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue