})
}
+ 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,
}
}
+#[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 {
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};
// 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
mod cache;
pub mod tcx;
pub mod visit;
-pub mod transform;
pub mod traversal;
/// Types for locals
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
- }
- }
-}
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};
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") &&
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,
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 };
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;
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.
_ => 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);
mem::transmute::<Mir, Mir<'tcx>>(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
})
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();
mem::transmute::<Mir, Mir<'tcx>>(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
})
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;
/// When building statics/constants, returns `None` since
/// intermediate values do not have to be dropped in that case.
pub fn local_scope(&self) -> Option<region::Scope> {
- 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!(),
}
}
//!
use hair::*;
-use rustc::mir::transform::MirSource;
use rustc::middle::const_val::{ConstEvalErr, ConstVal};
use rustc_const_eval::ConstContext;
/// `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,
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,
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,
}
}
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;
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);
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
sig.inputs().len(),
vec![],
span
- );
- (mir, MirSource::Fn(ctor_id))
+ )
}
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 {
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;
}
}
- 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
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;
//! (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;
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
// 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;
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
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);
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};
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;
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>,
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};
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};
(liveness::LocalSet,
HashMap<BasicBlock, liveness::LocalSet>) {
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,
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
//! 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};
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.
// 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;
//! 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;
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;
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<Promoted>,
+}
+
+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<T: ?Sized>() -> Cow<'static, str> {
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| {
};
$(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());
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,
}
fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
- 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"),
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"),
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};
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
regioncx: &mut RegionInferenceContext<'tcx>,
mir: &Mir<'tcx>,
- mir_source: MirSource,
+ param_env: ty::ParamEnv<'tcx>,
liveness: &LivenessResults,
) {
ConstraintGeneration {
regioncx,
mir,
liveness,
- mir_source,
+ param_env,
}.add_constraints();
}
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> {
// `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);
//! 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;
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();
// 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();
// 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;
/// 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);
// 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
}
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;
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;
use std::rc::Rc;
use std::usize;
-use transform::MirPass;
+use transform::{MirPass, MirSource};
use super::promote_consts::{self, Candidate, TempState};
bitflags! {
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 {
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;
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;
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 }
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;
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;
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 {
}
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);
use rustc::ty::TyCtxt;
use std::fmt::Debug;
use std::io::{self, Write};
-use syntax::ast::NodeId;
use rustc_data_structures::indexed_vec::Idx;
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"];"#)?;
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() {
/// 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=<fn {}(", dot::escape_html(&tcx.node_path_str(nid)))?;
+ write!(w, " label=<fn {}(", dot::escape_html(&tcx.item_path_str(def_id)))?;
// fn argument types.
for (i, arg) in mir.args_iter().enumerate() {
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::indexed_set::IdxSetBuf;
use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
-use rustc::mir::transform::MirSource;
use rustc::ty::item_path;
use std::path::{Path, PathBuf};
use std::fs;
use rustc::ty::TyCtxt;
use std::io::{self, Write};
+use transform::MirSource;
pub type LocalSet = IdxSetBuf<Local>;
}
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);
}
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)?;
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;
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
}
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);
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| {
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 {
};
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)?;
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(())
});
}
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(())
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.
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)
}
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;
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,
_ => {}
};