@@ -49,6 +49,9 @@ pub trait Value<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Sized {
49
49
ecx : & InterpCx < ' mir , ' tcx , M > ,
50
50
field : usize ,
51
51
) -> InterpResult < ' tcx , Self > ;
52
+
53
+ /// Strip a layer of pattern types to get at the inner type
54
+ fn strip_pat_ty ( self ) -> Self ;
52
55
}
53
56
54
57
/// A thing that we can project into given *mutable* access to `ecx`, and that has a layout.
@@ -88,6 +91,9 @@ pub trait ValueMut<'mir, 'tcx, M: Machine<'mir, 'tcx>>: Sized {
88
91
ecx : & mut InterpCx < ' mir , ' tcx , M > ,
89
92
field : usize ,
90
93
) -> InterpResult < ' tcx , Self > ;
94
+
95
+ /// Strip a layer of pattern types to get at the inner type
96
+ fn strip_pat_ty ( self ) -> Self ;
91
97
}
92
98
93
99
// We cannot have a general impl which shows that Value implies ValueMut. (When we do, it says we
@@ -131,6 +137,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M> for OpTy<'tc
131
137
) -> InterpResult < ' tcx , Self > {
132
138
ecx. operand_field ( self , field)
133
139
}
140
+
141
+ #[ inline( always) ]
142
+ fn strip_pat_ty ( mut self ) -> Self {
143
+ let ty:: Pat ( raw_ptr_ty, _) = * self . layout . ty . kind ( ) else {
144
+ bug ! ( "NonNull must contain a pattern type, but had {}" , self . layout. ty)
145
+ } ;
146
+ self . layout . ty = raw_ptr_ty;
147
+ self
148
+ }
134
149
}
135
150
136
151
impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > ValueMut < ' mir , ' tcx , M >
@@ -179,6 +194,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueMut<'mir, 'tcx, M>
179
194
) -> InterpResult < ' tcx , Self > {
180
195
ecx. operand_field ( self , field)
181
196
}
197
+
198
+ #[ inline( always) ]
199
+ fn strip_pat_ty ( mut self ) -> Self {
200
+ let ty:: Pat ( raw_ptr_ty, _) = * self . layout . ty . kind ( ) else {
201
+ bug ! ( "NonNull must contain a pattern type, but had {}" , self . layout. ty)
202
+ } ;
203
+ self . layout . ty = raw_ptr_ty;
204
+ self
205
+ }
182
206
}
183
207
184
208
impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > Value < ' mir , ' tcx , M >
@@ -220,6 +244,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> Value<'mir, 'tcx, M>
220
244
) -> InterpResult < ' tcx , Self > {
221
245
ecx. mplace_field ( self , field)
222
246
}
247
+
248
+ #[ inline( always) ]
249
+ fn strip_pat_ty ( mut self ) -> Self {
250
+ let ty:: Pat ( raw_ptr_ty, _) = * self . layout . ty . kind ( ) else {
251
+ bug ! ( "NonNull must contain a pattern type, but had {}" , self . layout. ty)
252
+ } ;
253
+ self . layout . ty = raw_ptr_ty;
254
+ self
255
+ }
223
256
}
224
257
225
258
impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > ValueMut < ' mir , ' tcx , M >
@@ -269,6 +302,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueMut<'mir, 'tcx, M>
269
302
) -> InterpResult < ' tcx , Self > {
270
303
ecx. mplace_field ( self , field)
271
304
}
305
+
306
+ #[ inline( always) ]
307
+ fn strip_pat_ty ( mut self ) -> Self {
308
+ let ty:: Pat ( raw_ptr_ty, _) = * self . layout . ty . kind ( ) else {
309
+ bug ! ( "NonNull must contain a pattern type, but had {}" , self . layout. ty)
310
+ } ;
311
+ self . layout . ty = raw_ptr_ty;
312
+ self
313
+ }
272
314
}
273
315
274
316
impl < ' mir , ' tcx : ' mir , M : Machine < ' mir , ' tcx > > ValueMut < ' mir , ' tcx , M >
@@ -320,6 +362,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueMut<'mir, 'tcx, M>
320
362
) -> InterpResult < ' tcx , Self > {
321
363
ecx. place_field ( self , field)
322
364
}
365
+
366
+ #[ inline( always) ]
367
+ fn strip_pat_ty ( mut self ) -> Self {
368
+ let ty:: Pat ( raw_ptr_ty, _) = * self . layout . ty . kind ( ) else {
369
+ bug ! ( "NonNull must contain a pattern type, but had {}" , self . layout. ty)
370
+ } ;
371
+ self . layout . ty = raw_ptr_ty;
372
+ self
373
+ }
323
374
}
324
375
325
376
macro_rules! make_value_visitor {
@@ -466,7 +517,7 @@ macro_rules! make_value_visitor {
466
517
) ;
467
518
// ... that contains a `NonNull`... (gladly, only a single field here)
468
519
assert_eq!( nonnull_ptr. layout( ) . fields. count( ) , 1 ) ;
469
- let raw_ptr = nonnull_ptr. project_field( self . ecx( ) , 0 ) ?; // the actual raw ptr
520
+ let raw_ptr = nonnull_ptr. project_field( self . ecx( ) , 0 ) ?. strip_pat_ty ( ) ; // the actual raw ptr
470
521
// ... whose only field finally is a raw ptr we can dereference.
471
522
self . visit_box( & raw_ptr) ?;
472
523
0 commit comments