1
Fork 0

rustc: add some abstractions to ty::layout for a more concise API.

This commit is contained in:
Eduard-Mihai Burtescu 2017-03-10 06:25:51 +02:00
parent c977daf97c
commit 43b227f3bd
17 changed files with 188 additions and 80 deletions

View file

@ -89,7 +89,7 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
let from = unpack_option_like(self.infcx.tcx.global_tcx(), from); let from = unpack_option_like(self.infcx.tcx.global_tcx(), from);
match (&from.sty, sk_to) { match (&from.sty, sk_to) {
(&ty::TyFnDef(..), SizeSkeleton::Known(size_to)) (&ty::TyFnDef(..), SizeSkeleton::Known(size_to))
if size_to == Pointer.size(&self.infcx.tcx.data_layout) => { if size_to == Pointer.size(self.infcx) => {
struct_span_err!(self.infcx.tcx.sess, span, E0591, struct_span_err!(self.infcx.tcx.sess, span, E0591,
"`{}` is zero-sized and can't be transmuted to `{}`", "`{}` is zero-sized and can't be transmuted to `{}`",
from, to) from, to)

View file

@ -202,6 +202,16 @@ impl TargetDataLayout {
} }
} }
pub trait HasDataLayout: Copy {
fn data_layout(&self) -> &TargetDataLayout;
}
impl<'a> HasDataLayout for &'a TargetDataLayout {
fn data_layout(&self) -> &TargetDataLayout {
self
}
}
/// Endianness of the target, which must match cfg(target-endian). /// Endianness of the target, which must match cfg(target-endian).
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Endian { pub enum Endian {
@ -242,7 +252,9 @@ impl Size {
Size::from_bytes((self.bytes() + mask) & !mask) Size::from_bytes((self.bytes() + mask) & !mask)
} }
pub fn checked_add(self, offset: Size, dl: &TargetDataLayout) -> Option<Size> { pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: C) -> Option<Size> {
let dl = cx.data_layout();
// Each Size is less than dl.obj_size_bound(), so the sum is // Each Size is less than dl.obj_size_bound(), so the sum is
// also less than 1 << 62 (and therefore can't overflow). // also less than 1 << 62 (and therefore can't overflow).
let bytes = self.bytes() + offset.bytes(); let bytes = self.bytes() + offset.bytes();
@ -254,7 +266,9 @@ impl Size {
} }
} }
pub fn checked_mul(self, count: u64, dl: &TargetDataLayout) -> Option<Size> { pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: C) -> Option<Size> {
let dl = cx.data_layout();
// Each Size is less than dl.obj_size_bound(), so the sum is // Each Size is less than dl.obj_size_bound(), so the sum is
// also less than 1 << 62 (and therefore can't overflow). // also less than 1 << 62 (and therefore can't overflow).
match self.bytes().checked_mul(count) { match self.bytes().checked_mul(count) {
@ -354,7 +368,9 @@ impl Integer {
} }
} }
pub fn align(&self, dl: &TargetDataLayout)-> Align { pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
let dl = cx.data_layout();
match *self { match *self {
I1 => dl.i1_align, I1 => dl.i1_align,
I8 => dl.i8_align, I8 => dl.i8_align,
@ -408,7 +424,9 @@ impl Integer {
} }
/// Find the smallest integer with the given alignment. /// Find the smallest integer with the given alignment.
pub fn for_abi_align(dl: &TargetDataLayout, align: Align) -> Option<Integer> { pub fn for_abi_align<C: HasDataLayout>(cx: C, align: Align) -> Option<Integer> {
let dl = cx.data_layout();
let wanted = align.abi(); let wanted = align.abi();
for &candidate in &[I8, I16, I32, I64] { for &candidate in &[I8, I16, I32, I64] {
let ty = Int(candidate); let ty = Int(candidate);
@ -420,7 +438,9 @@ impl Integer {
} }
/// Get the Integer type from an attr::IntType. /// Get the Integer type from an attr::IntType.
pub fn from_attr(dl: &TargetDataLayout, ity: attr::IntType) -> Integer { pub fn from_attr<C: HasDataLayout>(cx: C, ity: attr::IntType) -> Integer {
let dl = cx.data_layout();
match ity { match ity {
attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8, attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8,
attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16, attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16,
@ -450,7 +470,7 @@ impl Integer {
let min_default = I8; let min_default = I8;
if let Some(ity) = repr.int { if let Some(ity) = repr.int {
let discr = Integer::from_attr(&tcx.data_layout, ity); let discr = Integer::from_attr(tcx, ity);
let fit = if ity.is_signed() { signed_fit } else { unsigned_fit }; let fit = if ity.is_signed() { signed_fit } else { unsigned_fit };
if discr < fit { if discr < fit {
bug!("Integer::repr_discr: `#[repr]` hint too small for \ bug!("Integer::repr_discr: `#[repr]` hint too small for \
@ -491,7 +511,9 @@ pub enum Primitive {
} }
impl Primitive { impl Primitive {
pub fn size(self, dl: &TargetDataLayout) -> Size { pub fn size<C: HasDataLayout>(self, cx: C) -> Size {
let dl = cx.data_layout();
match self { match self {
Int(I1) | Int(I8) => Size::from_bits(8), Int(I1) | Int(I8) => Size::from_bits(8),
Int(I16) => Size::from_bits(16), Int(I16) => Size::from_bits(16),
@ -502,7 +524,9 @@ impl Primitive {
} }
} }
pub fn align(self, dl: &TargetDataLayout) -> Align { pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
let dl = cx.data_layout();
match self { match self {
Int(I1) => dl.i1_align, Int(I1) => dl.i1_align,
Int(I8) => dl.i8_align, Int(I8) => dl.i8_align,
@ -682,8 +706,8 @@ impl<'a, 'gcx, 'tcx> Struct {
} }
/// Determine whether a structure would be zero-sized, given its fields. /// Determine whether a structure would be zero-sized, given its fields.
pub fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I) fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I)
-> Result<bool, LayoutError<'gcx>> -> Result<bool, LayoutError<'gcx>>
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> { where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
for field in fields { for field in fields {
let field = field?; let field = field?;
@ -831,7 +855,7 @@ pub struct Union {
} }
impl<'a, 'gcx, 'tcx> Union { impl<'a, 'gcx, 'tcx> Union {
pub fn new(dl: &TargetDataLayout, packed: bool) -> Union { fn new(dl: &TargetDataLayout, packed: bool) -> Union {
Union { Union {
align: if packed { dl.i8_align } else { dl.aggregate_align }, align: if packed { dl.i8_align } else { dl.aggregate_align },
min_size: Size::from_bytes(0), min_size: Size::from_bytes(0),
@ -840,10 +864,10 @@ impl<'a, 'gcx, 'tcx> Union {
} }
/// Extend the Struct with more fields. /// Extend the Struct with more fields.
pub fn extend<I>(&mut self, dl: &TargetDataLayout, fn extend<I>(&mut self, dl: &TargetDataLayout,
fields: I, fields: I,
scapegoat: Ty<'gcx>) scapegoat: Ty<'gcx>)
-> Result<(), LayoutError<'gcx>> -> Result<(), LayoutError<'gcx>>
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> { where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
for (index, field) in fields.enumerate() { for (index, field) in fields.enumerate() {
let field = field?; let field = field?;
@ -1452,7 +1476,9 @@ impl<'a, 'gcx, 'tcx> Layout {
} }
} }
pub fn size(&self, dl: &TargetDataLayout) -> Size { pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
let dl = cx.data_layout();
match *self { match *self {
Scalar { value, .. } | RawNullablePointer { value, .. } => { Scalar { value, .. } | RawNullablePointer { value, .. } => {
value.size(dl) value.size(dl)
@ -1494,7 +1520,9 @@ impl<'a, 'gcx, 'tcx> Layout {
} }
} }
pub fn align(&self, dl: &TargetDataLayout) -> Align { pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
let dl = cx.data_layout();
match *self { match *self {
Scalar { value, .. } | RawNullablePointer { value, .. } => { Scalar { value, .. } | RawNullablePointer { value, .. } => {
value.align(dl) value.align(dl)
@ -1534,11 +1562,13 @@ impl<'a, 'gcx, 'tcx> Layout {
} }
} }
pub fn field_offset(&self, pub fn field_offset<C: HasDataLayout>(&self,
dl: &TargetDataLayout, cx: C,
i: usize, i: usize,
variant_index: Option<usize>) variant_index: Option<usize>)
-> Size { -> Size {
let dl = cx.data_layout();
match *self { match *self {
Scalar { .. } | Scalar { .. } |
CEnum { .. } | CEnum { .. } |
@ -1617,7 +1647,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
// First try computing a static layout. // First try computing a static layout.
let err = match ty.layout(infcx) { let err = match ty.layout(infcx) {
Ok(layout) => { Ok(layout) => {
return Ok(SizeSkeleton::Known(layout.size(&tcx.data_layout))); return Ok(SizeSkeleton::Known(layout.size(tcx)));
} }
Err(err) => err Err(err) => err
}; };
@ -1748,18 +1778,55 @@ impl<'tcx> Deref for TyLayout<'tcx> {
} }
} }
impl<'a, 'gcx, 'tcx> TyLayout<'gcx> { pub trait HasTyCtxt<'tcx>: HasDataLayout {
pub fn of(infcx: &InferCtxt<'a, 'gcx, 'tcx>, ty: Ty<'gcx>) fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
-> Result<Self, LayoutError<'gcx>> { }
let ty = normalize_associated_type(infcx, ty);
impl<'a, 'gcx, 'tcx> HasDataLayout for TyCtxt<'a, 'gcx, 'tcx> {
fn data_layout(&self) -> &TargetDataLayout {
&self.data_layout
}
}
impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
self.global_tcx()
}
}
impl<'a, 'gcx, 'tcx> HasDataLayout for &'a InferCtxt<'a, 'gcx, 'tcx> {
fn data_layout(&self) -> &TargetDataLayout {
&self.tcx.data_layout
}
}
impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for &'a InferCtxt<'a, 'gcx, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
self.tcx.global_tcx()
}
}
pub trait LayoutTyper<'tcx>: HasTyCtxt<'tcx> {
type TyLayout;
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout;
}
impl<'a, 'gcx, 'tcx> LayoutTyper<'gcx> for &'a InferCtxt<'a, 'gcx, 'tcx> {
type TyLayout = Result<TyLayout<'gcx>, LayoutError<'gcx>>;
fn layout_of(self, ty: Ty<'gcx>) -> Self::TyLayout {
let ty = normalize_associated_type(self, ty);
Ok(TyLayout { Ok(TyLayout {
ty: ty, ty: ty,
layout: ty.layout(infcx)?, layout: ty.layout(self)?,
variant_index: None variant_index: None
}) })
} }
}
impl<'a, 'tcx> TyLayout<'tcx> {
pub fn for_variant(&self, variant_index: usize) -> Self { pub fn for_variant(&self, variant_index: usize) -> Self {
TyLayout { TyLayout {
variant_index: Some(variant_index), variant_index: Some(variant_index),
@ -1767,8 +1834,8 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
} }
} }
pub fn field_offset(&self, dl: &TargetDataLayout, i: usize) -> Size { pub fn field_offset<C: HasDataLayout>(&self, cx: C, i: usize) -> Size {
self.layout.field_offset(dl, i, self.variant_index) self.layout.field_offset(cx, i, self.variant_index)
} }
pub fn field_count(&self) -> usize { pub fn field_count(&self) -> usize {
@ -1808,9 +1875,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
} }
} }
pub fn field_type(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>, i: usize) -> Ty<'gcx> { pub fn field_type<C: HasTyCtxt<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
let ptr_field_type = |pointee: Ty<'gcx>| { let tcx = cx.tcx();
let slice = |element: Ty<'gcx>| {
let ptr_field_type = |pointee: Ty<'tcx>| {
let slice = |element: Ty<'tcx>| {
assert!(i < 2); assert!(i < 2);
if i == 0 { if i == 0 {
tcx.mk_mut_ptr(element) tcx.mk_mut_ptr(element)
@ -1877,8 +1946,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
} }
} }
pub fn field(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, i: usize) pub fn field<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> C::TyLayout {
-> Result<Self, LayoutError<'gcx>> { cx.layout_of(self.field_type(cx, i))
TyLayout::of(infcx, self.field_type(infcx.tcx.global_tcx(), i))
} }
} }

View file

@ -733,7 +733,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
}); });
if let Layout::General { ref variants, ref size, discr, .. } = *layout { if let Layout::General { ref variants, ref size, discr, .. } = *layout {
let discr_size = Primitive::Int(discr).size(&cx.tcx.data_layout).bytes(); let discr_size = Primitive::Int(discr).size(cx.tcx).bytes();
debug!("enum `{}` is {} bytes large with layout:\n{:#?}", debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
t, size.bytes(), layout); t, size.bytes(), layout);

View file

@ -35,13 +35,13 @@ use type_of;
use rustc::hir; use rustc::hir;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::{Layout, LayoutTyper};
use libc::c_uint; use libc::c_uint;
use std::cmp; use std::cmp;
pub use syntax::abi::Abi; pub use syntax::abi::Abi;
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
use rustc::ty::layout::Layout;
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
enum ArgKind { enum ArgKind {

View file

@ -46,8 +46,8 @@ use super::Disr;
use std; use std;
use llvm::{ValueRef, True, IntEQ, IntNE}; use llvm::{ValueRef, True, IntEQ, IntNE};
use rustc::ty::layout;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, LayoutTyper};
use common::*; use common::*;
use builder::Builder; use builder::Builder;
use base; use base;
@ -246,9 +246,8 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
assert_eq!(size%align, 0); assert_eq!(size%align, 0);
assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align); assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align);
let align_units = size/align; let align_units = size/align;
let dl = &cx.tcx().data_layout;
let layout_align = layout::Align::from_bytes(align, align).unwrap(); let layout_align = layout::Align::from_bytes(align, align).unwrap();
if let Some(ity) = layout::Integer::for_abi_align(dl, layout_align) { if let Some(ity) = layout::Integer::for_abi_align(cx, layout_align) {
Type::array(&Type::from_integer(cx, ity), align_units) Type::array(&Type::from_integer(cx, ity), align_units)
} else { } else {
Type::array(&Type::vector(&Type::i32(cx), align/4), Type::array(&Type::vector(&Type::i32(cx), align/4),

View file

@ -1295,8 +1295,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
// (delay format until we actually need it) // (delay format until we actually need it)
let record = |kind, opt_discr_size, variants| { let record = |kind, opt_discr_size, variants| {
let type_desc = format!("{:?}", ty); let type_desc = format!("{:?}", ty);
let overall_size = layout.size(&tcx.data_layout); let overall_size = layout.size(tcx);
let align = layout.align(&tcx.data_layout); let align = layout.align(tcx);
tcx.sess.code_stats.borrow_mut().record_type_size(kind, tcx.sess.code_stats.borrow_mut().record_type_size(kind,
type_desc, type_desc,
align, align,
@ -1332,8 +1332,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
session::FieldInfo { session::FieldInfo {
name: field_name.to_string(), name: field_name.to_string(),
offset: offset.bytes(), offset: offset.bytes(),
size: field_layout.size(&tcx.data_layout).bytes(), size: field_layout.size(tcx).bytes(),
align: field_layout.align(&tcx.data_layout).abi(), align: field_layout.align(tcx).abi(),
} }
} }
} }
@ -1343,8 +1343,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
session::VariantInfo { session::VariantInfo {
name: Some(name.to_string()), name: Some(name.to_string()),
kind: session::SizeKind::Exact, kind: session::SizeKind::Exact,
align: value.align(&tcx.data_layout).abi(), align: value.align(tcx).abi(),
size: value.size(&tcx.data_layout).bytes(), size: value.size(tcx).bytes(),
fields: vec![], fields: vec![],
} }
}; };

View file

@ -27,7 +27,7 @@ use monomorphize;
use type_::Type; use type_::Type;
use value::Value; use value::Value;
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::Layout; use rustc::ty::layout::{Layout, LayoutTyper};
use rustc::ty::subst::{Subst, Substs}; use rustc::ty::subst::{Subst, Substs};
use rustc::hir; use rustc::hir;
@ -63,7 +63,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
Layout::UntaggedUnion { .. } | Layout::UntaggedUnion { .. } |
Layout::RawNullablePointer { .. } | Layout::RawNullablePointer { .. } |
Layout::StructWrappedNullablePointer { .. } => { Layout::StructWrappedNullablePointer { .. } => {
!layout.is_unsized() && layout.size(&ccx.tcx().data_layout).bytes() == 0 !layout.is_unsized() && layout.size(ccx).bytes() == 0
} }
} }
} }
@ -126,7 +126,7 @@ pub fn type_is_imm_pair<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
/// Identify types which have size zero at runtime. /// Identify types which have size zero at runtime.
pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool { pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
let layout = ccx.layout_of(ty); let layout = ccx.layout_of(ty);
!layout.is_unsized() && layout.size(&ccx.tcx().data_layout).bytes() == 0 !layout.is_unsized() && layout.size(ccx).bytes() == 0
} }
/* /*

View file

@ -28,6 +28,7 @@ use type_::Type;
use rustc_data_structures::base_n; use rustc_data_structures::base_n;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{LayoutTyper, TyLayout};
use session::config::NoDebugInfo; use session::config::NoDebugInfo;
use session::Session; use session::Session;
use session::config; use session::config;
@ -828,18 +829,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
TypeOfDepthLock(self.local()) TypeOfDepthLock(self.local())
} }
pub fn layout_of(&self, ty: Ty<'tcx>) -> ty::layout::TyLayout<'tcx> {
self.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
ty::layout::TyLayout::of(&infcx, ty).unwrap_or_else(|e| {
match e {
ty::layout::LayoutError::SizeOverflow(_) =>
self.sess().fatal(&e.to_string()),
_ => bug!("failed to get layout for `{}`: {}", ty, e)
}
})
})
}
pub fn check_overflow(&self) -> bool { pub fn check_overflow(&self) -> bool {
self.shared.check_overflow self.shared.check_overflow
} }
@ -951,6 +940,54 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
} }
} }
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a SharedCrateContext<'a, 'tcx> {
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
&self.tcx.data_layout
}
}
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
self.tcx
}
}
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CrateContext<'a, 'tcx> {
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
&self.shared.tcx.data_layout
}
}
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CrateContext<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
self.shared.tcx
}
}
impl<'a, 'tcx> LayoutTyper<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
type TyLayout = TyLayout<'tcx>;
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
self.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
infcx.layout_of(ty).unwrap_or_else(|e| {
match e {
ty::layout::LayoutError::SizeOverflow(_) =>
self.sess().fatal(&e.to_string()),
_ => bug!("failed to get layout for `{}`: {}", ty, e)
}
})
})
}
}
impl<'a, 'tcx> LayoutTyper<'tcx> for &'a CrateContext<'a, 'tcx> {
type TyLayout = TyLayout<'tcx>;
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
self.shared.layout_of(ty)
}
}
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>); pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);
impl<'a, 'tcx> Drop for TypeOfDepthLock<'a, 'tcx> { impl<'a, 'tcx> Drop for TypeOfDepthLock<'a, 'tcx> {

View file

@ -35,7 +35,8 @@ use rustc_data_structures::ToHex;
use {type_of, machine, monomorphize}; use {type_of, machine, monomorphize};
use common::{self, CrateContext}; use common::{self, CrateContext};
use type_::Type; use type_::Type;
use rustc::ty::{self, AdtKind, Ty, layout}; use rustc::ty::{self, AdtKind, Ty};
use rustc::ty::layout::{self, LayoutTyper};
use session::config; use session::config;
use util::nodemap::FxHashMap; use util::nodemap::FxHashMap;
use util::common::path2cstr; use util::common::path2cstr;
@ -900,7 +901,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
let offsets = match *layout { let offsets = match *layout {
layout::Univariant { ref variant, .. } => &variant.offsets, layout::Univariant { ref variant, .. } => &variant.offsets,
layout::Vector { element, count } => { layout::Vector { element, count } => {
let element_size = element.size(&cx.tcx().data_layout).bytes(); let element_size = element.size(cx).bytes();
tmp = (0..count). tmp = (0..count).
map(|i| layout::Size::from_bytes(i*element_size)) map(|i| layout::Size::from_bytes(i*element_size))
.collect::<Vec<layout::Size>>(); .collect::<Vec<layout::Size>>();

View file

@ -18,6 +18,7 @@ use llvm;
use llvm::{ValueRef}; use llvm::{ValueRef};
use rustc::traits; use rustc::traits;
use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::LayoutTyper;
use common::*; use common::*;
use meth; use meth;
use monomorphize; use monomorphize;
@ -47,7 +48,7 @@ pub fn needs_drop_glue<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, t: Ty<'tcx>
if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) { if !scx.type_needs_drop(typ) && scx.type_is_sized(typ) {
scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| { scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
let layout = t.layout(&infcx).unwrap(); let layout = t.layout(&infcx).unwrap();
if layout.size(&scx.tcx().data_layout).bytes() == 0 { if layout.size(scx).bytes() == 0 {
// `Box<ZeroSizeType>` does not allocate. // `Box<ZeroSizeType>` does not allocate.
false false
} else { } else {

View file

@ -12,7 +12,8 @@ use llvm::{self, ValueRef, BasicBlockRef};
use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err}; use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
use rustc::middle::lang_items; use rustc::middle::lang_items;
use rustc::middle::const_val::ConstInt; use rustc::middle::const_val::ConstInt;
use rustc::ty::{self, layout, TypeFoldable}; use rustc::ty::{self, TypeFoldable};
use rustc::ty::layout::{self, LayoutTyper};
use rustc::mir; use rustc::mir;
use abi::{Abi, FnType, ArgType}; use abi::{Abi, FnType, ArgType};
use base::{self, Lifetime}; use base::{self, Lifetime};

View file

@ -18,7 +18,8 @@ use rustc::hir::def_id::DefId;
use rustc::infer::TransNormalize; use rustc::infer::TransNormalize;
use rustc::mir; use rustc::mir;
use rustc::mir::tcx::LvalueTy; use rustc::mir::tcx::LvalueTy;
use rustc::ty::{self, layout, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::layout::{self, LayoutTyper};
use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::subst::{Kind, Substs, Subst}; use rustc::ty::subst::{Kind, Substs, Subst};
use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@ -979,7 +980,6 @@ fn trans_const<'a, 'tcx>(
vals: &[ValueRef] vals: &[ValueRef]
) -> ValueRef { ) -> ValueRef {
let l = ccx.layout_of(t); let l = ccx.layout_of(t);
let dl = &ccx.tcx().data_layout;
let variant_index = match *kind { let variant_index = match *kind {
mir::AggregateKind::Adt(_, index, _, _) => index, mir::AggregateKind::Adt(_, index, _, _) => index,
_ => 0, _ => 0,
@ -1002,7 +1002,7 @@ fn trans_const<'a, 'tcx>(
let mut vals_with_discr = vec![lldiscr]; let mut vals_with_discr = vec![lldiscr];
vals_with_discr.extend_from_slice(vals); vals_with_discr.extend_from_slice(vals);
let mut contents = build_const_struct(ccx, &variant, &vals_with_discr[..]); let mut contents = build_const_struct(ccx, &variant, &vals_with_discr[..]);
let needed_padding = l.size(dl).bytes() - variant.stride().bytes(); let needed_padding = l.size(ccx).bytes() - variant.stride().bytes();
if needed_padding > 0 { if needed_padding > 0 {
contents.push(padding(ccx, needed_padding)); contents.push(padding(ccx, needed_padding));
} }

View file

@ -9,7 +9,8 @@
// except according to those terms. // except according to those terms.
use llvm::ValueRef; use llvm::ValueRef;
use rustc::ty::{self, layout, Ty, TypeFoldable}; use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::{self, LayoutTyper};
use rustc::mir; use rustc::mir;
use rustc::mir::tcx::LvalueTy; use rustc::mir::tcx::LvalueTy;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;

View file

@ -11,7 +11,8 @@
use libc::c_uint; use libc::c_uint;
use llvm::{self, ValueRef, BasicBlockRef}; use llvm::{self, ValueRef, BasicBlockRef};
use llvm::debuginfo::DIScope; use llvm::debuginfo::DIScope;
use rustc::ty::{self, layout}; use rustc::ty;
use rustc::ty::layout::{self, LayoutTyper};
use rustc::mir::{self, Mir}; use rustc::mir::{self, Mir};
use rustc::mir::tcx::LvalueTy; use rustc::mir::tcx::LvalueTy;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;

View file

@ -10,7 +10,7 @@
use llvm::ValueRef; use llvm::ValueRef;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::layout::Layout; use rustc::ty::layout::{Layout, LayoutTyper};
use rustc::mir; use rustc::mir;
use rustc::mir::tcx::LvalueTy; use rustc::mir::tcx::LvalueTy;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;

View file

@ -11,7 +11,7 @@
use llvm::{self, ValueRef}; use llvm::{self, ValueRef};
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};
use rustc::ty::cast::{CastTy, IntTy}; use rustc::ty::cast::{CastTy, IntTy};
use rustc::ty::layout::Layout; use rustc::ty::layout::{Layout, LayoutTyper};
use rustc::mir::tcx::LvalueTy; use rustc::mir::tcx::LvalueTy;
use rustc::mir; use rustc::mir;
use middle::lang_items::ExchangeMallocFnLangItem; use middle::lang_items::ExchangeMallocFnLangItem;

View file

@ -13,6 +13,7 @@ use adt;
use common::*; use common::*;
use machine; use machine;
use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::{self, Ty, TypeFoldable};
use rustc::ty::layout::LayoutTyper;
use trans_item::DefPathBasedNames; use trans_item::DefPathBasedNames;
use type_::Type; use type_::Type;
@ -117,14 +118,14 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
return llsizingty; return llsizingty;
} }
let r = layout.size(&cx.tcx().data_layout).bytes(); let r = layout.size(cx).bytes();
let l = machine::llsize_of_alloc(cx, llsizingty); let l = machine::llsize_of_alloc(cx, llsizingty);
if r != l { if r != l {
bug!("size differs (rustc: {}, llvm: {}) for type `{}` / {:#?}", bug!("size differs (rustc: {}, llvm: {}) for type `{}` / {:#?}",
r, l, t, layout); r, l, t, layout);
} }
let r = layout.align(&cx.tcx().data_layout).abi(); let r = layout.align(cx).abi();
let l = machine::llalign_of_min(cx, llsizingty) as u64; let l = machine::llalign_of_min(cx, llsizingty) as u64;
if r != l { if r != l {
bug!("align differs (rustc: {}, llvm: {}) for type `{}` / {:#?}", bug!("align differs (rustc: {}, llvm: {}) for type `{}` / {:#?}",
@ -324,13 +325,11 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
impl<'a, 'tcx> CrateContext<'a, 'tcx> { impl<'a, 'tcx> CrateContext<'a, 'tcx> {
pub fn align_of(&self, ty: Ty<'tcx>) -> machine::llalign { pub fn align_of(&self, ty: Ty<'tcx>) -> machine::llalign {
let layout = self.layout_of(ty); self.layout_of(ty).align(self).abi() as machine::llalign
layout.align(&self.tcx().data_layout).abi() as machine::llalign
} }
pub fn size_of(&self, ty: Ty<'tcx>) -> machine::llsize { pub fn size_of(&self, ty: Ty<'tcx>) -> machine::llsize {
let layout = self.layout_of(ty); self.layout_of(ty).size(self).bytes() as machine::llsize
layout.size(&self.tcx().data_layout).bytes() as machine::llsize
} }
} }