Auto merge of #37400 - eddyb:lazy-1, r=nikomatsakis
[1/n] Move the MIR map into the type context. *This is part of a series ([prev]() | [next](https://github.com/rust-lang/rust/pull/37401)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments.* <hr> The first commit reorganizes the `rustc::mir` module to contain the MIR types directly without an extraneous `repr` module which serves no practical purpose but is rather an eyesore. The second commit performs the actual move of the MIR map into the type context, for the purposes of future integration with requesting analysis/lowering by-products through `TyCtxt`. Local `Mir` bodies need to be mutated by passes (hence `RefCell`), and at least one pass (`qualify_consts`) needs simultaneous access to multiple `Mir` bodies (hence arena-allocation). `Mir` bodies loaded from other crates appear as if immutably borrowed (by `.borrow()`-ing one `Ref` and subsequently "leaking" it) to avoid, at least dynamically, *any* possibility of their local mutation. One caveat is that lint passes can now snoop at the MIR (helpful) or even mutate it (dangerous). However, lints are unstable anyway and we can find a way to deal with this in due time. Future work will result in a tighter API, potentially hiding mutation *completely* outside of MIR passes.
This commit is contained in:
commit
ef6f743407
@ -105,16 +105,7 @@ pub mod middle {
|
||||
pub mod weak_lang_items;
|
||||
}
|
||||
|
||||
pub mod mir {
|
||||
mod cache;
|
||||
pub mod repr;
|
||||
pub mod tcx;
|
||||
pub mod visit;
|
||||
pub mod transform;
|
||||
pub mod traversal;
|
||||
pub mod mir_map;
|
||||
}
|
||||
|
||||
pub mod mir;
|
||||
pub mod session;
|
||||
pub mod traits;
|
||||
pub mod ty;
|
||||
|
@ -29,8 +29,7 @@
|
||||
use hir::svh::Svh;
|
||||
use middle::lang_items;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use mir::repr::Mir;
|
||||
use mir::mir_map::MirMap;
|
||||
use mir::Mir;
|
||||
use session::Session;
|
||||
use session::search_paths::PathKind;
|
||||
use util::nodemap::{NodeSet, DefIdMap};
|
||||
@ -209,8 +208,7 @@ fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
|
||||
fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
|
||||
|
||||
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> Option<Mir<'tcx>>;
|
||||
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
|
||||
fn is_item_mir_available(&self, def: DefId) -> bool;
|
||||
|
||||
// This is basically a 1-based range of ints, which is a little
|
||||
@ -228,8 +226,7 @@ fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>) -> Vec<u8>;
|
||||
reachable: &NodeSet) -> Vec<u8>;
|
||||
fn metadata_encoding_version(&self) -> &[u8];
|
||||
}
|
||||
|
||||
@ -390,8 +387,8 @@ fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
|
||||
bug!("defid_for_inlined_node")
|
||||
}
|
||||
|
||||
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
|
||||
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> Mir<'tcx> { bug!("get_item_mir") }
|
||||
fn is_item_mir_available(&self, def: DefId) -> bool {
|
||||
bug!("is_item_mir_available")
|
||||
}
|
||||
@ -412,8 +409,7 @@ fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>) -> Vec<u8> { vec![] }
|
||||
reachable: &NodeSet) -> Vec<u8> { vec![] }
|
||||
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
use std::cell::{Ref, RefCell};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
|
||||
use mir::repr::{Mir, BasicBlock};
|
||||
use mir::{Mir, BasicBlock};
|
||||
|
||||
use rustc_serialize as serialize;
|
||||
|
||||
|
@ -1,38 +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 <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.
|
||||
|
||||
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
|
||||
use hir::def_id::DefId;
|
||||
use mir::repr::Mir;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct MirMap<'tcx> {
|
||||
pub map: DepTrackingMap<MirMapConfig<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> MirMap<'tcx> {
|
||||
pub fn new(graph: DepGraph) -> Self {
|
||||
MirMap {
|
||||
map: DepTrackingMap::new(graph)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MirMapConfig<'tcx> {
|
||||
data: PhantomData<&'tcx ()>
|
||||
}
|
||||
|
||||
impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> {
|
||||
type Key = DefId;
|
||||
type Value = Mir<'tcx>;
|
||||
fn to_dep_node(key: &DefId) -> DepNode<DefId> {
|
||||
DepNode::Mir(*key)
|
||||
}
|
||||
}
|
@ -32,7 +32,11 @@
|
||||
use syntax::ast::{self, Name};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use super::cache::Cache;
|
||||
mod cache;
|
||||
pub mod tcx;
|
||||
pub mod visit;
|
||||
pub mod transform;
|
||||
pub mod traversal;
|
||||
|
||||
macro_rules! newtype_index {
|
||||
($name:ident, $debug_name:expr) => (
|
||||
@ -106,7 +110,7 @@ pub struct Mir<'tcx> {
|
||||
pub span: Span,
|
||||
|
||||
/// A cache for various calculations
|
||||
cache: Cache
|
||||
cache: cache::Cache
|
||||
}
|
||||
|
||||
/// where execution begins
|
||||
@ -137,7 +141,7 @@ pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
|
||||
upvar_decls: upvar_decls,
|
||||
spread_arg: None,
|
||||
span: span,
|
||||
cache: Cache::new()
|
||||
cache: cache::Cache::new()
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
* building is complete.
|
||||
*/
|
||||
|
||||
use mir::repr::*;
|
||||
use mir::*;
|
||||
use ty::subst::{Subst, Substs};
|
||||
use ty::{self, AdtDef, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
|
@ -11,8 +11,7 @@
|
||||
use dep_graph::DepNode;
|
||||
use hir;
|
||||
use hir::map::DefPathData;
|
||||
use mir::mir_map::MirMap;
|
||||
use mir::repr::{Mir, Promoted};
|
||||
use mir::{Mir, Promoted};
|
||||
use ty::TyCtxt;
|
||||
use syntax::ast::NodeId;
|
||||
use util::common::time;
|
||||
@ -85,12 +84,11 @@ fn name<'a>(&self) -> Cow<'static, str> {
|
||||
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
|
||||
}
|
||||
|
||||
/// A pass which inspects the whole MirMap.
|
||||
/// A pass which inspects the whole Mir map.
|
||||
pub trait MirMapPass<'tcx>: Pass {
|
||||
fn run_pass<'a>(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
map: &mut MirMap<'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
|
||||
}
|
||||
|
||||
@ -114,13 +112,18 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
|
||||
fn run_pass<'a>(&mut self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
map: &mut MirMap<'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||
{
|
||||
let def_ids = map.map.keys();
|
||||
let def_ids = tcx.mir_map.borrow().keys();
|
||||
for def_id in def_ids {
|
||||
if !def_id.is_local() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let mir = map.map.get_mut(&def_id).unwrap();
|
||||
let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut();
|
||||
tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||
|
||||
let id = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
|
||||
@ -163,11 +166,11 @@ pub fn new() -> Passes {
|
||||
passes
|
||||
}
|
||||
|
||||
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) {
|
||||
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
|
||||
for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
|
||||
time(tcx.sess.time_passes(), &*pass.name(),
|
||||
|| pass.run_pass(tcx, map, pass_hooks));
|
||||
|| pass.run_pass(tcx, pass_hooks));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
use super::repr::*;
|
||||
use super::*;
|
||||
|
||||
/// Preorder traversal of a graph.
|
||||
///
|
||||
|
@ -12,7 +12,7 @@
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::{ClosureSubsts, Region, Ty};
|
||||
use mir::repr::*;
|
||||
use mir::*;
|
||||
use rustc_const_math::ConstUsize;
|
||||
use rustc_data_structures::tuple_slice::TupleSlice;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
@ -22,6 +22,7 @@
|
||||
use middle::region::RegionMaps;
|
||||
use middle::resolve_lifetime;
|
||||
use middle::stability;
|
||||
use mir::Mir;
|
||||
use ty::subst::{Kind, Substs};
|
||||
use traits;
|
||||
use ty::{self, TraitRef, Ty, TypeAndMut};
|
||||
@ -65,8 +66,9 @@ pub struct CtxtArenas<'tcx> {
|
||||
|
||||
// references
|
||||
generics: TypedArena<ty::Generics<'tcx>>,
|
||||
trait_defs: TypedArena<ty::TraitDef<'tcx>>,
|
||||
adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
|
||||
trait_def: TypedArena<ty::TraitDef<'tcx>>,
|
||||
adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
|
||||
mir: TypedArena<RefCell<Mir<'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> CtxtArenas<'tcx> {
|
||||
@ -81,8 +83,9 @@ pub fn new() -> CtxtArenas<'tcx> {
|
||||
layout: TypedArena::new(),
|
||||
|
||||
generics: TypedArena::new(),
|
||||
trait_defs: TypedArena::new(),
|
||||
adt_defs: TypedArena::new()
|
||||
trait_def: TypedArena::new(),
|
||||
adt_def: TypedArena::new(),
|
||||
mir: TypedArena::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,6 +361,15 @@ pub struct GlobalCtxt<'tcx> {
|
||||
|
||||
pub map: ast_map::Map<'tcx>,
|
||||
|
||||
/// Maps from the def-id of a function/method or const/static
|
||||
/// to its MIR. Mutation is done at an item granularity to
|
||||
/// allow MIR optimization passes to function and still
|
||||
/// access cross-crate MIR (e.g. inlining or const eval).
|
||||
///
|
||||
/// Note that cross-crate MIR appears to be always borrowed
|
||||
/// (in the `RefCell` sense) to prevent accidental mutation.
|
||||
pub mir_map: RefCell<DepTrackingMap<maps::Mir<'tcx>>>,
|
||||
|
||||
// Records the free variables refrenced by every closure
|
||||
// expression. Do not track deps for this, just recompute it from
|
||||
// scratch every time.
|
||||
@ -604,6 +616,10 @@ pub fn alloc_generics(self, generics: ty::Generics<'gcx>)
|
||||
self.global_interners.arenas.generics.alloc(generics)
|
||||
}
|
||||
|
||||
pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
|
||||
self.global_interners.arenas.mir.alloc(RefCell::new(mir))
|
||||
}
|
||||
|
||||
pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
|
||||
-> &'gcx ty::TraitDef<'gcx> {
|
||||
let did = def.trait_ref.def_id;
|
||||
@ -617,7 +633,7 @@ pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
|
||||
|
||||
pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
|
||||
-> &'gcx ty::TraitDef<'gcx> {
|
||||
self.global_interners.arenas.trait_defs.alloc(def)
|
||||
self.global_interners.arenas.trait_def.alloc(def)
|
||||
}
|
||||
|
||||
pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
|
||||
@ -633,7 +649,7 @@ pub fn intern_adt_def(self,
|
||||
variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
|
||||
-> ty::AdtDefMaster<'gcx> {
|
||||
let def = ty::AdtDefData::new(self, did, kind, variants);
|
||||
let interned = self.global_interners.arenas.adt_defs.alloc(def);
|
||||
let interned = self.global_interners.arenas.adt_def.alloc(def);
|
||||
self.insert_adt_def(did, interned);
|
||||
interned
|
||||
}
|
||||
@ -738,6 +754,7 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
|
||||
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||
fulfilled_predicates: RefCell::new(fulfilled_predicates),
|
||||
map: map,
|
||||
mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||
freevars: RefCell::new(freevars),
|
||||
maybe_unused_trait_imports: maybe_unused_trait_imports,
|
||||
tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
|
||||
|
@ -10,7 +10,10 @@
|
||||
|
||||
use dep_graph::{DepNode, DepTrackingMapConfig};
|
||||
use hir::def_id::DefId;
|
||||
use mir;
|
||||
use ty::{self, Ty};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use syntax::{attr, ast};
|
||||
@ -43,3 +46,4 @@ fn to_dep_node(key: &$key) -> DepNode<DefId> { DepNode::$node_name(*key) }
|
||||
dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
|
||||
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
|
||||
dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
|
||||
dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> }
|
||||
|
@ -24,6 +24,7 @@
|
||||
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
|
||||
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
|
||||
use mir::Mir;
|
||||
use traits;
|
||||
use ty;
|
||||
use ty::subst::{Subst, Substs};
|
||||
@ -34,7 +35,7 @@
|
||||
|
||||
use serialize::{self, Encodable, Encoder};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::{Cell, RefCell, Ref};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
@ -2519,6 +2520,19 @@ pub fn lookup_super_predicates(self, did: DefId) -> GenericPredicates<'gcx> {
|
||||
|| self.sess.cstore.item_super_predicates(self.global_tcx(), did))
|
||||
}
|
||||
|
||||
/// Given the did of an item, returns its MIR, borrowed immutably.
|
||||
pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
|
||||
lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || {
|
||||
let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did);
|
||||
let mir = self.alloc_mir(mir);
|
||||
|
||||
// Perma-borrow MIR from extern crates to prevent mutation.
|
||||
mem::forget(mir.borrow());
|
||||
|
||||
mir
|
||||
}).borrow()
|
||||
}
|
||||
|
||||
/// If `type_needs_drop` returns true, then `ty` is definitely
|
||||
/// non-copy and *might* have a destructor attached; if it returns
|
||||
/// false, then `ty` definitely has no destructor (i.e. no drop glue).
|
||||
|
@ -21,8 +21,8 @@
|
||||
//! `a[x]` would still overlap them both. But that is not this
|
||||
//! representation does today.)
|
||||
|
||||
use rustc::mir::repr::{Lvalue, LvalueElem};
|
||||
use rustc::mir::repr::{Operand, Projection, ProjectionElem};
|
||||
use rustc::mir::{Lvalue, LvalueElem};
|
||||
use rustc::mir::{Operand, Projection, ProjectionElem};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct AbstractOperand;
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Hook into libgraphviz for rendering dataflow graphs for MIR.
|
||||
|
||||
use syntax::ast::NodeId;
|
||||
use rustc::mir::repr::{BasicBlock, Mir};
|
||||
use rustc::mir::{BasicBlock, Mir};
|
||||
use rustc_data_structures::bitslice::bits_to_string;
|
||||
use rustc_data_structures::indexed_set::{IdxSet};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::{self, Mir, Location};
|
||||
use rustc::mir::{self, Mir, Location};
|
||||
use rustc_data_structures::bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
|
||||
use rustc_data_structures::bitslice::{BitwiseOperator};
|
||||
use rustc_data_structures::indexed_set::{IdxSet};
|
||||
@ -245,7 +245,7 @@ fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathInd
|
||||
fn statement_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -258,7 +258,7 @@ fn statement_effect(&self,
|
||||
fn terminator_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
statements_len: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -271,9 +271,9 @@ fn terminator_effect(&self,
|
||||
fn propagate_call_return(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: repr::BasicBlock,
|
||||
_dest_bb: repr::BasicBlock,
|
||||
dest_lval: &repr::Lvalue) {
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
|
||||
@ -306,7 +306,7 @@ fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathInd
|
||||
fn statement_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -319,7 +319,7 @@ fn statement_effect(&self,
|
||||
fn terminator_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
statements_len: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -332,9 +332,9 @@ fn terminator_effect(&self,
|
||||
fn propagate_call_return(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: repr::BasicBlock,
|
||||
_dest_bb: repr::BasicBlock,
|
||||
dest_lval: &repr::Lvalue) {
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 0 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
|
||||
@ -366,7 +366,7 @@ fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathInd
|
||||
fn statement_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -379,7 +379,7 @@ fn statement_effect(&self,
|
||||
fn terminator_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MovePathIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
statements_len: usize)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
@ -392,9 +392,9 @@ fn terminator_effect(&self,
|
||||
fn propagate_call_return(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
in_out: &mut IdxSet<MovePathIndex>,
|
||||
_call_bb: repr::BasicBlock,
|
||||
_dest_bb: repr::BasicBlock,
|
||||
dest_lval: &repr::Lvalue) {
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_lval to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
|
||||
@ -418,7 +418,7 @@ fn start_block_effect(&self,_move_data: &Self::Ctxt, _sets: &mut BlockSets<MoveO
|
||||
fn statement_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MoveOutIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx: usize) {
|
||||
let (tcx, mir, move_data) = (self.tcx, self.mir, &ctxt.move_data);
|
||||
let stmt = &mir[bb].statements[idx];
|
||||
@ -437,10 +437,10 @@ fn statement_effect(&self,
|
||||
}
|
||||
let bits_per_block = self.bits_per_block(ctxt);
|
||||
match stmt.kind {
|
||||
repr::StatementKind::SetDiscriminant { .. } => {
|
||||
mir::StatementKind::SetDiscriminant { .. } => {
|
||||
span_bug!(stmt.source_info.span, "SetDiscriminant should not exist in borrowck");
|
||||
}
|
||||
repr::StatementKind::Assign(ref lvalue, _) => {
|
||||
mir::StatementKind::Assign(ref lvalue, _) => {
|
||||
// assigning into this `lvalue` kills all
|
||||
// MoveOuts from it, and *also* all MoveOuts
|
||||
// for children and associated fragment sets.
|
||||
@ -453,16 +453,16 @@ fn statement_effect(&self,
|
||||
sets.kill_set.add(&moi);
|
||||
});
|
||||
}
|
||||
repr::StatementKind::StorageLive(_) |
|
||||
repr::StatementKind::StorageDead(_) |
|
||||
repr::StatementKind::Nop => {}
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn terminator_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<MoveOutIndex>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
statements_len: usize)
|
||||
{
|
||||
let (mir, move_data) = (self.mir, &ctxt.move_data);
|
||||
@ -481,9 +481,9 @@ fn terminator_effect(&self,
|
||||
fn propagate_call_return(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
in_out: &mut IdxSet<MoveOutIndex>,
|
||||
_call_bb: repr::BasicBlock,
|
||||
_dest_bb: repr::BasicBlock,
|
||||
dest_lval: &repr::Lvalue) {
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue) {
|
||||
let move_data = &ctxt.move_data;
|
||||
let bits_per_block = self.bits_per_block(ctxt);
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::{self, Mir};
|
||||
use rustc::mir::{self, Mir};
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::io;
|
||||
@ -78,14 +78,12 @@ fn build_sets(&mut self) {
|
||||
// the kill-sets.
|
||||
|
||||
{
|
||||
let sets = &mut self.flow_state.sets.for_block(repr::START_BLOCK.index());
|
||||
let sets = &mut self.flow_state.sets.for_block(mir::START_BLOCK.index());
|
||||
self.flow_state.operator.start_block_effect(&self.ctxt, sets);
|
||||
}
|
||||
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
let &repr::BasicBlockData { ref statements,
|
||||
ref terminator,
|
||||
is_cleanup: _ } = data;
|
||||
let &mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = data;
|
||||
|
||||
let sets = &mut self.flow_state.sets.for_block(bb.index());
|
||||
for j_stmt in 0..statements.len() {
|
||||
@ -122,7 +120,7 @@ fn walk_cfg(&mut self, in_out: &mut IdxSet<BD::Idx>) {
|
||||
in_out.subtract(sets.kill_set);
|
||||
}
|
||||
builder.propagate_bits_into_graph_successors_of(
|
||||
in_out, &mut self.changed, (repr::BasicBlock::new(bb_idx), bb_data));
|
||||
in_out, &mut self.changed, (mir::BasicBlock::new(bb_idx), bb_data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -336,7 +334,7 @@ pub trait BitDenotation {
|
||||
fn statement_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<Self::Idx>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx_stmt: usize);
|
||||
|
||||
/// Mutates the block-sets (the flow sets for the given
|
||||
@ -352,7 +350,7 @@ fn statement_effect(&self,
|
||||
fn terminator_effect(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
sets: &mut BlockSets<Self::Idx>,
|
||||
bb: repr::BasicBlock,
|
||||
bb: mir::BasicBlock,
|
||||
idx_term: usize);
|
||||
|
||||
/// Mutates the block-sets according to the (flow-dependent)
|
||||
@ -377,9 +375,9 @@ fn terminator_effect(&self,
|
||||
fn propagate_call_return(&self,
|
||||
ctxt: &Self::Ctxt,
|
||||
in_out: &mut IdxSet<Self::Idx>,
|
||||
call_bb: repr::BasicBlock,
|
||||
dest_bb: repr::BasicBlock,
|
||||
dest_lval: &repr::Lvalue);
|
||||
call_bb: mir::BasicBlock,
|
||||
dest_bb: mir::BasicBlock,
|
||||
dest_lval: &mir::Lvalue);
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
|
||||
@ -444,39 +442,39 @@ fn propagate_bits_into_graph_successors_of(
|
||||
&mut self,
|
||||
in_out: &mut IdxSet<D::Idx>,
|
||||
changed: &mut bool,
|
||||
(bb, bb_data): (repr::BasicBlock, &repr::BasicBlockData))
|
||||
(bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData))
|
||||
{
|
||||
match bb_data.terminator().kind {
|
||||
repr::TerminatorKind::Return |
|
||||
repr::TerminatorKind::Resume |
|
||||
repr::TerminatorKind::Unreachable => {}
|
||||
repr::TerminatorKind::Goto { ref target } |
|
||||
repr::TerminatorKind::Assert { ref target, cleanup: None, .. } |
|
||||
repr::TerminatorKind::Drop { ref target, location: _, unwind: None } |
|
||||
repr::TerminatorKind::DropAndReplace {
|
||||
mir::TerminatorKind::Return |
|
||||
mir::TerminatorKind::Resume |
|
||||
mir::TerminatorKind::Unreachable => {}
|
||||
mir::TerminatorKind::Goto { ref target } |
|
||||
mir::TerminatorKind::Assert { ref target, cleanup: None, .. } |
|
||||
mir::TerminatorKind::Drop { ref target, location: _, unwind: None } |
|
||||
mir::TerminatorKind::DropAndReplace {
|
||||
ref target, value: _, location: _, unwind: None
|
||||
} => {
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, target);
|
||||
}
|
||||
repr::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
|
||||
repr::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
|
||||
repr::TerminatorKind::DropAndReplace {
|
||||
mir::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
|
||||
mir::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
|
||||
mir::TerminatorKind::DropAndReplace {
|
||||
ref target, value: _, location: _, unwind: Some(ref unwind)
|
||||
} => {
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, target);
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
|
||||
}
|
||||
repr::TerminatorKind::If { ref targets, .. } => {
|
||||
mir::TerminatorKind::If { ref targets, .. } => {
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, &targets.0);
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, &targets.1);
|
||||
}
|
||||
repr::TerminatorKind::Switch { ref targets, .. } |
|
||||
repr::TerminatorKind::SwitchInt { ref targets, .. } => {
|
||||
mir::TerminatorKind::Switch { ref targets, .. } |
|
||||
mir::TerminatorKind::SwitchInt { ref targets, .. } => {
|
||||
for target in targets {
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, target);
|
||||
}
|
||||
}
|
||||
repr::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
|
||||
mir::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
|
||||
if let Some(ref unwind) = *cleanup {
|
||||
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
|
||||
}
|
||||
@ -494,7 +492,7 @@ fn propagate_bits_into_graph_successors_of(
|
||||
fn propagate_bits_into_entry_set_for(&mut self,
|
||||
in_out: &IdxSet<D::Idx>,
|
||||
changed: &mut bool,
|
||||
bb: &repr::BasicBlock) {
|
||||
bb: &mir::BasicBlock) {
|
||||
let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry;
|
||||
let set_changed = bitwise(entry_set.words_mut(),
|
||||
in_out.words(),
|
||||
|
@ -13,7 +13,7 @@
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::repr::{self, Mir};
|
||||
use rustc::mir::{self, Mir};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
use super::super::gather_moves::{MovePathIndex, LookupResult};
|
||||
@ -59,13 +59,11 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
ctxt: &O::Ctxt,
|
||||
results: &DataflowResults<O>,
|
||||
bb: repr::BasicBlock) where
|
||||
bb: mir::BasicBlock) where
|
||||
O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex>
|
||||
{
|
||||
let move_data = &ctxt.move_data;
|
||||
let repr::BasicBlockData { ref statements,
|
||||
ref terminator,
|
||||
is_cleanup: _ } = mir[bb];
|
||||
let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = mir[bb];
|
||||
|
||||
let (args, span) = match is_rustc_peek(tcx, terminator) {
|
||||
Some(args_and_span) => args_and_span,
|
||||
@ -73,7 +71,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
};
|
||||
assert!(args.len() == 1);
|
||||
let peek_arg_lval = match args[0] {
|
||||
repr::Operand::Consume(ref lval @ repr::Lvalue::Local(_)) => Some(lval),
|
||||
mir::Operand::Consume(ref lval @ mir::Lvalue::Local(_)) => Some(lval),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@ -103,21 +101,19 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
for (j, stmt) in statements.iter().enumerate() {
|
||||
debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
|
||||
let (lvalue, rvalue) = match stmt.kind {
|
||||
repr::StatementKind::Assign(ref lvalue, ref rvalue) => {
|
||||
mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
|
||||
(lvalue, rvalue)
|
||||
}
|
||||
repr::StatementKind::StorageLive(_) |
|
||||
repr::StatementKind::StorageDead(_) |
|
||||
repr::StatementKind::Nop => continue,
|
||||
repr::StatementKind::SetDiscriminant{ .. } =>
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::Nop => continue,
|
||||
mir::StatementKind::SetDiscriminant{ .. } =>
|
||||
span_bug!(stmt.source_info.span,
|
||||
"sanity_check should run before Deaggregator inserts SetDiscriminant"),
|
||||
};
|
||||
|
||||
if lvalue == peek_arg_lval {
|
||||
if let repr::Rvalue::Ref(_,
|
||||
repr::BorrowKind::Shared,
|
||||
ref peeking_at_lval) = *rvalue {
|
||||
if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_lval) = *rvalue {
|
||||
// Okay, our search is over.
|
||||
match move_data.rev_lookup.find(peeking_at_lval) {
|
||||
LookupResult::Exact(peek_mpi) => {
|
||||
@ -162,12 +158,12 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
terminator: &'a Option<repr::Terminator<'tcx>>)
|
||||
-> Option<(&'a [repr::Operand<'tcx>], Span)> {
|
||||
if let Some(repr::Terminator { ref kind, source_info, .. }) = *terminator {
|
||||
if let repr::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
|
||||
terminator: &'a Option<mir::Terminator<'tcx>>)
|
||||
-> Option<(&'a [mir::Operand<'tcx>], Span)> {
|
||||
if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
|
||||
if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
|
||||
{
|
||||
if let repr::Operand::Constant(ref func) = *oper
|
||||
if let mir::Operand::Constant(ref func) = *oper
|
||||
{
|
||||
if let ty::TyFnDef(def_id, _, &ty::BareFnTy { abi, .. }) = func.ty.sty
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
use super::patch::MirPatch;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::middle::lang_items;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
|
||||
use rustc::ty::{self, TyCtxt, ParameterEnvironment};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::util::nodemap::FnvHashMap;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec};
|
||||
|
||||
|
@ -17,8 +17,7 @@
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{FnKind};
|
||||
|
||||
use rustc::mir::repr;
|
||||
use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
|
||||
use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
|
||||
@ -56,15 +55,13 @@ pub struct MoveDataParamEnv<'tcx> {
|
||||
param_env: ty::ParameterEnvironment<'tcx>,
|
||||
}
|
||||
|
||||
pub fn borrowck_mir<'a, 'tcx: 'a>(
|
||||
bcx: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
fk: FnKind,
|
||||
_decl: &hir::FnDecl,
|
||||
mir: &'a Mir<'tcx>,
|
||||
body: &hir::Block,
|
||||
_sp: Span,
|
||||
id: ast::NodeId,
|
||||
attributes: &[ast::Attribute]) {
|
||||
pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
|
||||
fk: FnKind,
|
||||
_decl: &hir::FnDecl,
|
||||
body: &hir::Block,
|
||||
_sp: Span,
|
||||
id: ast::NodeId,
|
||||
attributes: &[ast::Attribute]) {
|
||||
match fk {
|
||||
FnKind::ItemFn(name, ..) |
|
||||
FnKind::Method(name, ..) => {
|
||||
@ -76,8 +73,10 @@ pub fn borrowck_mir<'a, 'tcx: 'a>(
|
||||
}
|
||||
|
||||
let tcx = bcx.tcx;
|
||||
|
||||
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
|
||||
|
||||
let mir = &tcx.item_mir(tcx.map.local_def_id(id));
|
||||
|
||||
let move_data = MoveData::gather_moves(mir, tcx, ¶m_env);
|
||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||
let flow_inits =
|
||||
@ -171,8 +170,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
|
||||
mir: &'b Mir<'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
move_data: MoveData<'tcx>,
|
||||
flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
|
||||
flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>
|
||||
flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
|
||||
flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
|
||||
}
|
||||
|
||||
impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
|
||||
@ -214,12 +213,12 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
path: MovePathIndex,
|
||||
mut cond: F)
|
||||
-> Option<MovePathIndex>
|
||||
where F: FnMut(&repr::LvalueProjection<'tcx>) -> bool
|
||||
where F: FnMut(&mir::LvalueProjection<'tcx>) -> bool
|
||||
{
|
||||
let mut next_child = move_data.move_paths[path].first_child;
|
||||
while let Some(child_index) = next_child {
|
||||
match move_data.move_paths[child_index].lvalue {
|
||||
repr::Lvalue::Projection(ref proj) => {
|
||||
mir::Lvalue::Projection(ref proj) => {
|
||||
if cond(proj) {
|
||||
return Some(child_index)
|
||||
}
|
||||
@ -252,7 +251,7 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
||||
/// FIXME: we have to do something for moving slice patterns.
|
||||
fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
lv: &repr::Lvalue<'tcx>) -> bool {
|
||||
lv: &mir::Lvalue<'tcx>) -> bool {
|
||||
let ty = lv.ty(mir, tcx).to_ty(tcx);
|
||||
match ty.sty {
|
||||
ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
|
||||
@ -339,7 +338,7 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
|
||||
{
|
||||
let move_data = &ctxt.move_data;
|
||||
for arg in mir.args_iter() {
|
||||
let lvalue = repr::Lvalue::Local(arg);
|
||||
let lvalue = mir::Lvalue::Local(arg);
|
||||
let lookup_result = move_data.rev_lookup.find(&lvalue);
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
lookup_result,
|
||||
@ -379,23 +378,23 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
|
||||
let block = &mir[loc.block];
|
||||
match block.statements.get(loc.statement_index) {
|
||||
Some(stmt) => match stmt.kind {
|
||||
repr::StatementKind::SetDiscriminant{ .. } => {
|
||||
mir::StatementKind::SetDiscriminant{ .. } => {
|
||||
span_bug!(stmt.source_info.span, "SetDiscrimant should not exist during borrowck");
|
||||
}
|
||||
repr::StatementKind::Assign(ref lvalue, _) => {
|
||||
mir::StatementKind::Assign(ref lvalue, _) => {
|
||||
debug!("drop_flag_effects: assignment {:?}", stmt);
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
move_data.rev_lookup.find(lvalue),
|
||||
|moi| callback(moi, DropFlagState::Present))
|
||||
}
|
||||
repr::StatementKind::StorageLive(_) |
|
||||
repr::StatementKind::StorageDead(_) |
|
||||
repr::StatementKind::Nop => {}
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::Nop => {}
|
||||
},
|
||||
None => {
|
||||
debug!("drop_flag_effects: replace {:?}", block.terminator());
|
||||
match block.terminator().kind {
|
||||
repr::TerminatorKind::DropAndReplace { ref location, .. } => {
|
||||
mir::TerminatorKind::DropAndReplace { ref location, .. } => {
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
move_data.rev_lookup.find(location),
|
||||
|moi| callback(moi, DropFlagState::Present))
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::ty::Ty;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
|
||||
/// This struct represents a patch to MIR, which can add
|
||||
|
@ -51,8 +51,6 @@
|
||||
use rustc::hir::intravisit;
|
||||
use rustc::hir::intravisit::{Visitor, FnKind};
|
||||
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
|
||||
pub mod check_loans;
|
||||
|
||||
pub mod gather_loans;
|
||||
@ -102,10 +100,9 @@ fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &MirMap<'tcx>) {
|
||||
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
let mut bccx = BorrowckCtxt {
|
||||
tcx: tcx,
|
||||
mir_map: Some(mir_map),
|
||||
free_region_map: FreeRegionMap::new(),
|
||||
stats: BorrowStats {
|
||||
loaned_paths_same: 0,
|
||||
@ -168,12 +165,9 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
|
||||
attributes: &[ast::Attribute]) {
|
||||
debug!("borrowck_fn(id={})", id);
|
||||
|
||||
let def_id = this.tcx.map.local_def_id(id);
|
||||
|
||||
if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
|
||||
let mir = this.mir_map.unwrap().map.get(&def_id).unwrap();
|
||||
this.with_temp_region_map(id, |this| {
|
||||
mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes)
|
||||
mir::borrowck_mir(this, fk, decl, body, sp, id, attributes)
|
||||
});
|
||||
}
|
||||
|
||||
@ -249,7 +243,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
|
||||
/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
|
||||
pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir_map: Option<&'a MirMap<'tcx>>,
|
||||
fn_parts: FnParts<'a>,
|
||||
cfg: &cfg::CFG)
|
||||
-> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
|
||||
@ -257,7 +250,6 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
|
||||
|
||||
let mut bccx = BorrowckCtxt {
|
||||
tcx: tcx,
|
||||
mir_map: mir_map,
|
||||
free_region_map: FreeRegionMap::new(),
|
||||
stats: BorrowStats {
|
||||
loaned_paths_same: 0,
|
||||
@ -297,10 +289,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
|
||||
free_region_map: FreeRegionMap,
|
||||
|
||||
// Statistics:
|
||||
stats: BorrowStats,
|
||||
|
||||
// NodeId to MIR mapping (for methods that carry the #[rustc_mir] attribute).
|
||||
mir_map: Option<&'a MirMap<'tcx>>,
|
||||
stats: BorrowStats
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -11,7 +11,7 @@
|
||||
use eval;
|
||||
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::repr::{Field, BorrowKind, Mutability};
|
||||
use rustc::mir::{Field, BorrowKind, Mutability};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
|
||||
use rustc::hir::{self, PatKind};
|
||||
use rustc::hir::def::Def;
|
||||
|
@ -13,7 +13,6 @@
|
||||
use rustc::hir::def::DefMap;
|
||||
use rustc::hir::lowering::lower_crate;
|
||||
use rustc_mir as mir;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
|
||||
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
|
||||
OutputTypes};
|
||||
@ -175,7 +174,7 @@ macro_rules! controller_entry_point {
|
||||
resolutions,
|
||||
&arenas,
|
||||
&crate_name,
|
||||
|tcx, mir_map, analysis, incremental_hashes_map, result| {
|
||||
|tcx, analysis, incremental_hashes_map, result| {
|
||||
{
|
||||
// Eventually, we will want to track plugins.
|
||||
let _ignore = tcx.dep_graph.in_ignore();
|
||||
@ -187,7 +186,6 @@ macro_rules! controller_entry_point {
|
||||
opt_crate,
|
||||
tcx.map.krate(),
|
||||
&analysis,
|
||||
mir_map.as_ref(),
|
||||
tcx,
|
||||
&crate_name);
|
||||
(control.after_analysis.callback)(&mut state);
|
||||
@ -203,10 +201,7 @@ macro_rules! controller_entry_point {
|
||||
println!("Pre-trans");
|
||||
tcx.print_debug_stats();
|
||||
}
|
||||
let trans = phase_4_translate_to_llvm(tcx,
|
||||
mir_map.unwrap(),
|
||||
analysis,
|
||||
&incremental_hashes_map);
|
||||
let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map);
|
||||
|
||||
if log_enabled!(::log::INFO) {
|
||||
println!("Post-trans");
|
||||
@ -348,7 +343,6 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx {
|
||||
pub hir_crate: Option<&'a hir::Crate>,
|
||||
pub ast_map: Option<&'a hir_map::Map<'ast>>,
|
||||
pub resolutions: Option<&'a Resolutions>,
|
||||
pub mir_map: Option<&'b MirMap<'tcx>>,
|
||||
pub analysis: Option<&'a ty::CrateAnalysis<'a>>,
|
||||
pub tcx: Option<TyCtxt<'b, 'tcx, 'tcx>>,
|
||||
pub trans: Option<&'a trans::CrateTranslation>,
|
||||
@ -375,7 +369,6 @@ fn empty(input: &'a Input,
|
||||
ast_map: None,
|
||||
resolutions: None,
|
||||
analysis: None,
|
||||
mir_map: None,
|
||||
tcx: None,
|
||||
trans: None,
|
||||
}
|
||||
@ -449,13 +442,11 @@ fn state_after_analysis(input: &'a Input,
|
||||
krate: Option<&'a ast::Crate>,
|
||||
hir_crate: &'a hir::Crate,
|
||||
analysis: &'a ty::CrateAnalysis<'a>,
|
||||
mir_map: Option<&'b MirMap<'tcx>>,
|
||||
tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
crate_name: &'a str)
|
||||
-> CompileState<'a, 'b, 'ast, 'tcx> {
|
||||
CompileState {
|
||||
analysis: Some(analysis),
|
||||
mir_map: mir_map,
|
||||
tcx: Some(tcx),
|
||||
expanded_crate: krate,
|
||||
hir_crate: Some(hir_crate),
|
||||
@ -812,17 +803,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
f: F)
|
||||
-> Result<R, usize>
|
||||
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
|
||||
Option<MirMap<'tcx>>,
|
||||
ty::CrateAnalysis,
|
||||
IncrementalHashesMap,
|
||||
CompileResult) -> R
|
||||
{
|
||||
macro_rules! try_with_f {
|
||||
($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => {
|
||||
($e: expr, ($t: expr, $a: expr, $h: expr)) => {
|
||||
match $e {
|
||||
Ok(x) => x,
|
||||
Err(x) => {
|
||||
f($t, $m, $a, $h, Err(x));
|
||||
f($t, $a, $h, Err(x));
|
||||
return Err(x);
|
||||
}
|
||||
}
|
||||
@ -888,7 +878,7 @@ macro_rules! try_with_f {
|
||||
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
|
||||
|
||||
// passes are timed inside typeck
|
||||
try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map));
|
||||
try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
|
||||
|
||||
time(time_passes,
|
||||
"const checking",
|
||||
@ -928,28 +918,28 @@ macro_rules! try_with_f {
|
||||
"rvalue checking",
|
||||
|| rvalues::check_crate(tcx));
|
||||
|
||||
let mut mir_map =
|
||||
time(time_passes,
|
||||
"MIR dump",
|
||||
|| mir::mir_map::build_mir_for_crate(tcx));
|
||||
time(time_passes,
|
||||
"MIR dump",
|
||||
|| mir::mir_map::build_mir_for_crate(tcx));
|
||||
|
||||
time(time_passes, "MIR passes", || {
|
||||
let mut passes = sess.mir_passes.borrow_mut();
|
||||
// Push all the built-in passes.
|
||||
passes.push_hook(box mir::transform::dump_mir::DumpMir);
|
||||
passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("initial"));
|
||||
passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
|
||||
passes.push_pass(
|
||||
box mir::transform::qualify_consts::QualifyAndPromoteConstants::default());
|
||||
passes.push_pass(box mir::transform::type_check::TypeckMir);
|
||||
passes.push_pass(
|
||||
box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
|
||||
passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("qualify-consts"));
|
||||
// And run everything.
|
||||
passes.run_passes(tcx, &mut mir_map);
|
||||
passes.run_passes(tcx);
|
||||
});
|
||||
|
||||
time(time_passes,
|
||||
"borrow checking",
|
||||
|| borrowck::check_crate(tcx, &mir_map));
|
||||
|| borrowck::check_crate(tcx));
|
||||
|
||||
// Avoid overwhelming user with errors if type checking failed.
|
||||
// I'm not sure how helpful this is, to be honest, but it avoids
|
||||
@ -958,11 +948,7 @@ macro_rules! try_with_f {
|
||||
// lint warnings and so on -- kindck used to do this abort, but
|
||||
// kindck is gone now). -nmatsakis
|
||||
if sess.err_count() > 0 {
|
||||
return Ok(f(tcx,
|
||||
Some(mir_map),
|
||||
analysis,
|
||||
incremental_hashes_map,
|
||||
Err(sess.err_count())));
|
||||
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
|
||||
}
|
||||
|
||||
analysis.reachable =
|
||||
@ -990,20 +976,15 @@ macro_rules! try_with_f {
|
||||
|
||||
// The above three passes generate errors w/o aborting
|
||||
if sess.err_count() > 0 {
|
||||
return Ok(f(tcx,
|
||||
Some(mir_map),
|
||||
analysis,
|
||||
incremental_hashes_map,
|
||||
Err(sess.err_count())));
|
||||
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
|
||||
}
|
||||
|
||||
Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(())))
|
||||
Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
|
||||
})
|
||||
}
|
||||
|
||||
/// Run the translation phase to LLVM, after which the AST and analysis can
|
||||
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mut mir_map: MirMap<'tcx>,
|
||||
analysis: ty::CrateAnalysis,
|
||||
incremental_hashes_map: &IncrementalHashesMap)
|
||||
-> trans::CrateTranslation {
|
||||
@ -1037,13 +1018,13 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
|
||||
passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
|
||||
|
||||
passes.run_passes(tcx, &mut mir_map);
|
||||
passes.run_passes(tcx);
|
||||
});
|
||||
|
||||
let translation =
|
||||
time(time_passes,
|
||||
"translation",
|
||||
move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map));
|
||||
move || trans::trans_crate(tcx, analysis, &incremental_hashes_map));
|
||||
|
||||
time(time_passes,
|
||||
"assert dep graph",
|
||||
|
@ -52,8 +52,6 @@
|
||||
use rustc::hir;
|
||||
use rustc::hir::print as pprust_hir;
|
||||
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpSourceMode {
|
||||
PpmNormal,
|
||||
@ -234,7 +232,7 @@ fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
|
||||
resolutions.clone(),
|
||||
arenas,
|
||||
id,
|
||||
|tcx, _, _, _, _| {
|
||||
|tcx, _, _, _| {
|
||||
let annotation = TypedAnnotation {
|
||||
tcx: tcx,
|
||||
};
|
||||
@ -695,7 +693,6 @@ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
|
||||
|
||||
fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir_map: Option<&MirMap<'tcx>>,
|
||||
code: blocks::Code,
|
||||
mode: PpFlowGraphMode,
|
||||
mut out: W)
|
||||
@ -725,7 +722,6 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
|
||||
blocks::FnLikeCode(fn_like) => {
|
||||
let (bccx, analysis_data) =
|
||||
borrowck::build_borrowck_dataflow_data_for_fn(tcx,
|
||||
mir_map,
|
||||
fn_like.to_fn_parts(),
|
||||
&cfg);
|
||||
|
||||
@ -952,32 +948,28 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
|
||||
resolutions.clone(),
|
||||
arenas,
|
||||
crate_name,
|
||||
|tcx, mir_map, _, _, _| {
|
||||
|tcx, _, _, _| {
|
||||
match ppm {
|
||||
PpmMir | PpmMirCFG => {
|
||||
if let Some(mir_map) = mir_map {
|
||||
if let Some(nodeid) = nodeid {
|
||||
let def_id = tcx.map.local_def_id(nodeid);
|
||||
match ppm {
|
||||
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out),
|
||||
PpmMirCFG => {
|
||||
write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
} else {
|
||||
match ppm {
|
||||
PpmMir => write_mir_pretty(tcx,
|
||||
mir_map.map.keys().into_iter(),
|
||||
&mir_map,
|
||||
&mut out),
|
||||
PpmMirCFG => write_mir_graphviz(tcx,
|
||||
mir_map.map.keys().into_iter(),
|
||||
&mir_map,
|
||||
&mut out),
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
}
|
||||
if let Some(nodeid) = nodeid {
|
||||
let def_id = tcx.map.local_def_id(nodeid);
|
||||
match ppm {
|
||||
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out),
|
||||
PpmMirCFG => {
|
||||
write_mir_graphviz(tcx, iter::once(def_id), &mut out)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
} else {
|
||||
match ppm {
|
||||
PpmMir => write_mir_pretty(tcx,
|
||||
tcx.mir_map.borrow().keys().into_iter(),
|
||||
&mut out),
|
||||
PpmMirCFG => write_mir_graphviz(tcx,
|
||||
tcx.mir_map.borrow().keys().into_iter(),
|
||||
&mut out),
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -995,12 +987,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
|
||||
|
||||
let out: &mut Write = &mut out;
|
||||
|
||||
print_flowgraph(variants,
|
||||
tcx,
|
||||
mir_map.as_ref(),
|
||||
code,
|
||||
mode,
|
||||
out)
|
||||
print_flowgraph(variants, tcx, code, mode, out)
|
||||
}
|
||||
None => {
|
||||
let message = format!("--pretty=flowgraph needs block, fn, or method; got \
|
||||
|
@ -23,8 +23,7 @@
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::map::DefKey;
|
||||
use rustc::mir::repr::Mir;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::Mir;
|
||||
use rustc::util::nodemap::{NodeSet, DefIdMap};
|
||||
use rustc_back::PanicStrategy;
|
||||
|
||||
@ -467,10 +466,11 @@ fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId> {
|
||||
self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
|
||||
}
|
||||
|
||||
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
|
||||
-> Option<Mir<'tcx>> {
|
||||
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> {
|
||||
self.dep_graph.read(DepNode::MetaData(def));
|
||||
self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index)
|
||||
self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| {
|
||||
bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def))
|
||||
})
|
||||
}
|
||||
|
||||
fn is_item_mir_available(&self, def: DefId) -> bool {
|
||||
@ -523,10 +523,9 @@ fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>
|
||||
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
reexports: &def::ExportMap,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>) -> Vec<u8>
|
||||
reachable: &NodeSet) -> Vec<u8>
|
||||
{
|
||||
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map)
|
||||
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
|
||||
}
|
||||
|
||||
fn metadata_encoding_version(&self) -> &[u8]
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
use rustc_const_math::ConstInt;
|
||||
|
||||
use rustc::mir::repr::Mir;
|
||||
use rustc::mir::Mir;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::Ref;
|
||||
|
@ -22,7 +22,6 @@
|
||||
use rustc::traits::specialization_graph;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::session::config::{self, CrateTypeProcMacro};
|
||||
use rustc::util::nodemap::{FnvHashMap, NodeSet};
|
||||
|
||||
@ -51,7 +50,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
|
||||
link_meta: &'a LinkMeta,
|
||||
cstore: &'a cstore::CStore,
|
||||
reachable: &'a NodeSet,
|
||||
mir_map: &'a MirMap<'tcx>,
|
||||
|
||||
lazy_state: LazyState,
|
||||
type_shorthands: FnvHashMap<Ty<'tcx>, usize>,
|
||||
@ -605,8 +603,8 @@ fn encode_fn_arg_names(&mut self, decl: &hir::FnDecl) -> LazySeq<ast::Name> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::repr::Mir<'tcx>>> {
|
||||
self.mir_map.map.get(&def_id).map(|mir| self.lazy(mir))
|
||||
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
|
||||
self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
|
||||
}
|
||||
|
||||
// Encodes the inherent implementations of a structure, enumeration, or trait.
|
||||
@ -1346,8 +1344,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cstore: &cstore::CStore,
|
||||
reexports: &def::ExportMap,
|
||||
link_meta: &LinkMeta,
|
||||
reachable: &NodeSet,
|
||||
mir_map: &MirMap<'tcx>)
|
||||
reachable: &NodeSet)
|
||||
-> Vec<u8> {
|
||||
let mut cursor = Cursor::new(vec![]);
|
||||
cursor.write_all(METADATA_HEADER).unwrap();
|
||||
@ -1362,7 +1359,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
link_meta: link_meta,
|
||||
cstore: cstore,
|
||||
reachable: reachable,
|
||||
mir_map: mir_map,
|
||||
lazy_state: LazyState::NoNode,
|
||||
type_shorthands: Default::default(),
|
||||
predicate_shorthands: Default::default(),
|
||||
|
@ -221,7 +221,7 @@ pub struct Entry<'tcx> {
|
||||
pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
|
||||
|
||||
pub ast: Option<Lazy<astencode::Ast<'tcx>>>,
|
||||
pub mir: Option<Lazy<mir::repr::Mir<'tcx>>>,
|
||||
pub mir: Option<Lazy<mir::Mir<'tcx>>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::hir;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! Routines for manipulating the control-flow graph.
|
||||
|
||||
use build::CFG;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'tcx> CFG<'tcx> {
|
||||
pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use build::Builder;
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Compile `expr`, yielding a compile-time constant. Assumes that
|
||||
|
@ -13,7 +13,7 @@
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use build::expr::category::Category;
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use build::expr::category::Category;
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Compile `expr` into a value that can be used as an operand.
|
||||
|
@ -22,7 +22,7 @@
|
||||
use rustc_const_math::{ConstInt, ConstIsize};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use build::expr::category::Category;
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Compile `expr` into a fresh temporary. This is used when building
|
||||
|
@ -14,7 +14,7 @@
|
||||
use build::expr::category::{Category, RvalueFunc};
|
||||
use hair::*;
|
||||
use rustc::ty;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
/// Compile `expr`, storing the result into `destination`, which
|
||||
|
@ -12,7 +12,7 @@
|
||||
use build::scope::LoopScope;
|
||||
use hair::*;
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use syntax_pos::Span;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
use build::{BlockAnd, Builder};
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
pub trait EvalInto<'tcx> {
|
||||
fn eval_into<'a, 'gcx>(self,
|
||||
|
@ -18,7 +18,7 @@
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{AdtDef, Ty};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use hair::*;
|
||||
use syntax::ast::{Name, NodeId};
|
||||
use syntax_pos::Span;
|
||||
|
@ -25,7 +25,7 @@
|
||||
use build::{BlockAnd, BlockAndExtension, Builder};
|
||||
use build::matches::{Binding, MatchPair, Candidate};
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use syntax_pos::Span;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
use build::Builder;
|
||||
use build::matches::MatchPair;
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use std::u32;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||
|
@ -17,7 +17,7 @@
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{self, Ty};
|
||||
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
use rustc::middle::region::{CodeExtent, CodeExtentData, ROOT_CODE_EXTENT};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::util::nodemap::NodeMap;
|
||||
use rustc::hir;
|
||||
use syntax::abi::Abi;
|
||||
|
@ -91,7 +91,7 @@
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::ty::subst::{Kind, Subst};
|
||||
use rustc::ty::{Ty, TyCtxt};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use syntax_pos::Span;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Def-use analysis.
|
||||
|
||||
use rustc::mir::repr::{Local, Location, Lvalue, Mir};
|
||||
use rustc::mir::{Local, Location, Lvalue, Mir};
|
||||
use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use std::marker::PhantomData;
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
use dot;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::TyCtxt;
|
||||
use std::fmt::Debug;
|
||||
use std::io::{self, Write};
|
||||
@ -22,14 +21,13 @@
|
||||
/// Write a graphviz DOT graph of a list of MIRs.
|
||||
pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
iter: I,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
w: &mut W)
|
||||
-> io::Result<()>
|
||||
where W: Write, I: Iterator<Item=DefId>
|
||||
{
|
||||
for def_id in iter {
|
||||
let nodeid = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
let mir = &mir_map.map[&def_id];
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
|
||||
writeln!(w, "digraph Mir_{} {{", nodeid)?;
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc::ty::{self, AdtKind, VariantDef, Ty};
|
||||
use rustc::ty::cast::CastKind as TyCastKind;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::hir;
|
||||
use syntax::ptr::P;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
use hair::*;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::MirSource;
|
||||
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! unit-tested and separated from the Rust source and compiler data
|
||||
//! structures.
|
||||
|
||||
use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal};
|
||||
use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -19,13 +19,12 @@
|
||||
use build;
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::repr::Mir;
|
||||
use rustc::mir::Mir;
|
||||
use rustc::mir::transform::MirSource;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use pretty;
|
||||
use hair::cx::Cx;
|
||||
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::infer::InferCtxtBuilder;
|
||||
use rustc::traits::Reveal;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
@ -37,16 +36,10 @@
|
||||
|
||||
use std::mem;
|
||||
|
||||
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> {
|
||||
let mut map = MirMap::new(tcx.dep_graph.clone());
|
||||
{
|
||||
let mut dump = BuildMir {
|
||||
tcx: tcx,
|
||||
map: &mut map,
|
||||
};
|
||||
tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump);
|
||||
}
|
||||
map
|
||||
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
tcx.visit_all_items_in_krate(DepNode::Mir, &mut BuildMir {
|
||||
tcx: tcx
|
||||
});
|
||||
}
|
||||
|
||||
/// A pass to lift all the types and substitutions in a Mir
|
||||
@ -83,8 +76,7 @@ fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
|
||||
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
|
||||
|
||||
struct BuildMir<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
map: &'a mut MirMap<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>
|
||||
}
|
||||
|
||||
/// Helper type of a temporary returned by BuildMir::cx(...).
|
||||
@ -93,8 +85,7 @@ struct BuildMir<'a, 'tcx: 'a> {
|
||||
struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
src: MirSource,
|
||||
def_id: DefId,
|
||||
infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>,
|
||||
map: &'a mut MirMap<'gcx>,
|
||||
infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
|
||||
@ -104,8 +95,7 @@ fn cx<'b>(&'b mut self, src: MirSource) -> CxBuilder<'b, 'gcx, 'tcx> {
|
||||
CxBuilder {
|
||||
src: src,
|
||||
infcx: self.tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable),
|
||||
def_id: def_id,
|
||||
map: self.map
|
||||
def_id: def_id
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,13 +104,14 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
|
||||
fn build<F>(&'tcx mut self, f: F)
|
||||
where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec)
|
||||
{
|
||||
let src = self.src;
|
||||
let mir = self.infcx.enter(|infcx| {
|
||||
let (src, def_id) = (self.src, self.def_id);
|
||||
self.infcx.enter(|infcx| {
|
||||
let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src));
|
||||
|
||||
// Convert the Mir to global types.
|
||||
let tcx = infcx.tcx.global_tcx();
|
||||
let mut globalizer = GlobalizeMir {
|
||||
tcx: infcx.tcx.global_tcx(),
|
||||
tcx: tcx,
|
||||
span: mir.span
|
||||
};
|
||||
globalizer.visit_mir(&mut mir);
|
||||
@ -128,13 +119,11 @@ fn build<F>(&'tcx mut self, f: F)
|
||||
mem::transmute::<Mir, Mir<'gcx>>(mir)
|
||||
};
|
||||
|
||||
pretty::dump_mir(infcx.tcx.global_tcx(), "mir_map", &0,
|
||||
src, &mir, Some(&scope_auxiliary));
|
||||
pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary));
|
||||
|
||||
mir
|
||||
let mir = tcx.alloc_mir(mir);
|
||||
assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none());
|
||||
});
|
||||
|
||||
assert!(self.map.map.insert(self.def_id, mir).is_none())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
use build::{ScopeAuxiliaryVec, ScopeId};
|
||||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::MirSource;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_data_structures::fnv::FnvHashMap;
|
||||
@ -90,14 +89,13 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
/// Write out a human-readable textual representation for the given MIR.
|
||||
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
iter: I,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
w: &mut Write)
|
||||
-> io::Result<()>
|
||||
where I: Iterator<Item=DefId>, 'tcx: 'a
|
||||
{
|
||||
let mut first = true;
|
||||
for def_id in iter {
|
||||
let mir = &mir_map.map[&def_id];
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
|
||||
if first {
|
||||
first = false;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
//! future.
|
||||
|
||||
use def_use::DefUseAnalysis;
|
||||
use rustc::mir::repr::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
|
||||
use rustc::mir::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::ty::TyCtxt;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource};
|
||||
use pretty;
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{Ty, TyCtxt};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Performs various peephole optimizations.
|
||||
|
||||
use rustc::mir::repr::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor};
|
||||
use rustc::ty::TyCtxt;
|
||||
|
@ -12,7 +12,7 @@
|
||||
//! specified.
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
//! initialization and can otherwise silence errors, if
|
||||
//! move analysis runs after promotion on broken MIR.
|
||||
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
|
||||
use rustc::mir::traversal::ReversePostorder;
|
||||
use rustc::ty::TyCtxt;
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::hir;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::hir::def_id::DefId;
|
||||
@ -25,10 +24,9 @@
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::ty::{self, TyCtxt, Ty};
|
||||
use rustc::ty::cast::CastTy;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::traversal::{self, ReversePostorder};
|
||||
use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::traversal::ReversePostorder;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::util::nodemap::DefIdMap;
|
||||
use syntax::abi::Abi;
|
||||
@ -142,7 +140,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
param_env: ty::ParameterEnvironment<'tcx>,
|
||||
qualif_map: &'a mut DefIdMap<Qualif>,
|
||||
mir_map: Option<&'a MirMap<'tcx>>,
|
||||
temp_qualif: IndexVec<Local, Option<Qualif>>,
|
||||
return_qualif: Option<Qualif>,
|
||||
qualif: Qualif,
|
||||
@ -155,7 +152,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
||||
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParameterEnvironment<'tcx>,
|
||||
qualif_map: &'a mut DefIdMap<Qualif>,
|
||||
mir_map: Option<&'a MirMap<'tcx>>,
|
||||
def_id: DefId,
|
||||
mir: &'a Mir<'tcx>,
|
||||
mode: Mode)
|
||||
@ -172,7 +168,6 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
tcx: tcx,
|
||||
param_env: param_env,
|
||||
qualif_map: qualif_map,
|
||||
mir_map: mir_map,
|
||||
temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
|
||||
return_qualif: None,
|
||||
qualif: Qualif::empty(),
|
||||
@ -595,7 +590,6 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
||||
} else {
|
||||
let qualif = qualify_const_item_cached(self.tcx,
|
||||
self.qualif_map,
|
||||
self.mir_map,
|
||||
def_id);
|
||||
self.add(qualif);
|
||||
}
|
||||
@ -949,7 +943,6 @@ fn visit_terminator(&mut self,
|
||||
|
||||
fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
qualif_map: &mut DefIdMap<Qualif>,
|
||||
mir_map: Option<&MirMap<'tcx>>,
|
||||
def_id: DefId)
|
||||
-> Qualif {
|
||||
match qualif_map.entry(def_id) {
|
||||
@ -960,124 +953,100 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
let extern_mir;
|
||||
let param_env_and_mir = if def_id.is_local() {
|
||||
mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| {
|
||||
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
(ty::ParameterEnvironment::for_item(tcx, node_id), mir)
|
||||
})
|
||||
} else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) {
|
||||
// These should only be monomorphic constants.
|
||||
extern_mir = mir;
|
||||
Some((tcx.empty_parameter_environment(), &extern_mir))
|
||||
let param_env = if def_id.is_local() {
|
||||
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
ty::ParameterEnvironment::for_item(tcx, node_id)
|
||||
} else {
|
||||
None
|
||||
// These should only be monomorphic constants.
|
||||
tcx.empty_parameter_environment()
|
||||
};
|
||||
|
||||
let (param_env, mir) = param_env_and_mir.unwrap_or_else(|| {
|
||||
bug!("missing constant MIR for {}", tcx.item_path_str(def_id))
|
||||
});
|
||||
|
||||
let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, mir_map,
|
||||
def_id, mir, Mode::Const);
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, def_id, mir, Mode::Const);
|
||||
let qualif = qualifier.qualify_const();
|
||||
qualifier.qualif_map.insert(def_id, qualif);
|
||||
qualif
|
||||
}
|
||||
|
||||
pub struct QualifyAndPromoteConstants;
|
||||
#[derive(Default)]
|
||||
pub struct QualifyAndPromoteConstants {
|
||||
qualif_map: DefIdMap<Qualif>
|
||||
}
|
||||
|
||||
impl Pass for QualifyAndPromoteConstants {}
|
||||
|
||||
impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&mut self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
map: &mut MirMap<'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
|
||||
let mut qualif_map = DefIdMap();
|
||||
impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let id = src.item_id();
|
||||
let def_id = tcx.map.local_def_id(id);
|
||||
let mode = match src {
|
||||
MirSource::Fn(_) => {
|
||||
if is_const_fn(tcx, def_id) {
|
||||
Mode::ConstFn
|
||||
} else {
|
||||
Mode::Fn
|
||||
}
|
||||
}
|
||||
MirSource::Const(_) => {
|
||||
match self.qualif_map.entry(def_id) {
|
||||
Entry::Occupied(_) => return,
|
||||
Entry::Vacant(entry) => {
|
||||
// Guard against `const` recursion.
|
||||
entry.insert(Qualif::RECURSIVE);
|
||||
}
|
||||
}
|
||||
Mode::Const
|
||||
}
|
||||
MirSource::Static(_, hir::MutImmutable) => Mode::Static,
|
||||
MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
|
||||
MirSource::Promoted(..) => return
|
||||
};
|
||||
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
|
||||
|
||||
// First, visit `const` items, potentially recursing, to get
|
||||
// accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications.
|
||||
let keys = map.map.keys();
|
||||
for &def_id in &keys {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let id = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
if let MirSource::Const(_) = src {
|
||||
qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id);
|
||||
if mode == Mode::Fn || mode == Mode::ConstFn {
|
||||
// This is ugly because Qualifier holds onto mir,
|
||||
// which can't be mutated until its scope ends.
|
||||
let (temps, candidates) = {
|
||||
let mut qualifier = Qualifier::new(tcx, param_env,
|
||||
&mut self.qualif_map,
|
||||
def_id, mir, mode);
|
||||
if mode == Mode::ConstFn {
|
||||
// Enforce a constant-like CFG for `const fn`.
|
||||
qualifier.qualify_const();
|
||||
} else {
|
||||
while let Some((bb, data)) = qualifier.rpo.next() {
|
||||
qualifier.visit_basic_block_data(bb, data);
|
||||
}
|
||||
}
|
||||
|
||||
(qualifier.temp_promotion_state, qualifier.promotion_candidates)
|
||||
};
|
||||
|
||||
// Do the actual promotion, now that we know what's viable.
|
||||
promote_consts::promote_candidates(mir, tcx, temps, candidates);
|
||||
} else {
|
||||
let mut qualifier = Qualifier::new(tcx, param_env,
|
||||
&mut self.qualif_map,
|
||||
def_id, mir, mode);
|
||||
let qualif = qualifier.qualify_const();
|
||||
|
||||
if mode == Mode::Const {
|
||||
qualifier.qualif_map.insert(def_id, qualif);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, handle everything else, without recursing,
|
||||
// as the MIR map is not shared, since promotion
|
||||
// in functions (including `const fn`) mutates it.
|
||||
for &def_id in &keys {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let id = tcx.map.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
let mode = match src {
|
||||
MirSource::Fn(_) => {
|
||||
if is_const_fn(tcx, def_id) {
|
||||
Mode::ConstFn
|
||||
} else {
|
||||
Mode::Fn
|
||||
}
|
||||
// Statics must be Sync.
|
||||
if mode == Mode::Static {
|
||||
let ty = mir.return_ty;
|
||||
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
|
||||
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
|
||||
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
infcx.report_fulfillment_errors(&err);
|
||||
}
|
||||
MirSource::Const(_) => continue,
|
||||
MirSource::Static(_, hir::MutImmutable) => Mode::Static,
|
||||
MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
|
||||
MirSource::Promoted(..) => bug!()
|
||||
};
|
||||
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
|
||||
|
||||
let mir = map.map.get_mut(&def_id).unwrap();
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||
}
|
||||
|
||||
if mode == Mode::Fn || mode == Mode::ConstFn {
|
||||
// This is ugly because Qualifier holds onto mir,
|
||||
// which can't be mutated until its scope ends.
|
||||
let (temps, candidates) = {
|
||||
let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
|
||||
None, def_id, mir, mode);
|
||||
if mode == Mode::ConstFn {
|
||||
// Enforce a constant-like CFG for `const fn`.
|
||||
qualifier.qualify_const();
|
||||
} else {
|
||||
while let Some((bb, data)) = qualifier.rpo.next() {
|
||||
qualifier.visit_basic_block_data(bb, data);
|
||||
}
|
||||
}
|
||||
|
||||
(qualifier.temp_promotion_state,
|
||||
qualifier.promotion_candidates)
|
||||
};
|
||||
|
||||
// Do the actual promotion, now that we know what's viable.
|
||||
promote_consts::promote_candidates(mir, tcx, temps, candidates);
|
||||
} else {
|
||||
let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
|
||||
None, def_id, mir, mode);
|
||||
qualifier.qualify_const();
|
||||
}
|
||||
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||
}
|
||||
|
||||
// Statics must be Sync.
|
||||
if mode == Mode::Static {
|
||||
let ty = mir.return_ty;
|
||||
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
|
||||
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
|
||||
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
|
||||
infcx.report_fulfillment_errors(&err);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
@ -35,9 +35,8 @@
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::traversal;
|
||||
use std::fmt;
|
||||
|
||||
pub struct SimplifyCfg<'a> { label: &'a str }
|
||||
|
@ -15,10 +15,10 @@
|
||||
use rustc::traits::{self, Reveal};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
|
||||
use rustc::mir::repr::*;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::visit::{self, Visitor};
|
||||
use rustc::mir::visit::Visitor;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
@ -44,7 +44,6 @@
|
||||
use rustc::dep_graph::{DepNode, WorkProduct};
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::util::common::time;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use session::config::{self, NoDebugInfo};
|
||||
use rustc_incremental::IncrementalHashesMap;
|
||||
use session::Session;
|
||||
@ -866,7 +865,7 @@ pub fn new(ccx: &'blk CrateContext<'blk, 'tcx>,
|
||||
false
|
||||
};
|
||||
|
||||
let mir = def_id.and_then(|id| ccx.get_mir(id));
|
||||
let mir = def_id.map(|id| ccx.tcx().item_mir(id));
|
||||
|
||||
let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) =
|
||||
(no_debug, definition, &mir) {
|
||||
@ -1278,8 +1277,7 @@ enum MetadataKind {
|
||||
let metadata = cstore.encode_metadata(cx.tcx(),
|
||||
cx.export_map(),
|
||||
cx.link_meta(),
|
||||
reachable_ids,
|
||||
cx.mir_map());
|
||||
reachable_ids);
|
||||
if kind == MetadataKind::Uncompressed {
|
||||
return metadata;
|
||||
}
|
||||
@ -1527,7 +1525,6 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
|
||||
}
|
||||
|
||||
pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir_map: &MirMap<'tcx>,
|
||||
analysis: ty::CrateAnalysis,
|
||||
incremental_hashes_map: &IncrementalHashesMap)
|
||||
-> CrateTranslation {
|
||||
@ -1551,7 +1548,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
let link_meta = link::build_link_meta(incremental_hashes_map, name);
|
||||
|
||||
let shared_ccx = SharedCrateContext::new(tcx,
|
||||
&mir_map,
|
||||
export_map,
|
||||
Sha256::new(),
|
||||
link_meta.clone(),
|
||||
|
@ -198,15 +198,13 @@
|
||||
use rustc::ty::subst::{Substs, Subst};
|
||||
use rustc::ty::{self, TypeFoldable, TyCtxt};
|
||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir::{self, Location};
|
||||
use rustc::mir::visit as mir_visit;
|
||||
use rustc::mir::visit::Visitor as MirVisitor;
|
||||
use rustc::mir::repr::Location;
|
||||
|
||||
use rustc_const_eval as const_eval;
|
||||
|
||||
use syntax::abi::Abi;
|
||||
use errors;
|
||||
use syntax_pos::DUMMY_SP;
|
||||
use base::custom_coerce_unsize_info;
|
||||
use context::SharedCrateContext;
|
||||
@ -347,8 +345,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
|
||||
// Scan the MIR in order to find function calls, closures, and
|
||||
// drop-glue
|
||||
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
|
||||
|| format!("Could not find MIR for static: {:?}", def_id));
|
||||
let mir = scx.tcx().item_mir(def_id);
|
||||
|
||||
let empty_substs = scx.empty_substs_for_def_id(def_id);
|
||||
let visitor = MirNeighborCollector {
|
||||
@ -368,8 +365,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
|
||||
// Scan the MIR in order to find function calls, closures, and
|
||||
// drop-glue
|
||||
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def),
|
||||
|| format!("Could not find MIR for function: {}", instance));
|
||||
let mir = scx.tcx().item_mir(instance.def);
|
||||
|
||||
let visitor = MirNeighborCollector {
|
||||
scx: scx,
|
||||
@ -452,11 +448,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
|
||||
match *rvalue {
|
||||
mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id,
|
||||
ref substs), _) => {
|
||||
let mir = errors::expect(self.scx.sess().diagnostic(),
|
||||
self.scx.get_mir(def_id),
|
||||
|| {
|
||||
format!("Could not find MIR for closure: {:?}", def_id)
|
||||
});
|
||||
let mir = self.scx.tcx().item_mir(def_id);
|
||||
|
||||
let concrete_substs = monomorphize::apply_param_substs(self.scx,
|
||||
self.param_substs,
|
||||
@ -1249,8 +1241,7 @@ fn collect_const_item_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
{
|
||||
// Scan the MIR in order to find function calls, closures, and
|
||||
// drop-glue
|
||||
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
|
||||
|| format!("Could not find MIR for const: {:?}", def_id));
|
||||
let mir = scx.tcx().item_mir(def_id);
|
||||
|
||||
let visitor = MirNeighborCollector {
|
||||
scx: scx,
|
||||
|
@ -19,6 +19,7 @@
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::TransNormalize;
|
||||
use rustc::mir::Mir;
|
||||
use rustc::util::common::MemoizationMap;
|
||||
use middle::lang_items::LangItem;
|
||||
use rustc::ty::subst::Substs;
|
||||
@ -32,7 +33,6 @@
|
||||
use debuginfo::{self, DebugLoc};
|
||||
use declare;
|
||||
use machine;
|
||||
use mir::CachedMir;
|
||||
use monomorphize;
|
||||
use type_::Type;
|
||||
use value::Value;
|
||||
@ -46,7 +46,7 @@
|
||||
use libc::{c_uint, c_char};
|
||||
use std::ops::Deref;
|
||||
use std::ffi::CString;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::{Cell, RefCell, Ref};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::InternedString;
|
||||
@ -250,10 +250,8 @@ pub fn validate_substs(substs: &Substs) {
|
||||
// Function context. Every LLVM function we create will have one of
|
||||
// these.
|
||||
pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||
// The MIR for this function. At present, this is optional because
|
||||
// we only have MIR available for things that are local to the
|
||||
// crate.
|
||||
pub mir: Option<CachedMir<'a, 'tcx>>,
|
||||
// The MIR for this function.
|
||||
pub mir: Option<Ref<'tcx, Mir<'tcx>>>,
|
||||
|
||||
// The ValueRef returned from a call to llvm::LLVMAddFunction; the
|
||||
// address of the first instruction in the sequence of
|
||||
@ -313,8 +311,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||
pub fn mir(&self) -> CachedMir<'a, 'tcx> {
|
||||
self.mir.clone().expect("fcx.mir was empty")
|
||||
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
|
||||
self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty")
|
||||
}
|
||||
|
||||
pub fn cleanup(&self) {
|
||||
@ -490,7 +488,7 @@ pub fn set_lpad(&self, lpad: Option<LandingPad>) {
|
||||
self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
|
||||
}
|
||||
|
||||
pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
|
||||
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
|
||||
self.fcx.mir()
|
||||
}
|
||||
|
||||
@ -609,7 +607,7 @@ pub fn llbb(&self) -> BasicBlockRef {
|
||||
self.bcx.llbb
|
||||
}
|
||||
|
||||
pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
|
||||
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
|
||||
self.bcx.mir()
|
||||
}
|
||||
|
||||
|
@ -15,15 +15,12 @@
|
||||
use rustc::hir::def::ExportMap;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::traits;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::mir::repr as mir;
|
||||
use base;
|
||||
use builder::Builder;
|
||||
use common::BuilderRef_res;
|
||||
use debuginfo;
|
||||
use declare;
|
||||
use glue::DropGlueKind;
|
||||
use mir::CachedMir;
|
||||
use monomorphize::Instance;
|
||||
|
||||
use partitioning::CodegenUnit;
|
||||
@ -76,8 +73,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
stats: Stats,
|
||||
check_overflow: bool,
|
||||
mir_map: &'a MirMap<'tcx>,
|
||||
mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>,
|
||||
|
||||
use_dll_storage_attrs: bool,
|
||||
|
||||
@ -184,19 +179,6 @@ fn to_dep_node(key: &ty::PolyTraitRef<'tcx>) -> DepNode<DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
// Cache for mir loaded from metadata
|
||||
struct MirCache<'tcx> {
|
||||
data: PhantomData<&'tcx ()>
|
||||
}
|
||||
|
||||
impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
|
||||
type Key = DefId;
|
||||
type Value = Rc<mir::Mir<'tcx>>;
|
||||
fn to_dep_node(key: &DefId) -> DepNode<DefId> {
|
||||
DepNode::Mir(*key)
|
||||
}
|
||||
}
|
||||
|
||||
// # Global Cache
|
||||
|
||||
pub struct ProjectionCache<'gcx> {
|
||||
@ -453,7 +435,6 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
|
||||
|
||||
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
mir_map: &'b MirMap<'tcx>,
|
||||
export_map: ExportMap,
|
||||
symbol_hasher: Sha256,
|
||||
link_meta: LinkMeta,
|
||||
@ -517,8 +498,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
link_meta: link_meta,
|
||||
symbol_hasher: RefCell::new(symbol_hasher),
|
||||
tcx: tcx,
|
||||
mir_map: mir_map,
|
||||
mir_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
|
||||
stats: Stats {
|
||||
n_glues_created: Cell::new(0),
|
||||
n_null_glues: Cell::new(0),
|
||||
@ -582,23 +561,6 @@ pub fn use_dll_storage_attrs(&self) -> bool {
|
||||
self.use_dll_storage_attrs
|
||||
}
|
||||
|
||||
pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
|
||||
if def_id.is_local() {
|
||||
self.mir_map.map.get(&def_id).map(CachedMir::Ref)
|
||||
} else {
|
||||
if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() {
|
||||
return Some(CachedMir::Owned(mir));
|
||||
}
|
||||
|
||||
let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id);
|
||||
let cached = mir.map(Rc::new);
|
||||
if let Some(ref mir) = cached {
|
||||
self.mir_cache.borrow_mut().insert(def_id, mir.clone());
|
||||
}
|
||||
cached.map(CachedMir::Owned)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
|
||||
&self.translation_items
|
||||
}
|
||||
@ -617,10 +579,6 @@ pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
|
||||
&self.symbol_hasher
|
||||
}
|
||||
|
||||
pub fn mir_map(&self) -> &MirMap<'tcx> {
|
||||
&self.mir_map
|
||||
}
|
||||
|
||||
pub fn metadata_symbol_name(&self) -> String {
|
||||
format!("rust_metadata_{}_{}",
|
||||
self.link_meta().crate_name,
|
||||
@ -1008,10 +966,6 @@ pub fn use_dll_storage_attrs(&self) -> bool {
|
||||
self.shared.use_dll_storage_attrs()
|
||||
}
|
||||
|
||||
pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
|
||||
self.shared.get_mir(def_id)
|
||||
}
|
||||
|
||||
pub fn symbol_map(&self) -> &SymbolMap<'tcx> {
|
||||
&*self.local().symbol_map
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
use llvm;
|
||||
use llvm::debuginfo::{DIScope, DISubprogram};
|
||||
use common::{CrateContext, FunctionContext};
|
||||
use rustc::mir::repr::{Mir, VisibilityScope};
|
||||
use rustc::mir::{Mir, VisibilityScope};
|
||||
|
||||
use libc::c_uint;
|
||||
use std::ptr;
|
||||
@ -45,7 +45,7 @@ pub fn is_valid(&self) -> bool {
|
||||
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
|
||||
/// If debuginfo is disabled, the returned vector is empty.
|
||||
pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> {
|
||||
let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
|
||||
let mir = fcx.mir();
|
||||
let null_scope = MirDebugScope {
|
||||
scope_metadata: ptr::null_mut(),
|
||||
file_start_pos: BytePos(0),
|
||||
|
@ -32,7 +32,7 @@
|
||||
use common::{CrateContext, FunctionContext, Block, BlockAndBuilder};
|
||||
use monomorphize::{self, Instance};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||
use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_extras)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(dotdot_in_tuple_patterns)]
|
||||
|
@ -13,9 +13,7 @@
|
||||
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir::repr::TerminatorKind;
|
||||
use rustc::mir::repr::Location;
|
||||
use rustc::mir::{self, Location, TerminatorKind};
|
||||
use rustc::mir::visit::{Visitor, LvalueContext};
|
||||
use rustc::mir::traversal;
|
||||
use common::{self, Block, BlockAndBuilder};
|
||||
|
@ -12,7 +12,7 @@
|
||||
use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
|
||||
use rustc::middle::lang_items;
|
||||
use rustc::ty;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use abi::{Abi, FnType, ArgType};
|
||||
use adt;
|
||||
use base;
|
||||
|
@ -16,7 +16,7 @@
|
||||
use rustc_const_math::{ConstInt, ConstIsize, ConstUsize, ConstMathErr};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::TransNormalize;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
@ -261,9 +261,7 @@ fn trans_def(ccx: &'a CrateContext<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
let mir = ccx.get_mir(instance.def).unwrap_or_else(|| {
|
||||
bug!("missing constant MIR for {}", instance)
|
||||
});
|
||||
let mir = ccx.tcx().item_mir(instance.def);
|
||||
MirConstContext::new(ccx, &mir, instance.substs, args).trans()
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use llvm::ValueRef;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use adt;
|
||||
|
@ -11,7 +11,7 @@
|
||||
use libc::c_uint;
|
||||
use llvm::{self, ValueRef};
|
||||
use rustc::ty;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use session::config::FullDebugInfo;
|
||||
use base;
|
||||
@ -23,8 +23,7 @@
|
||||
use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
|
||||
use syntax::parse::token::keywords;
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::cell::Ref;
|
||||
use std::iter;
|
||||
|
||||
use basic_block::BasicBlock;
|
||||
@ -39,25 +38,9 @@
|
||||
|
||||
use self::operand::{OperandRef, OperandValue};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum CachedMir<'mir, 'tcx: 'mir> {
|
||||
Ref(&'mir mir::Mir<'tcx>),
|
||||
Owned(Rc<mir::Mir<'tcx>>)
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
|
||||
type Target = mir::Mir<'tcx>;
|
||||
fn deref(&self) -> &mir::Mir<'tcx> {
|
||||
match *self {
|
||||
CachedMir::Ref(r) => r,
|
||||
CachedMir::Owned(ref rc) => rc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Master context for translating MIR.
|
||||
pub struct MirContext<'bcx, 'tcx:'bcx> {
|
||||
mir: CachedMir<'bcx, 'tcx>,
|
||||
mir: Ref<'tcx, mir::Mir<'tcx>>,
|
||||
|
||||
/// Function context
|
||||
fcx: &'bcx common::FunctionContext<'bcx, 'tcx>,
|
||||
@ -223,7 +206,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
|
||||
let scopes = debuginfo::create_mir_scopes(fcx);
|
||||
|
||||
let mut mircx = MirContext {
|
||||
mir: mir.clone(),
|
||||
mir: Ref::clone(&mir),
|
||||
fcx: fcx,
|
||||
llpersonalityslot: None,
|
||||
blocks: block_bcxs,
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use llvm::ValueRef;
|
||||
use rustc::ty::Ty;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
use base;
|
||||
|
@ -12,7 +12,7 @@
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::cast::{CastTy, IntTy};
|
||||
use rustc::ty::layout::Layout;
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
|
||||
use asm;
|
||||
use base;
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::mir::repr as mir;
|
||||
use rustc::mir;
|
||||
|
||||
use base;
|
||||
use common::{self, BlockAndBuilder};
|
||||
|
@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths,
|
||||
resolutions,
|
||||
&arenas,
|
||||
&name,
|
||||
|tcx, _, analysis, _, result| {
|
||||
|tcx, analysis, _, result| {
|
||||
if let Err(_) = result {
|
||||
sess.fatal("Compilation failed, aborting rustdoc");
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
extern crate syntax;
|
||||
|
||||
use rustc::mir::transform::{self, MirPass, MirSource};
|
||||
use rustc::mir::repr::{Mir, Literal, Location};
|
||||
use rustc::mir::{Mir, Literal, Location};
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
|
Loading…
Reference in New Issue
Block a user