@@ -1265,12 +1265,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1265
1265
// if they referred to the same allocation, since then a change to one would
1266
1266
// implicitly change the other.
1267
1267
//
1268
- // TODO(solson): It would be valid to attempt reading a primitive value out of
1269
- // the source and writing that into the destination without making an
1270
- // allocation. This would be a pure optimization.
1271
- let dest_ptr = self . alloc_ptr ( dest_ty) ?;
1272
- self . copy ( src_ptr, dest_ptr, dest_ty) ?;
1273
- write_dest ( self , Value :: ByRef ( dest_ptr) ) ;
1268
+ // It is a valid optimization to attempt reading a primitive value out of the
1269
+ // source and write that into the destination without making an allocation, so
1270
+ // we do so here.
1271
+ if let Ok ( Some ( src_val) ) = self . try_read_value ( src_ptr, dest_ty) {
1272
+ write_dest ( self , src_val) ;
1273
+ } else {
1274
+ let dest_ptr = self . alloc_ptr ( dest_ty) ?;
1275
+ self . copy ( src_ptr, dest_ptr, dest_ty) ?;
1276
+ write_dest ( self , Value :: ByRef ( dest_ptr) ) ;
1277
+ }
1274
1278
1275
1279
} else {
1276
1280
// Finally, we have the simple case where neither source nor destination are
@@ -1400,6 +1404,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1400
1404
}
1401
1405
1402
1406
fn read_value ( & mut self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Value > {
1407
+ if let Some ( val) = self . try_read_value ( ptr, ty) ? {
1408
+ Ok ( val)
1409
+ } else {
1410
+ bug ! ( "primitive read failed for type: {:?}" , ty) ;
1411
+ }
1412
+ }
1413
+
1414
+ fn try_read_value ( & mut self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Option < Value > > {
1403
1415
use syntax:: ast:: FloatTy ;
1404
1416
1405
1417
let val = match ty. sty {
@@ -1439,11 +1451,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1439
1451
ty:: TyFloat ( FloatTy :: F32 ) => PrimVal :: from_f32 ( self . memory . read_f32 ( ptr) ?) ,
1440
1452
ty:: TyFloat ( FloatTy :: F64 ) => PrimVal :: from_f64 ( self . memory . read_f64 ( ptr) ?) ,
1441
1453
1442
- // TODO(solson): Should this even be here? Fn items aren't primvals, are they?
1443
- ty:: TyFnDef ( def_id, substs, fn_ty) => {
1444
- PrimVal :: from_ptr ( self . memory . create_fn_ptr ( self . tcx , def_id, substs, fn_ty) )
1445
- } ,
1446
-
1447
1454
ty:: TyFnPtr ( _) => self . memory . read_ptr ( ptr) . map ( PrimVal :: from_ptr) ?,
1448
1455
ty:: TyBox ( ty) |
1449
1456
ty:: TyRef ( _, ty:: TypeAndMut { ty, .. } ) |
@@ -1460,7 +1467,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1460
1467
ty:: TyStr => PrimVal :: from_uint ( self . memory . read_usize ( extra) ?) ,
1461
1468
_ => bug ! ( "unsized primval ptr read from {:?}" , ty) ,
1462
1469
} ;
1463
- return Ok ( Value :: ByValPair ( PrimVal :: from_ptr ( p) , extra) ) ;
1470
+ return Ok ( Some ( Value :: ByValPair ( PrimVal :: from_ptr ( p) , extra) ) ) ;
1464
1471
}
1465
1472
}
1466
1473
@@ -1474,14 +1481,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
1474
1481
PrimVal :: from_uint ( self . memory . read_uint ( ptr, size) ?)
1475
1482
}
1476
1483
} else {
1477
- bug ! ( "primitive read of non-clike enum: {:?}" , ty ) ;
1484
+ return Ok ( None ) ;
1478
1485
}
1479
1486
} ,
1480
1487
1481
- _ => bug ! ( "primitive read of non-primitive type: {:?}" , ty ) ,
1488
+ _ => return Ok ( None ) ,
1482
1489
} ;
1483
1490
1484
- Ok ( Value :: ByVal ( val) )
1491
+ Ok ( Some ( Value :: ByVal ( val) ) )
1485
1492
}
1486
1493
1487
1494
fn frame ( & self ) -> & Frame < ' tcx > {
0 commit comments