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)]
|
#[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
|
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>>(
|
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
@ -326,14 +326,14 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||||
Ok(match self.as_mplace_or_imm() {
|
match self.as_mplace_or_imm() {
|
||||||
Left(mplace) => mplace.meta,
|
Left(mplace) => mplace.meta,
|
||||||
Right(_) => {
|
Right(_) => {
|
||||||
debug_assert!(self.layout.is_sized(), "unsized immediates are not a thing");
|
debug_assert!(self.layout.is_sized(), "unsized immediates are not a thing");
|
||||||
MemPlaceMeta::None
|
MemPlaceMeta::None
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::Ty;
|
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::{
|
use super::{
|
||||||
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg,
|
||||||
@ -48,27 +48,6 @@ pub fn has_meta(self) -> bool {
|
|||||||
Self::None => false,
|
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)]
|
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||||
@ -224,8 +203,8 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||||
Ok(self.meta)
|
self.meta
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
@ -257,14 +236,14 @@ fn layout(&self) -> TyAndLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta<Prov>> {
|
fn meta(&self) -> MemPlaceMeta<Prov> {
|
||||||
Ok(match self.as_mplace_or_local() {
|
match self.as_mplace_or_local() {
|
||||||
Left(mplace) => mplace.meta,
|
Left(mplace) => mplace.meta,
|
||||||
Right(_) => {
|
Right(_) => {
|
||||||
debug_assert!(self.layout.is_sized(), "unsized locals should live in memory");
|
debug_assert!(self.layout.is_sized(), "unsized locals should live in memory");
|
||||||
MemPlaceMeta::None
|
MemPlaceMeta::None
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
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>;
|
fn layout(&self) -> TyAndLayout<'tcx>;
|
||||||
|
|
||||||
/// Get the metadata of a wide value.
|
/// 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>>(
|
fn len<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
&self,
|
&self,
|
||||||
ecx: &InterpCx<'mir, 'tcx, M>,
|
ecx: &InterpCx<'mir, 'tcx, M>,
|
||||||
) -> InterpResult<'tcx, u64> {
|
) -> 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.
|
/// 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>,
|
ecx: &InterpCx<'mir, 'tcx, M>,
|
||||||
) -> InterpResult<'tcx, Self>;
|
) -> InterpResult<'tcx, Self>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
&self,
|
&self,
|
||||||
offset: Size,
|
offset: Size,
|
||||||
@ -53,6 +69,7 @@ fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
|||||||
self.offset_with_meta(offset, MemPlaceMeta::None, layout, ecx)
|
self.offset_with_meta(offset, MemPlaceMeta::None, layout, ecx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>(
|
||||||
&self,
|
&self,
|
||||||
layout: TyAndLayout<'tcx>,
|
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`)
|
// But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
|
||||||
throw_inval!(ConstPropNonsense);
|
throw_inval!(ConstPropNonsense);
|
||||||
}
|
}
|
||||||
let base_meta = base.meta()?;
|
let base_meta = base.meta();
|
||||||
// Re-use parent metadata to determine dynamic field layout.
|
// Re-use parent metadata to determine dynamic field layout.
|
||||||
// With custom DSTS, this *will* execute user-defined code, but the same
|
// With custom DSTS, this *will* execute user-defined code, but the same
|
||||||
// happens at run-time so that's okay.
|
// happens at run-time so that's okay.
|
||||||
@ -153,7 +170,7 @@ pub fn project_downcast<P: Projectable<'tcx, M::Provenance>>(
|
|||||||
base: &P,
|
base: &P,
|
||||||
variant: VariantIdx,
|
variant: VariantIdx,
|
||||||
) -> InterpResult<'tcx, P> {
|
) -> InterpResult<'tcx, P> {
|
||||||
assert!(!base.meta()?.has_meta());
|
assert!(!base.meta().has_meta());
|
||||||
// Downcasts only change the layout.
|
// Downcasts only change the layout.
|
||||||
// (In particular, no check about whether this is even the active variant -- that's by design,
|
// (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.)
|
// see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
|
||||||
|
Loading…
Reference in New Issue
Block a user