From d6aa56f44e062bfe06144318cbd88ac0b58d5814 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 10 Nov 2017 19:20:35 +0200 Subject: [PATCH] rustc: split off BodyOwnerKind from MirSource. --- src/librustc/hir/map/mod.rs | 22 ++++++ src/librustc/hir/mod.rs | 12 +++ src/librustc/middle/region.rs | 3 +- src/librustc/mir/mod.rs | 1 - src/librustc/mir/transform.rs | 74 ------------------- src/librustc_mir/borrow_check.rs | 15 ++-- src/librustc_mir/build/mod.rs | 17 +++-- src/librustc_mir/build/scope.rs | 12 ++- src/librustc_mir/hair/cx/mod.rs | 28 ++++--- src/librustc_mir/shim.rs | 8 +- src/librustc_mir/transform/add_call_guards.rs | 3 +- src/librustc_mir/transform/add_validation.rs | 8 +- .../transform/clean_end_regions.rs | 3 +- src/librustc_mir/transform/copy_prop.rs | 28 ++++--- src/librustc_mir/transform/deaggregator.rs | 17 +++-- src/librustc_mir/transform/dump_mir.rs | 3 +- src/librustc_mir/transform/elaborate_drops.rs | 16 ++-- src/librustc_mir/transform/erase_regions.rs | 3 +- src/librustc_mir/transform/generator.rs | 9 +-- src/librustc_mir/transform/inline.rs | 15 ++-- src/librustc_mir/transform/instcombine.rs | 3 +- src/librustc_mir/transform/mod.rs | 46 ++++++++---- .../transform/nll/constraint_generation.rs | 11 +-- .../transform/nll/free_regions.rs | 10 +-- src/librustc_mir/transform/nll/mod.rs | 14 ++-- src/librustc_mir/transform/no_landing_pads.rs | 3 +- src/librustc_mir/transform/qualify_consts.rs | 22 +++--- src/librustc_mir/transform/rustc_peek.rs | 7 +- src/librustc_mir/transform/simplify.rs | 3 +- .../transform/simplify_branches.rs | 3 +- src/librustc_mir/transform/type_check.rs | 9 +-- src/librustc_mir/util/graphviz.rs | 14 ++-- src/librustc_mir/util/liveness.rs | 7 +- src/librustc_mir/util/pretty.rs | 57 +++++++------- src/librustc_passes/consts.rs | 7 +- 35 files changed, 238 insertions(+), 275 deletions(-) delete mode 100644 src/librustc/mir/transform.rs diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 453d30dde75..1b590c2b2c4 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -448,6 +448,28 @@ impl<'hir> Map<'hir> { }) } + pub fn body_owner_kind(&self, id: NodeId) -> BodyOwnerKind { + // Handle constants in enum discriminants, types, and repeat expressions. + let def_id = self.local_def_id(id); + let def_key = self.def_key(def_id); + if def_key.disambiguated_data.data == DefPathData::Initializer { + return BodyOwnerKind::Const; + } + + match self.get(id) { + NodeItem(&Item { node: ItemConst(..), .. }) | + NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) | + NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => { + BodyOwnerKind::Const + } + NodeItem(&Item { node: ItemStatic(_, m, _), .. }) => { + BodyOwnerKind::Static(m) + } + // Default to function if it's not a constant or static. + _ => BodyOwnerKind::Fn + } + } + pub fn ty_param_owner(&self, id: NodeId) -> NodeId { match self.get(id) { NodeItem(&Item { node: ItemTrait(..), .. }) => id, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 39e222230e5..a7206f5d420 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1028,6 +1028,18 @@ impl Body { } } +#[derive(Copy, Clone, Debug)] +pub enum BodyOwnerKind { + /// Functions and methods. + Fn, + + /// Constants and associated constants. + Const, + + /// Initializer of a `static` item. + Static(Mutability), +} + /// An expression #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] pub struct Expr { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 89707839144..a7882992d61 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -31,7 +31,6 @@ use hir; use hir::def_id::DefId; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local}; -use mir::transform::MirSource; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; @@ -1298,7 +1297,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> { // The body of the every fn is a root scope. self.cx.parent = self.cx.var_parent; - if let MirSource::Fn(_) = MirSource::from_node(self.tcx, owner_id) { + if let hir::BodyOwnerKind::Fn = self.tcx.hir.body_owner_kind(owner_id) { self.visit_expr(&body.value); } else { // Only functions have an outer terminating (drop) scope, while diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index cd017650633..18c26500dbe 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -41,7 +41,6 @@ use syntax_pos::Span; mod cache; pub mod tcx; pub mod visit; -pub mod transform; pub mod traversal; /// Types for locals diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs deleted file mode 100644 index 00f8926711e..00000000000 --- a/src/librustc/mir/transform.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! See [the README](README.md) for details on writing your own pass. - -use hir; -use hir::def_id::DefId; -use hir::map::DefPathData; -use mir::Promoted; -use ty::TyCtxt; -use syntax::ast::NodeId; - -/// Where a specific Mir comes from. -#[derive(Debug, Copy, Clone)] -pub enum MirSource { - /// Functions and methods. - Fn(NodeId), - - /// Constants and associated constants. - Const(NodeId), - - /// Initializer of a `static` item. - Static(NodeId, hir::Mutability), - - /// Promoted rvalues within a function. - Promoted(NodeId, Promoted), -} - -impl<'a, 'gcx, 'tcx> MirSource { - pub fn from_local_def_id(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> MirSource { - let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id"); - Self::from_node(tcx, id) - } - - pub fn from_node(tcx: TyCtxt<'a, 'gcx, 'tcx>, id: NodeId) -> MirSource { - use hir::*; - - // Handle constants in enum discriminants, types, and repeat expressions. - let def_id = tcx.hir.local_def_id(id); - let def_key = tcx.def_key(def_id); - if def_key.disambiguated_data.data == DefPathData::Initializer { - return MirSource::Const(id); - } - - match tcx.hir.get(id) { - map::NodeItem(&Item { node: ItemConst(..), .. }) | - map::NodeTraitItem(&TraitItem { node: TraitItemKind::Const(..), .. }) | - map::NodeImplItem(&ImplItem { node: ImplItemKind::Const(..), .. }) => { - MirSource::Const(id) - } - map::NodeItem(&Item { node: ItemStatic(_, m, _), .. }) => { - MirSource::Static(id, m) - } - // Default to function if it's not a constant or static. - _ => MirSource::Fn(id) - } - } - - pub fn item_id(&self) -> NodeId { - match *self { - MirSource::Fn(id) | - MirSource::Const(id) | - MirSource::Static(id, _) | - MirSource::Promoted(id, _) => id - } - } -} diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs index c56631d429c..deffb85bf87 100644 --- a/src/librustc_mir/borrow_check.rs +++ b/src/librustc_mir/borrow_check.rs @@ -18,7 +18,6 @@ use rustc::ty::maps::Providers; use rustc::mir::{AssertMessage, BasicBlock, BorrowKind, Location, Lvalue, Local}; use rustc::mir::{Mir, Mutability, Operand, Projection, ProjectionElem, Rvalue}; use rustc::mir::{Statement, StatementKind, Terminator, TerminatorKind}; -use rustc::mir::transform::MirSource; use transform::nll; use rustc_data_structures::indexed_set::{self, IdxSetBuf}; @@ -50,8 +49,7 @@ pub fn provide(providers: &mut Providers) { fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { let input_mir = tcx.mir_validated(def_id); - let src = MirSource::from_local_def_id(tcx, def_id); - debug!("run query mir_borrowck: {}", tcx.node_path_str(src.item_id())); + debug!("run query mir_borrowck: {}", tcx.item_path_str(def_id)); if { !tcx.has_attr(def_id, "rustc_mir_borrowck") && @@ -63,21 +61,20 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { tcx.infer_ctxt().enter(|infcx| { let input_mir: &Mir = &input_mir.borrow(); - do_mir_borrowck(&infcx, input_mir, def_id, src); + do_mir_borrowck(&infcx, input_mir, def_id); }); debug!("mir_borrowck done"); } fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, input_mir: &Mir<'gcx>, - def_id: DefId, - src: MirSource) + def_id: DefId) { let tcx = infcx.tcx; let attributes = tcx.get_attrs(def_id); let param_env = tcx.param_env(def_id); - - let id = src.item_id(); + let id = tcx.hir.as_local_node_id(def_id) + .expect("do_mir_borrowck: non-local DefId"); let move_data: MoveData<'tcx> = match MoveData::gather_moves(input_mir, tcx, param_env) { Ok(move_data) => move_data, @@ -117,7 +114,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, let opt_regioncx = if !tcx.sess.opts.debugging_opts.nll { None } else { - Some(nll::compute_regions(infcx, src, mir)) + Some(nll::compute_regions(infcx, def_id, mir)) }; let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 2073d495300..0489a03c97e 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -16,7 +16,6 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::middle::region; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; @@ -30,6 +29,7 @@ use syntax::abi::Abi; use syntax::ast; use syntax::symbol::keywords; use syntax_pos::Span; +use transform::MirSource; use util as mir_util; /// Construct the MIR for a given def-id. @@ -83,12 +83,11 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t _ => unsupported(), }; - let src = MirSource::from_node(tcx, id); tcx.infer_ctxt().enter(|infcx| { - let cx = Cx::new(&infcx, src); + let cx = Cx::new(&infcx, id); let mut mir = if cx.tables().tainted_by_errors { build::construct_error(cx, body_id) - } else if let MirSource::Fn(id) = src { + } else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) let fn_hir_id = tcx.hir.node_to_hir_id(id); @@ -150,7 +149,8 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t mem::transmute::>(mir) }; - mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir, |_, _| Ok(()) ); + mir_util::dump_mir(tcx, None, "mir_map", &0, + MirSource::item(def_id), &mir, |_, _| Ok(()) ); mir }) @@ -214,8 +214,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let span = tcx.hir.span(ctor_id); if let hir::VariantData::Tuple(ref fields, ctor_id) = *v { tcx.infer_ctxt().enter(|infcx| { - let (mut mir, src) = - shim::build_adt_ctor(&infcx, ctor_id, fields, span); + let mut mir = shim::build_adt_ctor(&infcx, ctor_id, fields, span); // Convert the Mir to global types. let tcx = infcx.tcx.global_tcx(); @@ -228,7 +227,9 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mem::transmute::>(mir) }; - mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir, |_, _| Ok(()) ); + mir_util::dump_mir(tcx, None, "mir_map", &0, + MirSource::item(tcx.hir.local_def_id(ctor_id)), + &mir, |_, _| Ok(()) ); mir }) diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 07d5f69eeed..3c3dabdfa54 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -91,9 +91,9 @@ use build::{BlockAnd, BlockAndExtension, Builder, CFG}; use hair::LintLevel; use rustc::middle::region; use rustc::ty::{Ty, TyCtxt}; +use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; use rustc::mir::*; -use rustc::mir::transform::MirSource; use syntax_pos::{Span}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::fx::FxHashMap; @@ -596,15 +596,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// When building statics/constants, returns `None` since /// intermediate values do not have to be dropped in that case. pub fn local_scope(&self) -> Option { - match self.hir.src { - MirSource::Const(_) | - MirSource::Static(..) => + match self.hir.body_owner_kind { + hir::BodyOwnerKind::Const | + hir::BodyOwnerKind::Static(_) => // No need to free storage in this context. None, - MirSource::Fn(_) => + hir::BodyOwnerKind::Fn => Some(self.topmost_scope()), - MirSource::Promoted(..) => - bug!(), } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 9d88b1b0a16..50264238aac 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -15,7 +15,6 @@ //! use hair::*; -use rustc::mir::transform::MirSource; use rustc::middle::const_val::{ConstEvalErr, ConstVal}; use rustc_const_eval::ConstContext; @@ -51,8 +50,8 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { /// `const`, or the body of a `const fn`. constness: hir::Constness, - /// What are we compiling? - pub src: MirSource, + /// What kind of body is being compiled. + pub body_owner_kind: hir::BodyOwnerKind, /// True if this constant/function needs overflow checks. check_overflow: bool, @@ -60,21 +59,20 @@ pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - src: MirSource) -> Cx<'a, 'gcx, 'tcx> { - let constness = match src { - MirSource::Const(_) | - MirSource::Static(..) => hir::Constness::Const, - MirSource::Fn(id) => { - let fn_like = FnLikeNode::from_node(infcx.tcx.hir.get(id)); + src_id: ast::NodeId) -> Cx<'a, 'gcx, 'tcx> { + let tcx = infcx.tcx; + let src_def_id = tcx.hir.local_def_id(src_id); + let body_owner_kind = tcx.hir.body_owner_kind(src_id); + + let constness = match body_owner_kind { + hir::BodyOwnerKind::Const | + hir::BodyOwnerKind::Static(_) => hir::Constness::Const, + hir::BodyOwnerKind::Fn => { + let fn_like = FnLikeNode::from_node(infcx.tcx.hir.get(src_id)); fn_like.map_or(hir::Constness::NotConst, |f| f.constness()) } - MirSource::Promoted(..) => bug!(), }; - let tcx = infcx.tcx; - let src_id = src.item_id(); - let src_def_id = tcx.hir.local_def_id(src_id); - let attrs = tcx.hir.attrs(src_id); // Some functions always have overflow checks enabled, @@ -99,7 +97,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { region_scope_tree: tcx.region_scope_tree(src_def_id), tables: tcx.typeck_tables_of(src_def_id), constness, - src, + body_owner_kind, check_overflow, } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index a3a986918a4..e1f0e01b88c 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -13,7 +13,6 @@ use rustc::hir::def_id::DefId; use rustc::infer; use rustc::middle::const_val::ConstVal; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::ty::maps::Providers; @@ -826,7 +825,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, ctor_id: ast::NodeId, fields: &[hir::StructField], span: Span) - -> (Mir<'tcx>, MirSource) + -> Mir<'tcx> { let tcx = infcx.tcx; let def_id = tcx.hir.local_def_id(ctor_id); @@ -875,7 +874,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, is_cleanup: false }; - let mir = Mir::new( + Mir::new( IndexVec::from_elem_n(start_block, 1), IndexVec::from_elem_n( VisibilityScopeData { span: span, parent_scope: None }, 1 @@ -888,6 +887,5 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, sig.inputs().len(), vec![], span - ); - (mir, MirSource::Fn(ctor_id)) + ) } diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index 3f4cc3c1486..5be369f85bc 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -10,9 +10,8 @@ use rustc::ty::TyCtxt; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use transform::MirPass; +use transform::{MirPass, MirSource}; #[derive(PartialEq)] pub enum AddCallGuards { diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index aeb61e8c884..c6f2154eaa4 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -17,9 +17,8 @@ use rustc::ty::{self, TyCtxt, RegionKind}; use rustc::hir; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::middle::region; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct AddValidation; @@ -107,8 +106,9 @@ fn fn_contains_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource) -> } } - let fn_like = match src { - MirSource::Fn(node_id) => { + let node_id = tcx.hir.as_local_node_id(src.def_id).unwrap(); + let fn_like = match tcx.hir.body_owner_kind(node_id) { + hir::BodyOwnerKind::Fn => { match FnLikeNode::from_node(tcx.hir.get(node_id)) { Some(fn_like) => fn_like, None => return false, // e.g. struct ctor shims -- such auto-generated code cannot diff --git a/src/librustc_mir/transform/clean_end_regions.rs b/src/librustc_mir/transform/clean_end_regions.rs index 1096d26213b..7986313aa81 100644 --- a/src/librustc_mir/transform/clean_end_regions.rs +++ b/src/librustc_mir/transform/clean_end_regions.rs @@ -22,11 +22,10 @@ use rustc_data_structures::fx::FxHashSet; use rustc::middle::region; -use rustc::mir::transform::MirSource; use rustc::mir::{BasicBlock, Location, Mir, Rvalue, Statement, StatementKind}; use rustc::mir::visit::{MutVisitor, Visitor, TyContext}; use rustc::ty::{Ty, RegionKind, TyCtxt}; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct CleanEndRegions; diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index ea72125274c..2966290c296 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -29,11 +29,11 @@ //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the //! future. +use rustc::hir; use rustc::mir::{Constant, Local, LocalKind, Location, Lvalue, Mir, Operand, Rvalue, StatementKind}; -use rustc::mir::transform::MirSource; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; -use transform::MirPass; +use transform::{MirPass, MirSource}; use util::def_use::DefUseAnalysis; pub struct CopyPropagation; @@ -43,19 +43,17 @@ impl MirPass for CopyPropagation { tcx: TyCtxt<'a, 'tcx, 'tcx>, source: MirSource, mir: &mut Mir<'tcx>) { - match source { - MirSource::Const(_) => { - // Don't run on constants, because constant qualification might reject the - // optimized IR. - return - } - MirSource::Static(..) | MirSource::Promoted(..) => { - // Don't run on statics and promoted statics, because trans might not be able to - // evaluate the optimized IR. - return - } - MirSource::Fn(function_node_id) => { - if tcx.is_const_fn(tcx.hir.local_def_id(function_node_id)) { + // Don't run on constant MIR, because trans might not be able to + // evaluate the modified MIR. + // FIXME(eddyb) Remove check after miri is merged. + let id = tcx.hir.as_local_node_id(source.def_id).unwrap(); + match (tcx.hir.body_owner_kind(id), source.promoted) { + (_, Some(_)) | + (hir::BodyOwnerKind::Const, _) | + (hir::BodyOwnerKind::Static(_), _) => return, + + (hir::BodyOwnerKind::Fn, _) => { + if tcx.is_const_fn(source.def_id) { // Don't run on const functions, as, again, trans might not be able to evaluate // the optimized IR. return diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index d74a5971f9f..61b4716c564 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc::hir; use rustc::ty::TyCtxt; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc_data_structures::indexed_vec::Idx; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct Deaggregator; @@ -21,16 +21,21 @@ impl MirPass for Deaggregator { tcx: TyCtxt<'a, 'tcx, 'tcx>, source: MirSource, mir: &mut Mir<'tcx>) { - let node_id = source.item_id(); - let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id)); + let node_path = tcx.item_path_str(source.def_id); debug!("running on: {:?}", node_path); // we only run when mir_opt_level > 2 if tcx.sess.opts.debugging_opts.mir_opt_level <= 2 { return; } - // Do not trigger on constants. Could be revised in future - if let MirSource::Fn(_) = source {} else { return; } + // Don't run on constant MIR, because trans might not be able to + // evaluate the modified MIR. + // FIXME(eddyb) Remove check after miri is merged. + let id = tcx.hir.as_local_node_id(source.def_id).unwrap(); + match (tcx.hir.body_owner_kind(id), source.promoted) { + (hir::BodyOwnerKind::Fn, None) => {}, + _ => return + } // In fact, we might not want to trigger in other cases. // Ex: when we could use SROA. See issue #35259 diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index 37ec1efa5ce..98753eaa5a3 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -16,10 +16,9 @@ use std::fs::File; use std::io; use rustc::mir::Mir; -use rustc::mir::transform::MirSource; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::TyCtxt; -use transform::MirPass; +use transform::{MirPass, MirSource}; use util as mir_util; pub struct Marker(pub &'static str); diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index a900a0146ab..c24256cc92c 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -15,14 +15,14 @@ use dataflow::{on_all_children_bits, on_all_drop_children_bits}; use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits}; use dataflow::MoveDataParamEnv; use dataflow; +use rustc::hir; use rustc::ty::{self, TyCtxt}; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::middle::const_val::ConstVal; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_data_structures::indexed_vec::Idx; -use transform::MirPass; +use transform::{MirPass, MirSource}; use util::patch::MirPatch; use util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop}; use util::elaborate_drops::{DropElaborator, DropStyle, DropFlagMode}; @@ -40,12 +40,16 @@ impl MirPass for ElaborateDrops { mir: &mut Mir<'tcx>) { debug!("elaborate_drops({:?} @ {:?})", src, mir.span); - match src { - MirSource::Fn(..) => {}, + + // Don't run on constant MIR, because trans might not be able to + // evaluate the modified MIR. + // FIXME(eddyb) Remove check after miri is merged. + let id = tcx.hir.as_local_node_id(src.def_id).unwrap(); + match (tcx.hir.body_owner_kind(id), src.promoted) { + (hir::BodyOwnerKind::Fn, None) => {}, _ => return } - let id = src.item_id(); - let param_env = tcx.param_env(tcx.hir.local_def_id(id)); + let param_env = tcx.param_env(src.def_id); let move_data = MoveData::gather_moves(mir, tcx, param_env).unwrap(); let elaborate_patch = { let mir = &*mir; diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 85193487ee3..dfa048e2e4b 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -18,8 +18,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, TyContext}; -use rustc::mir::transform::MirSource; -use transform::MirPass; +use transform::{MirPass, MirSource}; struct EraseRegionsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index e1adc4fab1d..7d12d50355b 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -63,7 +63,6 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::mir::visit::{LvalueContext, Visitor, MutVisitor}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior}; use rustc::ty::subst::{Kind, Substs}; @@ -76,7 +75,7 @@ use std::collections::HashMap; use std::borrow::Cow; use std::iter::once; use std::mem; -use transform::MirPass; +use transform::{MirPass, MirSource}; use transform::simplify; use transform::no_landing_pads::no_landing_pads; use dataflow::{self, MaybeStorageLive, state_for_location}; @@ -339,7 +338,7 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (liveness::LocalSet, HashMap) { let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len()); - let node_id = source.item_id(); + let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap(); let analysis = MaybeStorageLive::new(mir); let storage_live = dataflow::do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, analysis, @@ -764,8 +763,8 @@ impl MirPass for StateTransform { assert!(mir.generator_drop.is_none()); - let node_id = source.item_id(); - let def_id = tcx.hir.local_def_id(source.item_id()); + let def_id = source.def_id; + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let hir_id = tcx.hir.node_to_hir_id(node_id); // Get the interior types which typeck computed diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 2e973ec4a92..5dec6177b36 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -10,19 +10,19 @@ //! Inlining pass for MIR functions +use rustc::hir; use rustc::hir::def_id::DefId; use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::mir::visit::*; use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; -use transform::MirPass; +use transform::{MirPass, MirSource}; use super::simplify::{remove_dead_blocks, CfgSimplifier}; use syntax::{attr}; @@ -78,12 +78,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let mut callsites = VecDeque::new(); - let param_env; + let param_env = self.tcx.param_env(self.source.def_id); // Only do inlining into fn bodies. - if let MirSource::Fn(caller_id) = self.source { - let caller_def_id = self.tcx.hir.local_def_id(caller_id); - param_env = self.tcx.param_env(caller_def_id); + let id = self.tcx.hir.as_local_node_id(self.source.def_id).unwrap(); + let body_owner_kind = self.tcx.hir.body_owner_kind(id); + if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) { for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() { // Don't inline calls that are in cleanup blocks. @@ -252,8 +252,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // FIXME: Give a bonus to functions with only a single caller - let def_id = tcx.hir.local_def_id(self.source.item_id()); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env(self.source.def_id); let mut first_block = true; let mut cost = 0; diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 083185cc93f..b091f2f4b6d 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -11,13 +11,12 @@ //! Performs various peephole optimizations. use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local}; -use rustc::mir::transform::MirSource; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::TyCtxt; use rustc::util::nodemap::FxHashSet; use rustc_data_structures::indexed_vec::Idx; use std::mem; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct InstCombine; diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 9b79e7aa114..441f9be9be1 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -10,8 +10,7 @@ use build; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc::mir::Mir; -use rustc::mir::transform::MirSource; +use rustc::mir::{Mir, Promoted}; use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc::ty::steal::Steal; @@ -108,6 +107,24 @@ fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea tcx.alloc_steal_mir(mir) } +/// Where a specific Mir comes from. +#[derive(Debug, Copy, Clone)] +pub struct MirSource { + pub def_id: DefId, + + /// If `Some`, this is a promoted rvalue within the parent function. + pub promoted: Option, +} + +impl MirSource { + pub fn item(def_id: DefId) -> Self { + MirSource { + def_id, + promoted: None + } + } +} + /// Generates a default name for the pass based on the name of the /// type `T`. pub fn default_name() -> Cow<'static, str> { @@ -133,9 +150,13 @@ pub trait MirPass { mir: &mut Mir<'tcx>); } -pub macro run_passes($tcx:ident, $mir:ident, $source:ident, $suite_index:expr; $($pass:expr,)*) {{ +pub macro run_passes($tcx:ident, $mir:ident, $def_id:ident, $suite_index:expr; $($pass:expr,)*) {{ let suite_index: usize = $suite_index; - let run_passes = |mir: &mut _, source| { + let run_passes = |mir: &mut _, promoted| { + let source = MirSource { + def_id: $def_id, + promoted + }; let mut index = 0; let mut run_pass = |pass: &MirPass| { let run_hooks = |mir: &_, index, is_after| { @@ -150,10 +171,11 @@ pub macro run_passes($tcx:ident, $mir:ident, $source:ident, $suite_index:expr; $ }; $(run_pass(&$pass);)* }; - run_passes(&mut $mir, $source); + + run_passes(&mut $mir, None); for (index, promoted_mir) in $mir.promoted.iter_enumerated_mut() { - run_passes(promoted_mir, MirSource::Promoted($source.item_id(), index)); + run_passes(promoted_mir, Some(index)); // Let's make sure we don't miss any nested instances assert!(promoted_mir.promoted.is_empty()); @@ -165,8 +187,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea let _ = tcx.unsafety_check_result(def_id); let mut mir = tcx.mir_built(def_id).steal(); - let source = MirSource::from_local_def_id(tcx, def_id); - run_passes![tcx, mir, source, 0; + run_passes![tcx, mir, def_id, 0; // Remove all `EndRegion` statements that are not involved in borrows. clean_end_regions::CleanEndRegions, @@ -179,15 +200,15 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea } fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal> { - let source = MirSource::from_local_def_id(tcx, def_id); - if let MirSource::Const(_) = source { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + if let hir::BodyOwnerKind::Const = tcx.hir.body_owner_kind(node_id) { // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. let _ = tcx.mir_const_qualif(def_id); } let mut mir = tcx.mir_const(def_id).steal(); - run_passes![tcx, mir, source, 1; + run_passes![tcx, mir, def_id, 1; // What we need to run borrowck etc. qualify_consts::QualifyAndPromoteConstants, simplify::SimplifyCfg::new("qualify-consts"), @@ -202,8 +223,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx let _ = tcx.borrowck(def_id); let mut mir = tcx.mir_validated(def_id).steal(); - let source = MirSource::from_local_def_id(tcx, def_id); - run_passes![tcx, mir, source, 2; + run_passes![tcx, mir, def_id, 2; no_landing_pads::NoLandingPads, simplify_branches::SimplifyBranches::new("initial"), diff --git a/src/librustc_mir/transform/nll/constraint_generation.rs b/src/librustc_mir/transform/nll/constraint_generation.rs index a2f9bbb174e..b095a198d8f 100644 --- a/src/librustc_mir/transform/nll/constraint_generation.rs +++ b/src/librustc_mir/transform/nll/constraint_generation.rs @@ -10,7 +10,6 @@ use rustc::hir; use rustc::mir::{BasicBlock, BorrowKind, Location, Lvalue, Mir, Rvalue, Statement, StatementKind}; -use rustc::mir::transform::MirSource; use rustc::mir::visit::Visitor; use rustc::mir::Lvalue::Projection; use rustc::mir::{LvalueProjection, ProjectionElem}; @@ -31,7 +30,7 @@ pub(super) fn generate_constraints<'a, 'gcx, 'tcx>( infcx: &InferCtxt<'a, 'gcx, 'tcx>, regioncx: &mut RegionInferenceContext<'tcx>, mir: &Mir<'tcx>, - mir_source: MirSource, + param_env: ty::ParamEnv<'tcx>, liveness: &LivenessResults, ) { ConstraintGeneration { @@ -39,7 +38,7 @@ pub(super) fn generate_constraints<'a, 'gcx, 'tcx>( regioncx, mir, liveness, - mir_source, + param_env, }.add_constraints(); } @@ -48,7 +47,7 @@ struct ConstraintGeneration<'cx, 'gcx: 'tcx, 'tcx: 'cx> { regioncx: &'cx mut RegionInferenceContext<'tcx>, mir: &'cx Mir<'tcx>, liveness: &'cx LivenessResults, - mir_source: MirSource, + param_env: ty::ParamEnv<'tcx>, } impl<'cx, 'gcx, 'tcx> ConstraintGeneration<'cx, 'gcx, 'tcx> { @@ -153,13 +152,11 @@ impl<'cx, 'gcx, 'tcx> ConstraintGeneration<'cx, 'gcx, 'tcx> { // `dtorck_constraint_for_ty` could not resolve (e.g., // associated types and parameters). We need to normalize // associated types here and possibly recursively process. - let def_id = tcx.hir.local_def_id(self.mir_source.item_id()); - let param_env = self.infcx.tcx.param_env(def_id); for ty in dtorck_types { // FIXME -- I think that this may disregard some region obligations // or something. Do we care? -nmatsakis let cause = ObligationCause::dummy(); - match traits::fully_normalize(self.infcx, cause, param_env, &ty) { + match traits::fully_normalize(self.infcx, cause, self.param_env, &ty) { Ok(ty) => match ty.sty { ty::TyParam(..) | ty::TyProjection(..) | ty::TyAnon(..) => { self.add_regular_live_constraint(ty, location); diff --git a/src/librustc_mir/transform/nll/free_regions.rs b/src/librustc_mir/transform/nll/free_regions.rs index 006a2f9047a..554d212880e 100644 --- a/src/librustc_mir/transform/nll/free_regions.rs +++ b/src/librustc_mir/transform/nll/free_regions.rs @@ -22,9 +22,9 @@ //! The code in this file doesn't *do anything* with those results; it //! just returns them for other code to use. +use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; use rustc::middle::free_region::FreeRegionMap; -use rustc::mir::transform::MirSource; use rustc::ty; use rustc::ty::subst::Substs; use rustc::util::nodemap::FxHashMap; @@ -43,12 +43,9 @@ pub struct FreeRegions<'tcx> { pub fn free_regions<'a, 'gcx, 'tcx>( infcx: &InferCtxt<'a, 'gcx, 'tcx>, - source: MirSource, + item_def_id: DefId, ) -> FreeRegions<'tcx> { - debug!("free_regions(source={:?})", source); - - let item_id = source.item_id(); - let item_def_id = infcx.tcx.hir.local_def_id(item_id); + debug!("free_regions(item_def_id={:?})", item_def_id); let mut indices = FxHashMap(); @@ -63,6 +60,7 @@ pub fn free_regions<'a, 'gcx, 'tcx>( // Extract the late-bound regions. Use the liberated fn sigs, // where the late-bound regions will have been converted into free // regions, and add them to the map. + let item_id = infcx.tcx.hir.as_local_node_id(item_def_id).unwrap(); let fn_hir_id = infcx.tcx.hir.node_to_hir_id(item_id); let tables = infcx.tcx.typeck_tables_of(item_def_id); let fn_sig = tables.liberated_fn_sigs()[fn_hir_id].clone(); diff --git a/src/librustc_mir/transform/nll/mod.rs b/src/librustc_mir/transform/nll/mod.rs index e24def2292e..f27d0a8da16 100644 --- a/src/librustc_mir/transform/nll/mod.rs +++ b/src/librustc_mir/transform/nll/mod.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::ty::{self, RegionKind}; +use rustc::hir::def_id::DefId; use rustc::mir::Mir; -use rustc::mir::transform::MirSource; use rustc::infer::InferCtxt; +use rustc::ty::{self, RegionKind}; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use std::collections::BTreeSet; +use transform::MirSource; use util::liveness::{self, LivenessMode, LivenessResult, LocalSet}; use util as mir_util; @@ -34,11 +35,11 @@ mod renumber; /// This may result in errors being reported. pub fn compute_regions<'a, 'gcx, 'tcx>( infcx: &InferCtxt<'a, 'gcx, 'tcx>, - source: MirSource, + def_id: DefId, mir: &mut Mir<'tcx>, ) -> RegionInferenceContext<'tcx> { // Compute named region information. - let free_regions = &free_regions::free_regions(infcx, source); + let free_regions = &free_regions::free_regions(infcx, def_id); // Replace all regions with fresh inference variables. let num_region_variables = renumber::renumber_mir(infcx, free_regions, mir); @@ -65,12 +66,13 @@ pub fn compute_regions<'a, 'gcx, 'tcx>( // Create the region inference context, generate the constraints, // and then solve them. let mut regioncx = RegionInferenceContext::new(free_regions, num_region_variables, mir); - constraint_generation::generate_constraints(infcx, &mut regioncx, &mir, source, liveness); + let param_env = infcx.tcx.param_env(def_id); + constraint_generation::generate_constraints(infcx, &mut regioncx, &mir, param_env, liveness); regioncx.solve(infcx, &mir); // Dump MIR results into a file, if that is enabled. This let us // write unit-tests. - dump_mir_results(infcx, liveness, source, &mir, ®ioncx); + dump_mir_results(infcx, liveness, MirSource::item(def_id), &mir, ®ioncx); regioncx } diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 60f902361d9..dd5898cb561 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -14,8 +14,7 @@ use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::visit::MutVisitor; -use rustc::mir::transform::MirSource; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct NoLandingPads; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 318406549ac..ab29134c325 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -26,7 +26,6 @@ use rustc::ty::cast::CastTy; use rustc::ty::maps::Providers; use rustc::mir::*; use rustc::mir::traversal::ReversePostorder; -use rustc::mir::transform::MirSource; use rustc::mir::visit::{LvalueContext, Visitor}; use rustc::middle::lang_items; use syntax::abi::Abi; @@ -38,7 +37,7 @@ use std::fmt; use std::rc::Rc; use std::usize; -use transform::MirPass; +use transform::{MirPass, MirSource}; use super::promote_consts::{self, Candidate, TempState}; bitflags! { @@ -962,24 +961,27 @@ impl MirPass for QualifyAndPromoteConstants { return; } - let id = src.item_id(); - let def_id = tcx.hir.local_def_id(id); + if src.promoted.is_some() { + return; + } + + let def_id = src.def_id; + let id = tcx.hir.as_local_node_id(def_id).unwrap(); let mut const_promoted_temps = None; - let mode = match src { - MirSource::Fn(_) => { + let mode = match tcx.hir.body_owner_kind(id) { + hir::BodyOwnerKind::Fn => { if tcx.is_const_fn(def_id) { Mode::ConstFn } else { Mode::Fn } } - MirSource::Const(_) => { + hir::BodyOwnerKind::Const => { const_promoted_temps = Some(tcx.mir_const_qualif(def_id).1); Mode::Const } - MirSource::Static(_, hir::MutImmutable) => Mode::Static, - MirSource::Static(_, hir::MutMutable) => Mode::StaticMut, - MirSource::Promoted(..) => return + hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static, + hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut, }; if mode == Mode::Fn || mode == Mode::ConstFn { diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index c14587d3087..32d4a14c7f7 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -14,10 +14,9 @@ use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; use rustc::mir::{self, Mir, Location}; -use rustc::mir::transform::MirSource; use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_data_structures::indexed_vec::Idx; -use transform::MirPass; +use transform::{MirPass, MirSource}; use dataflow::do_dataflow; use dataflow::MoveDataParamEnv; @@ -35,8 +34,8 @@ pub struct SanityCheck; impl MirPass for SanityCheck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { - let id = src.item_id(); - let def_id = tcx.hir.local_def_id(id); + let def_id = src.def_id; + let id = tcx.hir.as_local_node_id(def_id).unwrap(); if !tcx.has_attr(def_id, "rustc_mir_borrowck") { debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id)); return; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index d63a693443b..02ae6328461 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -41,10 +41,9 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::ty::TyCtxt; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::mir::visit::{MutVisitor, Visitor, LvalueContext}; use std::borrow::Cow; -use transform::MirPass; +use transform::{MirPass, MirSource}; pub struct SimplifyCfg { label: String } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 208509fb368..20c33bab1aa 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -12,9 +12,8 @@ use rustc::ty::{self, TyCtxt}; use rustc::middle::const_val::ConstVal; -use rustc::mir::transform::MirSource; use rustc::mir::*; -use transform::MirPass; +use transform::{MirPass, MirSource}; use std::borrow::Cow; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 9d6df524699..dc462cd9c74 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -18,12 +18,11 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants}; use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::tcx::LvalueTy; -use rustc::mir::transform::MirSource; use rustc::mir::visit::Visitor; use std::fmt; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; -use transform::MirPass; +use transform::{MirPass, MirSource}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::Idx; @@ -795,8 +794,8 @@ impl MirPass for TypeckMir { tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { - let item_id = src.item_id(); - let def_id = tcx.hir.local_def_id(item_id); + let def_id = src.def_id; + let id = tcx.hir.as_local_node_id(def_id).unwrap(); debug!("run_pass: {:?}", def_id); if tcx.sess.err_count() > 0 { @@ -806,7 +805,7 @@ impl MirPass for TypeckMir { } let param_env = tcx.param_env(def_id); tcx.infer_ctxt().enter(|infcx| { - let mut checker = TypeChecker::new(&infcx, item_id, param_env); + let mut checker = TypeChecker::new(&infcx, id, param_env); { let mut verifier = TypeVerifier::new(&mut checker, mir); verifier.visit_mir(mir); diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index a38d317b823..b3c7b4bce03 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -14,7 +14,6 @@ use rustc::mir::*; use rustc::ty::TyCtxt; use std::fmt::Debug; use std::io::{self, Write}; -use syntax::ast::NodeId; use rustc_data_structures::indexed_vec::Idx; @@ -28,21 +27,20 @@ pub fn write_mir_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, where W: Write { for def_id in dump_mir_def_ids(tcx, single) { - let nodeid = tcx.hir.as_local_node_id(def_id).unwrap(); let mir = &tcx.optimized_mir(def_id); - write_mir_fn_graphviz(tcx, nodeid, mir, w)?; + write_mir_fn_graphviz(tcx, def_id, mir, w)?; } Ok(()) } /// Write a graphviz DOT graph of the MIR. pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, - nodeid: NodeId, + def_id: DefId, mir: &Mir, w: &mut W) -> io::Result<()> where W: Write { - writeln!(w, "digraph Mir_{} {{", nodeid)?; + writeln!(w, "digraph Mir_{} {{", tcx.hir.as_local_node_id(def_id).unwrap())?; // Global graph properties writeln!(w, r#" graph [fontname="monospace"];"#)?; @@ -50,7 +48,7 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>, writeln!(w, r#" edge [fontname="monospace"];"#)?; // Graph label - write_graph_label(tcx, nodeid, mir, w)?; + write_graph_label(tcx, def_id, mir, w)?; // Nodes for (block, _) in mir.basic_blocks().iter_enumerated() { @@ -138,11 +136,11 @@ fn write_edges(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result /// will appear below the graph, showing the type of the `fn` this MIR represents and the types of /// all the variables and temporaries. fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - nid: NodeId, + def_id: DefId, mir: &Mir, w: &mut W) -> io::Result<()> { - write!(w, " label=; @@ -357,7 +357,7 @@ pub fn dump_mir<'a, 'tcx>( } let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(tcx.hir.local_def_id(source.item_id())) + tcx.item_path_str(source.def_id) }); dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result); } @@ -375,7 +375,8 @@ fn dump_matched_mir_node<'a, 'tcx>( let p = Path::new(file_dir); file_path.push(p); }; - let file_name = format!("rustc.node{}{}-liveness.mir", source.item_id(), pass_name); + let item_id = tcx.hir.as_local_node_id(source.def_id).unwrap(); + let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name); file_path.push(&file_name); let _ = fs::File::create(&file_path).and_then(|mut file| { writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?; diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 95df07f06f4..5dc7a324c2d 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -11,7 +11,6 @@ use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::*; -use rustc::mir::transform::MirSource; use rustc::ty::TyCtxt; use rustc::ty::item_path; use rustc_data_structures::fx::FxHashMap; @@ -21,6 +20,7 @@ use std::fs; use std::io::{self, Write}; use std::path::{PathBuf, Path}; use super::graphviz::write_mir_fn_graphviz; +use transform::MirSource; const INDENT: &'static str = " "; /// Alignment for lining up comments following MIR statements @@ -71,7 +71,7 @@ where } let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(tcx.hir.local_def_id(source.item_id())) + tcx.item_path_str(source.def_id) }); dump_matched_mir_node(tcx, pass_num, pass_name, &node_path, disambiguator, source, mir, extra_data); @@ -85,9 +85,8 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, None => return false, Some(ref filters) => filters, }; - let node_id = source.item_id(); let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below - tcx.item_path_str(tcx.hir.local_def_id(node_id)) + tcx.item_path_str(source.def_id) }); filters.split("&") .any(|filter| { @@ -112,9 +111,9 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(tcx: TyCtxt<'a, 'gcx, 'tcx>, where F: FnMut(PassWhere, &mut Write) -> io::Result<()> { - let promotion_id = match source { - MirSource::Promoted(_, id) => format!("-{:?}", id), - _ => String::new() + let promotion_id = match source.promoted { + Some(id) => format!("-{:?}", id), + None => String::new() }; let pass_num = if tcx.sess.opts.debugging_opts.dump_mir_exclude_pass_number { @@ -133,11 +132,9 @@ where }; let _ = fs::create_dir_all(&file_path); - let function_name = tcx.hir.def_path_from_id(source.item_id()) - .map(|d| d.to_filename_friendly_no_crate()) - .unwrap_or(format!("node{}", source.item_id())); + let item_name = tcx.hir.def_path(source.def_id).to_filename_friendly_no_crate(); let file_name = format!("rustc.{}{}{}.{}.{}.mir", - function_name, promotion_id, pass_num, pass_name, disambiguator); + item_name, promotion_id, pass_num, pass_name, disambiguator); file_path.push(&file_name); let _ = fs::File::create(&file_path).and_then(|mut file| { writeln!(file, "// MIR for `{}`", node_path)?; @@ -157,7 +154,7 @@ where if tcx.sess.opts.debugging_opts.dump_mir_graphviz { file_path.set_extension("dot"); let _ = fs::File::create(&file_path).and_then(|mut file| { - write_mir_fn_graphviz(tcx, source.item_id(), mir, &mut file)?; + write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?; Ok(()) }); } @@ -183,13 +180,15 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, writeln!(w, "")?; } - let id = tcx.hir.as_local_node_id(def_id).unwrap(); - let src = MirSource::from_node(tcx, id); - write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?; + write_mir_fn(tcx, MirSource::item(def_id), mir, &mut |_, _| Ok(()), w)?; for (i, mir) in mir.promoted.iter_enumerated() { writeln!(w, "")?; - write_mir_fn(tcx, MirSource::Promoted(id, i), mir, &mut |_, _| Ok(()), w)?; + let src = MirSource { + def_id, + promoted: Some(i) + }; + write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?; } } Ok(()) @@ -367,20 +366,22 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) -> io::Result<()> { - match src { - MirSource::Fn(_) => write!(w, "fn")?, - MirSource::Const(_) => write!(w, "const")?, - MirSource::Static(_, hir::MutImmutable) => write!(w, "static")?, - MirSource::Static(_, hir::MutMutable) => write!(w, "static mut")?, - MirSource::Promoted(_, i) => write!(w, "{:?} in", i)?, + let id = tcx.hir.as_local_node_id(src.def_id).unwrap(); + let body_owner_kind = tcx.hir.body_owner_kind(id); + match (body_owner_kind, src.promoted) { + (_, Some(i)) => write!(w, "{:?} in", i)?, + (hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?, + (hir::BodyOwnerKind::Const, _) => write!(w, "const")?, + (hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?, + (hir::BodyOwnerKind::Static(hir::MutMutable), _) => write!(w, "static mut")?, } item_path::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere - write!(w, " {}", tcx.node_path_str(src.item_id())) + write!(w, " {}", tcx.item_path_str(src.def_id)) })?; - match src { - MirSource::Fn(_) => { + match (body_owner_kind, src.promoted) { + (hir::BodyOwnerKind::Fn, None) => { write!(w, "(")?; // fn argument types. @@ -393,9 +394,9 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) write!(w, ") -> {}", mir.return_ty) } - MirSource::Const(..) | - MirSource::Static(..) | - MirSource::Promoted(..) => { + (hir::BodyOwnerKind::Const, _) | + (hir::BodyOwnerKind::Static(_), _) | + (_, Some(_)) => { assert_eq!(mir.arg_count, 0); write!(w, ": {} =", mir.return_ty) } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 4515d9c7837..776b5f3c984 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -37,7 +37,6 @@ use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; use rustc::middle::mem_categorization::Categorization; -use rustc::mir::transform::MirSource; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::{queries, Providers}; use rustc::ty::subst::Substs; @@ -184,9 +183,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> { self.in_fn = false; self.in_static = false; - match MirSource::from_node(self.tcx, item_id) { - MirSource::Fn(_) => self.in_fn = true, - MirSource::Static(_, _) => self.in_static = true, + match self.tcx.hir.body_owner_kind(item_id) { + hir::BodyOwnerKind::Fn => self.in_fn = true, + hir::BodyOwnerKind::Static(_) => self.in_static = true, _ => {} };