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,
}
/// 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, _),
(&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, _)) => {
}
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"),
}
// except according to those terms.
use attributes;
-use common;
use llvm;
use rustc::dep_graph::DepGraphSafe;
use rustc::hir;
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> {
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>,
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>:
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<mir::Local> {
let mir = fx.mir;
use type_of::LayoutLlvmExt;
use value::Value;
-use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, IntrinsicDeclarationMethods};
+use interfaces::*;
use super::{FunctionCx, LocalRef};
use super::operand::{OperandRef, OperandValue};
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};
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)
+ }
}