diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 7428e3f16417d..efb1ba52b0c81 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 { + 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 a7a00dd0707b0..57e23766980fc 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 1162573a3f641..05d98ca068a01 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 e20a93e4e3e66..fb1f4df78fe91 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 9b330bc5f8e8a..2a5753ab27647 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 cd0c2ffacd586..f9f162bb82367 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, + 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 5581b926ccd04..923b04c0eccb4 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 0ee51f1956b8b..9fcd57a1ec5a3 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 919d80a9d6b08..680f216589ea1 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 37ff92bc1c9d6..c470ad3b881b4 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, TyLayout = TyLayout<'tcx>> +{ +} + +impl<'tcx, T> Backend<'tcx> for T where + Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyLayout = TyLayout<'tcx>> +{} diff --git a/src/librustc_codegen_llvm/interfaces/builder.rs b/src/librustc_codegen_llvm/interfaces/builder.rs index c7a753cea87ee..2ddef097f36ce 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 Backend for T { - type Value = ::Value; - type BasicBlock = ::BasicBlock; - type Type = ::Type; - type Context = ::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> + bundle: Option<&OperandBundleDef>, ) -> 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; - - 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, - args: &[Self::Value] - ) -> Self::Value; - fn cleanup_ret( - &self, cleanup: Self::Value, - unwind: Option, - ) -> Self::Value; - fn catch_pad( - &self, - parent: Self::Value, - args: &[Self::Value] - ) -> Self::Value; + fn cleanup_pad(&self, parent: Option, args: &[Self::Value]) -> Self::Value; + fn cleanup_ret(&self, cleanup: Self::Value, unwind: Option) -> 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; + fn call( + &self, + llfn: Self::Value, + args: &[Self::Value], + bundle: Option<&OperandBundleDef>, + ) -> 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 2366fefd941c7..b5e0169472d06 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 0000000000000..333fda226a9ea --- /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 or the MIT license +// , 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 39b95344c7101..f31a3adc5b8fe 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; + fn declare_intrinsic(&self, key: &str) -> Option; } diff --git a/src/librustc_codegen_llvm/interfaces/misc.rs b/src/librustc_codegen_llvm/interfaces/misc.rs new file mode 100644 index 0000000000000..c483d82495de4 --- /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 or the MIT license +// , 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, 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 9f963f63383bf..a978e295967e5 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 109ef91dcfa4a..a61087812316c 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 ff594c40095e1..e88e81a55665f 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, 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 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 4c7401eac0707..60a7de477bdbb 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 2eed9273cad1c..798cc8c83089e 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` from a value of type `Foo`, 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 7c7ad740e797c..6a8a8948cc716 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 d448ca1735b73..5ccb20886b6f9 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 94f25aa082bfd..e3e3843476af4 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 b6142d50bb76c..285cbb21aa14b 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 c7e8e467f5079..2b9d07a5234bc 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 21c815784a4b5..d806f159f95dd 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, 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) + } +}