diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 557cc596e16..8d948eb10a7 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -295,9 +295,9 @@ fn layout(&self) -> TyAndLayout<'tcx> { } #[inline(always)] - fn meta(&self) -> InterpResult<'tcx, MemPlaceMeta> { + fn meta(&self) -> MemPlaceMeta { 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> { - Ok(match self.as_mplace_or_imm() { + fn meta(&self) -> MemPlaceMeta { + 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>>( diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 0a731189981..65c5cd656cb 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -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> { - Ok(self.meta) + fn meta(&self) -> MemPlaceMeta { + 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> { - Ok(match self.as_mplace_or_local() { + fn meta(&self) -> MemPlaceMeta { + 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>>( diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index ecf594773fe..c69321d109e 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -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>; + fn meta(&self) -> MemPlaceMeta; + /// 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>( // 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>( 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.)