a bit of meta-related cleanup on Projectable
This commit is contained in:
parent
a09df43d9f
commit
7cdeff266c
@ -295,9 +295,9 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
||||
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||
debug_assert!(self.layout.is_sized()); // unsized ImmTy can only exist temporarily and should never reach this here
|
||||
Ok(MemPlaceMeta::None)
|
||||
MemPlaceMeta::None
|
||||
}
|
||||
|
||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
@ -326,14 +326,14 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
||||
Ok(match self.as_mplace_or_imm() {
|
||||
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||
match self.as_mplace_or_imm() {
|
||||
Left(mplace) => mplace.meta,
|
||||
Right(_) => {
|
||||
debug_assert!(self.layout.is_sized(), "unsized immediates are not a thing");
|
||||
MemPlaceMeta::None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
|
@ -13,7 +13,7 @@
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_target::abi::{self, Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
|
||||
use rustc_target::abi::{Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT};
|
||||
|
||||
use super::{
|
||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
||||
@ -48,27 +48,6 @@ pub fn has_meta(self) -> bool {
|
||||
Self::None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn len<'tcx>(
|
||||
&self,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
if layout.is_unsized() {
|
||||
// We need to consult `meta` metadata
|
||||
match layout.ty.kind() {
|
||||
ty::Slice(..) | ty::Str => self.unwrap_meta().to_target_usize(cx),
|
||||
_ => bug!("len not supported on unsized type {:?}", layout.ty),
|
||||
}
|
||||
} else {
|
||||
// Go through the layout. There are lots of types that support a length,
|
||||
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
|
||||
match layout.fields {
|
||||
abi::FieldsShape::Array { count, .. } => Ok(count),
|
||||
_ => bug!("len not supported on sized type {:?}", layout.ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
@ -224,8 +203,8 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
||||
Ok(self.meta)
|
||||
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||
self.meta
|
||||
}
|
||||
|
||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
@ -257,14 +236,14 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
||||
Ok(match self.as_mplace_or_local() {
|
||||
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||
match self.as_mplace_or_local() {
|
||||
Left(mplace) => mplace.meta,
|
||||
Right(_) => {
|
||||
debug_assert!(self.layout.is_sized(), "unsized locals should live in memory");
|
||||
MemPlaceMeta::None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
|
@ -25,13 +25,28 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
|
||||
fn layout(&self) -> TyAndLayout<'tcx>;
|
||||
|
||||
/// Get the metadata of a wide value.
|
||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>>;
|
||||
fn meta(&self) -> MemPlaceMeta<Prov>;
|
||||
|
||||
/// Get the length of a slice/string/array stored here.
|
||||
fn len<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
&self,
|
||||
ecx: &InterpCx<'mir, 'tcx, M>,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
self.meta()?.len(self.layout(), ecx)
|
||||
let layout = self.layout();
|
||||
if layout.is_unsized() {
|
||||
// We need to consult `meta` metadata
|
||||
match layout.ty.kind() {
|
||||
ty::Slice(..) | ty::Str => self.meta().unwrap_meta().to_target_usize(ecx),
|
||||
_ => bug!("len not supported on unsized type {:?}", layout.ty),
|
||||
}
|
||||
} else {
|
||||
// Go through the layout. There are lots of types that support a length,
|
||||
// e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
|
||||
match layout.fields {
|
||||
abi::FieldsShape::Array { count, .. } => Ok(count),
|
||||
_ => bug!("len not supported on sized type {:?}", layout.ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Offset the value by the given amount, replacing the layout and metadata.
|
||||
@ -43,6 +58,7 @@ fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
ecx: &InterpCx<'mir, 'tcx, M>,
|
||||
) -> InterpResult<'tcx, Self>;
|
||||
|
||||
#[inline]
|
||||
fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
&self,
|
||||
offset: Size,
|
||||
@ -53,6 +69,7 @@ fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
self.offset_with_meta(offset, MemPlaceMeta::None, layout, ecx)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||
&self,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
@ -125,7 +142,7 @@ pub fn project_field<P: Projectable<'tcx, M::Provenance>>(
|
||||
// But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
|
||||
throw_inval!(ConstPropNonsense);
|
||||
}
|
||||
let base_meta = base.meta()?;
|
||||
let base_meta = base.meta();
|
||||
// Re-use parent metadata to determine dynamic field layout.
|
||||
// With custom DSTS, this *will* execute user-defined code, but the same
|
||||
// happens at run-time so that's okay.
|
||||
@ -153,7 +170,7 @@ pub fn project_downcast<P: Projectable<'tcx, M::Provenance>>(
|
||||
base: &P,
|
||||
variant: VariantIdx,
|
||||
) -> InterpResult<'tcx, P> {
|
||||
assert!(!base.meta()?.has_meta());
|
||||
assert!(!base.meta().has_meta());
|
||||
// Downcasts only change the layout.
|
||||
// (In particular, no check about whether this is even the active variant -- that's by design,
|
||||
// see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
|
||||
|
Loading…
Reference in New Issue
Block a user