@@ -351,30 +351,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
351
351
}
352
352
Rvalue :: BinaryOp ( op, ref left, ref right) => {
353
353
trace ! ( "rvalue binop {:?} for {:?} and {:?}" , op, left, right) ;
354
- let right = self . eval_operand ( right, source_info) ?;
355
- let def_id = if self . tcx . is_closure ( self . source . def_id ( ) ) {
356
- self . tcx . closure_base_def_id ( self . source . def_id ( ) )
357
- } else {
358
- self . source . def_id ( )
359
- } ;
360
- let generics = self . tcx . generics_of ( def_id) ;
361
- if generics. requires_monomorphization ( self . tcx ) {
362
- // FIXME: can't handle code with generics
363
- return None ;
364
- }
365
354
366
355
let r = self . use_ecx ( source_info, |this| {
367
- this. ecx . read_immediate ( right)
356
+ this. ecx . read_immediate ( this . ecx . eval_operand ( right, None ) ? )
368
357
} ) ?;
369
358
if op == BinOp :: Shr || op == BinOp :: Shl {
370
- let left_ty = left. ty ( & self . local_decls , self . tcx ) ;
371
- let left_bits = self
372
- . tcx
373
- . layout_of ( self . param_env . and ( left_ty) )
374
- . unwrap ( )
375
- . size
376
- . bits ( ) ;
377
- let right_size = right. layout . size ;
359
+ let left_bits = place_layout. size . bits ( ) ;
360
+ let right_size = r. layout . size ;
378
361
let r_bits = r. to_scalar ( ) . and_then ( |r| r. to_bits ( right_size) ) ;
379
362
if r_bits. ok ( ) . map_or ( false , |b| b >= left_bits as u128 ) {
380
363
let source_scope_local_data = match self . source_scope_local_data {
@@ -395,26 +378,29 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
395
378
return None ;
396
379
}
397
380
}
398
- let left = self . eval_operand ( left, source_info) ?;
399
- let l = self . use_ecx ( source_info, |this| {
400
- this. ecx . read_immediate ( left)
401
- } ) ?;
402
381
trace ! ( "const evaluating {:?} for {:?} and {:?}" , op, left, right) ;
403
- let ( val, overflow, _ty) = self . use_ecx ( source_info, |this| {
404
- this. ecx . overflowing_binary_op ( op, l, r)
382
+ let val = self . use_ecx ( source_info, |this| {
383
+ let l = this. ecx . read_immediate ( this. ecx . eval_operand ( left, None ) ?) ?;
384
+ let ( val, overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
385
+
386
+ // We check overflow in debug mode already
387
+ // so should only check in release mode.
388
+ if !this. tcx . sess . overflow_checks ( ) && overflow {
389
+ let err = err_panic ! ( Overflow ( op) ) . into ( ) ;
390
+ return Err ( err) ;
391
+ }
392
+
393
+ let val = ImmTy {
394
+ imm : Immediate :: Scalar ( val. into ( ) ) ,
395
+ layout : place_layout,
396
+ } ;
397
+
398
+ let dest = this. ecx . eval_place ( place) ?;
399
+ this. ecx . write_immediate ( * val, dest) ?;
400
+
401
+ Ok ( val)
405
402
} ) ?;
406
- // We check overflow in debug mode already
407
- // so should only check in release mode.
408
- if !self . tcx . sess . overflow_checks ( ) && overflow {
409
- let err = err_panic ! ( Overflow ( op) ) . into ( ) ;
410
- let _: Option < ( ) > = self . use_ecx ( source_info, |_| Err ( err) ) ;
411
- return None ;
412
- }
413
- let res = ImmTy {
414
- imm : Immediate :: Scalar ( val. into ( ) ) ,
415
- layout : place_layout,
416
- } ;
417
- Some ( res. into ( ) )
403
+ Some ( val. into ( ) )
418
404
} ,
419
405
}
420
406
}
0 commit comments