@@ -317,14 +317,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
317
317
match global_value. value {
318
318
Value :: ByRef ( ptr) => self . memory . mark_static_initalized ( ptr. alloc_id , mutable) ?,
319
319
Value :: ByVal ( val) => if let PrimVal :: Ptr ( ptr) = val {
320
- self . memory . mark_static_initalized ( ptr. alloc_id , mutable) ?;
320
+ self . memory . mark_inner_allocation ( ptr. alloc_id , mutable) ?;
321
321
} ,
322
322
Value :: ByValPair ( val1, val2) => {
323
323
if let PrimVal :: Ptr ( ptr) = val1 {
324
- self . memory . mark_static_initalized ( ptr. alloc_id , mutable) ?;
324
+ self . memory . mark_inner_allocation ( ptr. alloc_id , mutable) ?;
325
325
}
326
326
if let PrimVal :: Ptr ( ptr) = val2 {
327
- self . memory . mark_static_initalized ( ptr. alloc_id , mutable) ?;
327
+ self . memory . mark_inner_allocation ( ptr. alloc_id , mutable) ?;
328
328
}
329
329
} ,
330
330
}
@@ -374,7 +374,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
374
374
discr_val : u128 ,
375
375
variant_idx : usize ,
376
376
discr_size : u64 ,
377
- ) -> EvalResult < ' tcx > {
377
+ ) -> EvalResult < ' tcx >
378
+ where J :: IntoIter : ExactSizeIterator ,
379
+ {
378
380
// FIXME(solson)
379
381
let dest_ptr = self . force_allocation ( dest) ?. to_ptr ( ) ;
380
382
@@ -397,7 +399,19 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
397
399
dest : Lvalue < ' tcx > ,
398
400
dest_ty : Ty < ' tcx > ,
399
401
operands : J ,
400
- ) -> EvalResult < ' tcx > {
402
+ ) -> EvalResult < ' tcx >
403
+ where J :: IntoIter : ExactSizeIterator ,
404
+ {
405
+ if self . type_size ( dest_ty) ? == Some ( 0 ) {
406
+ // zst assigning is a nop
407
+ return Ok ( ( ) ) ;
408
+ }
409
+ if self . ty_to_primval_kind ( dest_ty) . is_ok ( ) {
410
+ let mut iter = operands. into_iter ( ) ;
411
+ assert_eq ! ( iter. len( ) , 1 ) ;
412
+ let ( value, value_ty) = iter. next ( ) . unwrap ( ) . into_val_ty_pair ( self ) ?;
413
+ return self . write_value ( value, dest, value_ty) ;
414
+ }
401
415
for ( field_index, operand) in operands. into_iter ( ) . enumerate ( ) {
402
416
let ( value, value_ty) = operand. into_val_ty_pair ( self ) ?;
403
417
let field_dest = self . lvalue_field ( dest, field_index, dest_ty, value_ty) ?;
@@ -795,7 +809,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
795
809
}
796
810
}
797
811
798
- fn get_field_count ( & self , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , usize > {
812
+ pub fn get_field_count ( & self , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , usize > {
799
813
let layout = self . type_layout ( ty) ?;
800
814
801
815
use rustc:: ty:: layout:: Layout :: * ;
@@ -1052,8 +1066,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1052
1066
a : PrimVal ,
1053
1067
b : PrimVal ,
1054
1068
ptr : Pointer ,
1055
- ty : Ty < ' tcx >
1069
+ mut ty : Ty < ' tcx >
1056
1070
) -> EvalResult < ' tcx > {
1071
+ while self . get_field_count ( ty) ? == 1 {
1072
+ ty = self . get_field_ty ( ty, 0 ) ?;
1073
+ }
1057
1074
assert_eq ! ( self . get_field_count( ty) ?, 2 ) ;
1058
1075
let field_0 = self . get_field_offset ( ty, 0 ) ?. bytes ( ) ;
1059
1076
let field_1 = self . get_field_offset ( ty, 1 ) ?. bytes ( ) ;
@@ -1109,7 +1126,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1109
1126
1110
1127
ty:: TyAdt ( ref def, _) if def. is_box ( ) => PrimValKind :: Ptr ,
1111
1128
1112
- ty:: TyAdt ( .. ) => {
1129
+ ty:: TyAdt ( ref def , substs ) => {
1113
1130
use rustc:: ty:: layout:: Layout :: * ;
1114
1131
match * self . type_layout ( ty) ? {
1115
1132
CEnum { discr, signed, .. } => {
@@ -1132,6 +1149,18 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1132
1149
}
1133
1150
}
1134
1151
1152
+ // represent single field structs as their single field
1153
+ Univariant { .. } => {
1154
+ // enums with just one variant are no different, but `.struct_variant()` doesn't work for enums
1155
+ let variant = & def. variants [ 0 ] ;
1156
+ // FIXME: also allow structs with only a single non zst field
1157
+ if variant. fields . len ( ) == 1 {
1158
+ return self . ty_to_primval_kind ( variant. fields [ 0 ] . ty ( self . tcx , substs) ) ;
1159
+ } else {
1160
+ return Err ( EvalError :: TypeNotPrimitive ( ty) ) ;
1161
+ }
1162
+ }
1163
+
1135
1164
_ => return Err ( EvalError :: TypeNotPrimitive ( ty) ) ,
1136
1165
}
1137
1166
}
@@ -1320,8 +1349,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1320
1349
}
1321
1350
return self . unsize_into_ptr ( src, src_ty, dest, dest_ty, src_ty. boxed_ty ( ) , dest_ty. boxed_ty ( ) ) ;
1322
1351
}
1323
- // FIXME(solson)
1324
- let dest = self . force_allocation ( dest) ?. to_ptr ( ) ;
1352
+ if self . ty_to_primval_kind ( src_ty) . is_ok ( ) {
1353
+ let sty = self . get_field_ty ( src_ty, 0 ) ?;
1354
+ let dty = self . get_field_ty ( dest_ty, 0 ) ?;
1355
+ return self . unsize_into ( src, sty, dest, dty) ;
1356
+ }
1325
1357
// unsizing of generic struct with pointer fields
1326
1358
// Example: `Arc<T>` -> `Arc<Trait>`
1327
1359
// here we need to increase the size of every &T thin ptr field to a fat ptr
@@ -1338,6 +1370,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1338
1370
_ => bug ! ( "expected pointer, got {:?}" , src) ,
1339
1371
} ;
1340
1372
1373
+ // FIXME(solson)
1374
+ let dest = self . force_allocation ( dest) ?. to_ptr ( ) ;
1341
1375
let iter = src_fields. zip ( dst_fields) . enumerate ( ) ;
1342
1376
for ( i, ( src_f, dst_f) ) in iter {
1343
1377
let src_fty = monomorphize_field_ty ( self . tcx , src_f, substs_a) ;
0 commit comments