about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-19 01:34:50 +0000
committerbors <bors@rust-lang.org>2017-12-19 01:34:50 +0000
commitb76f224af867b198e4051806cc6e1ac686085cdc (patch)
tree3b2ac06f4ee7ca2ebef45cb53f098123ed235de6
parente7db42fb5b9a620c5669711546663d0ccebf9291 (diff)
parent6e78b665786b3f37730d5af3363ce74ad832282d (diff)
downloadrust-b76f224af867b198e4051806cc6e1ac686085cdc.tar.gz
rust-b76f224af867b198e4051806cc6e1ac686085cdc.zip
Auto merge of #45525 - MaikKlein:collector, r=eddyb
Move collector to librustc_mir::monomorphize

cc https://github.com/rust-lang/rust/issues/44334 and https://github.com/rust-lang/rust/issues/45276

* I moved the collector to rustc_mir

*  I renamed `TransItem` to `MonoItem`. _(I still need to fix up comments and variable names)_

* I got rid of `common.rs` and `monomorphize.rs` from `librustc_trans_utils`. I moved most of the functionality into `TyCtxt`. I realized that the `librustc_trans_utils::common.rs` was just copy pasted from `librustc_trans::common.rs`.

Should I also get rid of the `librustc_trans::common.rs` in this PR? Most of the functionality seems a bit useless, I decided to put some of it into `TyCtxt` but maybe that is not the correct action here.

Should I also get rid of `librustc_trans_utils` completely here? Or should I do it in a separate PR?
-rw-r--r--src/Cargo.lock2
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/mir/mod.rs1
-rw-r--r--src/librustc/mir/mono.rs (renamed from src/librustc/middle/trans.rs)16
-rw-r--r--src/librustc/traits/trans/mod.rs8
-rw-r--r--src/librustc/ty/instance.rs51
-rw-r--r--src/librustc/ty/maps/mod.rs2
-rw-r--r--src/librustc_mir/Cargo.toml1
-rw-r--r--src/librustc_mir/interpret/const_eval.rs4
-rw-r--r--src/librustc_mir/interpret/step.rs4
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs4
-rw-r--r--src/librustc_mir/lib.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs (renamed from src/librustc_trans_utils/collector.rs)255
-rw-r--r--src/librustc_mir/monomorphize/item.rs (renamed from src/librustc_trans_utils/trans_item.rs)82
-rw-r--r--src/librustc_mir/monomorphize/mod.rs (renamed from src/librustc_trans_utils/monomorphize.rs)6
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs (renamed from src/librustc_trans/partitioning.rs)60
-rw-r--r--src/librustc_trans/Cargo.toml1
-rw-r--r--src/librustc_trans/abi.rs4
-rw-r--r--src/librustc_trans/back/symbol_names.rs6
-rw-r--r--src/librustc_trans/base.rs28
-rw-r--r--src/librustc_trans/callee.rs4
-rw-r--r--src/librustc_trans/common.rs38
-rw-r--r--src/librustc_trans/consts.rs12
-rw-r--r--src/librustc_trans/context.rs17
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs6
-rw-r--r--src/librustc_trans/debuginfo/mod.rs5
-rw-r--r--src/librustc_trans/lib.rs5
-rw-r--r--src/librustc_trans/mir/block.rs5
-rw-r--r--src/librustc_trans/trans_item.rs80
-rw-r--r--src/librustc_trans_utils/common.rs92
-rw-r--r--src/librustc_trans_utils/lib.rs8
31 files changed, 372 insertions, 438 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 54a58854f0a..c22187ee13e 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 8dc927c451b..f00830f9ec9 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 a83c3f29d25..0ac2c2d4de8 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<Local, LocalDecl<'tcx>>;
diff --git a/src/librustc/middle/trans.rs b/src/librustc/mir/mono.rs
index 7744c9c3d12..5f74f088237 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<StableHashingContext<'tcx>> for TransItem<'tcx> {
+impl<'tcx> HashStable<StableHashingContext<'tcx>> for MonoItem<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                            hcx: &mut StableHashingContext<'tcx>,
                                            hasher: &mut StableHasher<W>) {
         ::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<TransItem<'tcx>, (Linkage, Visibility)>,
+    items: FxHashMap<MonoItem<'tcx>, (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<TransItem<'tcx>, (Linkage, Visibility)> {
+    pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
         &self.items
     }
 
     pub fn items_mut(&mut self)
-        -> &mut FxHashMap<TransItem<'tcx>, (Linkage, Visibility)>
+        -> &mut FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)>
     {
         &mut self.items
     }
diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs
index 73fdbfe8831..c873580e3ad 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 61b19227744..5b87273194c 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 {
@@ -60,14 +70,45 @@ 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 7ba063adff4..f6dd8b6e021 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 40ea4e1801b..a54f15532b1 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 c0cce6a4618..a37cf41baab 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 0b5801c3539..140da7e1097 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 1f6e4a7cde7..3eef0578360 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 e7dd94f75e5..4d26230e061 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
index 56b1a0238a1..44dedde5229 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::<i32>`. Nonetheless, in order to translate this program, we need
+//! `print_val::<i32>`. 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<TransItem<'tcx>, (usize, usize)>,
-    targets: Vec<TransItem<'tcx>>,
+    index: FxHashMap<MonoItem<'tcx>, (usize, usize)>,
+    targets: Vec<MonoItem<'tcx>>,
 
-    // 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<I>(&mut self,
-                          source: TransItem<'tcx>,
+                          source: MonoItem<'tcx>,
                           new_targets: I)
-        where I: Iterator<Item=(TransItem<'tcx>, bool)> + ExactSizeIterator
+        where I: Iterator<Item=(MonoItem<'tcx>, 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<F>(&self, source: TransItem<'tcx>, mut f: F)
-        where F: FnMut(TransItem<'tcx>)
+    pub fn with_inlining_candidates<F>(&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<F>(&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<TransItem<'tcx>>,
+pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                          mode: MonoItemCollectionMode)
+                                          -> (FxHashSet<MonoItem<'tcx>>,
                                                      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<TransItem<'tcx>> {
+                           mode: MonoItemCollectionMode)
+                           -> Vec<MonoItem<'tcx>> {
     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<TransItem<'tcx>>,
+                                   starting_point: MonoItem<'tcx>,
+                                   visited: &mut FxHashSet<MonoItem<'tcx>>,
                                    recursion_depths: &mut DefIdMap<usize>,
                                    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<TransItem<'tcx>>,
+    output: &'a mut Vec<MonoItem<'tcx>>,
     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<TransItem<'tcx>>)
+                            output: &mut Vec<MonoItem<'tcx>>)
 {
     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<TransItem<'tcx>>)
+                          output: &mut Vec<MonoItem<'tcx>>)
 {
     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<TransItem<'tcx>>)
+                                output: &mut Vec<MonoItem<'tcx>>)
 {
     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<TransItem<'tcx>>) {
+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<MonoItem<'tcx>>) {
     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<TransItem<'tcx>>,
+    mode: MonoItemCollectionMode,
+    output: &'b mut Vec<MonoItem<'tcx>>,
     entry_fn: Option<DefId>,
 }
 
@@ -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<TransItem<'tcx>>) {
+fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                                 item: &'tcx hir::Item,
+                                                 output: &mut Vec<MonoItem<'tcx>>) {
     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<TransItem<'tcx>>)
+                                output: &mut Vec<MonoItem<'tcx>>)
 {
     let mir = tcx.instance_mir(instance.def);
 
diff --git a/src/librustc_trans_utils/trans_item.rs b/src/librustc_mir/monomorphize/item.rs
index 817ceefeb7f..c3fb126ea18 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<Linkage> {
-    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<Linkage> {
 /// 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<Linkage> {
-        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
index d586d1ac315..fcf0d71dccb 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
index 03c0f13e2f5..e2640d695c6 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<TransItem<'tcx>, (Linkage, Visibility)> {
+    fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (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<NodeId>, 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<CodegenUnit<'tcx>>
-    where I: Iterator<Item = TransItem<'tcx>>
+    where I: Iterator<Item = MonoItem<'tcx>>
 {
     // 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<CodegenUnit<'tcx>>,
-    roots: FxHashSet<TransItem<'tcx>>,
-    internalization_candidates: FxHashSet<TransItem<'tcx>>,
+    roots: FxHashSet<MonoItem<'tcx>>,
+    internalization_candidates: FxHashSet<MonoItem<'tcx>>,
 }
 
 /// 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<CodegenUnit<'tcx>>,
-    trans_item_placements: FxHashMap<TransItem<'tcx>, TransItemPlacement>,
-    internalization_candidates: FxHashSet<TransItem<'tcx>>,
+    trans_item_placements: FxHashMap<MonoItem<'tcx>, TransItemPlacement>,
+    internalization_candidates: FxHashSet<MonoItem<'tcx>>,
 }
 
 fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                              trans_items: I)
                                              -> PreInliningPartitioning<'tcx>
-    where I: Iterator<Item = TransItem<'tcx>>
+    where I: Iterator<Item = MonoItem<'tcx>>
 {
     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<TransItem<'tcx>>) {
+                             visited: &mut FxHashSet<MonoItem<'tcx>>) {
         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<TransItem<'tcx>, Vec<TransItem<'tcx>>> = FxHashMap();
+    let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = 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<DefId> {
     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 131cf59a571..f1549d98421 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 78ab25f222e..32dc1067d37 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 695950e6727..825f306499a 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 911ec561887..79b3d314e12 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<Item=&'a TransItem<'tcx>>
+    where I: Iterator<Item=&'a MonoItem<'tcx>>
 {
     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 4afeac2e8f5..0a0f2615a1b 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 762cf7a0055..b1bdee3fa5f 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 800c7733c3d..f9fbcebd32e 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 b2bb605d01b..d5e71062f74 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 d09272df345..12cd874f868 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 e9350256c30..ae202f3f142 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 f6cc1215699..c4849c621e8 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 eba2928d84c..1cb3a66e4d8 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 991f99e0f6c..31d8e092c4a 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<Span> {
-        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 47968afd70d..00000000000
--- 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 <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.
-
-#![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 3a42462e41e..77afc2899c3 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