@@ -25,13 +25,28 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
2525 fn layout ( & self ) -> TyAndLayout < ' tcx > ;
2626
2727 /// Get the metadata of a wide value.
28- fn meta ( & self ) -> InterpResult < ' tcx , MemPlaceMeta < Prov > > ;
28+ fn meta ( & self ) -> MemPlaceMeta < Prov > ;
2929
30+ /// Get the length of a slice/string/array stored here.
3031 fn len < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
3132 & self ,
3233 ecx : & InterpCx < ' mir , ' tcx , M > ,
3334 ) -> InterpResult < ' tcx , u64 > {
34- self . meta ( ) ?. len ( self . layout ( ) , ecx)
35+ let layout = self . layout ( ) ;
36+ if layout. is_unsized ( ) {
37+ // We need to consult `meta` metadata
38+ match layout. ty . kind ( ) {
39+ ty:: Slice ( ..) | ty:: Str => self . meta ( ) . unwrap_meta ( ) . to_target_usize ( ecx) ,
40+ _ => bug ! ( "len not supported on unsized type {:?}" , layout. ty) ,
41+ }
42+ } else {
43+ // Go through the layout. There are lots of types that support a length,
44+ // e.g., SIMD types. (But not all repr(simd) types even have FieldsShape::Array!)
45+ match layout. fields {
46+ abi:: FieldsShape :: Array { count, .. } => Ok ( count) ,
47+ _ => bug ! ( "len not supported on sized type {:?}" , layout. ty) ,
48+ }
49+ }
3550 }
3651
3752 /// Offset the value by the given amount, replacing the layout and metadata.
@@ -43,6 +58,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
4358 ecx : & InterpCx < ' mir , ' tcx , M > ,
4459 ) -> InterpResult < ' tcx , Self > ;
4560
61+ #[ inline]
4662 fn offset < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
4763 & self ,
4864 offset : Size ,
@@ -53,6 +69,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
5369 self . offset_with_meta ( offset, MemPlaceMeta :: None , layout, ecx)
5470 }
5571
72+ #[ inline]
5673 fn transmute < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
5774 & self ,
5875 layout : TyAndLayout < ' tcx > ,
@@ -125,7 +142,7 @@ where
125142 // But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
126143 throw_inval ! ( ConstPropNonsense ) ;
127144 }
128- let base_meta = base. meta ( ) ? ;
145+ let base_meta = base. meta ( ) ;
129146 // Re-use parent metadata to determine dynamic field layout.
130147 // With custom DSTS, this *will* execute user-defined code, but the same
131148 // happens at run-time so that's okay.
@@ -153,7 +170,7 @@ where
153170 base : & P ,
154171 variant : VariantIdx ,
155172 ) -> InterpResult < ' tcx , P > {
156- assert ! ( !base. meta( ) ? . has_meta( ) ) ;
173+ assert ! ( !base. meta( ) . has_meta( ) ) ;
157174 // Downcasts only change the layout.
158175 // (In particular, no check about whether this is even the active variant -- that's by design,
159176 // see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
0 commit comments