diff --git a/src/Cargo.lock b/src/Cargo.lock index 54a58854f0a27..c22187ee13e8e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1923,6 +1923,7 @@ dependencies = [ "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_trans_utils 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -2026,6 +2027,7 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_incremental 0.0.0", "rustc_llvm 0.0.0", + "rustc_mir 0.0.0", "rustc_platform_intrinsics 0.0.0", "rustc_trans_utils 0.0.0", "serialize 0.0.0", diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 8dc927c451b89..f00830f9ec992 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -136,7 +136,6 @@ pub mod middle { pub mod recursion_limit; pub mod resolve_lifetime; pub mod stability; - pub mod trans; pub mod weak_lang_items; } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a83c3f29d25bc..0ac2c2d4de8c0 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -44,6 +44,7 @@ pub mod tcx; pub mod visit; pub mod traversal; pub mod interpret; +pub mod mono; /// Types for locals type LocalDecls<'tcx> = IndexVec>; diff --git a/src/librustc/middle/trans.rs b/src/librustc/mir/mono.rs similarity index 91% rename from src/librustc/middle/trans.rs rename to src/librustc/mir/mono.rs index 7744c9c3d1238..5f74f08823783 100644 --- a/src/librustc/middle/trans.rs +++ b/src/librustc/mir/mono.rs @@ -17,24 +17,24 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] -pub enum TransItem<'tcx> { +pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), Static(NodeId), GlobalAsm(NodeId), } -impl<'tcx> HashStable> for TransItem<'tcx> { +impl<'tcx> HashStable> for MonoItem<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { ::std::mem::discriminant(self).hash_stable(hcx, hasher); match *self { - TransItem::Fn(ref instance) => { + MonoItem::Fn(ref instance) => { instance.hash_stable(hcx, hasher); } - TransItem::Static(node_id) | - TransItem::GlobalAsm(node_id) => { + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { node_id.hash_stable(hcx, hasher); }) @@ -49,7 +49,7 @@ pub struct CodegenUnit<'tcx> { /// contain something unique to this crate (e.g., a module path) /// as well as the crate name and disambiguator. name: InternedString, - items: FxHashMap, (Linkage, Visibility)>, + items: FxHashMap, (Linkage, Visibility)>, } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -110,12 +110,12 @@ impl<'tcx> CodegenUnit<'tcx> { self.name = name; } - pub fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { + pub fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { &self.items } pub fn items_mut(&mut self) - -> &mut FxHashMap, (Linkage, Visibility)> + -> &mut FxHashMap, (Linkage, Visibility)> { &mut self.items } diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index 73fdbfe8831e3..c873580e3ad6c 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -17,6 +17,7 @@ use dep_graph::{DepKind, DepTrackingMapConfig}; use infer::TransNormalize; use std::marker::PhantomData; use syntax_pos::DUMMY_SP; +use hir::def_id::DefId; use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable}; use ty::{self, Ty, TyCtxt}; use ty::subst::{Subst, Substs}; @@ -119,6 +120,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { let substituted = self.erase_regions(&substituted); AssociatedTypeNormalizerEnv::new(self, param_env).fold(&substituted) } + + pub fn trans_impl_self_ty(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) + -> Ty<'tcx> + { + self.trans_apply_param_substs(substs, &self.type_of(def_id)) + } } struct AssociatedTypeNormalizer<'a, 'gcx: 'a> { @@ -214,4 +221,3 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> { DepKind::TraitSelect } } - diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 61b19227744c1..5b87273194c69 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -45,6 +45,16 @@ pub enum InstanceDef<'tcx> { CloneShim(DefId, Ty<'tcx>), } +impl<'a, 'tcx> Instance<'tcx> { + pub fn ty(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>) + -> Ty<'tcx> + { + let ty = tcx.type_of(self.def.def_id()); + tcx.trans_apply_param_substs(self.substs, &ty) + } +} + impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(&self) -> DefId { @@ -59,15 +69,46 @@ impl<'tcx> InstanceDef<'tcx> { } } - #[inline] - pub fn def_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> { - tcx.type_of(self.def_id()) - } - #[inline] pub fn attrs<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> { tcx.get_attrs(self.def_id()) } + + pub fn is_inline<'a>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx> + ) -> bool { + use hir::map::DefPathData; + let def_id = match *self { + ty::InstanceDef::Item(def_id) => def_id, + ty::InstanceDef::DropGlue(_, Some(_)) => return false, + _ => return true + }; + match tcx.def_key(def_id).disambiguated_data.data { + DefPathData::StructCtor | + DefPathData::EnumVariant(..) | + DefPathData::ClosureExpr => true, + _ => false + } + } + + pub fn requires_local<'a>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx> + ) -> bool { + use syntax::attr::requests_inline; + if self.is_inline(tcx) { + return true + } + if let ty::InstanceDef::DropGlue(..) = *self { + // Drop glue wants to be instantiated at every translation + // unit, but without an #[inline] hint. We should make this + // available to normal end-users. + return true + } + requests_inline(&self.attrs(tcx)[..]) || + tcx.is_const_fn(self.def_id()) + } } impl<'tcx> fmt::Display for Instance<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 7ba063adff4c2..f6dd8b6e021b6 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -27,7 +27,7 @@ use middle::resolve_lifetime::{ResolveLifetimes, Region, ObjectLifetimeDefault}; use middle::stability::{self, DeprecationEntry}; use middle::lang_items::{LanguageItems, LangItem}; use middle::exported_symbols::SymbolExportLevel; -use middle::trans::{CodegenUnit, Stats}; +use mir::mono::{CodegenUnit, Stats}; use mir; use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 40ea4e1801b26..a54f15532b18f 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -23,3 +23,4 @@ syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } byteorder = { version = "1.1", features = ["i128"] } rustc_apfloat = { path = "../librustc_apfloat" } +rustc_trans_utils = { path = "../librustc_trans_utils" } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index c0cce6a461832..a37cf41baaba3 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -57,9 +57,7 @@ pub fn eval_body<'a, 'tcx>( if ecx.tcx.has_attr(instance.def_id(), "linkage") { return Err(ConstEvalError::NotConst("extern global".to_string()).into()); } - // FIXME(eddyb) use `Instance::ty` when it becomes available. - let instance_ty = - ecx.monomorphize(instance.def.def_ty(tcx), instance.substs); + let instance_ty = instance.ty(tcx); if tcx.interpret_interner.borrow().get_cached(cid).is_none() { let mir = ecx.load_mir(instance.def)?; let layout = ecx.layout_of(instance_ty)?; diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 0b5801c353995..140da7e1097f5 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -172,9 +172,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { M::global_item_with_linkage(self, cid.instance, mutability)?; return Ok(false); } - // FIXME(eddyb) use `Instance::ty` when it becomes available. - let instance_ty = - self.monomorphize(instance.def.def_ty(self.tcx), instance.substs); + let instance_ty = instance.ty(self.tcx); let layout = self.layout_of(instance_ty)?; assert!(!layout.is_unsized()); let ptr = self.memory.allocate( diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index 1f6e4a7cde783..3eef0578360ce 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -72,9 +72,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { ty::TyFnPtr(sig) => { let fn_ptr = self.value_to_primval(func)?.to_ptr()?; let instance = self.memory.get_fn(fn_ptr)?; - // FIXME(eddyb) use `Instance::ty` when it becomes available. - let instance_ty = - self.monomorphize(instance.def.def_ty(self.tcx), instance.substs); + let instance_ty = instance.ty(self.tcx); match instance_ty.sty { ty::TyFnDef(..) => { let real_sig = instance_ty.fn_sig(self.tcx); diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index e7dd94f75e5b4..4d26230e0612b 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -54,6 +54,7 @@ extern crate core; // for NonZero extern crate log_settings; extern crate rustc_apfloat; extern crate byteorder; +extern crate rustc_trans_utils; mod diagnostics; @@ -65,6 +66,7 @@ mod shim; pub mod transform; pub mod util; pub mod interpret; +pub mod monomorphize; use rustc::ty::maps::Providers; diff --git a/src/librustc_trans_utils/collector.rs b/src/librustc_mir/monomorphize/collector.rs similarity index 82% rename from src/librustc_trans_utils/collector.rs rename to src/librustc_mir/monomorphize/collector.rs index 56b1a0238a1a6..44dedde522941 100644 --- a/src/librustc_trans_utils/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Translation Item Collection +//! Mono Item Collection //! =========================== //! //! This module is responsible for discovering all items that will contribute to @@ -22,7 +22,7 @@ //! in crate X might produce monomorphizations that are compiled into crate Y. //! We also have to collect these here. //! -//! The following kinds of "translation items" are handled here: +//! The following kinds of "mono items" are handled here: //! //! - Functions //! - Methods @@ -43,24 +43,24 @@ //! ----------------- //! Let's define some terms first: //! -//! - A "translation item" is something that results in a function or global in -//! the LLVM IR of a codegen unit. Translation items do not stand on their -//! own, they can reference other translation items. For example, if function -//! `foo()` calls function `bar()` then the translation item for `foo()` -//! references the translation item for function `bar()`. In general, the -//! definition for translation item A referencing a translation item B is that +//! - A "mono item" is something that results in a function or global in +//! the LLVM IR of a codegen unit. Mono items do not stand on their +//! own, they can reference other mono items. For example, if function +//! `foo()` calls function `bar()` then the mono item for `foo()` +//! references the mono item for function `bar()`. In general, the +//! definition for mono item A referencing a mono item B is that //! the LLVM artifact produced for A references the LLVM artifact produced //! for B. //! -//! - Translation items and the references between them form a directed graph, -//! where the translation items are the nodes and references form the edges. -//! Let's call this graph the "translation item graph". +//! - Mono items and the references between them form a directed graph, +//! where the mono items are the nodes and references form the edges. +//! Let's call this graph the "mono item graph". //! -//! - The translation item graph for a program contains all translation items +//! - The mono item graph for a program contains all mono items //! that are needed in order to produce the complete LLVM IR of the program. //! //! The purpose of the algorithm implemented in this module is to build the -//! translation item graph for the current crate. It runs in two phases: +//! mono item graph for the current crate. It runs in two phases: //! //! 1. Discover the roots of the graph by traversing the HIR of the crate. //! 2. Starting from the roots, find neighboring nodes by inspecting the MIR @@ -69,26 +69,26 @@ //! //! ### Discovering roots //! -//! The roots of the translation item graph correspond to the non-generic +//! The roots of the mono item graph correspond to the non-generic //! syntactic items in the source code. We find them by walking the HIR of the //! crate, and whenever we hit upon a function, method, or static item, we -//! create a translation item consisting of the items DefId and, since we only +//! create a mono item consisting of the items DefId and, since we only //! consider non-generic items, an empty type-substitution set. //! //! ### Finding neighbor nodes -//! Given a translation item node, we can discover neighbors by inspecting its +//! Given a mono item node, we can discover neighbors by inspecting its //! MIR. We walk the MIR and any time we hit upon something that signifies a -//! reference to another translation item, we have found a neighbor. Since the -//! translation item we are currently at is always monomorphic, we also know the +//! reference to another mono item, we have found a neighbor. Since the +//! mono item we are currently at is always monomorphic, we also know the //! concrete type arguments of its neighbors, and so all neighbors again will be //! monomorphic. The specific forms a reference to a neighboring node can take //! in MIR are quite diverse. Here is an overview: //! //! #### Calling Functions/Methods -//! The most obvious form of one translation item referencing another is a +//! The most obvious form of one mono item referencing another is a //! function or method call (represented by a CALL terminator in MIR). But //! calls are not the only thing that might introduce a reference between two -//! function translation items, and as we will see below, they are just a +//! function mono items, and as we will see below, they are just a //! specialized of the form described next, and consequently will don't get any //! special treatment in the algorithm. //! @@ -112,10 +112,10 @@ //! } //! ``` //! The MIR of none of these functions will contain an explicit call to -//! `print_val::`. Nonetheless, in order to translate this program, we need +//! `print_val::`. Nonetheless, in order to mono this program, we need //! an instance of this function. Thus, whenever we encounter a function or //! method in operand position, we treat it as a neighbor of the current -//! translation item. Calls are just a special case of that. +//! mono item. Calls are just a special case of that. //! //! #### Closures //! In a way, closures are a simple case. Since every closure object needs to be @@ -124,8 +124,8 @@ //! true for closures inlined from other crates. //! //! #### Drop glue -//! Drop glue translation items are introduced by MIR drop-statements. The -//! generated translation item will again have drop-glue item neighbors if the +//! Drop glue mono items are introduced by MIR drop-statements. The +//! generated mono item will again have drop-glue item neighbors if the //! type to be dropped contains nested values that also need to be dropped. It //! might also have a function item neighbor for the explicit `Drop::drop` //! implementation of its type. @@ -150,8 +150,8 @@ //! defined in the source code of that crate. It will also contain monomorphic //! instantiations of any extern generic functions and of functions marked with //! #[inline]. -//! The collection algorithm handles this more or less transparently. If it is -//! about to create a translation item for something with an external `DefId`, +//! The collection algorithm handles this more or less mono. If it is +//! about to create a mono item for something with an external `DefId`, //! it will take a look if the MIR for that item is available, and if so just //! proceed normally. If the MIR is not available, it assumes that the item is //! just linked to and no node is created; which is exactly what we want, since @@ -159,14 +159,14 @@ //! //! Eager and Lazy Collection Mode //! ------------------------------ -//! Translation item collection can be performed in one of two modes: +//! Mono item collection can be performed in one of two modes: //! //! - Lazy mode means that items will only be instantiated when actually //! referenced. The goal is to produce the least amount of machine code //! possible. //! //! - Eager mode is meant to be used in conjunction with incremental compilation -//! where a stable set of translation items is more important than a minimal +//! where a stable set of mono items is more important than a minimal //! one. Thus, eager mode will instantiate drop-glue for every drop-able type //! in the crate, even of no drop call for that type exists (yet). It will //! also instantiate default implementations of trait methods, something that @@ -183,9 +183,9 @@ //! statics we cannot inspect these properly. //! //! ### Const Fns -//! Ideally, no translation item should be generated for const fns unless there +//! Ideally, no mono item should be generated for const fns unless there //! is a call to them that cannot be evaluated at compile time. At the moment -//! this is not implemented however: a translation item will be produced +//! this is not implemented however: a mono item will be produced //! regardless of whether it is actually needed or not. use rustc::hir; @@ -195,42 +195,41 @@ use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; use rustc::middle::lang_items::{ExchangeMallocFnLangItem}; -use rustc::middle::trans::TransItem; use rustc::traits; use rustc::ty::subst::Substs; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::mir::{self, Location}; use rustc::mir::visit::Visitor as MirVisitor; +use rustc::mir::mono::MonoItem; -use common::{def_ty, instance_ty, type_has_metadata}; use monomorphize::{self, Instance}; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; -use trans_item::{TransItemExt, DefPathBasedNames, InstantiationMode}; +use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; use rustc_data_structures::bitvec::BitVector; use syntax::attr; #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] -pub enum TransItemCollectionMode { +pub enum MonoItemCollectionMode { Eager, Lazy } -/// Maps every translation item to all translation items it references in its +/// Maps every mono item to all mono items it references in its /// body. pub struct InliningMap<'tcx> { - // Maps a source translation item to the range of translation items + // Maps a source mono item to the range of mono items // accessed by it. // The two numbers in the tuple are the start (inclusive) and // end index (exclusive) within the `targets` vecs. - index: FxHashMap, (usize, usize)>, - targets: Vec>, + index: FxHashMap, (usize, usize)>, + targets: Vec>, - // Contains one bit per translation item in the `targets` field. That bit - // is true if that translation item needs to be inlined into every CGU. + // Contains one bit per mono item in the `targets` field. That bit + // is true if that mono item needs to be inlined into every CGU. inlines: BitVector, } @@ -245,9 +244,9 @@ impl<'tcx> InliningMap<'tcx> { } fn record_accesses(&mut self, - source: TransItem<'tcx>, + source: MonoItem<'tcx>, new_targets: I) - where I: Iterator, bool)> + ExactSizeIterator + where I: Iterator, bool)> + ExactSizeIterator { assert!(!self.index.contains_key(&source)); @@ -271,8 +270,8 @@ impl<'tcx> InliningMap<'tcx> { // Internally iterate over all items referenced by `source` which will be // made available for inlining. - pub fn with_inlining_candidates(&self, source: TransItem<'tcx>, mut f: F) - where F: FnMut(TransItem<'tcx>) + pub fn with_inlining_candidates(&self, source: MonoItem<'tcx>, mut f: F) + where F: FnMut(MonoItem<'tcx>) { if let Some(&(start_index, end_index)) = self.index.get(&source) { for (i, candidate) in self.targets[start_index .. end_index] @@ -287,7 +286,7 @@ impl<'tcx> InliningMap<'tcx> { // Internally iterate over all items and the things each accesses. pub fn iter_accesses(&self, mut f: F) - where F: FnMut(TransItem<'tcx>, &[TransItem<'tcx>]) + where F: FnMut(MonoItem<'tcx>, &[MonoItem<'tcx>]) { for (&accessor, &(start_index, end_index)) in &self.index { f(accessor, &self.targets[start_index .. end_index]) @@ -295,13 +294,13 @@ impl<'tcx> InliningMap<'tcx> { } } -pub fn collect_crate_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - mode: TransItemCollectionMode) - -> (FxHashSet>, +pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + mode: MonoItemCollectionMode) + -> (FxHashSet>, InliningMap<'tcx>) { let roots = collect_roots(tcx, mode); - debug!("Building translation item graph, beginning at roots"); + debug!("Building mono item graph, beginning at roots"); let mut visited = FxHashSet(); let mut recursion_depths = DefIdMap(); let mut inlining_map = InliningMap::new(); @@ -320,8 +319,8 @@ pub fn collect_crate_translation_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Find all non-generic items by walking the HIR. These items serve as roots to // start monomorphizing from. fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - mode: TransItemCollectionMode) - -> Vec> { + mode: MonoItemCollectionMode) + -> Vec> { debug!("Collecting roots"); let mut roots = Vec::new(); @@ -348,10 +347,10 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, roots } -// Collect all monomorphized translation items reachable from `starting_point` +// Collect all monomorphized items reachable from `starting_point` fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - starting_point: TransItem<'tcx>, - visited: &mut FxHashSet>, + starting_point: MonoItem<'tcx>, + visited: &mut FxHashSet>, recursion_depths: &mut DefIdMap, inlining_map: &mut InliningMap<'tcx>) { if !visited.insert(starting_point.clone()) { @@ -364,23 +363,23 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let recursion_depth_reset; match starting_point { - TransItem::Static(node_id) => { + MonoItem::Static(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let instance = Instance::mono(tcx, def_id); // Sanity check whether this ended up being collected accidentally - debug_assert!(should_trans_locally(tcx, &instance)); + debug_assert!(should_monomorphize_locally(tcx, &instance)); - let ty = instance_ty(tcx, &instance); + let ty = instance.ty(tcx); visit_drop_use(tcx, ty, true, &mut neighbors); recursion_depth_reset = None; collect_neighbours(tcx, instance, true, &mut neighbors); } - TransItem::Fn(instance) => { + MonoItem::Fn(instance) => { // Sanity check whether this ended up being collected accidentally - debug_assert!(should_trans_locally(tcx, &instance)); + debug_assert!(should_monomorphize_locally(tcx, &instance)); // Keep track of the monomorphization recursion depth recursion_depth_reset = Some(check_recursion_limit(tcx, @@ -390,7 +389,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, collect_neighbours(tcx, instance, false, &mut neighbors); } - TransItem::GlobalAsm(..) => { + MonoItem::GlobalAsm(..) => { recursion_depth_reset = None; } } @@ -409,16 +408,16 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn record_accesses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - caller: TransItem<'tcx>, - callees: &[TransItem<'tcx>], + caller: MonoItem<'tcx>, + callees: &[MonoItem<'tcx>], inlining_map: &mut InliningMap<'tcx>) { - let is_inlining_candidate = |trans_item: &TransItem<'tcx>| { - trans_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy + let is_inlining_candidate = |mono_item: &MonoItem<'tcx>| { + mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy }; let accesses = callees.into_iter() - .map(|trans_item| { - (*trans_item, is_inlining_candidate(trans_item)) + .map(|mono_item| { + (*mono_item, is_inlining_candidate(mono_item)) }); inlining_map.record_accesses(caller, accesses); @@ -495,7 +494,7 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct MirNeighborCollector<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a mir::Mir<'tcx>, - output: &'a mut Vec>, + output: &'a mut Vec>, param_substs: &'tcx Substs<'tcx>, const_context: bool, } @@ -522,10 +521,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. if target_ty.is_trait() && !source_ty.is_trait() { - create_trans_items_for_vtable_methods(self.tcx, - target_ty, - source_ty, - self.output); + create_mono_items_for_vtable_methods(self.tcx, + target_ty, + source_ty, + self.output); } } mir::Rvalue::Cast(mir::CastKind::ReifyFnPointer, ref operand, _) => { @@ -542,7 +541,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::TyClosure(def_id, substs) => { let instance = monomorphize::resolve_closure( self.tcx, def_id, substs, ty::ClosureKind::FnOnce); - self.output.push(create_fn_trans_item(instance)); + self.output.push(create_fn_mono_item(instance)); } _ => bug!(), } @@ -554,8 +553,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { .require(ExchangeMallocFnLangItem) .unwrap_or_else(|e| tcx.sess.fatal(&e)); let instance = Instance::mono(tcx, exchange_malloc_fn_def_id); - if should_trans_locally(tcx, &instance) { - self.output.push(create_fn_trans_item(instance)); + if should_monomorphize_locally(tcx, &instance) { + self.output.push(create_fn_mono_item(instance)); } } _ => { /* not interesting */ } @@ -645,9 +644,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let tcx = self.tcx; let instance = Instance::mono(tcx, static_.def_id); - if should_trans_locally(tcx, &instance) { + if should_monomorphize_locally(tcx, &instance) { let node_id = tcx.hir.as_local_node_id(static_.def_id).unwrap(); - self.output.push(TransItem::Static(node_id)); + self.output.push(MonoItem::Static(node_id)); } self.super_static(static_, context, location); @@ -657,7 +656,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn visit_drop_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, is_direct_call: bool, - output: &mut Vec>) + output: &mut Vec>) { let instance = monomorphize::resolve_drop_in_place(tcx, ty); visit_instance_use(tcx, instance, is_direct_call, output); @@ -666,7 +665,7 @@ fn visit_drop_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn visit_fn_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, is_direct_call: bool, - output: &mut Vec>) + output: &mut Vec>) { if let ty::TyFnDef(def_id, substs) = ty.sty { let instance = ty::Instance::resolve(tcx, @@ -680,10 +679,10 @@ fn visit_fn_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn visit_instance_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: ty::Instance<'tcx>, is_direct_call: bool, - output: &mut Vec>) + output: &mut Vec>) { debug!("visit_item_use({:?}, is_direct_call={:?})", instance, is_direct_call); - if !should_trans_locally(tcx, &instance) { + if !should_monomorphize_locally(tcx, &instance) { return } @@ -697,26 +696,26 @@ fn visit_instance_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::InstanceDef::DropGlue(_, None) => { // don't need to emit shim if we are calling directly. if !is_direct_call { - output.push(create_fn_trans_item(instance)); + output.push(create_fn_mono_item(instance)); } } ty::InstanceDef::DropGlue(_, Some(_)) => { - output.push(create_fn_trans_item(instance)); + output.push(create_fn_mono_item(instance)); } ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Item(..) | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::CloneShim(..) => { - output.push(create_fn_trans_item(instance)); + output.push(create_fn_mono_item(instance)); } } } // Returns true if we should translate an instance in the local crate. // Returns false if we can just link to the upstream crate and therefore don't -// need a translation item. -fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instance<'tcx>) - -> bool { +// need a mono item. +fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instance<'tcx>) + -> bool { let def_id = match instance.def { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::ClosureOnceShim { .. } | @@ -740,7 +739,7 @@ fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instan false } else { if !tcx.is_mir_available(def_id) { - bug!("Cannot create local trans-item for {:?}", def_id) + bug!("Cannot create local mono-item for {:?}", def_id) } true } @@ -790,12 +789,25 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, target_ty: Ty<'tcx>) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { - if type_has_metadata(tcx, inner_source) { + let type_has_metadata = |ty: Ty<'tcx>| -> bool { + use syntax_pos::DUMMY_SP; + if ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) { + return false; + } + let tail = tcx.struct_tail(ty); + match tail.sty { + ty::TyForeign(..) => false, + ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true, + _ => bug!("unexpected unsized tail: {:?}", tail.sty), + } + }; + if type_has_metadata(inner_source) { (inner_source, inner_target) } else { tcx.struct_lockstep_tails(inner_source, inner_target) } }; + match (&source_ty.sty, &target_ty.sty) { (&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }), &ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) | @@ -838,17 +850,17 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn create_fn_trans_item<'a, 'tcx>(instance: Instance<'tcx>) -> TransItem<'tcx> { - debug!("create_fn_trans_item(instance={})", instance); - TransItem::Fn(instance) +fn create_fn_mono_item<'a, 'tcx>(instance: Instance<'tcx>) -> MonoItem<'tcx> { + debug!("create_fn_mono_item(instance={})", instance); + MonoItem::Fn(instance) } -/// Creates a `TransItem` for each method that is referenced by the vtable for +/// Creates a `MonoItem` for each method that is referenced by the vtable for /// the given trait/impl pair. -fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - trait_ty: Ty<'tcx>, - impl_ty: Ty<'tcx>, - output: &mut Vec>) { +fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_ty: Ty<'tcx>, + impl_ty: Ty<'tcx>, + output: &mut Vec>) { assert!(!trait_ty.needs_subst() && !trait_ty.has_escaping_regions() && !impl_ty.needs_subst() && !impl_ty.has_escaping_regions()); @@ -865,8 +877,8 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap()) - .filter(|&instance| should_trans_locally(tcx, &instance)) - .map(|instance| create_fn_trans_item(instance)); + .filter(|&instance| should_monomorphize_locally(tcx, &instance)) + .map(|instance| create_fn_mono_item(instance)); output.extend(methods); } // Also add the destructor @@ -880,8 +892,8 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - mode: TransItemCollectionMode, - output: &'b mut Vec>, + mode: MonoItemCollectionMode, + output: &'b mut Vec>, entry_fn: Option, } @@ -900,10 +912,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { } hir::ItemImpl(..) => { - if self.mode == TransItemCollectionMode::Eager { - create_trans_items_for_default_impls(self.tcx, - item, - self.output); + if self.mode == MonoItemCollectionMode::Eager { + create_mono_items_for_default_impls(self.tcx, + item, + self.output); } } @@ -911,12 +923,12 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemStruct(_, ref generics) | hir::ItemUnion(_, ref generics) => { if !generics.is_parameterized() { - if self.mode == TransItemCollectionMode::Eager { + if self.mode == MonoItemCollectionMode::Eager { let def_id = self.tcx.hir.local_def_id(item.id); debug!("RootCollector: ADT drop-glue for {}", def_id_to_string(self.tcx, def_id)); - let ty = def_ty(self.tcx, def_id, Substs::empty()); + let ty = Instance::new(def_id, Substs::empty()).ty(self.tcx); visit_drop_use(self.tcx, ty, true, self.output); } } @@ -925,16 +937,16 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { debug!("RootCollector: ItemGlobalAsm({})", def_id_to_string(self.tcx, self.tcx.hir.local_def_id(item.id))); - self.output.push(TransItem::GlobalAsm(item.id)); + self.output.push(MonoItem::GlobalAsm(item.id)); } hir::ItemStatic(..) => { debug!("RootCollector: ItemStatic({})", def_id_to_string(self.tcx, self.tcx.hir.local_def_id(item.id))); - self.output.push(TransItem::Static(item.id)); + self.output.push(MonoItem::Static(item.id)); } hir::ItemConst(..) => { - // const items only generate translation items if they are + // const items only generate mono items if they are // actually used somewhere. Just declaring them is insufficient. } hir::ItemFn(..) => { @@ -946,7 +958,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { def_id_to_string(tcx, def_id)); let instance = Instance::mono(tcx, def_id); - self.output.push(TransItem::Fn(instance)); + self.output.push(MonoItem::Fn(instance)); } } } @@ -968,7 +980,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { def_id_to_string(tcx, def_id)); let instance = Instance::mono(tcx, def_id); - self.output.push(TransItem::Fn(instance)); + self.output.push(MonoItem::Fn(instance)); } } _ => { /* Nothing to do here */ } @@ -979,10 +991,10 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { fn is_root(&self, def_id: DefId) -> bool { !item_has_type_parameters(self.tcx, def_id) && match self.mode { - TransItemCollectionMode::Eager => { + MonoItemCollectionMode::Eager => { true } - TransItemCollectionMode::Lazy => { + MonoItemCollectionMode::Lazy => { self.entry_fn == Some(def_id) || self.tcx.is_exported_symbol(def_id) || attr::contains_name(&self.tcx.get_attrs(def_id), @@ -997,9 +1009,9 @@ fn item_has_type_parameters<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId generics.parent_types as usize + generics.types.len() > 0 } -fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &'tcx hir::Item, - output: &mut Vec>) { +fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &'tcx hir::Item, + output: &mut Vec>) { match item.node { hir::ItemImpl(_, _, @@ -1013,7 +1025,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let impl_def_id = tcx.hir.local_def_id(item.id); - debug!("create_trans_items_for_default_impls(item={})", + debug!("create_mono_items_for_default_impls(item={})", def_id_to_string(tcx, impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { @@ -1036,9 +1048,10 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, method.def_id, callee_substs).unwrap(); - let trans_item = create_fn_trans_item(instance); - if trans_item.is_instantiable(tcx) && should_trans_locally(tcx, &instance) { - output.push(trans_item); + let mono_item = create_fn_mono_item(instance); + if mono_item.is_instantiable(tcx) + && should_monomorphize_locally(tcx, &instance) { + output.push(mono_item); } } } @@ -1053,7 +1066,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>, const_context: bool, - output: &mut Vec>) + output: &mut Vec>) { let mir = tcx.instance_mir(instance.def); diff --git a/src/librustc_trans_utils/trans_item.rs b/src/librustc_mir/monomorphize/item.rs similarity index 88% rename from src/librustc_trans_utils/trans_item.rs rename to src/librustc_mir/monomorphize/item.rs index 817ceefeb7fe9..c3fb126ea1822 100644 --- a/src/librustc_trans_utils/trans_item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -14,11 +14,9 @@ //! item-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. -use common; use monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::middle::trans::Linkage; use rustc::session::config::OptLevel; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; @@ -27,11 +25,12 @@ use syntax::ast; use syntax::attr::{self, InlineAttr}; use std::fmt::{self, Write}; use std::iter; - -pub use rustc::middle::trans::TransItem; +use rustc::mir::mono::Linkage; +use syntax_pos::symbol::Symbol; +pub use rustc::mir::mono::MonoItem; pub fn linkage_by_name(name: &str) -> Option { - use rustc::middle::trans::Linkage::*; + use rustc::mir::mono::Linkage::*; // Use the names from src/llvm/docs/LangRef.rst here. Most types are only // applicable to variable declarations and may not really make sense for @@ -60,7 +59,7 @@ pub fn linkage_by_name(name: &str) -> Option { /// Describes how a translation item will be instantiated in object files. #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum InstantiationMode { - /// There will be exactly one instance of the given TransItem. It will have + /// There will be exactly one instance of the given MonoItem. It will have /// external linkage so that it can be linked to from other codegen units. GloballyShared { /// In some compilation scenarios we may decide to take functions that @@ -77,14 +76,39 @@ pub enum InstantiationMode { may_conflict: bool, }, - /// Each codegen unit containing a reference to the given TransItem will + /// Each codegen unit containing a reference to the given MonoItem will /// have its own private copy of the function (with internal linkage). LocalCopy, } -pub trait TransItemExt<'a, 'tcx>: fmt::Debug { - fn as_trans_item(&self) -> &TransItem<'tcx>; +pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { + fn as_mono_item(&self) -> &MonoItem<'tcx>; + + fn is_generic_fn(&self) -> bool { + match *self.as_mono_item() { + MonoItem::Fn(ref instance) => { + instance.substs.types().next().is_some() + } + MonoItem::Static(..) | + MonoItem::GlobalAsm(..) => false, + } + } + fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName { + match *self.as_mono_item() { + MonoItem::Fn(instance) => tcx.symbol_name(instance), + MonoItem::Static(node_id) => { + let def_id = tcx.hir.local_def_id(node_id); + tcx.symbol_name(Instance::mono(tcx, def_id)) + } + MonoItem::GlobalAsm(node_id) => { + let def_id = tcx.hir.local_def_id(node_id); + ty::SymbolName { + name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str() + } + } + } + } fn instantiation_mode(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> InstantiationMode { @@ -93,12 +117,12 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug { tcx.sess.opts.optimize != OptLevel::No }); - match *self.as_trans_item() { - TransItem::Fn(ref instance) => { + match *self.as_mono_item() { + MonoItem::Fn(ref instance) => { // If this function isn't inlined or otherwise has explicit // linkage, then we'll be creating a globally shared version. if self.explicit_linkage(tcx).is_some() || - !common::requests_inline(tcx, instance) + !instance.def.requires_local(tcx) { return InstantiationMode::GloballyShared { may_conflict: false } } @@ -123,20 +147,20 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug { } } } - TransItem::Static(..) => { + MonoItem::Static(..) => { InstantiationMode::GloballyShared { may_conflict: false } } - TransItem::GlobalAsm(..) => { + MonoItem::GlobalAsm(..) => { InstantiationMode::GloballyShared { may_conflict: false } } } } fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { - let def_id = match *self.as_trans_item() { - TransItem::Fn(ref instance) => instance.def_id(), - TransItem::Static(node_id) => tcx.hir.local_def_id(node_id), - TransItem::GlobalAsm(..) => return None, + let def_id = match *self.as_mono_item() { + MonoItem::Fn(ref instance) => instance.def_id(), + MonoItem::Static(node_id) => tcx.hir.local_def_id(node_id), + MonoItem::GlobalAsm(..) => return None, }; let attributes = tcx.get_attrs(def_id); @@ -183,11 +207,11 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug { /// which will never be accessed) in its place. fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { debug!("is_instantiable({:?})", self); - let (def_id, substs) = match *self.as_trans_item() { - TransItem::Fn(ref instance) => (instance.def_id(), instance.substs), - TransItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()), + let (def_id, substs) = match *self.as_mono_item() { + MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), + MonoItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()), // global asm never has predicates - TransItem::GlobalAsm(..) => return true + MonoItem::GlobalAsm(..) => return true }; let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs); @@ -197,16 +221,16 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug { fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { let hir_map = &tcx.hir; - return match *self.as_trans_item() { - TransItem::Fn(instance) => { + return match *self.as_mono_item() { + MonoItem::Fn(instance) => { to_string_internal(tcx, "fn ", instance) }, - TransItem::Static(node_id) => { + MonoItem::Static(node_id) => { let def_id = hir_map.local_def_id(node_id); let instance = Instance::new(def_id, tcx.intern_substs(&[])); to_string_internal(tcx, "static ", instance) }, - TransItem::GlobalAsm(..) => { + MonoItem::GlobalAsm(..) => { "global_asm".to_string() } }; @@ -224,14 +248,14 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug { } } -impl<'a, 'tcx> TransItemExt<'a, 'tcx> for TransItem<'tcx> { - fn as_trans_item(&self) -> &TransItem<'tcx> { +impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { + fn as_mono_item(&self) -> &MonoItem<'tcx> { self } } //=----------------------------------------------------------------------------- -// TransItem String Keys +// MonoItem String Keys //=----------------------------------------------------------------------------- // The code below allows for producing a unique string key for a trans item. diff --git a/src/librustc_trans_utils/monomorphize.rs b/src/librustc_mir/monomorphize/mod.rs similarity index 97% rename from src/librustc_trans_utils/monomorphize.rs rename to src/librustc_mir/monomorphize/mod.rs index d586d1ac31506..fcf0d71dccb48 100644 --- a/src/librustc_trans_utils/monomorphize.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -16,6 +16,11 @@ use rustc::ty::subst::Kind; use rustc::ty::{self, Ty, TyCtxt}; pub use rustc::ty::Instance; +pub use self::item::{MonoItem, MonoItemExt}; + +pub mod collector; +pub mod item; +pub mod partitioning; fn fn_once_adapter_instance<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -124,4 +129,3 @@ pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } } - diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs similarity index 93% rename from src/librustc_trans/partitioning.rs rename to src/librustc_mir/monomorphize/partitioning.rs index 03c0f13e2f5f7..e2640d695c6d0 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -102,21 +102,21 @@ //! source-level module, functions from the same module will be available for //! inlining, even when they are not marked #[inline]. -use collector::InliningMap; -use common; +use monomorphize::collector::InliningMap; use rustc::dep_graph::WorkProductId; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; -use rustc::middle::trans::{Linkage, Visibility}; +use rustc::mir::mono::{Linkage, Visibility}; use rustc::ty::{self, TyCtxt, InstanceDef}; use rustc::ty::item_path::characteristic_def_id_of_type; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use std::collections::hash_map::Entry; use syntax::ast::NodeId; use syntax::symbol::{Symbol, InternedString}; -use trans_item::{TransItem, BaseTransItemExt, TransItemExt, InstantiationMode}; +use rustc::mir::mono::MonoItem; +use monomorphize::item::{MonoItemExt, InstantiationMode}; -pub use rustc::middle::trans::CodegenUnit; +pub use rustc::mir::mono::CodegenUnit; pub enum PartitioningStrategy { /// Generate one codegen unit per source-level module. @@ -129,7 +129,7 @@ pub enum PartitioningStrategy { pub trait CodegenUnitExt<'tcx> { fn as_codegen_unit(&self) -> &CodegenUnit<'tcx>; - fn contains_item(&self, item: &TransItem<'tcx>) -> bool { + fn contains_item(&self, item: &MonoItem<'tcx>) -> bool { self.items().contains_key(item) } @@ -139,7 +139,7 @@ pub trait CodegenUnitExt<'tcx> { &self.as_codegen_unit().name() } - fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { + fn items(&self) -> &FxHashMap, (Linkage, Visibility)> { &self.as_codegen_unit().items() } @@ -149,17 +149,17 @@ pub trait CodegenUnitExt<'tcx> { fn items_in_deterministic_order<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Vec<(TransItem<'tcx>, - (Linkage, Visibility))> { + -> Vec<(MonoItem<'tcx>, + (Linkage, Visibility))> { // The codegen tests rely on items being process in the same order as // they appear in the file, so for local items, we sort by node_id first #[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct ItemSortKey(Option, ty::SymbolName); fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: TransItem<'tcx>) -> ItemSortKey { + item: MonoItem<'tcx>) -> ItemSortKey { ItemSortKey(match item { - TransItem::Fn(ref instance) => { + MonoItem::Fn(ref instance) => { match instance.def { // We only want to take NodeIds of user-defined // instances into account. The others don't matter for @@ -178,8 +178,8 @@ pub trait CodegenUnitExt<'tcx> { } } } - TransItem::Static(node_id) | - TransItem::GlobalAsm(node_id) => { + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => { Some(node_id) } }, item.symbol_name(tcx)) @@ -207,7 +207,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, strategy: PartitioningStrategy, inlining_map: &InliningMap<'tcx>) -> Vec> - where I: Iterator> + where I: Iterator> { // In the first step, we place all regular translation items into their // respective 'home' codegen unit. Regular translation items are all @@ -254,8 +254,8 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, struct PreInliningPartitioning<'tcx> { codegen_units: Vec>, - roots: FxHashSet>, - internalization_candidates: FxHashSet>, + roots: FxHashSet>, + internalization_candidates: FxHashSet>, } /// For symbol internalization, we need to know whether a symbol/trans-item is @@ -269,14 +269,14 @@ enum TransItemPlacement { struct PostInliningPartitioning<'tcx> { codegen_units: Vec>, - trans_item_placements: FxHashMap, TransItemPlacement>, - internalization_candidates: FxHashSet>, + trans_item_placements: FxHashMap, TransItemPlacement>, + internalization_candidates: FxHashSet>, } fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I) -> PreInliningPartitioning<'tcx> - where I: Iterator> + where I: Iterator> { let mut roots = FxHashSet(); let mut codegen_units = FxHashMap(); @@ -309,7 +309,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(explicit_linkage) => (explicit_linkage, Visibility::Default), None => { match trans_item { - TransItem::Fn(ref instance) => { + MonoItem::Fn(ref instance) => { let visibility = match instance.def { InstanceDef::Item(def_id) => { if def_id.is_local() { @@ -333,8 +333,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; (Linkage::External, visibility) } - TransItem::Static(node_id) | - TransItem::GlobalAsm(node_id) => { + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_exported_symbol(def_id) { Visibility::Default @@ -469,9 +469,9 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit internalization_candidates, }; - fn follow_inlining<'tcx>(trans_item: TransItem<'tcx>, + fn follow_inlining<'tcx>(trans_item: MonoItem<'tcx>, inlining_map: &InliningMap<'tcx>, - visited: &mut FxHashSet>) { + visited: &mut FxHashSet>) { if !visited.insert(trans_item) { return; } @@ -501,7 +501,7 @@ fn internalize_symbols<'a, 'tcx>(_tcx: TyCtxt<'a, 'tcx, 'tcx>, // Build a map from every translation item to all the translation items that // reference it. - let mut accessor_map: FxHashMap, Vec>> = FxHashMap(); + let mut accessor_map: FxHashMap, Vec>> = FxHashMap(); inlining_map.iter_accesses(|accessor, accessees| { for accessee in accessees { accessor_map.entry(*accessee) @@ -548,10 +548,10 @@ fn internalize_symbols<'a, 'tcx>(_tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - trans_item: TransItem<'tcx>) + trans_item: MonoItem<'tcx>) -> Option { match trans_item { - TransItem::Fn(instance) => { + MonoItem::Fn(instance) => { let def_id = match instance.def { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::FnPtrShim(..) | @@ -575,7 +575,7 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(impl_def_id) = tcx.impl_of_method(def_id) { // This is a method within an inherent impl, find out what the // self-type is: - let impl_self_ty = common::def_ty(tcx, impl_def_id, instance.substs); + let impl_self_ty = tcx.trans_impl_self_ty(impl_def_id, instance.substs); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { return Some(def_id); } @@ -583,8 +583,8 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(def_id) } - TransItem::Static(node_id) | - TransItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index 131cf59a57184..f1549d9842154 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -28,6 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" } rustc_llvm = { path = "../librustc_llvm" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } rustc_trans_utils = { path = "../librustc_trans_utils" } +rustc_mir = { path = "../librustc_mir" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 78ab25f222e50..32dc1067d37c1 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -11,7 +11,7 @@ use llvm::{self, ValueRef, AttributePlace}; use base; use builder::Builder; -use common::{instance_ty, ty_fn_sig, C_usize}; +use common::{ty_fn_sig, C_usize}; use context::CrateContext; use cabi_x86; use cabi_x86_64; @@ -649,7 +649,7 @@ pub struct FnType<'tcx> { impl<'a, 'tcx> FnType<'tcx> { pub fn of_instance(ccx: &CrateContext<'a, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { - let fn_ty = instance_ty(ccx.tcx(), &instance); + let fn_ty = instance.ty(ccx.tcx()); let sig = ty_fn_sig(ccx, fn_ty); let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); FnType::new(ccx, sig, &[]) diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 695950e672785..825f306499a7c 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -98,10 +98,10 @@ //! DefPaths which are much more robust in the face of changes to the code base. use monomorphize::Instance; -use trans_item::{BaseTransItemExt, InstantiationMode}; +use trans_item::{BaseMonoItemExt, InstantiationMode}; use rustc::middle::weak_lang_items; -use rustc::middle::trans::TransItem; +use rustc::mir::mono::MonoItem; use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -211,7 +211,7 @@ fn get_symbol_hash<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // codegen units) then this symbol may become an exported (but hidden // visibility) symbol. This means that multiple crates may do the same // and we want to be sure to avoid any symbol conflicts here. - match TransItem::Fn(instance).instantiation_mode(tcx) { + match MonoItem::Fn(instance).instantiation_mode(tcx) { InstantiationMode::GloballyShared { may_conflict: true } => { avoid_cross_crate_conflicts = true; } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 911ec56188752..79b3d314e12ff 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -38,8 +38,8 @@ use llvm; use metadata; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::middle::lang_items::StartFnLangItem; -use rustc::middle::trans::{Linkage, Visibility, Stats}; -use rustc::middle::cstore::EncodedMetadata; +use rustc::mir::mono::{Linkage, Visibility, Stats}; +use rustc::middle::cstore::{EncodedMetadata}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf}; use rustc::ty::maps::Providers; @@ -55,7 +55,7 @@ use attributes; use builder::Builder; use callee; use common::{C_bool, C_bytes_in_context, C_i32, C_usize}; -use collector::{self, TransItemCollectionMode}; +use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode}; use common::{self, C_struct_in_context, C_array, CrateContext, val_ty}; use consts; use context::{self, LocalCrateContext, SharedCrateContext}; @@ -64,10 +64,10 @@ use declare; use meth; use mir; use monomorphize::Instance; -use partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt}; +use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt}; use symbol_names_test; use time_graph; -use trans_item::{TransItem, BaseTransItemExt, TransItemExt, DefPathBasedNames}; +use trans_item::{MonoItem, BaseMonoItemExt, MonoItemExt, DefPathBasedNames}; use type_::Type; use type_of::LayoutLlvmExt; use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet}; @@ -89,7 +89,7 @@ use syntax::ast; use mir::operand::OperandValue; pub use rustc_trans_utils::{find_exported_symbols, check_for_rustc_errors_attr}; -pub use rustc_trans_utils::trans_item::linkage_by_name; +pub use rustc_mir::monomorphize::item::linkage_by_name; pub struct StatRecorder<'a, 'tcx: 'a> { ccx: &'a CrateContext<'a, 'tcx>, @@ -468,7 +468,7 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance // release builds. info!("trans_instance({})", instance); - let fn_ty = common::instance_ty(ccx.tcx(), &instance); + let fn_ty = instance.ty(ccx.tcx()); let sig = common::ty_fn_sig(ccx, fn_ty); let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); @@ -530,7 +530,7 @@ fn maybe_create_entry_wrapper(ccx: &CrateContext) { let instance = Instance::mono(ccx.tcx(), main_def_id); - if !ccx.codegen_unit().contains_item(&TransItem::Fn(instance)) { + if !ccx.codegen_unit().contains_item(&MonoItem::Fn(instance)) { // We want to create the wrapper in the same codegen unit as Rust's main // function. return; @@ -943,7 +943,7 @@ fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { #[inline(never)] // give this a place in the profiler fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I) - where I: Iterator> + where I: Iterator> { let mut symbols: Vec<_> = trans_items.map(|trans_item| { (trans_item, trans_item.symbol_name(tcx)) @@ -1002,7 +1002,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( let mode_string = s.to_lowercase(); let mode_string = mode_string.trim(); if mode_string == "eager" { - TransItemCollectionMode::Eager + MonoItemCollectionMode::Eager } else { if mode_string != "lazy" { let message = format!("Unknown codegen-item collection mode '{}'. \ @@ -1011,15 +1011,15 @@ fn collect_and_partition_translation_items<'a, 'tcx>( tcx.sess.warn(&message); } - TransItemCollectionMode::Lazy + MonoItemCollectionMode::Lazy } } - None => TransItemCollectionMode::Lazy + None => MonoItemCollectionMode::Lazy }; let (items, inlining_map) = time(time_passes, "translation item collection", || { - collector::collect_crate_translation_items(tcx, collection_mode) + collector::collect_crate_mono_items(tcx, collection_mode) }); assert_symbols_are_distinct(tcx, items.iter()); @@ -1042,7 +1042,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( let translation_items: DefIdSet = items.iter().filter_map(|trans_item| { match *trans_item { - TransItem::Fn(ref instance) => Some(instance.def_id()), + MonoItem::Fn(ref instance) => Some(instance.def_id()), _ => None, } }).collect(); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 4afeac2e8f589..0a0f2615a1bd1 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -48,7 +48,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(!instance.substs.has_escaping_regions()); assert!(!instance.substs.has_param_types()); - let fn_ty = common::instance_ty(ccx.tcx(), &instance); + let fn_ty = instance.ty(ccx.tcx()); if let Some(&llfn) = ccx.instances().borrow().get(&instance) { return llfn; } @@ -96,7 +96,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert_eq!(common::val_ty(llfn), llptrty); debug!("get_fn: not casting pointer!"); - if common::is_inline_instance(tcx, &instance) { + if instance.def.is_inline(tcx) { attributes::inline(llfn, attributes::InlineAttr::Hint); } let attrs = instance.def.attrs(ccx.tcx()); diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 762cf7a0055d5..b1bdee3fa5fc5 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -16,7 +16,6 @@ use llvm; use llvm::{ValueRef, ContextRef, TypeKind}; use llvm::{True, False, Bool, OperandBundleDef}; use rustc::hir::def_id::DefId; -use rustc::hir::map::DefPathData; use rustc::middle::lang_items::LangItem; use abi; use base; @@ -29,7 +28,7 @@ use value::Value; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{HasDataLayout, LayoutOf}; -use rustc::ty::subst::{Kind, Substs}; +use rustc::ty::subst::Kind; use rustc::hir; use libc::{c_uint, c_char}; @@ -430,38 +429,3 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -pub fn is_inline_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: &ty::Instance<'tcx> -) -> bool { - let def_id = match instance.def { - ty::InstanceDef::Item(def_id) => def_id, - ty::InstanceDef::DropGlue(_, Some(_)) => return false, - _ => return true - }; - match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::StructCtor | - DefPathData::EnumVariant(..) | - DefPathData::ClosureExpr => true, - _ => false - } -} - -/// Given a DefId and some Substs, produces the monomorphic item type. -pub fn def_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - substs: &'tcx Substs<'tcx>) - -> Ty<'tcx> -{ - let ty = tcx.type_of(def_id); - tcx.trans_apply_param_substs(substs, &ty) -} - -/// Return the substituted type of an instance. -pub fn instance_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: &ty::Instance<'tcx>) - -> Ty<'tcx> -{ - let ty = instance.def.def_ty(tcx); - tcx.trans_apply_param_substs(instance.substs, &ty) -} diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 800c7733c3d62..f9fbcebd32e72 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -16,8 +16,8 @@ use rustc::hir::map as hir_map; use rustc::middle::const_val::ConstEvalErr; use debuginfo; use base; -use trans_item::{TransItem, TransItemExt}; -use common::{self, CrateContext, val_ty}; +use monomorphize::{MonoItem, MonoItemExt}; +use common::{CrateContext, val_ty}; use declare; use monomorphize::Instance; use type_::Type; @@ -110,7 +110,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { return g; } - let ty = common::instance_ty(ccx.tcx(), &instance); + let ty = instance.ty(ccx.tcx()); let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) { let llty = ccx.layout_of(ty).llvm_type(ccx); @@ -118,11 +118,11 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { hir_map::NodeItem(&hir::Item { ref attrs, span, node: hir::ItemStatic(..), .. }) => { - let sym = TransItem::Static(id).symbol_name(ccx.tcx()); + let sym = MonoItem::Static(id).symbol_name(ccx.tcx()); let defined_in_current_codegen_unit = ccx.codegen_unit() .items() - .contains_key(&TransItem::Static(id)); + .contains_key(&MonoItem::Static(id)); assert!(!defined_in_current_codegen_unit); if declare::get_declared_value(ccx, &sym[..]).is_some() { @@ -266,7 +266,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }; let instance = Instance::mono(ccx.tcx(), def_id); - let ty = common::instance_ty(ccx.tcx(), &instance); + let ty = instance.ty(ccx.tcx()); let llty = ccx.layout_of(ty).llvm_type(ccx); let g = if val_llty == llty { g diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index b2bb605d01b46..d5e71062f74d7 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -22,19 +22,18 @@ use base; use declare; use monomorphize::Instance; -use partitioning::CodegenUnit; +use monomorphize::partitioning::CodegenUnit; use type_::Type; use type_of::PointeeInfo; use rustc_data_structures::base_n; -use rustc::middle::trans::Stats; +use rustc::mir::mono::Stats; use rustc_data_structures::stable_hasher::StableHashingContextProvider; use rustc::session::config::{self, NoDebugInfo}; use rustc::session::Session; use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc_trans_utils; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; @@ -325,7 +324,17 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { } pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - rustc_trans_utils::common::type_has_metadata(self.tcx, ty) + use syntax_pos::DUMMY_SP; + if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) { + return false; + } + + let tail = self.tcx.struct_tail(ty); + match tail.sty { + ty::TyForeign(..) => false, + ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true, + _ => bug!("unexpected unsized tail: {:?}", tail.sty), + } } pub fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index d09272df3451d..12cd874f86887 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -27,10 +27,10 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, use rustc::hir::def::CtorKind; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::ty::fold::TypeVisitor; -use rustc::ty::subst::Substs; use rustc::ty::util::TypeIdHasher; use rustc::ich::Fingerprint; -use common::{self, CrateContext}; +use rustc::ty::Instance; +use common::CrateContext; use rustc::ty::{self, AdtKind, Ty}; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; use rustc::session::{Session, config}; @@ -1656,7 +1656,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, }; let is_local_to_unit = is_node_local_to_unit(cx, node_id); - let variable_type = common::def_ty(cx.tcx(), node_def_id, Substs::empty()); + let variable_type = Instance::mono(cx.tcx(), node_def_id).ty(cx.tcx()); let type_metadata = type_metadata(cx, variable_type, span); let var_name = tcx.item_name(node_def_id).to_string(); let linkage_name = mangled_name_of_item(cx, node_def_id, ""); diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index e9350256c3055..ae202f3f14291 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -27,7 +27,7 @@ use rustc::hir::def_id::{DefId, CrateNum}; use rustc::ty::subst::Substs; use abi::Abi; -use common::{self, CrateContext}; +use common::CrateContext; use builder::Builder; use monomorphize::Instance; use rustc::ty::{self, Ty}; @@ -427,8 +427,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let self_type = cx.tcx().impl_of_method(instance.def_id()).and_then(|impl_def_id| { // If the method does *not* belong to a trait, proceed if cx.tcx().trait_id_of_impl(impl_def_id).is_none() { - let impl_self_ty = - common::def_ty(cx.tcx(), impl_def_id, instance.substs); + let impl_self_ty = cx.tcx().trans_impl_self_ty(impl_def_id, instance.substs); // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g. `<*mut T>::null`). diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index f6cc1215699c6..c4849c621e8d5 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,6 +43,7 @@ extern crate libc; #[macro_use] extern crate rustc; extern crate jobserver; extern crate num_cpus; +extern crate rustc_mir; extern crate rustc_allocator; extern crate rustc_apfloat; extern crate rustc_back; @@ -84,8 +85,7 @@ use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashSet, FxHashMap}; -use rustc_trans_utils::collector; -use rustc_trans_utils::monomorphize; +use rustc_mir::monomorphize; mod diagnostics; @@ -138,7 +138,6 @@ mod llvm_util; mod metadata; mod meth; mod mir; -mod partitioning; mod symbol_names_test; mod time_graph; mod trans_item; diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index eba2928d84c18..1cb3a66e4d8cf 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -273,7 +273,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { args = &args[..1 + place.has_extra() as usize]; let (drop_fn, fn_ty) = match ty.sty { ty::TyDynamic(..) => { - let fn_ty = common::instance_ty(bcx.ccx.tcx(), &drop_fn); + let fn_ty = drop_fn.ty(bcx.ccx.tcx()); let sig = common::ty_fn_sig(bcx.ccx, fn_ty); let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig); let fn_ty = FnType::new_vtable(bcx.ccx, sig, &[]); @@ -535,8 +535,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { }).collect(); - let callee_ty = common::instance_ty( - bcx.ccx.tcx(), instance.as_ref().unwrap()); + let callee_ty = instance.as_ref().unwrap().ty(bcx.ccx.tcx()); trans_intrinsic_call(&bcx, callee_ty, &fn_ty, &args, dest, terminator.source_info.span); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 991f99e0f6c99..31d8e092c4ae4 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -19,35 +19,33 @@ use attributes; use base; use consts; use context::CrateContext; -use common; use declare; use llvm; use monomorphize::Instance; use type_of::LayoutLlvmExt; use rustc::hir; -use rustc::middle::trans::{Linkage, Visibility}; -use rustc::ty::{self, TyCtxt, TypeFoldable}; +use rustc::mir::mono::{Linkage, Visibility}; +use rustc::ty::{TyCtxt, TypeFoldable}; use rustc::ty::layout::LayoutOf; use syntax::ast; use syntax::attr; use syntax_pos::Span; -use syntax_pos::symbol::Symbol; use std::fmt; -pub use rustc::middle::trans::TransItem; +pub use rustc::mir::mono::MonoItem; -pub use rustc_trans_utils::trans_item::*; -pub use rustc_trans_utils::trans_item::TransItemExt as BaseTransItemExt; +pub use rustc_mir::monomorphize::item::*; +pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; -pub trait TransItemExt<'a, 'tcx>: fmt::Debug + BaseTransItemExt<'a, 'tcx> { +pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { fn define(&self, ccx: &CrateContext<'a, 'tcx>) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", self.to_string(ccx.tcx()), self.to_raw_string(), ccx.codegen_unit().name()); - match *self.as_trans_item() { - TransItem::Static(node_id) => { + match *self.as_mono_item() { + MonoItem::Static(node_id) => { let tcx = ccx.tcx(); let item = tcx.hir.expect_item(node_id); if let hir::ItemStatic(_, m, _) = item.node { @@ -61,7 +59,7 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug + BaseTransItemExt<'a, 'tcx> { span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") } } - TransItem::GlobalAsm(node_id) => { + MonoItem::GlobalAsm(node_id) => { let item = ccx.tcx().hir.expect_item(node_id); if let hir::ItemGlobalAsm(ref ga) = item.node { asm::trans_global_asm(ccx, ga); @@ -69,7 +67,7 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug + BaseTransItemExt<'a, 'tcx> { span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") } } - TransItem::Fn(instance) => { + MonoItem::Fn(instance) => { base::trans_instance(&ccx, instance); } } @@ -93,14 +91,14 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug + BaseTransItemExt<'a, 'tcx> { debug!("symbol {}", &symbol_name); - match *self.as_trans_item() { - TransItem::Static(node_id) => { + match *self.as_mono_item() { + MonoItem::Static(node_id) => { predefine_static(ccx, node_id, linkage, visibility, &symbol_name); } - TransItem::Fn(instance) => { + MonoItem::Fn(instance) => { predefine_fn(ccx, instance, linkage, visibility, &symbol_name); } - TransItem::GlobalAsm(..) => {} + MonoItem::GlobalAsm(..) => {} } debug!("END PREDEFINING '{} ({})' in cgu {}", @@ -109,62 +107,36 @@ pub trait TransItemExt<'a, 'tcx>: fmt::Debug + BaseTransItemExt<'a, 'tcx> { ccx.codegen_unit().name()); } - fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName { - match *self.as_trans_item() { - TransItem::Fn(instance) => tcx.symbol_name(instance), - TransItem::Static(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); - tcx.symbol_name(Instance::mono(tcx, def_id)) - } - TransItem::GlobalAsm(node_id) => { - let def_id = tcx.hir.local_def_id(node_id); - ty::SymbolName { - name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str() - } - } - } - } - fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option { - match *self.as_trans_item() { - TransItem::Fn(Instance { def, .. }) => { + match *self.as_mono_item() { + MonoItem::Fn(Instance { def, .. }) => { tcx.hir.as_local_node_id(def.def_id()) } - TransItem::Static(node_id) | - TransItem::GlobalAsm(node_id) => { + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => { Some(node_id) } }.map(|node_id| tcx.hir.span(node_id)) } - fn is_generic_fn(&self) -> bool { - match *self.as_trans_item() { - TransItem::Fn(ref instance) => { - instance.substs.types().next().is_some() - } - TransItem::Static(..) | - TransItem::GlobalAsm(..) => false, - } - } - fn to_raw_string(&self) -> String { - match *self.as_trans_item() { - TransItem::Fn(instance) => { + match *self.as_mono_item() { + MonoItem::Fn(instance) => { format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize) } - TransItem::Static(id) => { + MonoItem::Static(id) => { format!("Static({:?})", id) } - TransItem::GlobalAsm(id) => { + MonoItem::GlobalAsm(id) => { format!("GlobalAsm({:?})", id) } } } } -impl<'a, 'tcx> TransItemExt<'a, 'tcx> for TransItem<'tcx> {} +impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {} fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, node_id: ast::NodeId, @@ -173,7 +145,7 @@ fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, symbol_name: &str) { let def_id = ccx.tcx().hir.local_def_id(node_id); let instance = Instance::mono(ccx.tcx(), def_id); - let ty = common::instance_ty(ccx.tcx(), &instance); + let ty = instance.ty(ccx.tcx()); let llty = ccx.layout_of(ty).llvm_type(ccx); let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| { @@ -198,7 +170,7 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(!instance.substs.needs_infer() && !instance.substs.has_param_types()); - let mono_ty = common::instance_ty(ccx.tcx(), &instance); + let mono_ty = instance.ty(ccx.tcx()); let attrs = instance.def.attrs(ccx.tcx()); let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty); unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) }; @@ -224,7 +196,7 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance); - if common::is_inline_instance(ccx.tcx(), &instance) { + if instance.def.is_inline(ccx.tcx()) { attributes::inline(lldecl, attributes::InlineAttr::Hint); } attributes::from_fn_attrs(ccx, &attrs, lldecl); diff --git a/src/librustc_trans_utils/common.rs b/src/librustc_trans_utils/common.rs deleted file mode 100644 index 47968afd70d97..0000000000000 --- a/src/librustc_trans_utils/common.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![allow(non_camel_case_types, non_snake_case)] - -//! Code that is useful in various trans modules. - -use rustc::hir::def_id::DefId; -use rustc::hir::map::DefPathData; -use rustc::traits; -use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::subst::Substs; - -use syntax::attr; -use syntax_pos::DUMMY_SP; - -pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) -} - -pub fn type_has_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - if type_is_sized(tcx, ty) { - return false; - } - - let tail = tcx.struct_tail(ty); - match tail.sty { - ty::TyForeign(..) => false, - ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), - } -} - -pub fn requests_inline<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: &ty::Instance<'tcx> -) -> bool { - if is_inline_instance(tcx, instance) { - return true - } - if let ty::InstanceDef::DropGlue(..) = instance.def { - // Drop glue wants to be instantiated at every translation - // unit, but without an #[inline] hint. We should make this - // available to normal end-users. - return true - } - attr::requests_inline(&instance.def.attrs(tcx)[..]) || - tcx.is_const_fn(instance.def.def_id()) -} - -pub fn is_inline_instance<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: &ty::Instance<'tcx> -) -> bool { - let def_id = match instance.def { - ty::InstanceDef::Item(def_id) => def_id, - ty::InstanceDef::DropGlue(_, Some(_)) => return false, - _ => return true - }; - match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::StructCtor | - DefPathData::EnumVariant(..) | - DefPathData::ClosureExpr => true, - _ => false - } -} - -/// Given a DefId and some Substs, produces the monomorphic item type. -pub fn def_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - substs: &'tcx Substs<'tcx>) - -> Ty<'tcx> -{ - let ty = tcx.type_of(def_id); - tcx.trans_apply_param_substs(substs, &ty) -} - -/// Return the substituted type of an instance. -pub fn instance_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - instance: &ty::Instance<'tcx>) - -> Ty<'tcx> -{ - let ty = instance.def.def_ty(tcx); - tcx.trans_apply_param_substs(instance.substs, &ty) -} diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 3a42462e41e56..77afc2899c329 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -35,9 +35,9 @@ extern crate log; #[macro_use] extern crate rustc; extern crate rustc_back; -extern crate rustc_data_structures; extern crate syntax; extern crate syntax_pos; +extern crate rustc_data_structures; use rustc::ty::{TyCtxt, Instance}; use rustc::hir; @@ -45,11 +45,7 @@ use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; use rustc::util::nodemap::NodeSet; -pub mod common; pub mod link; -pub mod collector; -pub mod trans_item; -pub mod monomorphize; pub mod trans_crate; /// check for the #[rustc_error] annotation, which forces an @@ -107,7 +103,7 @@ pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet { (generics.parent_types == 0 && generics.types.is_empty()) && // Functions marked with #[inline] are only ever translated // with "internal" linkage and are never exported. - !common::requests_inline(tcx, &Instance::mono(tcx, def_id)) + !Instance::mono(tcx, def_id).def.requires_local(tcx) } _ => false