@@ -223,7 +223,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
223
223
}
224
224
225
225
pub fn monomorphize ( & self , ty : Ty < ' tcx > , substs : & ' tcx Substs < ' tcx > ) -> Ty < ' tcx > {
226
- let substituted = ty. subst ( self . tcx , substs) ;
226
+ // miri doesn't care about lifetimes, and will choke on some crazy ones
227
+ // let's simply get rid of them
228
+ let without_lifetimes = self . tcx . erase_regions ( & ty) ;
229
+ let substituted = without_lifetimes. subst ( self . tcx , substs) ;
227
230
self . tcx . normalize_associated_type ( & substituted)
228
231
}
229
232
@@ -355,18 +358,44 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
355
358
Ok ( ( ) )
356
359
}
357
360
358
- fn assign_fields < I : IntoIterator < Item = u64 > > (
361
+ pub fn assign_discr_and_fields <
362
+ I : IntoIterator < Item = u64 > ,
363
+ V : IntoValTyPair < ' tcx > ,
364
+ J : IntoIterator < Item = V > ,
365
+ > (
359
366
& mut self ,
360
367
dest : Lvalue < ' tcx > ,
361
368
offsets : I ,
362
- operands : & [ mir:: Operand < ' tcx > ] ,
369
+ operands : J ,
370
+ discr_val : u128 ,
371
+ discr_size : u64 ,
372
+ ) -> EvalResult < ' tcx , ( ) > {
373
+ // FIXME(solson)
374
+ let dest_ptr = self . force_allocation ( dest) ?. to_ptr ( ) ;
375
+
376
+ let mut offsets = offsets. into_iter ( ) ;
377
+ let discr_offset = offsets. next ( ) . unwrap ( ) ;
378
+ let discr_dest = dest_ptr. offset ( discr_offset) ;
379
+ self . memory . write_uint ( discr_dest, discr_val, discr_size) ?;
380
+
381
+ self . assign_fields ( dest, offsets, operands)
382
+ }
383
+
384
+ pub fn assign_fields <
385
+ I : IntoIterator < Item = u64 > ,
386
+ V : IntoValTyPair < ' tcx > ,
387
+ J : IntoIterator < Item = V > ,
388
+ > (
389
+ & mut self ,
390
+ dest : Lvalue < ' tcx > ,
391
+ offsets : I ,
392
+ operands : J ,
363
393
) -> EvalResult < ' tcx , ( ) > {
364
394
// FIXME(solson)
365
395
let dest = self . force_allocation ( dest) ?. to_ptr ( ) ;
366
396
367
397
for ( offset, operand) in offsets. into_iter ( ) . zip ( operands) {
368
- let value = self . eval_operand ( operand) ?;
369
- let value_ty = self . operand_ty ( operand) ;
398
+ let ( value, value_ty) = operand. into_val_ty_pair ( self ) ?;
370
399
let field_dest = dest. offset ( offset) ;
371
400
self . write_value_to_ptr ( value, field_dest, value_ty) ?;
372
401
}
@@ -431,18 +460,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
431
460
if let mir:: AggregateKind :: Adt ( adt_def, variant, _, _) = * kind {
432
461
let discr_val = adt_def. variants [ variant] . disr_val . to_u128_unchecked ( ) ;
433
462
let discr_size = discr. size ( ) . bytes ( ) ;
434
- let discr_offset = variants[ variant] . offsets [ 0 ] . bytes ( ) ;
435
463
436
- // FIXME(solson)
437
- let dest = self . force_allocation ( dest) ?;
438
- let discr_dest = ( dest. to_ptr ( ) ) . offset ( discr_offset) ;
439
-
440
- self . memory . write_uint ( discr_dest, discr_val, discr_size) ?;
441
-
442
- // Don't include the first offset; it's for the discriminant.
443
- let field_offsets = variants[ variant] . offsets . iter ( ) . skip ( 1 )
444
- . map ( |s| s. bytes ( ) ) ;
445
- self . assign_fields ( dest, field_offsets, operands) ?;
464
+ self . assign_discr_and_fields (
465
+ dest,
466
+ variants[ variant] . offsets . iter ( ) . cloned ( ) . map ( Size :: bytes) ,
467
+ operands,
468
+ discr_val,
469
+ discr_size,
470
+ ) ?;
446
471
} else {
447
472
bug ! ( "tried to assign {:?} to Layout::General" , kind) ;
448
473
}
@@ -660,22 +685,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
660
685
let path = discrfield. iter ( ) . skip ( 2 ) . map ( |& i| i as usize ) ;
661
686
662
687
// Handle the field index for the outer non-null variant.
663
- let inner_ty = match ty. sty {
688
+ let ( inner_offset , inner_ty) = match ty. sty {
664
689
ty:: TyAdt ( adt_def, substs) => {
665
690
let variant = & adt_def. variants [ nndiscr as usize ] ;
666
691
let index = discrfield[ 1 ] ;
667
692
let field = & variant. fields [ index as usize ] ;
668
- field. ty ( self . tcx , substs)
693
+ ( self . get_field_offset ( ty , index as usize ) ? , field. ty ( self . tcx , substs) )
669
694
}
670
695
_ => bug ! ( "non-enum for StructWrappedNullablePointer: {}" , ty) ,
671
696
} ;
672
697
673
- self . field_path_offset_and_ty ( inner_ty, path)
698
+ self . field_path_offset_and_ty ( inner_offset , inner_ty, path)
674
699
}
675
700
676
- fn field_path_offset_and_ty < I : Iterator < Item = usize > > ( & self , mut ty : Ty < ' tcx > , path : I ) -> EvalResult < ' tcx , ( Size , Ty < ' tcx > ) > {
677
- let mut offset = Size :: from_bytes ( 0 ) ;
678
-
701
+ fn field_path_offset_and_ty < I : Iterator < Item = usize > > (
702
+ & self ,
703
+ mut offset : Size ,
704
+ mut ty : Ty < ' tcx > ,
705
+ path : I ,
706
+ ) -> EvalResult < ' tcx , ( Size , Ty < ' tcx > ) > {
679
707
// Skip the initial 0 intended for LLVM GEP.
680
708
for field_index in path {
681
709
let field_offset = self . get_field_offset ( ty, field_index) ?;
@@ -722,6 +750,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
722
750
let bytes = field_index as u64 * self . memory . pointer_size ( ) ;
723
751
Ok ( Size :: from_bytes ( bytes) )
724
752
}
753
+ StructWrappedNullablePointer { ref nonnull, .. } => {
754
+ Ok ( nonnull. offsets [ field_index] )
755
+ }
725
756
_ => {
726
757
let msg = format ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ;
727
758
Err ( EvalError :: Unimplemented ( msg) )
@@ -736,6 +767,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
736
767
match * layout {
737
768
Univariant { ref variant, .. } => Ok ( variant. offsets . len ( ) ) ,
738
769
FatPointer { .. } => Ok ( 2 ) ,
770
+ StructWrappedNullablePointer { ref nonnull, .. } => Ok ( nonnull. offsets . len ( ) ) ,
739
771
_ => {
740
772
let msg = format ! ( "can't handle type: {:?}, with layout: {:?}" , ty, layout) ;
741
773
Err ( EvalError :: Unimplemented ( msg) )
@@ -1464,3 +1496,21 @@ pub fn monomorphize_field_ty<'a, 'tcx:'a >(tcx: TyCtxt<'a, 'tcx, 'tcx>, f: &ty::
1464
1496
pub fn is_inhabited < ' a , ' tcx : ' a > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , ty : Ty < ' tcx > ) -> bool {
1465
1497
ty. uninhabited_from ( & mut FxHashSet :: default ( ) , tcx) . is_empty ( )
1466
1498
}
1499
+
1500
+ pub trait IntoValTyPair < ' tcx > {
1501
+ fn into_val_ty_pair < ' a > ( self , ecx : & mut EvalContext < ' a , ' tcx > ) -> EvalResult < ' tcx , ( Value , Ty < ' tcx > ) > where ' tcx : ' a ;
1502
+ }
1503
+
1504
+ impl < ' tcx > IntoValTyPair < ' tcx > for ( Value , Ty < ' tcx > ) {
1505
+ fn into_val_ty_pair < ' a > ( self , _: & mut EvalContext < ' a , ' tcx > ) -> EvalResult < ' tcx , ( Value , Ty < ' tcx > ) > where ' tcx : ' a {
1506
+ Ok ( self )
1507
+ }
1508
+ }
1509
+
1510
+ impl < ' b , ' tcx : ' b > IntoValTyPair < ' tcx > for & ' b mir:: Operand < ' tcx > {
1511
+ fn into_val_ty_pair < ' a > ( self , ecx : & mut EvalContext < ' a , ' tcx > ) -> EvalResult < ' tcx , ( Value , Ty < ' tcx > ) > where ' tcx : ' a {
1512
+ let value = ecx. eval_operand ( self ) ?;
1513
+ let value_ty = ecx. operand_ty ( self ) ;
1514
+ Ok ( ( value, value_ty) )
1515
+ }
1516
+ }
0 commit comments