@@ -25,13 +25,28 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
25
25
fn layout ( & self ) -> TyAndLayout < ' tcx > ;
26
26
27
27
/// Get the metadata of a wide value.
28
- fn meta ( & self ) -> InterpResult < ' tcx , MemPlaceMeta < Prov > > ;
28
+ fn meta ( & self ) -> MemPlaceMeta < Prov > ;
29
29
30
+ /// Get the length of a slice/string/array stored here.
30
31
fn len < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
31
32
& self ,
32
33
ecx : & InterpCx < ' mir , ' tcx , M > ,
33
34
) -> 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
+ }
35
50
}
36
51
37
52
/// 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 {
43
58
ecx : & InterpCx < ' mir , ' tcx , M > ,
44
59
) -> InterpResult < ' tcx , Self > ;
45
60
61
+ #[ inline]
46
62
fn offset < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
47
63
& self ,
48
64
offset : Size ,
@@ -53,6 +69,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
53
69
self . offset_with_meta ( offset, MemPlaceMeta :: None , layout, ecx)
54
70
}
55
71
72
+ #[ inline]
56
73
fn transmute < ' mir , M : Machine < ' mir , ' tcx , Provenance = Prov > > (
57
74
& self ,
58
75
layout : TyAndLayout < ' tcx > ,
@@ -125,7 +142,7 @@ where
125
142
// But const-prop actually feeds us such nonsense MIR! (see test `const_prop/issue-86351.rs`)
126
143
throw_inval ! ( ConstPropNonsense ) ;
127
144
}
128
- let base_meta = base. meta ( ) ? ;
145
+ let base_meta = base. meta ( ) ;
129
146
// Re-use parent metadata to determine dynamic field layout.
130
147
// With custom DSTS, this *will* execute user-defined code, but the same
131
148
// happens at run-time so that's okay.
@@ -153,7 +170,7 @@ where
153
170
base : & P ,
154
171
variant : VariantIdx ,
155
172
) -> InterpResult < ' tcx , P > {
156
- assert ! ( !base. meta( ) ? . has_meta( ) ) ;
173
+ assert ! ( !base. meta( ) . has_meta( ) ) ;
157
174
// Downcasts only change the layout.
158
175
// (In particular, no check about whether this is even the active variant -- that's by design,
159
176
// see https://github.com/rust-lang/rust/issues/93688#issuecomment-1032929496.)
0 commit comments