mirror of
https://github.com/rust-lang/rust
synced 2024-10-06 16:51:35 +00:00
rustc: add some abstractions to ty::layout for a more concise API.
This commit is contained in:
parent
c977daf97c
commit
43b227f3bd
|
@ -89,7 +89,7 @@ fn check_transmute(&self, span: Span, from: Ty<'gcx>, to: Ty<'gcx>) {
|
|||
let from = unpack_option_like(self.infcx.tcx.global_tcx(), from);
|
||||
match (&from.sty, sk_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,
|
||||
"`{}` is zero-sized and can't be transmuted to `{}`",
|
||||
from, to)
|
||||
|
|
|
@ -202,6 +202,16 @@ pub fn ptr_sized_integer(&self) -> Integer {
|
|||
}
|
||||
}
|
||||
|
||||
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).
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Endian {
|
||||
|
@ -242,7 +252,9 @@ pub fn abi_align(self, align: Align) -> Size {
|
|||
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
|
||||
// also less than 1 << 62 (and therefore can't overflow).
|
||||
let bytes = self.bytes() + offset.bytes();
|
||||
|
@ -254,7 +266,9 @@ pub fn checked_add(self, offset: Size, dl: &TargetDataLayout) -> Option<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
|
||||
// also less than 1 << 62 (and therefore can't overflow).
|
||||
match self.bytes().checked_mul(count) {
|
||||
|
@ -354,7 +368,9 @@ pub fn size(&self) -> Size {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn align(&self, dl: &TargetDataLayout)-> Align {
|
||||
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
match *self {
|
||||
I1 => dl.i1_align,
|
||||
I8 => dl.i8_align,
|
||||
|
@ -408,7 +424,9 @@ pub fn fit_unsigned(x: u64) -> Integer {
|
|||
}
|
||||
|
||||
/// 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();
|
||||
for &candidate in &[I8, I16, I32, I64] {
|
||||
let ty = Int(candidate);
|
||||
|
@ -420,7 +438,9 @@ pub fn for_abi_align(dl: &TargetDataLayout, align: Align) -> Option<Integer> {
|
|||
}
|
||||
|
||||
/// 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 {
|
||||
attr::SignedInt(IntTy::I8) | attr::UnsignedInt(UintTy::U8) => I8,
|
||||
attr::SignedInt(IntTy::I16) | attr::UnsignedInt(UintTy::U16) => I16,
|
||||
|
@ -450,7 +470,7 @@ fn repr_discr(tcx: TyCtxt, ty: Ty, repr: &ReprOptions, min: i64, max: i64)
|
|||
let min_default = I8;
|
||||
|
||||
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 };
|
||||
if discr < fit {
|
||||
bug!("Integer::repr_discr: `#[repr]` hint too small for \
|
||||
|
@ -491,7 +511,9 @@ pub enum 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 {
|
||||
Int(I1) | Int(I8) => Size::from_bits(8),
|
||||
Int(I16) => Size::from_bits(16),
|
||||
|
@ -502,7 +524,9 @@ pub fn size(self, dl: &TargetDataLayout) -> Size {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn align(self, dl: &TargetDataLayout) -> Align {
|
||||
pub fn align<C: HasDataLayout>(self, cx: C) -> Align {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
match self {
|
||||
Int(I1) => dl.i1_align,
|
||||
Int(I8) => dl.i8_align,
|
||||
|
@ -682,8 +706,8 @@ pub fn stride(&self) -> Size {
|
|||
}
|
||||
|
||||
/// Determine whether a structure would be zero-sized, given its fields.
|
||||
pub fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I)
|
||||
-> Result<bool, LayoutError<'gcx>>
|
||||
fn would_be_zero_sized<I>(dl: &TargetDataLayout, fields: I)
|
||||
-> Result<bool, LayoutError<'gcx>>
|
||||
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
|
||||
for field in fields {
|
||||
let field = field?;
|
||||
|
@ -831,7 +855,7 @@ pub struct Union {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Union {
|
||||
pub fn new(dl: &TargetDataLayout, packed: bool) -> Union {
|
||||
fn new(dl: &TargetDataLayout, packed: bool) -> Union {
|
||||
Union {
|
||||
align: if packed { dl.i8_align } else { dl.aggregate_align },
|
||||
min_size: Size::from_bytes(0),
|
||||
|
@ -840,10 +864,10 @@ pub fn new(dl: &TargetDataLayout, packed: bool) -> Union {
|
|||
}
|
||||
|
||||
/// Extend the Struct with more fields.
|
||||
pub fn extend<I>(&mut self, dl: &TargetDataLayout,
|
||||
fields: I,
|
||||
scapegoat: Ty<'gcx>)
|
||||
-> Result<(), LayoutError<'gcx>>
|
||||
fn extend<I>(&mut self, dl: &TargetDataLayout,
|
||||
fields: I,
|
||||
scapegoat: Ty<'gcx>)
|
||||
-> Result<(), LayoutError<'gcx>>
|
||||
where I: Iterator<Item=Result<&'a Layout, LayoutError<'gcx>>> {
|
||||
for (index, field) in fields.enumerate() {
|
||||
let field = field?;
|
||||
|
@ -1452,7 +1476,9 @@ pub fn is_unsized(&self) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn size(&self, dl: &TargetDataLayout) -> Size {
|
||||
pub fn size<C: HasDataLayout>(&self, cx: C) -> Size {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
match *self {
|
||||
Scalar { value, .. } | RawNullablePointer { value, .. } => {
|
||||
value.size(dl)
|
||||
|
@ -1494,7 +1520,9 @@ pub fn size(&self, dl: &TargetDataLayout) -> Size {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn align(&self, dl: &TargetDataLayout) -> Align {
|
||||
pub fn align<C: HasDataLayout>(&self, cx: C) -> Align {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
match *self {
|
||||
Scalar { value, .. } | RawNullablePointer { value, .. } => {
|
||||
value.align(dl)
|
||||
|
@ -1534,11 +1562,13 @@ pub fn align(&self, dl: &TargetDataLayout) -> Align {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn field_offset(&self,
|
||||
dl: &TargetDataLayout,
|
||||
i: usize,
|
||||
variant_index: Option<usize>)
|
||||
-> Size {
|
||||
pub fn field_offset<C: HasDataLayout>(&self,
|
||||
cx: C,
|
||||
i: usize,
|
||||
variant_index: Option<usize>)
|
||||
-> Size {
|
||||
let dl = cx.data_layout();
|
||||
|
||||
match *self {
|
||||
Scalar { .. } |
|
||||
CEnum { .. } |
|
||||
|
@ -1617,7 +1647,7 @@ pub fn compute(ty: Ty<'gcx>, infcx: &InferCtxt<'a, 'gcx, 'tcx>)
|
|||
// First try computing a static layout.
|
||||
let err = match ty.layout(infcx) {
|
||||
Ok(layout) => {
|
||||
return Ok(SizeSkeleton::Known(layout.size(&tcx.data_layout)));
|
||||
return Ok(SizeSkeleton::Known(layout.size(tcx)));
|
||||
}
|
||||
Err(err) => err
|
||||
};
|
||||
|
@ -1748,18 +1778,55 @@ fn deref(&self) -> &Layout {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
|
||||
pub fn of(infcx: &InferCtxt<'a, 'gcx, 'tcx>, ty: Ty<'gcx>)
|
||||
-> Result<Self, LayoutError<'gcx>> {
|
||||
let ty = normalize_associated_type(infcx, ty);
|
||||
pub trait HasTyCtxt<'tcx>: HasDataLayout {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx>;
|
||||
}
|
||||
|
||||
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 {
|
||||
ty: ty,
|
||||
layout: ty.layout(infcx)?,
|
||||
layout: ty.layout(self)?,
|
||||
variant_index: None
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TyLayout<'tcx> {
|
||||
pub fn for_variant(&self, variant_index: usize) -> Self {
|
||||
TyLayout {
|
||||
variant_index: Some(variant_index),
|
||||
|
@ -1767,8 +1834,8 @@ pub fn for_variant(&self, variant_index: usize) -> Self {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn field_offset(&self, dl: &TargetDataLayout, i: usize) -> Size {
|
||||
self.layout.field_offset(dl, i, self.variant_index)
|
||||
pub fn field_offset<C: HasDataLayout>(&self, cx: C, i: usize) -> Size {
|
||||
self.layout.field_offset(cx, i, self.variant_index)
|
||||
}
|
||||
|
||||
pub fn field_count(&self) -> usize {
|
||||
|
@ -1808,9 +1875,11 @@ pub fn field_count(&self) -> usize {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn field_type(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>, i: usize) -> Ty<'gcx> {
|
||||
let ptr_field_type = |pointee: Ty<'gcx>| {
|
||||
let slice = |element: Ty<'gcx>| {
|
||||
pub fn field_type<C: HasTyCtxt<'tcx>>(&self, cx: C, i: usize) -> Ty<'tcx> {
|
||||
let tcx = cx.tcx();
|
||||
|
||||
let ptr_field_type = |pointee: Ty<'tcx>| {
|
||||
let slice = |element: Ty<'tcx>| {
|
||||
assert!(i < 2);
|
||||
if i == 0 {
|
||||
tcx.mk_mut_ptr(element)
|
||||
|
@ -1877,8 +1946,7 @@ pub fn field_type(&self, tcx: TyCtxt<'a, 'gcx, 'gcx>, i: usize) -> Ty<'gcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn field(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, i: usize)
|
||||
-> Result<Self, LayoutError<'gcx>> {
|
||||
TyLayout::of(infcx, self.field_type(infcx.tcx.global_tcx(), i))
|
||||
pub fn field<C: LayoutTyper<'tcx>>(&self, cx: C, i: usize) -> C::TyLayout {
|
||||
cx.layout_of(self.field_type(cx, i))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -733,7 +733,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
|||
});
|
||||
|
||||
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{:#?}",
|
||||
t, size.bytes(), layout);
|
||||
|
|
|
@ -35,13 +35,13 @@
|
|||
|
||||
use rustc::hir;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{Layout, LayoutTyper};
|
||||
|
||||
use libc::c_uint;
|
||||
use std::cmp;
|
||||
|
||||
pub use syntax::abi::Abi;
|
||||
pub use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
||||
use rustc::ty::layout::Layout;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
enum ArgKind {
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
use std;
|
||||
|
||||
use llvm::{ValueRef, True, IntEQ, IntNE};
|
||||
use rustc::ty::layout;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{self, LayoutTyper};
|
||||
use common::*;
|
||||
use builder::Builder;
|
||||
use base;
|
||||
|
@ -246,9 +246,8 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
|
|||
assert_eq!(size%align, 0);
|
||||
assert_eq!(align.count_ones(), 1, "Alignment must be a power fof 2. Got {}", align);
|
||||
let align_units = size/align;
|
||||
let dl = &cx.tcx().data_layout;
|
||||
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)
|
||||
} else {
|
||||
Type::array(&Type::vector(&Type::i32(cx), align/4),
|
||||
|
|
|
@ -1295,8 +1295,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
// (delay format until we actually need it)
|
||||
let record = |kind, opt_discr_size, variants| {
|
||||
let type_desc = format!("{:?}", ty);
|
||||
let overall_size = layout.size(&tcx.data_layout);
|
||||
let align = layout.align(&tcx.data_layout);
|
||||
let overall_size = layout.size(tcx);
|
||||
let align = layout.align(tcx);
|
||||
tcx.sess.code_stats.borrow_mut().record_type_size(kind,
|
||||
type_desc,
|
||||
align,
|
||||
|
@ -1332,8 +1332,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
session::FieldInfo {
|
||||
name: field_name.to_string(),
|
||||
offset: offset.bytes(),
|
||||
size: field_layout.size(&tcx.data_layout).bytes(),
|
||||
align: field_layout.align(&tcx.data_layout).abi(),
|
||||
size: field_layout.size(tcx).bytes(),
|
||||
align: field_layout.align(tcx).abi(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1343,8 +1343,8 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
session::VariantInfo {
|
||||
name: Some(name.to_string()),
|
||||
kind: session::SizeKind::Exact,
|
||||
align: value.align(&tcx.data_layout).abi(),
|
||||
size: value.size(&tcx.data_layout).bytes(),
|
||||
align: value.align(tcx).abi(),
|
||||
size: value.size(tcx).bytes(),
|
||||
fields: vec![],
|
||||
}
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
use type_::Type;
|
||||
use value::Value;
|
||||
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::hir;
|
||||
|
||||
|
@ -63,7 +63,7 @@ pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -
|
|||
Layout::UntaggedUnion { .. } |
|
||||
Layout::RawNullablePointer { .. } |
|
||||
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.
|
||||
pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
use rustc_data_structures::base_n;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{LayoutTyper, TyLayout};
|
||||
use session::config::NoDebugInfo;
|
||||
use session::Session;
|
||||
use session::config;
|
||||
|
@ -828,18 +829,6 @@ pub fn enter_type_of(&self, ty: Ty<'tcx>) -> TypeOfDepthLock<'b, 'tcx> {
|
|||
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 {
|
||||
self.shared.check_overflow
|
||||
}
|
||||
|
@ -951,6 +940,54 @@ pub fn eh_unwind_resume(&self) -> ValueRef {
|
|||
}
|
||||
}
|
||||
|
||||
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>);
|
||||
|
||||
impl<'a, 'tcx> Drop for TypeOfDepthLock<'a, 'tcx> {
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
use {type_of, machine, monomorphize};
|
||||
use common::{self, CrateContext};
|
||||
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 util::nodemap::FxHashMap;
|
||||
use util::common::path2cstr;
|
||||
|
@ -900,7 +901,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
|
|||
let offsets = match *layout {
|
||||
layout::Univariant { ref variant, .. } => &variant.offsets,
|
||||
layout::Vector { element, count } => {
|
||||
let element_size = element.size(&cx.tcx().data_layout).bytes();
|
||||
let element_size = element.size(cx).bytes();
|
||||
tmp = (0..count).
|
||||
map(|i| layout::Size::from_bytes(i*element_size))
|
||||
.collect::<Vec<layout::Size>>();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
use llvm::{ValueRef};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::layout::LayoutTyper;
|
||||
use common::*;
|
||||
use meth;
|
||||
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) {
|
||||
scx.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
|
||||
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.
|
||||
false
|
||||
} else {
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
|
||||
use rustc::middle::lang_items;
|
||||
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 abi::{Abi, FnType, ArgType};
|
||||
use base::{self, Lifetime};
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
use rustc::infer::TransNormalize;
|
||||
use rustc::mir;
|
||||
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::subst::{Kind, Substs, Subst};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
|
@ -979,7 +980,6 @@ fn trans_const<'a, 'tcx>(
|
|||
vals: &[ValueRef]
|
||||
) -> ValueRef {
|
||||
let l = ccx.layout_of(t);
|
||||
let dl = &ccx.tcx().data_layout;
|
||||
let variant_index = match *kind {
|
||||
mir::AggregateKind::Adt(_, index, _, _) => index,
|
||||
_ => 0,
|
||||
|
@ -1002,7 +1002,7 @@ fn trans_const<'a, 'tcx>(
|
|||
let mut vals_with_discr = vec![lldiscr];
|
||||
vals_with_discr.extend_from_slice(vals);
|
||||
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 {
|
||||
contents.push(padding(ccx, needed_padding));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
// except according to those terms.
|
||||
|
||||
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::tcx::LvalueTy;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
use libc::c_uint;
|
||||
use llvm::{self, ValueRef, BasicBlockRef};
|
||||
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::tcx::LvalueTy;
|
||||
use rustc::ty::subst::Substs;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use llvm::ValueRef;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::Layout;
|
||||
use rustc::ty::layout::{Layout, LayoutTyper};
|
||||
use rustc::mir;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
use llvm::{self, ValueRef};
|
||||
use rustc::ty::{self, Ty};
|
||||
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;
|
||||
use middle::lang_items::ExchangeMallocFnLangItem;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
use common::*;
|
||||
use machine;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::layout::LayoutTyper;
|
||||
use trans_item::DefPathBasedNames;
|
||||
use type_::Type;
|
||||
|
||||
|
@ -117,14 +118,14 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
|||
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);
|
||||
if r != l {
|
||||
bug!("size differs (rustc: {}, llvm: {}) for type `{}` / {:#?}",
|
||||
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;
|
||||
if r != l {
|
||||
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> {
|
||||
pub fn align_of(&self, ty: Ty<'tcx>) -> machine::llalign {
|
||||
let layout = self.layout_of(ty);
|
||||
layout.align(&self.tcx().data_layout).abi() as machine::llalign
|
||||
self.layout_of(ty).align(self).abi() as machine::llalign
|
||||
}
|
||||
|
||||
pub fn size_of(&self, ty: Ty<'tcx>) -> machine::llsize {
|
||||
let layout = self.layout_of(ty);
|
||||
layout.size(&self.tcx().data_layout).bytes() as machine::llsize
|
||||
self.layout_of(ty).size(self).bytes() as machine::llsize
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue