From: Denis Merigoux Date: Thu, 13 Sep 2018 15:41:40 +0000 (+0200) Subject: Generalized base::unsize_thin_ptr X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=78dd95f4c719797d64f988a35a6a25f2dfc7c124;p=rust.git Generalized base::unsize_thin_ptr --- diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index efb1ba52b0c..34d09acdb45 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -208,7 +208,7 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( let vtable_ptr = cx.layout_of(cx.tcx().mk_mut_ptr(target)) .field(cx, abi::FAT_PTR_EXTRA); cx.static_ptrcast(meth::get_vtable(cx, source, data.principal()), - cx.backend_type(vtable_ptr)) + cx.backend_type(&vtable_ptr)) } _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, @@ -217,12 +217,12 @@ pub fn unsized_info<'tcx, Cx: CodegenMethods<'tcx>>( } /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. -pub fn unsize_thin_ptr( - bx: &Builder<'a, 'll, 'tcx>, - src: &'ll Value, +pub fn unsize_thin_ptr<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( + bx: &Bx, + src: Bx::Value, src_ty: Ty<'tcx>, dst_ty: Ty<'tcx> -) -> (&'ll Value, &'ll Value) { +) -> (Bx::Value, Bx::Value) { debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty); match (&src_ty.sty, &dst_ty.sty) { (&ty::Ref(_, a, _), @@ -232,13 +232,13 @@ pub fn unsize_thin_ptr( (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => { assert!(bx.cx().type_is_sized(a)); - let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx())); + let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b))); (bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None)) } (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => { let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty()); assert!(bx.cx().type_is_sized(a)); - let ptr_ty = bx.cx().type_ptr_to(bx.cx().layout_of(b).llvm_type(bx.cx())); + let ptr_ty = bx.cx().type_ptr_to(bx.cx().backend_type(&bx.cx().layout_of(b))); (bx.pointercast(src, ptr_ty), unsized_info(bx.cx(), a, b, None)) } (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { @@ -263,8 +263,8 @@ pub fn unsize_thin_ptr( } let (lldata, llextra) = result.unwrap(); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - (bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 0, true)), - bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx(), 1, true))) + (bx.bitcast(lldata, bx.cx().scalar_pair_element_backend_type(&dst_layout, 0, true)), + bx.bitcast(llextra, bx.cx().scalar_pair_element_backend_type(&dst_layout, 1, true))) } _ => bug!("unsize_thin_ptr: called on bad types"), } diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index f9f162bb823..37abb1464d3 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -9,7 +9,6 @@ // except according to those terms. use attributes; -use common; use llvm; use rustc::dep_graph::DepGraphSafe; use rustc::hir; @@ -746,31 +745,6 @@ pub fn eh_unwind_resume(&self) -> &'b Value { llfn } - pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - common::type_needs_drop(self.tcx, ty) - } - - pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - common::type_is_sized(self.tcx, ty) - } - - pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - common::type_is_freeze(self.tcx, ty) - } - - pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - use syntax_pos::DUMMY_SP; - if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) { - return false; - } - - let tail = self.tcx.struct_tail(ty); - match tail.sty { - ty::Foreign(..) => false, - ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), - } - } } impl ty::layout::HasDataLayout for CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_llvm/glue.rs b/src/librustc_codegen_llvm/glue.rs index 680f216589e..dadb1390bc5 100644 --- a/src/librustc_codegen_llvm/glue.rs +++ b/src/librustc_codegen_llvm/glue.rs @@ -20,7 +20,7 @@ use rustc::ty::layout::{LayoutOf, HasTyCtxt}; use rustc::ty::{self, Ty}; use value::Value; -use interfaces::{BuilderMethods, ConstMethods}; +use interfaces::*; pub fn size_and_align_of_dst( bx: &Builder<'_, 'll, 'tcx>, diff --git a/src/librustc_codegen_llvm/interfaces/type_.rs b/src/librustc_codegen_llvm/interfaces/type_.rs index e88e81a5566..463f7970e91 100644 --- a/src/librustc_codegen_llvm/interfaces/type_.rs +++ b/src/librustc_codegen_llvm/interfaces/type_.rs @@ -61,10 +61,21 @@ pub trait DerivedTypeMethods<'tcx>: Backend<'tcx> { 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_needs_drop(&self, ty: Ty<'tcx>) -> bool; + fn type_is_sized(&self, ty: Ty<'tcx>) -> bool; + fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool; + fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool; } pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> { - fn backend_type(&self, ty: TyLayout<'tcx>) -> Self::Type; + fn backend_type(&self, ty: &TyLayout<'tcx>) -> Self::Type; + fn scalar_pair_element_backend_type<'a>( + &self, + ty: &TyLayout<'tcx>, + index: usize, + immediate: bool + ) -> Self::Type; } pub trait TypeMethods<'tcx>: diff --git a/src/librustc_codegen_llvm/mir/analyze.rs b/src/librustc_codegen_llvm/mir/analyze.rs index 14f48a4ab63..fd0e1db796c 100644 --- a/src/librustc_codegen_llvm/mir/analyze.rs +++ b/src/librustc_codegen_llvm/mir/analyze.rs @@ -22,6 +22,7 @@ use type_of::LayoutLlvmExt; use super::FunctionCx; use value::Value; +use interfaces::*; pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx, &'ll Value>) -> BitSet { let mir = fx.mir; diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index 2b9d07a5234..271a55ab1dc 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -25,7 +25,7 @@ use type_of::LayoutLlvmExt; use value::Value; -use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, IntrinsicDeclarationMethods}; +use interfaces::*; use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs index d806f159f95..55237e27d9e 100644 --- a/src/librustc_codegen_llvm/type_.rs +++ b/src/librustc_codegen_llvm/type_.rs @@ -20,9 +20,9 @@ use syntax::ast; -use rustc::ty::layout::{self, Align, Size}; +use rustc::ty::layout::{self, Align, Size, HasTyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc::ty::Ty; +use rustc::ty::{self, Ty}; use rustc::ty::layout::TyLayout; use rustc_data_structures::small_c_str::SmallCStr; use common::{self, TypeKind}; @@ -365,10 +365,44 @@ fn type_padding_filler( assert_eq!(size % unit_size, 0); self.type_array(self.type_from_integer(unit), size / unit_size) } + + fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { + common::type_needs_drop(self.tcx(), ty) + } + + fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { + common::type_is_sized(self.tcx(), ty) + } + + fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { + common::type_is_freeze(self.tcx(), ty) + } + + fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { + use syntax_pos::DUMMY_SP; + if ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all()) { + return false; + } + + let tail = self.tcx().struct_tail(ty); + match tail.sty { + ty::Foreign(..) => false, + ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, + _ => bug!("unexpected unsized tail: {:?}", tail.sty), + } + } } impl LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> { - fn backend_type(&self, ty: TyLayout<'tcx>) -> &'ll Type { + fn backend_type(&self, ty: &TyLayout<'tcx>) -> &'ll Type { ty.llvm_type(&self) } + fn scalar_pair_element_backend_type<'a>( + &self, + ty: &TyLayout<'tcx>, + index: usize, + immediate: bool + ) -> &'ll Type { + ty.scalar_pair_element_llvm_type(&self, index, immediate) + } }