compiler: Add is_uninhabited
and use LayoutS accessors
This reduces the need of the compiler to peek on the fields of LayoutS.
This commit is contained in:
parent
5f5c243ca0
commit
88a9edc091
20 changed files with 40 additions and 37 deletions
|
@ -395,7 +395,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
|||
|
||||
#[inline(always)]
|
||||
fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool {
|
||||
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited()
|
||||
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.is_uninhabited()
|
||||
}
|
||||
|
||||
fn load_mir(
|
||||
|
|
|
@ -27,7 +27,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
// discriminant, so we cannot do anything here.
|
||||
// When evaluating we will always error before even getting here, but ConstProp 'executes'
|
||||
// dead code, so we cannot ICE here.
|
||||
if dest.layout().for_variant(self, variant_index).abi.is_uninhabited() {
|
||||
if dest.layout().for_variant(self, variant_index).is_uninhabited() {
|
||||
throw_ub!(UninhabitedEnumVariantWritten(variant_index))
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
// For consistency with `write_discriminant`, and to make sure that
|
||||
// `project_downcast` cannot fail due to strange layouts, we declare immediate UB
|
||||
// for uninhabited variants.
|
||||
if op.layout().for_variant(self, index).abi.is_uninhabited() {
|
||||
if op.layout().for_variant(self, index).is_uninhabited() {
|
||||
throw_ub!(UninhabitedEnumVariantRead(index))
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
// Reading the discriminant of an uninhabited variant is UB. This is the basis for the
|
||||
// `uninhabited_enum_branching` MIR pass. It also ensures consistency with
|
||||
// `write_discriminant`.
|
||||
if op.layout().for_variant(self, index).abi.is_uninhabited() {
|
||||
if op.layout().for_variant(self, index).is_uninhabited() {
|
||||
throw_ub!(UninhabitedEnumVariantRead(index))
|
||||
}
|
||||
interp_ok(index)
|
||||
|
|
|
@ -364,7 +364,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let msg = match requirement {
|
||||
// For *all* intrinsics we first check `is_uninhabited` to give a more specific
|
||||
// error message.
|
||||
_ if layout.abi.is_uninhabited() => format!(
|
||||
_ if layout.is_uninhabited() => format!(
|
||||
"aborted execution: attempted to instantiate uninhabited type `{ty}`"
|
||||
),
|
||||
ValidityRequirement::Inhabited => bug!("handled earlier"),
|
||||
|
|
|
@ -315,7 +315,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let ptr = left.to_scalar().to_pointer(self)?;
|
||||
let pointee_ty = left.layout.ty.builtin_deref(true).unwrap();
|
||||
let pointee_layout = self.layout_of(pointee_ty)?;
|
||||
assert!(pointee_layout.abi.is_sized());
|
||||
assert!(pointee_layout.is_sized());
|
||||
|
||||
// The size always fits in `i64` as it can be at most `isize::MAX`.
|
||||
let pointee_size = i64::try_from(pointee_layout.size.bytes()).unwrap();
|
||||
|
@ -518,14 +518,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
|
||||
interp_ok(match null_op {
|
||||
SizeOf => {
|
||||
if !layout.abi.is_sized() {
|
||||
if !layout.is_sized() {
|
||||
span_bug!(self.cur_span(), "unsized type for `NullaryOp::SizeOf`");
|
||||
}
|
||||
let val = layout.size.bytes();
|
||||
ImmTy::from_uint(val, usize_layout())
|
||||
}
|
||||
AlignOf => {
|
||||
if !layout.abi.is_sized() {
|
||||
if !layout.is_sized() {
|
||||
span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`");
|
||||
}
|
||||
let val = layout.align.abi.bytes();
|
||||
|
|
|
@ -542,7 +542,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
throw_validation_failure!(self.path, NullPtr { ptr_kind })
|
||||
}
|
||||
// Do not allow references to uninhabited types.
|
||||
if place.layout.abi.is_uninhabited() {
|
||||
if place.layout.is_uninhabited() {
|
||||
let ty = place.layout.ty;
|
||||
throw_validation_failure!(self.path, PtrToUninhabited { ptr_kind, ty })
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
/// Add the entire given place to the "data" range of this visit.
|
||||
fn add_data_range_place(&mut self, place: &PlaceTy<'tcx, M::Provenance>) {
|
||||
// Only sized places can be added this way.
|
||||
debug_assert!(place.layout.abi.is_sized());
|
||||
debug_assert!(place.layout.is_sized());
|
||||
if let Some(data_bytes) = self.data_bytes.as_mut() {
|
||||
let offset = Self::data_range_offset(self.ecx, place);
|
||||
data_bytes.add_range(offset, place.layout.size);
|
||||
|
@ -945,7 +945,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
|||
layout: TyAndLayout<'tcx>,
|
||||
) -> Cow<'e, RangeSet> {
|
||||
assert!(layout.ty.is_union());
|
||||
assert!(layout.abi.is_sized(), "there are no unsized unions");
|
||||
assert!(layout.is_sized(), "there are no unsized unions");
|
||||
let layout_cx = LayoutCx::new(*ecx.tcx, ecx.param_env);
|
||||
return M::cached_union_data_range(ecx, layout.ty, || {
|
||||
let mut out = RangeSet(Vec::new());
|
||||
|
|
|
@ -29,7 +29,7 @@ pub fn check_validity_requirement<'tcx>(
|
|||
|
||||
// There is nothing strict or lax about inhabitedness.
|
||||
if kind == ValidityRequirement::Inhabited {
|
||||
return Ok(!layout.abi.is_uninhabited());
|
||||
return Ok(!layout.is_uninhabited());
|
||||
}
|
||||
|
||||
let layout_cx = LayoutCx::new(tcx, param_env_and_ty.param_env);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue