3
3
4
4
use std:: fmt:: Debug ;
5
5
6
- use either:: Left ;
7
-
8
6
use rustc_const_eval:: interpret:: { ImmTy , MPlaceTy , Projectable } ;
9
7
use rustc_const_eval:: interpret:: { InterpCx , InterpResult , OpTy , Scalar , StackPopCleanup } ;
10
8
use rustc_hir:: def:: DefKind ;
@@ -248,12 +246,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
248
246
source_info. scope . lint_root ( & self . body ( ) . source_scopes )
249
247
}
250
248
251
- fn use_ecx < F , T > ( & mut self , location : Location , f : F ) -> Option < T >
249
+ fn use_ecx < F , T > ( & mut self , f : F ) -> Option < T >
252
250
where
253
251
F : FnOnce ( & mut Self ) -> InterpResult < ' tcx , T > ,
254
252
{
255
- // Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway.
256
- self . ecx . frame_mut ( ) . loc = Left ( location) ;
257
253
match f ( self ) {
258
254
Ok ( val) => Some ( val) ,
259
255
Err ( error) => {
@@ -275,7 +271,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
275
271
fn eval_constant (
276
272
& mut self ,
277
273
c : & ConstOperand < ' tcx > ,
278
- location : Location ,
279
274
layout : Option < TyAndLayout < ' tcx > > ,
280
275
) -> Option < OpTy < ' tcx > > {
281
276
// FIXME we need to revisit this for #67176
@@ -291,7 +286,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
291
286
// manually normalized.
292
287
let val = self . tcx . try_normalize_erasing_regions ( self . param_env , c. const_ ) . ok ( ) ?;
293
288
294
- self . use_ecx ( location , |this| this. ecx . eval_mir_constant ( & val, Some ( c. span ) , layout) )
289
+ self . use_ecx ( |this| this. ecx . eval_mir_constant ( & val, Some ( c. span ) , layout) )
295
290
}
296
291
297
292
/// Returns the value, if any, of evaluating `place`.
@@ -313,11 +308,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
313
308
fn eval_operand (
314
309
& mut self ,
315
310
op : & Operand < ' tcx > ,
316
- location : Location ,
317
311
layout : Option < TyAndLayout < ' tcx > > ,
318
312
) -> Option < OpTy < ' tcx > > {
319
313
match * op {
320
- Operand :: Constant ( ref c) => self . eval_constant ( c, location , layout) ,
314
+ Operand :: Constant ( ref c) => self . eval_constant ( c, layout) ,
321
315
Operand :: Move ( place) | Operand :: Copy ( place) => self . eval_place ( place, layout) ,
322
316
}
323
317
}
@@ -329,8 +323,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
329
323
}
330
324
331
325
fn check_unary_op ( & mut self , op : UnOp , arg : & Operand < ' tcx > , location : Location ) -> Option < ( ) > {
332
- let arg = self . eval_operand ( arg, location , None ) ?;
333
- if let ( val, true ) = self . use_ecx ( location , |this| {
326
+ let arg = self . eval_operand ( arg, None ) ?;
327
+ if let ( val, true ) = self . use_ecx ( |this| {
334
328
let val = this. ecx . read_immediate ( & arg) ?;
335
329
let ( _res, overflow) = this. ecx . overflowing_unary_op ( op, & val) ?;
336
330
Ok ( ( val, overflow) )
@@ -360,11 +354,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
360
354
location : Location ,
361
355
) -> Option < ( ) > {
362
356
let r = self
363
- . eval_operand ( right, location , None )
364
- . and_then ( |r| self . use_ecx ( location , |this| this. ecx . read_immediate ( & r) ) ) ;
357
+ . eval_operand ( right, None )
358
+ . and_then ( |r| self . use_ecx ( |this| this. ecx . read_immediate ( & r) ) ) ;
365
359
let l = self
366
- . eval_operand ( left, location , None )
367
- . and_then ( |l| self . use_ecx ( location , |this| this. ecx . read_immediate ( & l) ) ) ;
360
+ . eval_operand ( left, None )
361
+ . and_then ( |l| self . use_ecx ( |this| this. ecx . read_immediate ( & l) ) ) ;
368
362
// Check for exceeding shifts *even if* we cannot evaluate the LHS.
369
363
if matches ! ( op, BinOp :: Shr | BinOp :: Shl ) {
370
364
let r = r. clone ( ) ?;
@@ -400,7 +394,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
400
394
401
395
if let ( Some ( l) , Some ( r) ) = ( l, r) {
402
396
// The remaining operators are handled through `overflowing_binary_op`.
403
- if self . use_ecx ( location , |this| {
397
+ if self . use_ecx ( |this| {
404
398
let ( _res, overflow) = this. ecx . overflowing_binary_op ( op, & l, & r) ?;
405
399
Ok ( overflow)
406
400
} ) ? {
@@ -501,11 +495,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
501
495
cond : & Operand < ' tcx > ,
502
496
location : Location ,
503
497
) -> Option < !> {
504
- let value = & self . eval_operand ( cond, location , None ) ?;
498
+ let value = & self . eval_operand ( cond, None ) ?;
505
499
trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
506
500
507
501
let expected = Scalar :: from_bool ( expected) ;
508
- let value_const = self . use_ecx ( location , |this| this. ecx . read_scalar ( value) ) ?;
502
+ let value_const = self . use_ecx ( |this| this. ecx . read_scalar ( value) ) ?;
509
503
510
504
if expected != value_const {
511
505
// Poison all places this operand references so that further code
@@ -529,7 +523,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
529
523
let mut eval_to_int = |op| {
530
524
// This can be `None` if the lhs wasn't const propagated and we just
531
525
// triggered the assert on the value of the rhs.
532
- self . eval_operand ( op, location , None )
526
+ self . eval_operand ( op, None )
533
527
. and_then ( |op| self . ecx . read_immediate ( & op) . ok ( ) )
534
528
. map_or ( DbgVal :: Underscore , |op| DbgVal :: Val ( op. to_const_int ( ) ) )
535
529
} ;
@@ -585,44 +579,43 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
585
579
return None ;
586
580
}
587
581
use rustc_middle:: mir:: Rvalue :: * ;
588
- let layout = self . use_ecx ( location , |this| this. ecx . eval_place ( * dest) ) ?. layout ;
582
+ let layout = self . use_ecx ( |this| this. ecx . eval_place ( * dest) ) ?. layout ;
589
583
trace ! ( ?layout) ;
590
584
591
585
let val: Value < ' _ > = match * rvalue {
592
586
ThreadLocalRef ( _) => return None ,
593
587
594
- Use ( ref operand) => self . eval_operand ( operand, location , Some ( layout) ) ?. into ( ) ,
588
+ Use ( ref operand) => self . eval_operand ( operand, Some ( layout) ) ?. into ( ) ,
595
589
596
590
CopyForDeref ( place) => self . eval_place ( place, Some ( layout) ) ?. into ( ) ,
597
591
598
592
BinaryOp ( bin_op, box ( ref left, ref right) ) => {
599
593
let layout =
600
594
rustc_const_eval:: util:: binop_left_homogeneous ( bin_op) . then_some ( layout) ;
601
- let left = self . eval_operand ( left, location , layout) ?;
602
- let left = self . use_ecx ( location , |this| this. ecx . read_immediate ( & left) ) ?;
595
+ let left = self . eval_operand ( left, layout) ?;
596
+ let left = self . use_ecx ( |this| this. ecx . read_immediate ( & left) ) ?;
603
597
604
598
let layout =
605
599
rustc_const_eval:: util:: binop_right_homogeneous ( bin_op) . then_some ( left. layout ) ;
606
- let right = self . eval_operand ( right, location , layout) ?;
607
- let right = self . use_ecx ( location , |this| this. ecx . read_immediate ( & right) ) ?;
600
+ let right = self . eval_operand ( right, layout) ?;
601
+ let right = self . use_ecx ( |this| this. ecx . read_immediate ( & right) ) ?;
608
602
609
- let val = self
610
- . use_ecx ( location , |this| this. ecx . wrapping_binary_op ( bin_op, & left, & right) ) ?;
603
+ let val =
604
+ self . use_ecx ( |this| this. ecx . wrapping_binary_op ( bin_op, & left, & right) ) ?;
611
605
val. into ( )
612
606
}
613
607
614
608
CheckedBinaryOp ( bin_op, box ( ref left, ref right) ) => {
615
- let left = self . eval_operand ( left, location , None ) ?;
616
- let left = self . use_ecx ( location , |this| this. ecx . read_immediate ( & left) ) ?;
609
+ let left = self . eval_operand ( left, None ) ?;
610
+ let left = self . use_ecx ( |this| this. ecx . read_immediate ( & left) ) ?;
617
611
618
612
let layout =
619
613
rustc_const_eval:: util:: binop_right_homogeneous ( bin_op) . then_some ( left. layout ) ;
620
- let right = self . eval_operand ( right, location , layout) ?;
621
- let right = self . use_ecx ( location , |this| this. ecx . read_immediate ( & right) ) ?;
614
+ let right = self . eval_operand ( right, layout) ?;
615
+ let right = self . use_ecx ( |this| this. ecx . read_immediate ( & right) ) ?;
622
616
623
- let ( val, overflowed) = self . use_ecx ( location, |this| {
624
- this. ecx . overflowing_binary_op ( bin_op, & left, & right)
625
- } ) ?;
617
+ let ( val, overflowed) =
618
+ self . use_ecx ( |this| this. ecx . overflowing_binary_op ( bin_op, & left, & right) ) ?;
626
619
let overflowed = ImmTy :: from_bool ( overflowed, self . tcx ) ;
627
620
Value :: Aggregate {
628
621
variant : VariantIdx :: new ( 0 ) ,
@@ -631,19 +624,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
631
624
}
632
625
633
626
UnaryOp ( un_op, ref operand) => {
634
- let operand = self . eval_operand ( operand, location , Some ( layout) ) ?;
635
- let val = self . use_ecx ( location , |this| this. ecx . read_immediate ( & operand) ) ?;
627
+ let operand = self . eval_operand ( operand, Some ( layout) ) ?;
628
+ let val = self . use_ecx ( |this| this. ecx . read_immediate ( & operand) ) ?;
636
629
637
- let val = self . use_ecx ( location , |this| this. ecx . wrapping_unary_op ( un_op, & val) ) ?;
630
+ let val = self . use_ecx ( |this| this. ecx . wrapping_unary_op ( un_op, & val) ) ?;
638
631
val. into ( )
639
632
}
640
633
641
634
Aggregate ( ref kind, ref fields) => Value :: Aggregate {
642
635
fields : fields
643
636
. iter ( )
644
637
. map ( |field| {
645
- self . eval_operand ( field, location, None )
646
- . map_or ( Value :: Uninit , Value :: Immediate )
638
+ self . eval_operand ( field, None ) . map_or ( Value :: Uninit , Value :: Immediate )
647
639
} )
648
640
. collect ( ) ,
649
641
variant : match * * kind {
@@ -675,7 +667,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
675
667
Ref ( ..) | AddressOf ( ..) => return None ,
676
668
677
669
NullaryOp ( ref null_op, ty) => {
678
- let op_layout = self . use_ecx ( location , |this| this. ecx . layout_of ( ty) ) ?;
670
+ let op_layout = self . use_ecx ( |this| this. ecx . layout_of ( ty) ) ?;
679
671
let val = match null_op {
680
672
NullOp :: SizeOf => op_layout. size . bytes ( ) ,
681
673
NullOp :: AlignOf => op_layout. align . abi . bytes ( ) ,
@@ -690,21 +682,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
690
682
691
683
Cast ( ref kind, ref value, to) => match kind {
692
684
CastKind :: IntToInt | CastKind :: IntToFloat => {
693
- let value = self . eval_operand ( value, location , None ) ?;
685
+ let value = self . eval_operand ( value, None ) ?;
694
686
let value = self . ecx . read_immediate ( & value) . ok ( ) ?;
695
687
let to = self . ecx . layout_of ( to) . ok ( ) ?;
696
688
let res = self . ecx . int_to_int_or_float ( & value, to) . ok ( ) ?;
697
689
res. into ( )
698
690
}
699
691
CastKind :: FloatToFloat | CastKind :: FloatToInt => {
700
- let value = self . eval_operand ( value, location , None ) ?;
692
+ let value = self . eval_operand ( value, None ) ?;
701
693
let value = self . ecx . read_immediate ( & value) . ok ( ) ?;
702
694
let to = self . ecx . layout_of ( to) . ok ( ) ?;
703
695
let res = self . ecx . float_to_float_or_int ( & value, to) . ok ( ) ?;
704
696
res. into ( )
705
697
}
706
698
CastKind :: Transmute => {
707
- let value = self . eval_operand ( value, location , None ) ?;
699
+ let value = self . eval_operand ( value, None ) ?;
708
700
let to = self . ecx . layout_of ( to) . ok ( ) ?;
709
701
// `offset` for immediates only supports scalar/scalar-pair ABIs,
710
702
// so bail out if the target is not one.
@@ -724,12 +716,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
724
716
let variant = match self . get_const ( place) ? {
725
717
Value :: Immediate ( op) => {
726
718
let op = op. clone ( ) ;
727
- self . use_ecx ( location , |this| this. ecx . read_discriminant ( & op) ) ?
719
+ self . use_ecx ( |this| this. ecx . read_discriminant ( & op) ) ?
728
720
}
729
721
Value :: Aggregate { variant, .. } => * variant,
730
722
Value :: Uninit => return None ,
731
723
} ;
732
- let imm = self . use_ecx ( location , |this| {
724
+ let imm = self . use_ecx ( |this| {
733
725
this. ecx . discriminant_for_variant (
734
726
place. ty ( this. local_decls ( ) , this. tcx ) . ty ,
735
727
variant,
@@ -791,7 +783,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
791
783
fn visit_constant ( & mut self , constant : & ConstOperand < ' tcx > , location : Location ) {
792
784
trace ! ( "visit_constant: {:?}" , constant) ;
793
785
self . super_constant ( constant, location) ;
794
- self . eval_constant ( constant, location , None ) ;
786
+ self . eval_constant ( constant, None ) ;
795
787
}
796
788
797
789
fn visit_assign ( & mut self , place : & Place < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
@@ -864,9 +856,8 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
864
856
self . check_assertion ( * expected, msg, cond, location) ;
865
857
}
866
858
TerminatorKind :: SwitchInt { ref discr, ref targets } => {
867
- if let Some ( ref value) = self . eval_operand ( discr, location, None )
868
- && let Some ( value_const) =
869
- self . use_ecx ( location, |this| this. ecx . read_scalar ( value) )
859
+ if let Some ( ref value) = self . eval_operand ( discr, None )
860
+ && let Some ( value_const) = self . use_ecx ( |this| this. ecx . read_scalar ( value) )
870
861
&& let Ok ( constant) = value_const. try_to_int ( )
871
862
&& let Ok ( constant) = constant. to_bits ( constant. size ( ) )
872
863
{
0 commit comments