@@ -351,30 +351,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
351351 }
352352 Rvalue :: BinaryOp ( op, ref left, ref right) => {
353353 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- }
365354
366355 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 ) ? )
368357 } ) ?;
369358 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 ;
378361 let r_bits = r. to_scalar ( ) . and_then ( |r| r. to_bits ( right_size) ) ;
379362 if r_bits. ok ( ) . map_or ( false , |b| b >= left_bits as u128 ) {
380363 let source_scope_local_data = match self . source_scope_local_data {
@@ -395,26 +378,29 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
395378 return None ;
396379 }
397380 }
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- } ) ?;
402381 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)
405402 } ) ?;
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 ( ) )
418404 } ,
419405 }
420406 }
0 commit comments