@@ -325,39 +325,28 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
325
325
} ,
326
326
327
327
Rvalue :: UnaryOp ( op, ref arg) => {
328
- let def_id = if self . tcx . is_closure ( self . source . def_id ( ) ) {
329
- self . tcx . closure_base_def_id ( self . source . def_id ( ) )
330
- } else {
331
- self . source . def_id ( )
332
- } ;
333
- let generics = self . tcx . generics_of ( def_id) ;
334
- if generics. requires_monomorphization ( self . tcx ) {
335
- // FIXME: can't handle code with generics
336
- return None ;
337
- }
328
+ let overflow_check = self . tcx . sess . overflow_checks ( ) ;
338
329
339
- let arg = self . eval_operand ( arg, source_info) ?;
340
- let oflo_check = self . tcx . sess . overflow_checks ( ) ;
341
- let val = self . use_ecx ( source_info, |this| {
342
- let prim = this. ecx . read_immediate ( arg) ?;
343
- match op {
344
- UnOp :: Neg => {
345
- // We check overflow in debug mode already
346
- // so should only check in release mode.
347
- if !oflo_check
348
- && prim. layout . ty . is_signed ( )
349
- && prim. to_bits ( ) ? == ( 1 << ( prim. layout . size . bits ( ) - 1 ) ) {
330
+ self . use_ecx ( source_info, |this| {
331
+ // We check overflow in debug mode already
332
+ // so should only check in release mode.
333
+ if op == UnOp :: Neg && !overflow_check {
334
+ let ty = arg. ty ( & this. local_decls , this. tcx ) ;
335
+
336
+ if ty. is_integral ( ) {
337
+ let arg = this. ecx . eval_operand ( arg, None ) ?;
338
+ let prim = this. ecx . read_immediate ( arg) ?;
339
+ // Need to do overflow check here: For actual CTFE, MIR
340
+ // generation emits code that does this before calling the op.
341
+ if prim. to_bits ( ) ? == ( 1 << ( prim. layout . size . bits ( ) - 1 ) ) {
350
342
throw_panic ! ( OverflowNeg )
351
343
}
352
344
}
353
- UnOp :: Not => {
354
- // Cannot overflow
355
- }
356
345
}
357
- // Now run the actual operation.
358
- this. ecx . unary_op ( op , prim )
359
- } ) ? ;
360
- Some ( val . into ( ) )
346
+
347
+ this. ecx . eval_rvalue_into_place ( rvalue , place ) ? ;
348
+ this . ecx . eval_place_to_op ( place , Some ( place_layout ) )
349
+ } )
361
350
}
362
351
Rvalue :: CheckedBinaryOp ( op, ref left, ref right) |
363
352
Rvalue :: BinaryOp ( op, ref left, ref right) => {
0 commit comments