@@ -10,14 +10,15 @@ use log::trace;
1010
1111use rustc_hir:: def:: { DefKind , Namespace } ;
1212use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
13+ use rustc_index:: IndexVec ;
1314use rustc_middle:: mir;
1415use rustc_middle:: ty:: {
1516 self ,
1617 layout:: { LayoutOf , TyAndLayout } ,
1718 List , TyCtxt ,
1819} ;
1920use rustc_span:: { def_id:: CrateNum , sym, Span , Symbol } ;
20- use rustc_target:: abi:: { Align , FieldsShape , Size , Variants } ;
21+ use rustc_target:: abi:: { Align , FieldIdx , FieldsShape , Size , Variants } ;
2122use rustc_target:: spec:: abi:: Abi ;
2223
2324use rand:: RngCore ;
@@ -229,20 +230,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
229230 this. layout_of ( ty) . unwrap ( )
230231 }
231232
232- /// Project to the given *named* field of the mplace (which must be a struct or union type).
233- fn mplace_field_named (
233+ /// Project to the given *named* field (which must be a struct or union type).
234+ fn project_field_named < P : Projectable < ' mir , ' tcx , Provenance > > (
234235 & self ,
235- mplace : & MPlaceTy < ' tcx , Provenance > ,
236+ base : & P ,
236237 name : & str ,
237- ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > {
238+ ) -> InterpResult < ' tcx , P > {
238239 let this = self . eval_context_ref ( ) ;
239- let adt = mplace . layout . ty . ty_adt_def ( ) . unwrap ( ) ;
240+ let adt = base . layout ( ) . ty . ty_adt_def ( ) . unwrap ( ) ;
240241 for ( idx, field) in adt. non_enum_variant ( ) . fields . iter ( ) . enumerate ( ) {
241242 if field. name . as_str ( ) == name {
242- return this. mplace_field ( mplace , idx) ;
243+ return this. project_field ( base , idx) ;
243244 }
244245 }
245- bug ! ( "No field named {} in type {}" , name, mplace . layout. ty) ;
246+ bug ! ( "No field named {} in type {}" , name, base . layout( ) . ty) ;
246247 }
247248
248249 /// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned,
@@ -270,7 +271,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
270271 ) -> InterpResult < ' tcx > {
271272 let this = self . eval_context_mut ( ) ;
272273 for ( idx, & val) in values. iter ( ) . enumerate ( ) {
273- let field = this. mplace_field ( dest, idx) ?;
274+ let field = this. project_field ( dest, idx) ?;
274275 this. write_int ( val, & field. into ( ) ) ?;
275276 }
276277 Ok ( ( ) )
@@ -284,7 +285,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
284285 ) -> InterpResult < ' tcx > {
285286 let this = self . eval_context_mut ( ) ;
286287 for & ( name, val) in values. iter ( ) {
287- let field = this. mplace_field_named ( dest, name) ?;
288+ let field = this. project_field_named ( dest, name) ?;
288289 this. write_int ( val, & field. into ( ) ) ?;
289290 }
290291 Ok ( ( ) )
@@ -479,6 +480,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
479480 self . ecx
480481 }
481482
483+ fn aggregate_field_order ( memory_index : & IndexVec < FieldIdx , u32 > , idx : usize ) -> usize {
484+ // We need to do an *inverse* lookup: find the field that has position `idx` in memory order.
485+ for ( src_field, & mem_pos) in memory_index. iter_enumerated ( ) {
486+ if mem_pos as usize == idx {
487+ return src_field. as_usize ( ) ;
488+ }
489+ }
490+ panic ! ( "invalid `memory_index`, could not find {}-th field in memory order" , idx) ;
491+ }
492+
482493 // Hook to detect `UnsafeCell`.
483494 fn visit_value ( & mut self , v : & MPlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
484495 trace ! ( "UnsafeCellVisitor: {:?} {:?}" , * v, v. layout. ty) ;
@@ -524,33 +535,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
524535 }
525536 }
526537
527- // Make sure we visit aggregates in increasing offset order.
528- fn visit_aggregate (
529- & mut self ,
530- place : & MPlaceTy < ' tcx , Provenance > ,
531- fields : impl Iterator < Item = InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > > ,
532- ) -> InterpResult < ' tcx > {
533- match place. layout . fields {
534- FieldsShape :: Array { .. } => {
535- // For the array layout, we know the iterator will yield sorted elements so
536- // we can avoid the allocation.
537- self . walk_aggregate ( place, fields)
538- }
539- FieldsShape :: Arbitrary { .. } => {
540- // Gather the subplaces and sort them before visiting.
541- let mut places = fields
542- . collect :: < InterpResult < ' tcx , Vec < MPlaceTy < ' tcx , Provenance > > > > ( ) ?;
543- // we just compare offsets, the abs. value never matters
544- places. sort_by_key ( |place| place. ptr . addr ( ) ) ;
545- self . walk_aggregate ( place, places. into_iter ( ) . map ( Ok ) )
546- }
547- FieldsShape :: Union { .. } | FieldsShape :: Primitive => {
548- // Uh, what?
549- bug ! ( "unions/primitives are not aggregates we should ever visit" )
550- }
551- }
552- }
553-
554538 fn visit_union (
555539 & mut self ,
556540 _v : & MPlaceTy < ' tcx , Provenance > ,
@@ -746,7 +730,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
746730 Ok ( mplace)
747731 }
748732
749- fn deref_pointer_as (
733+ /// Deref' a pointer *without* checking that the place is dereferenceable.
734+ fn deref_pointer_unchecked (
750735 & self ,
751736 val : & ImmTy < ' tcx , Provenance > ,
752737 layout : TyAndLayout < ' tcx > ,
@@ -811,10 +796,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
811796 tp : & MPlaceTy < ' tcx , Provenance > ,
812797 ) -> InterpResult < ' tcx , Option < Duration > > {
813798 let this = self . eval_context_mut ( ) ;
814- let seconds_place = this. mplace_field ( tp, 0 ) ?;
799+ let seconds_place = this. project_field ( tp, 0 ) ?;
815800 let seconds_scalar = this. read_scalar ( & seconds_place. into ( ) ) ?;
816801 let seconds = seconds_scalar. to_target_isize ( this) ?;
817- let nanoseconds_place = this. mplace_field ( tp, 1 ) ?;
802+ let nanoseconds_place = this. project_field ( tp, 1 ) ?;
818803 let nanoseconds_scalar = this. read_scalar ( & nanoseconds_place. into ( ) ) ?;
819804 let nanoseconds = nanoseconds_scalar. to_target_isize ( this) ?;
820805
0 commit comments