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
} ;
@@ -586,44 +580,43 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
586
580
return None ;
587
581
}
588
582
use rustc_middle:: mir:: Rvalue :: * ;
589
- let layout = self . use_ecx ( location , |this| this. ecx . eval_place ( * dest) ) ?. layout ;
583
+ let layout = self . use_ecx ( |this| this. ecx . eval_place ( * dest) ) ?. layout ;
590
584
trace ! ( ?layout) ;
591
585
592
586
let val: Value < ' _ > = match * rvalue {
593
587
ThreadLocalRef ( _) => return None ,
594
588
595
- Use ( ref operand) => self . eval_operand ( operand, location , Some ( layout) ) ?. into ( ) ,
589
+ Use ( ref operand) => self . eval_operand ( operand, Some ( layout) ) ?. into ( ) ,
596
590
597
591
CopyForDeref ( place) => self . eval_place ( place, Some ( layout) ) ?. into ( ) ,
598
592
599
593
BinaryOp ( bin_op, box ( ref left, ref right) ) => {
600
594
let layout =
601
595
rustc_const_eval:: util:: binop_left_homogeneous ( bin_op) . then_some ( layout) ;
602
- let left = self . eval_operand ( left, location , layout) ?;
603
- let left = self . use_ecx ( location , |this| this. ecx . read_immediate ( & left) ) ?;
596
+ let left = self . eval_operand ( left, layout) ?;
597
+ let left = self . use_ecx ( |this| this. ecx . read_immediate ( & left) ) ?;
604
598
605
599
let layout =
606
600
rustc_const_eval:: util:: binop_right_homogeneous ( bin_op) . then_some ( left. layout ) ;
607
- let right = self . eval_operand ( right, location , layout) ?;
608
- let right = self . use_ecx ( location , |this| this. ecx . read_immediate ( & right) ) ?;
601
+ let right = self . eval_operand ( right, layout) ?;
602
+ let right = self . use_ecx ( |this| this. ecx . read_immediate ( & right) ) ?;
609
603
610
- let val = self
611
- . use_ecx ( location , |this| this. ecx . wrapping_binary_op ( bin_op, & left, & right) ) ?;
604
+ let val =
605
+ self . use_ecx ( |this| this. ecx . wrapping_binary_op ( bin_op, & left, & right) ) ?;
612
606
val. into ( )
613
607
}
614
608
615
609
CheckedBinaryOp ( bin_op, box ( ref left, ref right) ) => {
616
- let left = self . eval_operand ( left, location , None ) ?;
617
- let left = self . use_ecx ( location , |this| this. ecx . read_immediate ( & left) ) ?;
610
+ let left = self . eval_operand ( left, None ) ?;
611
+ let left = self . use_ecx ( |this| this. ecx . read_immediate ( & left) ) ?;
618
612
619
613
let layout =
620
614
rustc_const_eval:: util:: binop_right_homogeneous ( bin_op) . then_some ( left. layout ) ;
621
- let right = self . eval_operand ( right, location , layout) ?;
622
- let right = self . use_ecx ( location , |this| this. ecx . read_immediate ( & right) ) ?;
615
+ let right = self . eval_operand ( right, layout) ?;
616
+ let right = self . use_ecx ( |this| this. ecx . read_immediate ( & right) ) ?;
623
617
624
- let ( val, overflowed) = self . use_ecx ( location, |this| {
625
- this. ecx . overflowing_binary_op ( bin_op, & left, & right)
626
- } ) ?;
618
+ let ( val, overflowed) =
619
+ self . use_ecx ( |this| this. ecx . overflowing_binary_op ( bin_op, & left, & right) ) ?;
627
620
let overflowed = ImmTy :: from_bool ( overflowed, self . tcx ) ;
628
621
Value :: Aggregate {
629
622
variant : VariantIdx :: new ( 0 ) ,
@@ -632,19 +625,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
632
625
}
633
626
634
627
UnaryOp ( un_op, ref operand) => {
635
- let operand = self . eval_operand ( operand, location , Some ( layout) ) ?;
636
- let val = self . use_ecx ( location , |this| this. ecx . read_immediate ( & operand) ) ?;
628
+ let operand = self . eval_operand ( operand, Some ( layout) ) ?;
629
+ let val = self . use_ecx ( |this| this. ecx . read_immediate ( & operand) ) ?;
637
630
638
- let val = self . use_ecx ( location , |this| this. ecx . wrapping_unary_op ( un_op, & val) ) ?;
631
+ let val = self . use_ecx ( |this| this. ecx . wrapping_unary_op ( un_op, & val) ) ?;
639
632
val. into ( )
640
633
}
641
634
642
635
Aggregate ( ref kind, ref fields) => Value :: Aggregate {
643
636
fields : fields
644
637
. iter ( )
645
638
. map ( |field| {
646
- self . eval_operand ( field, location, None )
647
- . map_or ( Value :: Uninit , Value :: Immediate )
639
+ self . eval_operand ( field, None ) . map_or ( Value :: Uninit , Value :: Immediate )
648
640
} )
649
641
. collect ( ) ,
650
642
variant : match * * kind {
@@ -676,7 +668,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
676
668
Ref ( ..) | AddressOf ( ..) => return None ,
677
669
678
670
NullaryOp ( ref null_op, ty) => {
679
- let op_layout = self . use_ecx ( location , |this| this. ecx . layout_of ( ty) ) ?;
671
+ let op_layout = self . use_ecx ( |this| this. ecx . layout_of ( ty) ) ?;
680
672
let val = match null_op {
681
673
NullOp :: SizeOf => op_layout. size . bytes ( ) ,
682
674
NullOp :: AlignOf => op_layout. align . abi . bytes ( ) ,
@@ -691,21 +683,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
691
683
692
684
Cast ( ref kind, ref value, to) => match kind {
693
685
CastKind :: IntToInt | CastKind :: IntToFloat => {
694
- let value = self . eval_operand ( value, location , None ) ?;
686
+ let value = self . eval_operand ( value, None ) ?;
695
687
let value = self . ecx . read_immediate ( & value) . ok ( ) ?;
696
688
let to = self . ecx . layout_of ( to) . ok ( ) ?;
697
689
let res = self . ecx . int_to_int_or_float ( & value, to) . ok ( ) ?;
698
690
res. into ( )
699
691
}
700
692
CastKind :: FloatToFloat | CastKind :: FloatToInt => {
701
- let value = self . eval_operand ( value, location , None ) ?;
693
+ let value = self . eval_operand ( value, None ) ?;
702
694
let value = self . ecx . read_immediate ( & value) . ok ( ) ?;
703
695
let to = self . ecx . layout_of ( to) . ok ( ) ?;
704
696
let res = self . ecx . float_to_float_or_int ( & value, to) . ok ( ) ?;
705
697
res. into ( )
706
698
}
707
699
CastKind :: Transmute => {
708
- let value = self . eval_operand ( value, location , None ) ?;
700
+ let value = self . eval_operand ( value, None ) ?;
709
701
let to = self . ecx . layout_of ( to) . ok ( ) ?;
710
702
// `offset` for immediates only supports scalar/scalar-pair ABIs,
711
703
// so bail out if the target is not one.
@@ -725,12 +717,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
725
717
let variant = match self . get_const ( place) ? {
726
718
Value :: Immediate ( op) => {
727
719
let op = op. clone ( ) ;
728
- self . use_ecx ( location , |this| this. ecx . read_discriminant ( & op) ) ?
720
+ self . use_ecx ( |this| this. ecx . read_discriminant ( & op) ) ?
729
721
}
730
722
Value :: Aggregate { variant, .. } => * variant,
731
723
Value :: Uninit => return None ,
732
724
} ;
733
- let imm = self . use_ecx ( location , |this| {
725
+ let imm = self . use_ecx ( |this| {
734
726
this. ecx . discriminant_for_variant (
735
727
place. ty ( this. local_decls ( ) , this. tcx ) . ty ,
736
728
variant,
@@ -792,7 +784,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
792
784
fn visit_constant ( & mut self , constant : & ConstOperand < ' tcx > , location : Location ) {
793
785
trace ! ( "visit_constant: {:?}" , constant) ;
794
786
self . super_constant ( constant, location) ;
795
- self . eval_constant ( constant, location , None ) ;
787
+ self . eval_constant ( constant, None ) ;
796
788
}
797
789
798
790
fn visit_assign ( & mut self , place : & Place < ' tcx > , rvalue : & Rvalue < ' tcx > , location : Location ) {
@@ -865,9 +857,8 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
865
857
self . check_assertion ( * expected, msg, cond, location) ;
866
858
}
867
859
TerminatorKind :: SwitchInt { ref discr, ref targets } => {
868
- if let Some ( ref value) = self . eval_operand ( discr, location, None )
869
- && let Some ( value_const) =
870
- self . use_ecx ( location, |this| this. ecx . read_scalar ( value) )
860
+ if let Some ( ref value) = self . eval_operand ( discr, None )
861
+ && let Some ( value_const) = self . use_ecx ( |this| this. ecx . read_scalar ( value) )
871
862
&& let Ok ( constant) = value_const. try_to_int ( )
872
863
&& let Ok ( constant) = constant. to_bits ( constant. size ( ) )
873
864
{
0 commit comments