Auto merge of #47915 - eddyb:layout-of, r=nikomatsakis
rustc: prefer ParamEnvAnd and LayoutCx over tuples for LayoutOf. This PR provides `tcx.layout_of(param_env.and(ty))` as the idiomatic replacement for the existing `(tcx, param_env).layout_of(ty)` and removes fragile (coherence-wise) layout-related tuple impls. r? @nikomatsakis
This commit is contained in:
commit
9af374abf9
@ -631,7 +631,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a LateContext<'a, 'tcx> {
|
||||
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
|
||||
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
(self.tcx, self.param_env.reveal_all()).layout_of(ty)
|
||||
self.tcx.layout_of(self.param_env.and(ty))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -895,7 +895,8 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
||||
tcx.layout_depth.set(depth+1);
|
||||
let layout = LayoutDetails::compute_uncached(tcx, param_env, ty);
|
||||
let cx = LayoutCx { tcx, param_env };
|
||||
let layout = cx.layout_raw_uncached(ty);
|
||||
tcx.layout_depth.set(depth);
|
||||
|
||||
layout
|
||||
@ -908,13 +909,18 @@ pub fn provide(providers: &mut ty::maps::Providers) {
|
||||
};
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutDetails {
|
||||
fn compute_uncached(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> Result<&'tcx Self, LayoutError<'tcx>> {
|
||||
let cx = (tcx, param_env);
|
||||
let dl = cx.data_layout();
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct LayoutCx<'tcx, C> {
|
||||
pub tcx: C,
|
||||
pub param_env: ty::ParamEnv<'tcx>
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
||||
fn layout_raw_uncached(self, ty: Ty<'tcx>)
|
||||
-> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
let param_env = self.param_env;
|
||||
let dl = self.data_layout();
|
||||
let scalar_unit = |value: Primitive| {
|
||||
let bits = value.size(dl).bits();
|
||||
assert!(bits <= 128);
|
||||
@ -924,7 +930,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
}
|
||||
};
|
||||
let scalar = |value: Primitive| {
|
||||
tcx.intern_layout(LayoutDetails::scalar(cx, scalar_unit(value)))
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)))
|
||||
};
|
||||
let scalar_pair = |a: Scalar, b: Scalar| {
|
||||
let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align);
|
||||
@ -1158,13 +1164,13 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
Ok(match ty.sty {
|
||||
// Basic scalars.
|
||||
ty::TyBool => {
|
||||
tcx.intern_layout(LayoutDetails::scalar(cx, Scalar {
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, Scalar {
|
||||
value: Int(I8, false),
|
||||
valid_range: 0..=1
|
||||
}))
|
||||
}
|
||||
ty::TyChar => {
|
||||
tcx.intern_layout(LayoutDetails::scalar(cx, Scalar {
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, Scalar {
|
||||
value: Int(I32, false),
|
||||
valid_range: 0..=0x10FFFF
|
||||
}))
|
||||
@ -1180,7 +1186,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
ty::TyFnPtr(_) => {
|
||||
let mut ptr = scalar_unit(Pointer);
|
||||
ptr.valid_range.start = 1;
|
||||
tcx.intern_layout(LayoutDetails::scalar(cx, ptr))
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, ptr))
|
||||
}
|
||||
|
||||
// The never type.
|
||||
@ -1198,13 +1204,13 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
|
||||
let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
|
||||
if pointee.is_sized(tcx, param_env, DUMMY_SP) {
|
||||
return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr)));
|
||||
return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
|
||||
}
|
||||
|
||||
let unsized_part = tcx.struct_tail(pointee);
|
||||
let metadata = match unsized_part.sty {
|
||||
ty::TyForeign(..) => {
|
||||
return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr)));
|
||||
return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
|
||||
}
|
||||
ty::TySlice(_) | ty::TyStr => {
|
||||
scalar_unit(Int(dl.ptr_sized_integer(), false))
|
||||
@ -1230,7 +1236,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
}
|
||||
}
|
||||
|
||||
let element = cx.layout_of(element)?;
|
||||
let element = self.layout_of(element)?;
|
||||
let count = count.val.to_const_int().unwrap().to_u64().unwrap();
|
||||
let size = element.size.checked_mul(count, dl)
|
||||
.ok_or(LayoutError::SizeOverflow(ty))?;
|
||||
@ -1247,7 +1253,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
})
|
||||
}
|
||||
ty::TySlice(element) => {
|
||||
let element = cx.layout_of(element)?;
|
||||
let element = self.layout_of(element)?;
|
||||
tcx.intern_layout(LayoutDetails {
|
||||
variants: Variants::Single { index: 0 },
|
||||
fields: FieldPlacement::Array {
|
||||
@ -1289,14 +1295,14 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
// Tuples, generators and closures.
|
||||
ty::TyGenerator(def_id, ref substs, _) => {
|
||||
let tys = substs.field_tys(def_id, tcx);
|
||||
univariant(&tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
univariant(&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
&ReprOptions::default(),
|
||||
StructKind::AlwaysSized)?
|
||||
}
|
||||
|
||||
ty::TyClosure(def_id, ref substs) => {
|
||||
let tys = substs.upvar_tys(def_id, tcx);
|
||||
univariant(&tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
univariant(&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
&ReprOptions::default(),
|
||||
StructKind::AlwaysSized)?
|
||||
}
|
||||
@ -1308,13 +1314,13 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
StructKind::MaybeUnsized
|
||||
};
|
||||
|
||||
univariant(&tys.iter().map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
univariant(&tys.iter().map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
&ReprOptions::default(), kind)?
|
||||
}
|
||||
|
||||
// SIMD vector types.
|
||||
ty::TyAdt(def, ..) if def.repr.simd() => {
|
||||
let element = cx.layout_of(ty.simd_type(tcx))?;
|
||||
let element = self.layout_of(ty.simd_type(tcx))?;
|
||||
let count = ty.simd_size(tcx) as u64;
|
||||
assert!(count > 0);
|
||||
let scalar = match element.abi {
|
||||
@ -1350,7 +1356,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
// Cache the field layouts.
|
||||
let variants = def.variants.iter().map(|v| {
|
||||
v.fields.iter().map(|field| {
|
||||
cx.layout_of(field.ty(tcx, substs))
|
||||
self.layout_of(field.ty(tcx, substs))
|
||||
}).collect::<Result<Vec<_>, _>>()
|
||||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
@ -1430,7 +1436,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?;
|
||||
st.variants = Variants::Single { index: v };
|
||||
// Exclude 0 from the range of a newtype ABI NonZero<T>.
|
||||
if Some(def.did) == cx.tcx().lang_items().non_zero() {
|
||||
if Some(def.did) == self.tcx.lang_items().non_zero() {
|
||||
match st.abi {
|
||||
Abi::Scalar(ref mut scalar) |
|
||||
Abi::ScalarPair(ref mut scalar, _) => {
|
||||
@ -1482,7 +1488,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
let count = (niche_variants.end - niche_variants.start + 1) as u128;
|
||||
for (field_index, field) in variants[i].iter().enumerate() {
|
||||
let (offset, niche, niche_start) =
|
||||
match field.find_niche(cx, count)? {
|
||||
match field.find_niche(self, count)? {
|
||||
Some(niche) => niche,
|
||||
None => continue
|
||||
};
|
||||
@ -1687,56 +1693,49 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
/// This is invoked by the `layout_raw` query to record the final
|
||||
/// layout of each type.
|
||||
#[inline]
|
||||
fn record_layout_for_printing(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
layout: TyLayout<'tcx>) {
|
||||
fn record_layout_for_printing(self, layout: TyLayout<'tcx>) {
|
||||
// If we are running with `-Zprint-type-sizes`, record layouts for
|
||||
// dumping later. Ignore layouts that are done with non-empty
|
||||
// environments or non-monomorphic layouts, as the user only wants
|
||||
// to see the stuff resulting from the final trans session.
|
||||
if
|
||||
!tcx.sess.opts.debugging_opts.print_type_sizes ||
|
||||
ty.has_param_types() ||
|
||||
ty.has_self_ty() ||
|
||||
!param_env.caller_bounds.is_empty()
|
||||
!self.tcx.sess.opts.debugging_opts.print_type_sizes ||
|
||||
layout.ty.has_param_types() ||
|
||||
layout.ty.has_self_ty() ||
|
||||
!self.param_env.caller_bounds.is_empty()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Self::record_layout_for_printing_outlined(tcx, ty, param_env, layout)
|
||||
self.record_layout_for_printing_outlined(layout)
|
||||
}
|
||||
|
||||
fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
layout: TyLayout<'tcx>) {
|
||||
let cx = (tcx, param_env);
|
||||
fn record_layout_for_printing_outlined(self, layout: TyLayout<'tcx>) {
|
||||
// (delay format until we actually need it)
|
||||
let record = |kind, opt_discr_size, variants| {
|
||||
let type_desc = format!("{:?}", ty);
|
||||
tcx.sess.code_stats.borrow_mut().record_type_size(kind,
|
||||
type_desc,
|
||||
layout.align,
|
||||
layout.size,
|
||||
opt_discr_size,
|
||||
variants);
|
||||
let type_desc = format!("{:?}", layout.ty);
|
||||
self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
|
||||
type_desc,
|
||||
layout.align,
|
||||
layout.size,
|
||||
opt_discr_size,
|
||||
variants);
|
||||
};
|
||||
|
||||
let adt_def = match ty.sty {
|
||||
let adt_def = match layout.ty.sty {
|
||||
ty::TyAdt(ref adt_def, _) => {
|
||||
debug!("print-type-size t: `{:?}` process adt", ty);
|
||||
debug!("print-type-size t: `{:?}` process adt", layout.ty);
|
||||
adt_def
|
||||
}
|
||||
|
||||
ty::TyClosure(..) => {
|
||||
debug!("print-type-size t: `{:?}` record closure", ty);
|
||||
debug!("print-type-size t: `{:?}` record closure", layout.ty);
|
||||
record(DataTypeKind::Closure, None, vec![]);
|
||||
return;
|
||||
}
|
||||
|
||||
_ => {
|
||||
debug!("print-type-size t: `{:?}` skip non-nominal", ty);
|
||||
debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
|
||||
return;
|
||||
}
|
||||
};
|
||||
@ -1748,7 +1747,7 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
layout: TyLayout<'tcx>| {
|
||||
let mut min_size = Size::from_bytes(0);
|
||||
let field_info: Vec<_> = flds.iter().enumerate().map(|(i, &name)| {
|
||||
match layout.field(cx, i) {
|
||||
match layout.field(self, i) {
|
||||
Err(err) => {
|
||||
bug!("no layout found for field {}: `{:?}`", name, err);
|
||||
}
|
||||
@ -1808,18 +1807,18 @@ impl<'a, 'tcx> LayoutDetails {
|
||||
Variants::NicheFilling { .. } |
|
||||
Variants::Tagged { .. } => {
|
||||
debug!("print-type-size `{:#?}` adt general variants def {}",
|
||||
ty, adt_def.variants.len());
|
||||
layout.ty, adt_def.variants.len());
|
||||
let variant_infos: Vec<_> =
|
||||
adt_def.variants.iter().enumerate().map(|(i, variant_def)| {
|
||||
let fields: Vec<_> =
|
||||
variant_def.fields.iter().map(|f| f.name).collect();
|
||||
build_variant_info(Some(variant_def.name),
|
||||
&fields,
|
||||
layout.for_variant(cx, i))
|
||||
layout.for_variant(self, i))
|
||||
})
|
||||
.collect();
|
||||
record(adt_kind.into(), match layout.variants {
|
||||
Variants::Tagged { ref discr, .. } => Some(discr.value.size(tcx)),
|
||||
Variants::Tagged { ref discr, .. } => Some(discr.value.size(self)),
|
||||
_ => None
|
||||
}, variant_infos);
|
||||
}
|
||||
@ -1855,7 +1854,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
|
||||
assert!(!ty.has_infer_types());
|
||||
|
||||
// First try computing a static layout.
|
||||
let err = match (tcx, param_env).layout_of(ty) {
|
||||
let err = match tcx.layout_of(param_env.and(ty)) {
|
||||
Ok(layout) => {
|
||||
return Ok(SizeSkeleton::Known(layout.size));
|
||||
}
|
||||
@ -2001,15 +2000,15 @@ impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T: Copy> HasDataLayout for (TyCtxt<'a, 'gcx, 'tcx>, T) {
|
||||
impl<'tcx, T: HasDataLayout> HasDataLayout for LayoutCx<'tcx, T> {
|
||||
fn data_layout(&self) -> &TargetDataLayout {
|
||||
self.0.data_layout()
|
||||
self.tcx.data_layout()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx, T: Copy> HasTyCtxt<'gcx> for (TyCtxt<'a, 'gcx, 'tcx>, T) {
|
||||
impl<'gcx, 'tcx, T: HasTyCtxt<'gcx>> HasTyCtxt<'gcx> for LayoutCx<'tcx, T> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
|
||||
self.0.tcx()
|
||||
self.tcx.tcx()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2042,17 +2041,15 @@ pub trait LayoutOf<T> {
|
||||
fn layout_of(self, ty: T) -> Self::TyLayout;
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx>) {
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
||||
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
|
||||
|
||||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode.
|
||||
#[inline]
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
let (tcx, param_env) = self;
|
||||
|
||||
let ty = tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
|
||||
let details = tcx.layout_raw(param_env.reveal_all().and(ty))?;
|
||||
let param_env = self.param_env.reveal_all();
|
||||
let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env);
|
||||
let details = self.tcx.layout_raw(param_env.and(ty))?;
|
||||
let layout = TyLayout {
|
||||
ty,
|
||||
details
|
||||
@ -2064,24 +2061,21 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx
|
||||
// completed, to avoid problems around recursive structures
|
||||
// and the like. (Admitedly, I wasn't able to reproduce a problem
|
||||
// here, but it seems like the right thing to do. -nmatsakis)
|
||||
LayoutDetails::record_layout_for_printing(tcx, ty, param_env, layout);
|
||||
self.record_layout_for_printing(layout);
|
||||
|
||||
Ok(layout)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>,
|
||||
ty::ParamEnv<'tcx>) {
|
||||
impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> {
|
||||
type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
|
||||
|
||||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode.
|
||||
#[inline]
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
let (tcx_at, param_env) = self;
|
||||
|
||||
let ty = tcx_at.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
|
||||
let details = tcx_at.layout_raw(param_env.reveal_all().and(ty))?;
|
||||
let param_env = self.param_env.reveal_all();
|
||||
let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
|
||||
let details = self.tcx.layout_raw(param_env.reveal_all().and(ty))?;
|
||||
let layout = TyLayout {
|
||||
ty,
|
||||
details
|
||||
@ -2093,12 +2087,45 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>,
|
||||
// completed, to avoid problems around recursive structures
|
||||
// and the like. (Admitedly, I wasn't able to reproduce a problem
|
||||
// here, but it seems like the right thing to do. -nmatsakis)
|
||||
LayoutDetails::record_layout_for_printing(tcx_at.tcx, ty, param_env, layout);
|
||||
let cx = LayoutCx {
|
||||
tcx: *self.tcx,
|
||||
param_env: self.param_env
|
||||
};
|
||||
cx.record_layout_for_printing(layout);
|
||||
|
||||
Ok(layout)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users.
|
||||
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode.
|
||||
#[inline]
|
||||
pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
|
||||
-> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
|
||||
let cx = LayoutCx {
|
||||
tcx: self,
|
||||
param_env: param_env_and_ty.param_env
|
||||
};
|
||||
cx.layout_of(param_env_and_ty.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::maps::TyCtxtAt<'a, 'tcx, 'tcx> {
|
||||
/// Computes the layout of a type. Note that this implicitly
|
||||
/// executes in "reveal all" mode.
|
||||
#[inline]
|
||||
pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
|
||||
-> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
|
||||
let cx = LayoutCx {
|
||||
tcx: self,
|
||||
param_env: param_env_and_ty.param_env
|
||||
};
|
||||
cx.layout_of(param_env_and_ty.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TyLayout<'tcx> {
|
||||
pub fn for_variant<C>(&self, cx: C, variant_index: usize) -> Self
|
||||
where C: LayoutOf<Ty<'tcx>> + HasTyCtxt<'tcx>,
|
||||
|
@ -17,7 +17,6 @@ use rustc::hir::map::blocks::FnLikeNode;
|
||||
use rustc::hir::def::{Def, CtorKind};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::ty::util::IntTypeExt;
|
||||
use rustc::ty::subst::{Substs, Subst};
|
||||
use rustc::util::common::ErrorReported;
|
||||
@ -313,7 +312,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
|
||||
if tcx.fn_sig(def_id).abi() == Abi::RustIntrinsic {
|
||||
let layout_of = |ty: Ty<'tcx>| {
|
||||
let ty = tcx.erase_regions(&ty);
|
||||
(tcx.at(e.span), cx.param_env).layout_of(ty).map_err(|err| {
|
||||
tcx.at(e.span).layout_of(cx.param_env.and(ty)).map_err(|err| {
|
||||
ConstEvalErr { span: e.span, kind: LayoutError(err) }
|
||||
})
|
||||
};
|
||||
|
@ -437,8 +437,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
|
||||
// PhantomData -- skip checking all ZST fields
|
||||
if def.repr.transparent() {
|
||||
let is_zst = (cx, cx.param_env(field.did))
|
||||
.layout_of(field_ty)
|
||||
let is_zst = cx
|
||||
.layout_of(cx.param_env(field.did).and(field_ty))
|
||||
.map(|layout| layout.is_zst())
|
||||
.unwrap_or(false);
|
||||
if is_zst {
|
||||
|
@ -172,7 +172,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> LayoutOf<Ty<'tcx>> for &'a EvalContext<'a, 'tcx
|
||||
type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>;
|
||||
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
(self.tcx, self.param_env).layout_of(ty)
|
||||
self.tcx.layout_of(self.param_env.and(ty))
|
||||
.map_err(|layout| EvalErrorKind::Layout(layout).into())
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::*;
|
||||
use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::ty::subst::{Subst,Substs};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
@ -655,7 +654,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>) -> Option<u64> {
|
||||
(tcx, param_env).layout_of(ty).ok().map(|layout| layout.size.bytes())
|
||||
tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes())
|
||||
}
|
||||
|
||||
fn subst_and_normalize<'a, 'tcx: 'a>(
|
||||
|
@ -464,8 +464,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CodegenCx<'a, 'tcx> {
|
||||
type TyLayout = TyLayout<'tcx>;
|
||||
|
||||
fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
|
||||
(self.tcx, ty::ParamEnv::empty(traits::Reveal::All))
|
||||
.layout_of(ty)
|
||||
self.tcx.layout_of(ty::ParamEnv::empty(traits::Reveal::All).and(ty))
|
||||
.unwrap_or_else(|e| match e {
|
||||
LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()),
|
||||
_ => bug!("failed to get layout for `{}`: {}", ty, e)
|
||||
|
@ -100,7 +100,6 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::ty::util::{Representability, IntTypeExt};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use errors::{DiagnosticBuilder, DiagnosticId};
|
||||
|
||||
use require_c_abi_if_variadic;
|
||||
@ -1553,7 +1552,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
|
||||
let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| {
|
||||
let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
|
||||
let param_env = tcx.param_env(field.did);
|
||||
let layout = (tcx, param_env).layout_of(ty);
|
||||
let layout = tcx.layout_of(param_env.and(ty));
|
||||
// We are currently checking the type this field came from, so it must be local
|
||||
let span = tcx.hir.span_if_local(field.did).unwrap();
|
||||
let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
|
||||
|
Loading…
Reference in New Issue
Block a user