@@ -370,9 +370,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
370
370
371
371
for ( offset, operand) in offsets. into_iter ( ) . zip ( operands) {
372
372
let value = self . eval_operand ( operand) ?;
373
- let value_ty = self . operand_ty ( operand) ;
374
- let field_dest = dest. offset ( offset) ;
375
- self . write_value_to_ptr ( value, field_dest, value_ty) ?;
373
+ if let Some ( value) = value {
374
+ let value_ty = self . operand_ty ( operand) ;
375
+ let field_dest = dest. offset ( offset) ;
376
+ self . write_value_to_ptr ( value, field_dest, value_ty) ?;
377
+ }
376
378
}
377
379
Ok ( ( ) )
378
380
}
@@ -393,8 +395,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
393
395
use rustc:: mir:: Rvalue :: * ;
394
396
match * rvalue {
395
397
Use ( ref operand) => {
396
- let value = self . eval_operand ( operand) ?;
397
- self . write_value ( value, dest, dest_ty) ?;
398
+ if let Some ( value) = self . eval_operand ( operand) ? {
399
+ self . write_value ( value, dest, dest_ty) ?;
400
+ }
398
401
}
399
402
400
403
BinaryOp ( bin_op, ref left, ref right) => {
@@ -456,7 +459,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
456
459
if nndiscr == variant as u64 {
457
460
assert_eq ! ( operands. len( ) , 1 ) ;
458
461
let operand = & operands[ 0 ] ;
459
- let value = self . eval_operand ( operand) ?;
462
+ let value = self . eval_operand ( operand) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
460
463
let value_ty = self . operand_ty ( operand) ;
461
464
self . write_value ( value, dest, value_ty) ?;
462
465
} else {
@@ -516,7 +519,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
516
519
UntaggedUnion { .. } => {
517
520
assert_eq ! ( operands. len( ) , 1 ) ;
518
521
let operand = & operands[ 0 ] ;
519
- let value = self . eval_operand ( operand) ?;
522
+ let value = self . eval_operand ( operand) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
520
523
let value_ty = self . operand_ty ( operand) ;
521
524
522
525
// FIXME(solson)
@@ -536,20 +539,20 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
536
539
}
537
540
538
541
Repeat ( ref operand, _) => {
539
- let ( elem_ty , length ) = match dest_ty . sty {
540
- ty :: TyArray ( elem_ty, n ) => ( elem_ty , n as u64 ) ,
541
- _ => bug ! ( "tried to assign array-repeat to non-array type {:?}" , dest_ty ) ,
542
- } ;
543
- self . inc_step_counter_and_check_limit ( length ) ? ;
544
- let elem_size = self . type_size ( elem_ty ) ? . expect ( "repeat element type must be sized" ) ;
545
- let value = self . eval_operand ( operand ) ? ;
546
-
547
- // FIXME(solson)
548
- let dest = self . force_allocation ( dest ) ? . to_ptr ( ) ;
549
-
550
- for i in 0 ..length {
551
- let elem_dest = dest . offset ( i * elem_size ) ;
552
- self . write_value_to_ptr ( value , elem_dest , elem_ty ) ? ;
542
+ if let Some ( value ) = self . eval_operand ( operand ) ? {
543
+ let ( elem_ty, length ) = match dest_ty . sty {
544
+ ty :: TyArray ( elem_ty , n ) => ( elem_ty , n as u64 ) ,
545
+ _ => bug ! ( "tried to assign array-repeat to non-array type {:?}" , dest_ty ) ,
546
+ } ;
547
+ self . inc_step_counter_and_check_limit ( length ) ? ;
548
+ let elem_size = self . type_size ( elem_ty ) ? . expect ( "repeat element type must be sized" ) ;
549
+ // FIXME(solson)
550
+ let dest = self . force_allocation ( dest ) ? . to_ptr ( ) ;
551
+
552
+ for i in 0 ..length {
553
+ let elem_dest = dest . offset ( i * elem_size ) ;
554
+ self . write_value_to_ptr ( value , elem_dest , elem_ty ) ? ;
555
+ }
553
556
}
554
557
}
555
558
@@ -586,13 +589,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
586
589
use rustc:: mir:: CastKind :: * ;
587
590
match kind {
588
591
Unsize => {
589
- let src = self . eval_operand ( operand) ?;
592
+ let src = self . eval_operand ( operand) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
590
593
let src_ty = self . operand_ty ( operand) ;
591
594
self . unsize_into ( src, src_ty, dest, dest_ty) ?;
592
595
}
593
596
594
597
Misc => {
595
- let src = self . eval_operand ( operand) ?;
598
+ let src = self . eval_operand ( operand) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
596
599
let src_ty = self . operand_ty ( operand) ;
597
600
if self . type_is_fat_ptr ( src_ty) {
598
601
trace ! ( "misc cast: {:?}" , src) ;
@@ -624,7 +627,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
624
627
625
628
UnsafeFnPointer => match dest_ty. sty {
626
629
ty:: TyFnPtr ( unsafe_fn_ty) => {
627
- let src = self . eval_operand ( operand) ?;
630
+ let src = self . eval_operand ( operand) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
628
631
let ptr = src. read_ptr ( & self . memory ) ?;
629
632
let ( def_id, substs, _, _) = self . memory . get_fn ( ptr. alloc_id ) ?;
630
633
let unsafe_fn_ty = self . tcx . erase_regions ( & unsafe_fn_ty) ;
@@ -749,12 +752,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
749
752
}
750
753
751
754
pub ( super ) fn eval_operand_to_primval ( & mut self , op : & mir:: Operand < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
752
- let value = self . eval_operand ( op) ?;
755
+ let value = self . eval_operand ( op) ?. ok_or ( EvalError :: ReadUndefBytes ) ? ;
753
756
let ty = self . operand_ty ( op) ;
754
757
self . value_to_primval ( value, ty)
755
758
}
756
759
757
- pub ( super ) fn eval_operand ( & mut self , op : & mir:: Operand < ' tcx > ) -> EvalResult < ' tcx , Value > {
760
+ pub ( super ) fn eval_operand ( & mut self , op : & mir:: Operand < ' tcx > ) -> EvalResult < ' tcx , Option < Value > > {
758
761
use rustc:: mir:: Operand :: * ;
759
762
match * op {
760
763
Consume ( ref lvalue) => self . eval_and_read_lvalue ( lvalue) ,
@@ -775,6 +778,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
775
778
promoted : None ,
776
779
} ;
777
780
self . read_lvalue ( Lvalue :: Global ( cid) ) ?
781
+ . expect ( "constants and statics can't be uninitialized" )
778
782
}
779
783
}
780
784
@@ -785,10 +789,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
785
789
promoted : Some ( index) ,
786
790
} ;
787
791
self . read_lvalue ( Lvalue :: Global ( cid) ) ?
792
+ . expect ( "promoteds can't be uninitialized" )
788
793
}
789
794
} ;
790
795
791
- Ok ( value)
796
+ Ok ( Some ( value) )
792
797
}
793
798
}
794
799
}
0 commit comments