about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDenis Merigoux <denis.merigoux@gmail.com>2018-09-13 14:58:19 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2018-11-16 14:15:13 +0200
commit034f69753b3e934789377cd6fa2b8c3f46364da0 (patch)
treeb5746f1c4883211b58111deec7c8b2b870c4d462
parent484e07c231e29febc68f2f21e970f8eb19818ad6 (diff)
downloadrust-034f69753b3e934789377cd6fa2b8c3f46364da0.tar.gz
rust-034f69753b3e934789377cd6fa2b8c3f46364da0.zip
Generalized base::unsized_info
-rw-r--r--src/librustc_codegen_llvm/base.rs19
-rw-r--r--src/librustc_codegen_llvm/builder.rs39
-rw-r--r--src/librustc_codegen_llvm/callee.rs28
-rw-r--r--src/librustc_codegen_llvm/common.rs10
-rw-r--r--src/librustc_codegen_llvm/consts.rs4
-rw-r--r--src/librustc_codegen_llvm/context.rs15
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs105
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs1
-rw-r--r--src/librustc_codegen_llvm/glue.rs2
-rw-r--r--src/librustc_codegen_llvm/interfaces/backend.rs13
-rw-r--r--src/librustc_codegen_llvm/interfaces/builder.rs150
-rw-r--r--src/librustc_codegen_llvm/interfaces/consts.rs20
-rw-r--r--src/librustc_codegen_llvm/interfaces/debuginfo.rs16
-rw-r--r--src/librustc_codegen_llvm/interfaces/intrinsic.rs13
-rw-r--r--src/librustc_codegen_llvm/interfaces/misc.rs21
-rw-r--r--src/librustc_codegen_llvm/interfaces/mod.rs43
-rw-r--r--src/librustc_codegen_llvm/interfaces/statics.rs26
-rw-r--r--src/librustc_codegen_llvm/interfaces/type_.rs45
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_llvm/meth.rs24
-rw-r--r--src/librustc_codegen_llvm/mir/block.rs4
-rw-r--r--src/librustc_codegen_llvm/mir/constant.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/place.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/rvalue.rs4
-rw-r--r--src/librustc_codegen_llvm/type_.rs21
26 files changed, 341 insertions, 290 deletions
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 7428e3f1641..efb1ba52b0c 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -55,7 +55,6 @@ use builder::{Builder, MemFlags};
 use callee;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use common::{self, IntPredicate, RealPredicate, TypeKind};
-use consts;
 use context::CodegenCx;
 use debuginfo;
 use declare;
@@ -188,16 +187,16 @@ pub fn compare_simd_types<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
 /// The `old_info` argument is a bit funny. It is intended for use
 /// in an upcast, where the new vtable for an object will be derived
 /// from the old one.
-pub fn unsized_info(
-    cx: &CodegenCx<'ll, 'tcx>,
+pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>(
+    cx: &Cx,
     source: Ty<'tcx>,
     target: Ty<'tcx>,
-    old_info: Option<&'ll Value>,
-) -> &'ll Value {
-    let (source, target) = cx.tcx.struct_lockstep_tails(source, target);
+    old_info: Option<Cx::Value>,
+) -> Cx::Value {
+    let (source, target) = cx.tcx().struct_lockstep_tails(source, target);
     match (&source.sty, &target.sty) {
         (&ty::Array(_, len), &ty::Slice(_)) => {
-            cx.const_usize(len.unwrap_usize(cx.tcx))
+            cx.const_usize(len.unwrap_usize(cx.tcx()))
         }
         (&ty::Dynamic(..), &ty::Dynamic(..)) => {
             // For now, upcasts are limited to changes in marker
@@ -206,10 +205,10 @@ pub fn unsized_info(
             old_info.expect("unsized_info: missing old info for trait upcast")
         }
         (_, &ty::Dynamic(ref data, ..)) => {
-            let vtable_ptr = cx.layout_of(cx.tcx.mk_mut_ptr(target))
+            let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target))
                 .field(cx, abi::FAT_PTR_EXTRA);
-            consts::ptrcast(meth::get_vtable(cx, source, data.principal()),
-                            vtable_ptr.llvm_type(cx))
+            cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()),
+                            cx.backend_type(vtable_ptr))
         }
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}",
                   source,
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index a7a00dd0707..57e23766980 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -15,8 +15,8 @@ use context::CodegenCx;
 use type_::Type;
 use value::Value;
 use libc::{c_uint, c_char};
-use rustc::ty::TyCtxt;
-use rustc::ty::layout::{Align, Size};
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::layout::{Align, Size, TyLayout};
 use rustc::session::{config, Session};
 use rustc_data_structures::small_c_str::SmallCStr;
 use interfaces::*;
@@ -56,7 +56,36 @@ bitflags! {
     }
 }
 
-impl HasCodegen for Builder<'a, 'll, 'tcx> {
+impl BackendTypes for Builder<'_, 'll, '_> {
+    type Value = &'ll Value;
+    type BasicBlock = &'ll BasicBlock;
+    type Type = &'ll Type;
+    type Context = &'ll llvm::Context;
+}
+
+impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
+    fn data_layout(&self) -> &ty::layout::TargetDataLayout {
+        self.cx.data_layout()
+    }
+}
+
+impl ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
+    fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
+        self.cx.tcx
+    }
+}
+
+impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
+    type Ty = Ty<'tcx>;
+    type TyLayout = TyLayout<'tcx>;
+
+    fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
+        self.cx.layout_of(ty)
+    }
+}
+
+
+impl HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
     type CodegenCx = CodegenCx<'ll, 'tcx>;
 }
 
@@ -98,10 +127,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         self.cx.sess()
     }
 
-    fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
-        self.cx.tcx
-    }
-
     fn llfn(&self) -> &'ll Value {
         unsafe {
             llvm::LLVMGetBasicBlockParent(self.llbb())
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 1162573a3f6..05d98ca068a 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -22,7 +22,7 @@ use llvm;
 use monomorphize::Instance;
 use type_of::LayoutLlvmExt;
 use value::Value;
-use interfaces::BaseTypeMethods;
+use interfaces::*;
 
 use rustc::hir::def_id::DefId;
 use rustc::ty::{self, TypeFoldable};
@@ -206,15 +206,16 @@ pub fn get_fn(
     llfn
 }
 
-pub fn resolve_and_get_fn(
-    cx: &CodegenCx<'ll, 'tcx>,
+pub fn resolve_and_get_fn<'tcx,
+    Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
+>(
+    cx: &Cx,
     def_id: DefId,
     substs: &'tcx Substs<'tcx>,
-) -> &'ll Value {
-    get_fn(
-        cx,
+) -> Cx::Value {
+    cx.get_fn(
         ty::Instance::resolve(
-            cx.tcx,
+            cx.tcx(),
             ty::ParamEnv::reveal_all(),
             def_id,
             substs
@@ -222,15 +223,16 @@ pub fn resolve_and_get_fn(
     )
 }
 
-pub fn resolve_and_get_fn_for_vtable(
-    cx: &CodegenCx<'ll, 'tcx>,
+pub fn resolve_and_get_fn_for_vtable<'tcx,
+    Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
+>(
+    cx: &Cx,
     def_id: DefId,
     substs: &'tcx Substs<'tcx>,
-) -> &'ll Value {
-    get_fn(
-        cx,
+) -> Cx::Value {
+    cx.get_fn(
         ty::Instance::resolve_for_vtable(
-            cx.tcx,
+            cx.tcx(),
             ty::ParamEnv::reveal_all(),
             def_id,
             substs
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index e20a93e4e3e..fb1f4df78fe 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -23,12 +23,11 @@ use declare;
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use value::Value;
-use interfaces::{Backend, ConstMethods, BaseTypeMethods};
+use interfaces::{BackendTypes, BuilderMethods, ConstMethods, BaseTypeMethods};
 
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{HasDataLayout, LayoutOf};
 use rustc::hir;
-use interfaces::BuilderMethods;
 
 use libc::{c_uint, c_char};
 
@@ -213,15 +212,14 @@ impl Funclet<'ll> {
     }
 }
 
-impl Backend for CodegenCx<'ll, 'tcx> {
+impl BackendTypes for CodegenCx<'ll, 'tcx> {
     type Value = &'ll Value;
     type BasicBlock = &'ll BasicBlock;
     type Type = &'ll Type;
     type Context = &'ll llvm::Context;
 }
 
-impl<'ll, 'tcx: 'll> ConstMethods for CodegenCx<'ll, 'tcx> {
-
+impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     // LLVM constant constructors.
     fn const_null(&self, t: &'ll Type) -> &'ll Value {
         unsafe {
@@ -319,7 +317,7 @@ impl<'ll, 'tcx: 'll> ConstMethods for CodegenCx<'ll, 'tcx> {
     fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
         let len = s.len();
         let cs = consts::ptrcast(self.const_cstr(s, false),
-            self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(&self)));
+            self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
         self.const_fat_ptr(cs, self.const_usize(len as u64))
     }
 
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 9b330bc5f8e..2a5753ab276 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -201,7 +201,7 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
         let g = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
 
-            let llty = self.layout_of(ty).llvm_type(&self);
+            let llty = self.layout_of(ty).llvm_type(self);
             let (g, attrs) = match self.tcx.hir.get(id) {
                 Node::Item(&hir::Item {
                     ref attrs, span, node: hir::ItemKind::Static(..), ..
@@ -329,7 +329,7 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> {
 
             let instance = Instance::mono(self.tcx, def_id);
             let ty = instance.ty(self.tcx);
-            let llty = self.layout_of(ty).llvm_type(&self);
+            let llty = self.layout_of(ty).llvm_type(self);
             let g = if val_llty == llty {
                 g
             } else {
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index cd0c2ffacd5..f9f162bb823 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -23,7 +23,7 @@ use value::Value;
 use monomorphize::partitioning::CodegenUnit;
 use type_::Type;
 use type_of::PointeeInfo;
-use interfaces::{BaseTypeMethods, DerivedTypeMethods, IntrinsicDeclarationMethods};
+use interfaces::*;
 
 use rustc_data_structures::base_n;
 use rustc_data_structures::small_c_str::SmallCStr;
@@ -322,7 +322,18 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
     }
 }
 
-impl IntrinsicDeclarationMethods for CodegenCx<'b, 'tcx> {
+impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+    fn vtables(&self) -> &RefCell<FxHashMap<(Ty<'tcx>,
+                                ty::PolyExistentialTraitRef<'tcx>), &'ll Value>>
+    {
+        &self.vtables
+    }
+    fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
+        callee::get_fn(&&self,instance)
+    }
+}
+
+impl IntrinsicDeclarationMethods<'tcx> for CodegenCx<'b, 'tcx> {
     fn get_intrinsic(&self, key: &str) -> &'b Value {
         if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
             return v;
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 5581b926ccd..923b04c0ecc 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -17,6 +17,7 @@ use super::utils::{debug_context, DIB, span_start,
 use super::namespace::mangled_name_of_instance;
 use super::type_names::compute_debuginfo_type_name;
 use super::{CrateDebugContext};
+use interfaces::*;
 use abi;
 use interfaces::ConstMethods;
 use value::Value;
@@ -1983,58 +1984,60 @@ pub fn extend_scope_to_file(
     }
 }
 
-/// Creates debug information for the given vtable, which is for the
-/// given type.
-///
-/// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_vtable_metadata(
-    cx: &CodegenCx<'ll, 'tcx>,
-    ty: ty::Ty<'tcx>,
-    vtable: &'ll Value,
-) {
-    if cx.dbg_cx.is_none() {
-        return;
-    }
-
-    let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
-
-    unsafe {
-        // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
-        // pointer will lead to hard to trace and debug LLVM assertions
-        // later on in llvm/lib/IR/Value.cpp.
-        let empty_array = create_DIArray(DIB(cx), &[]);
-
-        let name = const_cstr!("vtable");
+impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+    /// Creates debug information for the given vtable, which is for the
+    /// given type.
+    ///
+    /// Adds the created metadata nodes directly to the crate's IR.
+    fn create_vtable_metadata(
+        &self,
+        ty: ty::Ty<'tcx>,
+        vtable: &'ll Value,
+    ) {
+        if self.dbg_cx.is_none() {
+            return;
+        }
 
-        // Create a new one each time.  We don't want metadata caching
-        // here, because each vtable will refer to a unique containing
-        // type.
-        let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
-            DIB(cx),
-            NO_SCOPE_METADATA,
-            name.as_ptr(),
-            unknown_file_metadata(cx),
-            UNKNOWN_LINE_NUMBER,
-            Size::ZERO.bits(),
-            cx.tcx.data_layout.pointer_align.abi_bits() as u32,
-            DIFlags::FlagArtificial,
-            None,
-            empty_array,
-            0,
-            Some(type_metadata),
-            name.as_ptr()
-        );
+        let type_metadata = type_metadata(&self, ty, syntax_pos::DUMMY_SP);
 
-        llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
-                                                    NO_SCOPE_METADATA,
-                                                    name.as_ptr(),
-                                                    ptr::null(),
-                                                    unknown_file_metadata(cx),
-                                                    UNKNOWN_LINE_NUMBER,
-                                                    vtable_type,
-                                                    true,
-                                                    vtable,
-                                                    None,
-                                                    0);
+        unsafe {
+            // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
+            // pointer will lead to hard to trace and debug LLVM assertions
+            // later on in llvm/lib/IR/Value.cpp.
+            let empty_array = create_DIArray(DIB(&self), &[]);
+
+            let name = const_cstr!("vtable");
+
+            // Create a new one each time.  We don't want metadata caching
+            // here, because each vtable will refer to a unique containing
+            // type.
+            let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
+                DIB(&self),
+                NO_SCOPE_METADATA,
+                name.as_ptr(),
+                unknown_file_metadata(&self),
+                UNKNOWN_LINE_NUMBER,
+                Size::ZERO.bits(),
+                self.tcx.data_layout.pointer_align.abi_bits() as u32,
+                DIFlags::FlagArtificial,
+                None,
+                empty_array,
+                0,
+                Some(type_metadata),
+                name.as_ptr()
+            );
+
+            llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(&self),
+                                                        NO_SCOPE_METADATA,
+                                                        name.as_ptr(),
+                                                        ptr::null(),
+                                                        unknown_file_metadata(&self),
+                                                        UNKNOWN_LINE_NUMBER,
+                                                        vtable_type,
+                                                        true,
+                                                        vtable,
+                                                        None,
+                                                        0);
+        }
     }
 }
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 0ee51f1956b..9fcd57a1ec5 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -58,7 +58,6 @@ mod source_loc;
 pub use self::create_scope_map::{create_mir_scopes, MirDebugScope};
 pub use self::source_loc::start_emitting_source_locations;
 pub use self::metadata::create_global_var_metadata;
-pub use self::metadata::create_vtable_metadata;
 pub use self::metadata::extend_scope_to_file;
 pub use self::source_loc::set_source_location;
 
diff --git a/src/librustc_codegen_llvm/glue.rs b/src/librustc_codegen_llvm/glue.rs
index 919d80a9d6b..680f216589e 100644
--- a/src/librustc_codegen_llvm/glue.rs
+++ b/src/librustc_codegen_llvm/glue.rs
@@ -17,7 +17,7 @@ use std;
 use builder::Builder;
 use common::*;
 use meth;
-use rustc::ty::layout::LayoutOf;
+use rustc::ty::layout::{LayoutOf, HasTyCtxt};
 use rustc::ty::{self, Ty};
 use value::Value;
 use interfaces::{BuilderMethods, ConstMethods};
diff --git a/src/librustc_codegen_llvm/interfaces/backend.rs b/src/librustc_codegen_llvm/interfaces/backend.rs
index 37ff92bc1c9..c470ad3b881 100644
--- a/src/librustc_codegen_llvm/interfaces/backend.rs
+++ b/src/librustc_codegen_llvm/interfaces/backend.rs
@@ -8,11 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
+use rustc::ty::Ty;
 use std::fmt::Debug;
 
-pub trait Backend {
+pub trait BackendTypes {
     type Value: Debug + PartialEq + Copy;
     type BasicBlock;
     type Type: Debug + PartialEq + Copy;
     type Context;
 }
+
+pub trait Backend<'tcx>:
+    BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+{
+}
+
+impl<'tcx, T> Backend<'tcx> for T where
+    Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+{}
diff --git a/src/librustc_codegen_llvm/interfaces/builder.rs b/src/librustc_codegen_llvm/interfaces/builder.rs
index c7a753cea87..2ddef097f36 100644
--- a/src/librustc_codegen_llvm/interfaces/builder.rs
+++ b/src/librustc_codegen_llvm/interfaces/builder.rs
@@ -8,48 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use super::HasCodegen;
+use builder::MemFlags;
 use common::*;
 use libc::c_char;
-use rustc::ty::TyCtxt;
-use rustc::ty::layout::{Align, Size};
 use rustc::session::Session;
-use builder::MemFlags;
-use super::backend::Backend;
-use super::type_::TypeMethods;
-use super::consts::ConstMethods;
-use super::intrinsic::IntrinsicDeclarationMethods;
+use rustc::ty::layout::{Align, Size};
 
 use std::borrow::Cow;
 use std::ops::Range;
 use syntax::ast::AsmDialect;
 
-pub trait HasCodegen: Backend {
-    type CodegenCx: TypeMethods + ConstMethods + IntrinsicDeclarationMethods + Backend<
-        Value = Self::Value,
-        BasicBlock = Self::BasicBlock,
-        Type = Self::Type,
-        Context = Self::Context,
-    >;
-}
-
-impl<T: HasCodegen> Backend for T {
-    type Value = <T::CodegenCx as Backend>::Value;
-    type BasicBlock = <T::CodegenCx as Backend>::BasicBlock;
-    type Type = <T::CodegenCx as Backend>::Type;
-    type Context = <T::CodegenCx as Backend>::Context;
-}
-
-pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
-    fn new_block<'b>(
-        cx: &'a Self::CodegenCx,
-        llfn: Self::Value,
-        name: &'b str
-    ) -> Self;
+pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen<'tcx> {
+    fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
     fn with_cx(cx: &'a Self::CodegenCx) -> Self;
     fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
     fn sess(&self) -> &Session;
-    fn cx(&self) -> &'a Self::CodegenCx;
-    fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
+    fn cx(&self) -> &'a Self::CodegenCx; // FIXME(eddyb) remove 'a
     fn llfn(&self) -> Self::Value;
     fn llbb(&self) -> Self::BasicBlock;
     fn count_insn(&self, category: &str);
@@ -60,25 +35,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
     fn ret_void(&self);
     fn ret(&self, v: Self::Value);
     fn br(&self, dest: Self::BasicBlock);
-    fn cond_br(
-        &self,
-        cond: Self::Value,
-        then_llbb: Self::BasicBlock,
-        else_llbb: Self::BasicBlock,
-    );
-    fn switch(
-        &self,
-        v: Self::Value,
-        else_llbb: Self::BasicBlock,
-        num_cases: usize,
-    ) -> Self::Value;
+    fn cond_br(&self, cond: Self::Value, then_llbb: Self::BasicBlock, else_llbb: Self::BasicBlock);
+    fn switch(&self, v: Self::Value, else_llbb: Self::BasicBlock, num_cases: usize) -> Self::Value;
     fn invoke(
         &self,
         llfn: Self::Value,
         args: &[Self::Value],
         then: Self::BasicBlock,
         catch: Self::BasicBlock,
-        bundle: Option<&OperandBundleDef<Self::Value>>
+        bundle: Option<&OperandBundleDef<Self::Value>>,
     ) -> Self::Value;
     fn unreachable(&self);
     fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
@@ -117,7 +82,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
         ty: Self::Type,
         len: Self::Value,
         name: &str,
-        align: Align
+        align: Align,
     ) -> Self::Value;
 
     fn load(&self, ptr: Self::Value, align: Align) -> Self::Value;
@@ -135,13 +100,7 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
         align: Align,
         flags: MemFlags,
     ) -> Self::Value;
-    fn atomic_store(
-        &self,
-        val: Self::Value,
-        ptr: Self::Value,
-        order: AtomicOrdering,
-        size: Size
-    );
+    fn atomic_store(&self, val: Self::Value, ptr: Self::Value, order: AtomicOrdering, size: Size);
 
     fn gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
     fn inbounds_gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
@@ -174,16 +133,27 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
         output: Self::Type,
         volatile: bool,
         alignstack: bool,
-        dia: AsmDialect
+        dia: AsmDialect,
     ) -> Option<Self::Value>;
 
-
-    fn memcpy(&self, dst: Self::Value, dst_align: Align,
-                  src: Self::Value, src_align: Align,
-                  size: Self::Value, flags: MemFlags);
-    fn memmove(&self, dst: Self::Value, dst_align: Align,
-                  src: Self::Value, src_align: Align,
-                  size: Self::Value, flags: MemFlags);
+    fn memcpy(
+        &self,
+        dst: Self::Value,
+        dst_align: Align,
+        src: Self::Value,
+        src_align: Align,
+        size: Self::Value,
+        flags: MemFlags,
+    );
+    fn memmove(
+        &self,
+        dst: Self::Value,
+        dst_align: Align,
+        src: Self::Value,
+        src_align: Align,
+        size: Self::Value,
+        flags: MemFlags,
+    );
     fn memset(
         &self,
         ptr: Self::Value,
@@ -196,18 +166,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
     fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
     fn select(
-        &self, cond: Self::Value,
+        &self,
+        cond: Self::Value,
         then_val: Self::Value,
         else_val: Self::Value,
     ) -> Self::Value;
 
     fn va_arg(&self, list: Self::Value, ty: Self::Type) -> Self::Value;
     fn extract_element(&self, vec: Self::Value, idx: Self::Value) -> Self::Value;
-    fn insert_element(
-        &self, vec: Self::Value,
-        elt: Self::Value,
-        idx: Self::Value,
-    ) -> Self::Value;
+    fn insert_element(&self, vec: Self::Value, elt: Self::Value, idx: Self::Value) -> Self::Value;
     fn shuffle_vector(&self, v1: Self::Value, v2: Self::Value, mask: Self::Value) -> Self::Value;
     fn vector_splat(&self, num_elts: usize, elt: Self::Value) -> Self::Value;
     fn vector_reduce_fadd_fast(&self, acc: Self::Value, src: Self::Value) -> Self::Value;
@@ -224,36 +191,15 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
     fn vector_reduce_min(&self, src: Self::Value, is_signed: bool) -> Self::Value;
     fn vector_reduce_max(&self, src: Self::Value, is_signed: bool) -> Self::Value;
     fn extract_value(&self, agg_val: Self::Value, idx: u64) -> Self::Value;
-    fn insert_value(
-        &self,
-        agg_val: Self::Value,
-        elt: Self::Value,
-        idx: u64
-    ) -> Self::Value;
+    fn insert_value(&self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
 
-    fn landing_pad(
-        &self,
-        ty: Self::Type,
-        pers_fn: Self::Value,
-        num_clauses: usize
-    ) -> Self::Value;
+    fn landing_pad(&self, ty: Self::Type, pers_fn: Self::Value, num_clauses: usize) -> Self::Value;
     fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value);
     fn set_cleanup(&self, landing_pad: Self::Value);
     fn resume(&self, exn: Self::Value) -> Self::Value;
-    fn cleanup_pad(
-        &self,
-        parent: Option<Self::Value>,
-        args: &[Self::Value]
-    ) -> Self::Value;
-    fn cleanup_ret(
-        &self, cleanup: Self::Value,
-        unwind: Option<Self::BasicBlock>,
-    ) -> Self::Value;
-    fn catch_pad(
-        &self,
-        parent: Self::Value,
-        args: &[Self::Value]
-    ) -> Self::Value;
+    fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Value;
+    fn cleanup_ret(&self, cleanup: Self::Value, unwind: Option<Self::BasicBlock>) -> Self::Value;
+    fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Value;
     fn catch_ret(&self, pad: Self::Value, unwind: Self::BasicBlock) -> Self::Value;
     fn catch_switch(
         &self,
@@ -285,23 +231,25 @@ pub trait BuilderMethods<'a, 'tcx: 'a>: HasCodegen {
     fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
     fn set_invariant_load(&self, load: Self::Value);
 
-    fn check_store(
-        &self,
-        val: Self::Value,
-        ptr: Self::Value
-    ) -> Self::Value;
+    fn check_store(&self, val: Self::Value, ptr: Self::Value) -> Self::Value;
     fn check_call<'b>(
         &self,
         typ: &str,
         llfn: Self::Value,
-        args: &'b [Self::Value]
-    ) -> Cow<'b, [Self::Value]> where [Self::Value]: ToOwned;
+        args: &'b [Self::Value],
+    ) -> Cow<'b, [Self::Value]>
+    where
+        [Self::Value]: ToOwned;
     fn lifetime_start(&self, ptr: Self::Value, size: Size);
     fn lifetime_end(&self, ptr: Self::Value, size: Size);
 
     fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: Self::Value, size: Size);
 
-    fn call(&self, llfn: Self::Value, args: &[Self::Value],
-                bundle: Option<&OperandBundleDef<Self::Value>>) -> Self::Value;
+    fn call(
+        &self,
+        llfn: Self::Value,
+        args: &[Self::Value],
+        bundle: Option<&OperandBundleDef<Self::Value>>,
+    ) -> Self::Value;
     fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
 }
diff --git a/src/librustc_codegen_llvm/interfaces/consts.rs b/src/librustc_codegen_llvm/interfaces/consts.rs
index 2366fefd941..b5e0169472d 100644
--- a/src/librustc_codegen_llvm/interfaces/consts.rs
+++ b/src/librustc_codegen_llvm/interfaces/consts.rs
@@ -11,7 +11,7 @@
 use super::Backend;
 use syntax::symbol::LocalInternedString;
 
-pub trait ConstMethods: Backend {
+pub trait ConstMethods<'tcx>: Backend<'tcx> {
     // Constant constructors
     fn const_null(&self, t: Self::Type) -> Self::Value;
     fn const_undef(&self, t: Self::Type) -> Self::Value;
@@ -24,22 +24,10 @@ pub trait ConstMethods: Backend {
     fn const_u64(&self, i: u64) -> Self::Value;
     fn const_usize(&self, i: u64) -> Self::Value;
     fn const_u8(&self, i: u8) -> Self::Value;
-    fn const_cstr(
-        &self,
-        s: LocalInternedString,
-        null_terminated: bool,
-    ) -> Self::Value;
+    fn const_cstr(&self, s: LocalInternedString, null_terminated: bool) -> Self::Value;
     fn const_str_slice(&self, s: LocalInternedString) -> Self::Value;
-    fn const_fat_ptr(
-        &self,
-        ptr: Self::Value,
-        meta: Self::Value
-    ) -> Self::Value;
-    fn const_struct(
-        &self,
-        elts: &[Self::Value],
-        packed: bool
-    ) -> Self::Value;
+    fn const_fat_ptr(&self, ptr: Self::Value, meta: Self::Value) -> Self::Value;
+    fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
     fn const_array(&self, ty: Self::Type, elts: &[Self::Value]) -> Self::Value;
     fn const_vector(&self, elts: &[Self::Value]) -> Self::Value;
     fn const_bytes(&self, bytes: &[u8]) -> Self::Value;
diff --git a/src/librustc_codegen_llvm/interfaces/debuginfo.rs b/src/librustc_codegen_llvm/interfaces/debuginfo.rs
new file mode 100644
index 00000000000..333fda226a9
--- /dev/null
+++ b/src/librustc_codegen_llvm/interfaces/debuginfo.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::backend::Backend;
+use rustc::ty::Ty;
+
+pub trait DebugInfoMethods<'tcx>: Backend<'tcx> {
+    fn create_vtable_metadata(&self, ty: Ty<'tcx>, vtable: Self::Value);
+}
diff --git a/src/librustc_codegen_llvm/interfaces/intrinsic.rs b/src/librustc_codegen_llvm/interfaces/intrinsic.rs
index 39b95344c71..f31a3adc5b8 100644
--- a/src/librustc_codegen_llvm/interfaces/intrinsic.rs
+++ b/src/librustc_codegen_llvm/interfaces/intrinsic.rs
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 use super::backend::Backend;
-use super::builder::HasCodegen;
+use super::builder::BuilderMethods;
+use abi::FnType;
 use mir::operand::OperandRef;
 use rustc::ty::Ty;
-use abi::FnType;
 use syntax_pos::Span;
 
-pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: HasCodegen {
+pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: BuilderMethods<'a, 'tcx> {
     fn codegen_intrinsic_call(
         &self,
         callee_ty: Ty<'tcx>,
@@ -26,10 +26,7 @@ pub trait IntrinsicCallMethods<'a, 'tcx: 'a>: HasCodegen {
     );
 }
 
-pub trait IntrinsicDeclarationMethods: Backend {
+pub trait IntrinsicDeclarationMethods<'tcx>: Backend<'tcx> {
     fn get_intrinsic(&self, key: &str) -> Self::Value;
-    fn declare_intrinsic(
-        &self,
-        key: &str
-    ) -> Option<Self::Value>;
+    fn declare_intrinsic(&self, key: &str) -> Option<Self::Value>;
 }
diff --git a/src/librustc_codegen_llvm/interfaces/misc.rs b/src/librustc_codegen_llvm/interfaces/misc.rs
new file mode 100644
index 00000000000..c483d82495d
--- /dev/null
+++ b/src/librustc_codegen_llvm/interfaces/misc.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::backend::Backend;
+use rustc::ty::{self, Instance, Ty};
+use rustc::util::nodemap::FxHashMap;
+use std::cell::RefCell;
+
+pub trait MiscMethods<'tcx>: Backend<'tcx> {
+    fn vtables(
+        &self,
+    ) -> &RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), Self::Value>>;
+    fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
+}
diff --git a/src/librustc_codegen_llvm/interfaces/mod.rs b/src/librustc_codegen_llvm/interfaces/mod.rs
index 9f963f63383..a978e295967 100644
--- a/src/librustc_codegen_llvm/interfaces/mod.rs
+++ b/src/librustc_codegen_llvm/interfaces/mod.rs
@@ -8,16 +8,49 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-mod builder;
 mod backend;
+mod builder;
 mod consts;
-mod type_;
+mod debuginfo;
 mod intrinsic;
+mod misc;
 mod statics;
+mod type_;
 
-pub use self::builder::{BuilderMethods, HasCodegen};
-pub use self::backend::Backend;
+pub use self::backend::{Backend, BackendTypes};
+pub use self::builder::BuilderMethods;
 pub use self::consts::ConstMethods;
-pub use self::type_::{TypeMethods, BaseTypeMethods, DerivedTypeMethods};
+pub use self::debuginfo::DebugInfoMethods;
 pub use self::intrinsic::{IntrinsicCallMethods, IntrinsicDeclarationMethods};
+pub use self::misc::MiscMethods;
 pub use self::statics::StaticMethods;
+pub use self::type_::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods};
+
+pub trait CodegenMethods<'tcx>:
+    Backend<'tcx>
+    + TypeMethods<'tcx>
+    + MiscMethods<'tcx>
+    + ConstMethods<'tcx>
+    + StaticMethods<'tcx>
+    + DebugInfoMethods<'tcx>
+{
+}
+
+impl<'tcx, T> CodegenMethods<'tcx> for T where
+    Self: Backend<'tcx>
+        + TypeMethods<'tcx>
+        + MiscMethods<'tcx>
+        + ConstMethods<'tcx>
+        + StaticMethods<'tcx>
+        + DebugInfoMethods<'tcx>
+{}
+
+pub trait HasCodegen<'tcx>: Backend<'tcx> {
+    type CodegenCx: CodegenMethods<'tcx>
+        + BackendTypes<
+            Value = Self::Value,
+            BasicBlock = Self::BasicBlock,
+            Type = Self::Type,
+            Context = Self::Context,
+        >;
+}
diff --git a/src/librustc_codegen_llvm/interfaces/statics.rs b/src/librustc_codegen_llvm/interfaces/statics.rs
index 109ef91dcfa..a6108781231 100644
--- a/src/librustc_codegen_llvm/interfaces/statics.rs
+++ b/src/librustc_codegen_llvm/interfaces/statics.rs
@@ -8,29 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::ty::layout::Align;
-use rustc::hir::def_id::DefId;
 use super::backend::Backend;
+use rustc::hir::def_id::DefId;
+use rustc::ty::layout::Align;
 
-pub trait StaticMethods<'tcx>: Backend {
+pub trait StaticMethods<'tcx>: Backend<'tcx> {
     fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
     fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
-    fn static_addr_of_mut(
-        &self,
-        cv: Self::Value,
-        align: Align,
-        kind: Option<&str>,
-    ) -> Self::Value;
-    fn static_addr_of(
-        &self,
-        cv: Self::Value,
-        align: Align,
-        kind: Option<&str>,
-    ) -> Self::Value;
+    fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
+    fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
     fn get_static(&self, def_id: DefId) -> Self::Value;
-    fn codegen_static(
-        &self,
-        def_id: DefId,
-        is_mutable: bool,
-    );
+    fn codegen_static(&self, def_id: DefId, is_mutable: bool);
 }
diff --git a/src/librustc_codegen_llvm/interfaces/type_.rs b/src/librustc_codegen_llvm/interfaces/type_.rs
index ff594c40095..e88e81a5566 100644
--- a/src/librustc_codegen_llvm/interfaces/type_.rs
+++ b/src/librustc_codegen_llvm/interfaces/type_.rs
@@ -10,10 +10,14 @@
 
 use super::backend::Backend;
 use common::TypeKind;
-use syntax::ast;
+use rustc::ty::layout::TyLayout;
 use rustc::ty::layout::{self, Align, Size};
+use rustc::ty::Ty;
+use rustc::util::nodemap::FxHashMap;
+use std::cell::RefCell;
+use syntax::ast;
 
-pub trait BaseTypeMethods: Backend {
+pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
     fn type_void(&self) -> Self::Type;
     fn type_metadata(&self) -> Self::Type;
     fn type_i1(&self) -> Self::Type;
@@ -43,32 +47,31 @@ pub trait BaseTypeMethods: Backend {
     fn int_width(&self, ty: Self::Type) -> u64;
 
     fn val_ty(&self, v: Self::Value) -> Self::Type;
+    fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>>;
 }
 
-pub trait DerivedTypeMethods: Backend {
+pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> {
     fn type_bool(&self) -> Self::Type;
     fn type_i8p(&self) -> Self::Type;
     fn type_isize(&self) -> Self::Type;
     fn type_int(&self) -> Self::Type;
-    fn type_int_from_ty(
-        &self,
-        t: ast::IntTy
-    ) -> Self::Type;
-    fn type_uint_from_ty(
-        &self,
-        t: ast::UintTy
-    ) -> Self::Type;
-    fn type_float_from_ty(
-        &self,
-        t: ast::FloatTy
-    ) -> Self::Type;
+    fn type_int_from_ty(&self, t: ast::IntTy) -> Self::Type;
+    fn type_uint_from_ty(&self, t: ast::UintTy) -> Self::Type;
+    fn type_float_from_ty(&self, t: ast::FloatTy) -> Self::Type;
     fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
     fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
-    fn type_padding_filler(
-        &self,
-        size: Size,
-        align: Align
-    ) -> Self::Type;
+    fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type;
+}
+
+pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
+    fn backend_type(&self, ty: TyLayout<'tcx>) -> Self::Type;
+}
+
+pub trait TypeMethods<'tcx>:
+    BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
+{
 }
 
-pub trait TypeMethods: BaseTypeMethods + DerivedTypeMethods {}
+impl<T> TypeMethods<'tcx> for T where
+    Self: BaseTypeMethods<'tcx> + DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx>
+{}
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 4c7401eac07..60a7de477bd 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -25,7 +25,7 @@ use glue;
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::LayoutOf;
+use rustc::ty::layout::{LayoutOf, HasTyCtxt};
 use rustc::hir;
 use syntax::ast;
 use syntax::symbol::Symbol;
diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs
index 2eed9273cad..798cc8c8308 100644
--- a/src/librustc_codegen_llvm/meth.rs
+++ b/src/librustc_codegen_llvm/meth.rs
@@ -10,16 +10,14 @@
 
 use abi::{FnType, FnTypeExt};
 use callee;
-use context::CodegenCx;
 use builder::Builder;
 use monomorphize;
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, StaticMethods};
+use interfaces::*;
 
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::HasDataLayout;
-use debuginfo;
+use rustc::ty::layout::HasTyCtxt;
 
 #[derive(Copy, Clone, Debug)]
 pub struct VirtualIndex(u64);
@@ -82,17 +80,17 @@ impl<'a, 'tcx> VirtualIndex {
 /// The `trait_ref` encodes the erased self type. Hence if we are
 /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
 /// `trait_ref` would map `T:Trait`.
-pub fn get_vtable(
-    cx: &CodegenCx<'ll, 'tcx>,
+pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
+    cx: &Cx,
     ty: Ty<'tcx>,
     trait_ref: ty::PolyExistentialTraitRef<'tcx>,
-) -> &'ll Value {
-    let tcx = cx.tcx;
+) -> Cx::Value {
+    let tcx = cx.tcx();
 
     debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref);
 
     // Check the cache.
-    if let Some(&val) = cx.vtables.borrow().get(&(ty, trait_ref)) {
+    if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
         return val;
     }
 
@@ -106,13 +104,13 @@ pub fn get_vtable(
         })
     });
 
-    let (size, align) = cx.size_and_align_of(ty);
+    let (size, align) = cx.layout_of(ty).size_and_align();
     // /////////////////////////////////////////////////////////////////////////////////////////////
     // If you touch this code, be sure to also make the corresponding changes to
     // `get_vtable` in rust_mir/interpret/traits.rs
     // /////////////////////////////////////////////////////////////////////////////////////////////
     let components: Vec<_> = [
-        callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
+        cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)),
         cx.const_usize(size.bytes()),
         cx.const_usize(align.abi())
     ].iter().cloned().chain(methods).collect();
@@ -121,8 +119,8 @@ pub fn get_vtable(
     let align = cx.data_layout().pointer_align;
     let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
 
-    debuginfo::create_vtable_metadata(cx, ty, vtable);
+    cx.create_vtable_metadata(ty, vtable);
 
-    cx.vtables.borrow_mut().insert((ty, trait_ref), vtable);
+    cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
     vtable
 }
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 7c7ad740e79..6a8a8948cc7 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -11,7 +11,7 @@
 use llvm::{self, BasicBlock};
 use rustc::middle::lang_items;
 use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::ty::layout::{self, LayoutOf};
+use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
 use rustc::mir;
 use rustc::mir::interpret::EvalErrorKind;
 use abi::{Abi, ArgType, ArgTypeExt, FnType, FnTypeExt, LlvmType, PassMode};
@@ -57,7 +57,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
         debug!("codegen_terminator: {:?}", terminator);
 
         // Create the cleanup bundle, if needed.
-        let tcx = bx.tcx();
+        let tcx = self.cx.tcx;
         let span = terminator.source_info.span;
         let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb);
         let funclet = funclet_bb.and_then(|funclet_bb| self.funclets[funclet_bb].as_ref());
diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs
index d448ca1735b..5ccb20886b6 100644
--- a/src/librustc_codegen_llvm/mir/constant.rs
+++ b/src/librustc_codegen_llvm/mir/constant.rs
@@ -16,7 +16,7 @@ use rustc::mir;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc::mir::interpret::{GlobalId, Pointer, Scalar, Allocation, ConstValue, AllocType};
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size};
+use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size, HasTyCtxt};
 use builder::Builder;
 use common::{CodegenCx};
 use type_of::LayoutLlvmExt;
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index 94f25aa082b..e3e3843476a 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -13,7 +13,7 @@ use llvm::{self, BasicBlock};
 use llvm::debuginfo::DIScope;
 use llvm_util;
 use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
-use rustc::ty::layout::{LayoutOf, TyLayout};
+use rustc::ty::layout::{LayoutOf, TyLayout, HasTyCtxt};
 use rustc::mir::{self, Mir};
 use rustc::ty::subst::Substs;
 use rustc::session::config::DebugInfo;
diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs
index b6142d50bb7..285cbb21aa1 100644
--- a/src/librustc_codegen_llvm/mir/place.rs
+++ b/src/librustc_codegen_llvm/mir/place.rs
@@ -10,7 +10,7 @@
 
 use llvm::{self, LLVMConstInBoundsGEP};
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx};
+use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size, VariantIdx, HasTyCtxt};
 use rustc::mir;
 use rustc::mir::tcx::PlaceTy;
 use base;
diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs
index c7e8e467f50..2b9d07a5234 100644
--- a/src/librustc_codegen_llvm/mir/rvalue.rs
+++ b/src/librustc_codegen_llvm/mir/rvalue.rs
@@ -10,7 +10,7 @@
 
 use rustc::ty::{self, Ty};
 use rustc::ty::cast::{CastTy, IntTy};
-use rustc::ty::layout::{self, LayoutOf};
+use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
 use rustc::mir;
 use rustc::middle::lang_items::ExchangeMallocFnLangItem;
 use rustc_apfloat::{ieee, Float, Status, Round};
@@ -488,7 +488,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
             mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => {
                 assert!(bx.cx().type_is_sized(ty));
                 let val = bx.cx().const_usize(bx.cx().size_of(ty).bytes());
-                let tcx = bx.tcx();
+                let tcx = self.cx.tcx;
                 (bx, OperandRef {
                     val: OperandValue::Immediate(val),
                     layout: self.cx.layout_of(tcx.types.usize),
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index 21c815784a4..d806f159f95 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -15,16 +15,21 @@ pub use llvm::Type;
 use llvm;
 use llvm::{Bool, False, True};
 use context::CodegenCx;
-use interfaces::{BaseTypeMethods, DerivedTypeMethods, TypeMethods};
+use interfaces::*;
 use value::Value;
 
 
 use syntax::ast;
 use rustc::ty::layout::{self, Align, Size};
+use rustc::util::nodemap::FxHashMap;
+use rustc::ty::Ty;
+use rustc::ty::layout::TyLayout;
 use rustc_data_structures::small_c_str::SmallCStr;
 use common::{self, TypeKind};
+use type_of::LayoutLlvmExt;
 
 use std::fmt;
+use std::cell::RefCell;
 
 use libc::c_uint;
 
@@ -42,7 +47,7 @@ impl fmt::Debug for Type {
     }
 }
 
-impl BaseTypeMethods for CodegenCx<'ll, 'tcx> {
+impl BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn type_void(&self) -> &'ll Type {
         unsafe {
             llvm::LLVMVoidTypeInContext(self.llcx)
@@ -234,6 +239,10 @@ impl BaseTypeMethods for CodegenCx<'ll, 'tcx> {
     fn val_ty(&self, v: &'ll Value) -> &'ll Type {
         common::val_ty(v)
     }
+
+    fn scalar_lltypes(&self) -> &RefCell<FxHashMap<Ty<'tcx>, Self::Type>> {
+        &self.scalar_lltypes
+    }
 }
 
 impl Type {
@@ -264,7 +273,7 @@ impl Type {
     }
 }
 
-impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> {
+impl DerivedTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn type_bool(&self) -> &'ll Type {
         self.type_i8()
     }
@@ -358,4 +367,8 @@ impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> {
     }
 }
 
-impl TypeMethods for CodegenCx<'ll, 'tcx> {}
+impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+    fn backend_type(&self, ty: TyLayout<'tcx>) -> &'ll Type {
+        ty.llvm_type(&self)
+    }
+}