@@ -452,27 +452,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
452
452
} ;
453
453
}
454
454
455
- fn use_ecx < F , T > ( & mut self , f : F ) -> Option < T >
456
- where
457
- F : FnOnce ( & mut Self ) -> InterpResult < ' tcx , T > ,
458
- {
459
- match f ( self ) {
460
- Ok ( val) => Some ( val) ,
461
- Err ( error) => {
462
- trace ! ( "InterpCx operation failed: {:?}" , error) ;
463
- // Some errors shouldn't come up because creating them causes
464
- // an allocation, which we should avoid. When that happens,
465
- // dedicated error variants should be introduced instead.
466
- assert ! (
467
- !error. kind( ) . formatted_string( ) ,
468
- "const-prop encountered formatting error: {}" ,
469
- error
470
- ) ;
471
- None
472
- }
473
- }
474
- }
475
-
476
455
/// Returns the value, if any, of evaluating `c`.
477
456
fn eval_constant ( & mut self , c : & Constant < ' tcx > ) -> Option < OpTy < ' tcx > > {
478
457
// FIXME we need to revisit this for #67176
@@ -487,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
487
466
/// Returns the value, if any, of evaluating `place`.
488
467
fn eval_place ( & mut self , place : Place < ' tcx > ) -> Option < OpTy < ' tcx > > {
489
468
trace ! ( "eval_place(place={:?})" , place) ;
490
- self . use_ecx ( |this| this . ecx . eval_place_to_op ( place, None ) )
469
+ self . ecx . eval_place_to_op ( place, None ) . ok ( )
491
470
}
492
471
493
472
/// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
@@ -591,52 +570,54 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
591
570
rvalue : & Rvalue < ' tcx > ,
592
571
place : Place < ' tcx > ,
593
572
) -> Option < ( ) > {
594
- self . use_ecx ( |this| match rvalue {
573
+ match rvalue {
595
574
Rvalue :: BinaryOp ( op, box ( left, right) )
596
575
| Rvalue :: CheckedBinaryOp ( op, box ( left, right) ) => {
597
- let l = this . ecx . eval_operand ( left, None ) . and_then ( |x| this . ecx . read_immediate ( & x) ) ;
576
+ let l = self . ecx . eval_operand ( left, None ) . and_then ( |x| self . ecx . read_immediate ( & x) ) ;
598
577
let r =
599
- this . ecx . eval_operand ( right, None ) . and_then ( |x| this . ecx . read_immediate ( & x) ) ;
578
+ self . ecx . eval_operand ( right, None ) . and_then ( |x| self . ecx . read_immediate ( & x) ) ;
600
579
601
580
let const_arg = match ( l, r) {
602
581
( Ok ( x) , Err ( _) ) | ( Err ( _) , Ok ( x) ) => x, // exactly one side is known
603
- ( Err ( e ) , Err ( _) ) => return Err ( e ) , // neither side is known
604
- ( Ok ( _) , Ok ( _) ) => return this . ecx . eval_rvalue_into_place ( rvalue, place) , // both sides are known
582
+ ( Err ( _ ) , Err ( _) ) => return None , // neither side is known
583
+ ( Ok ( _) , Ok ( _) ) => return self . ecx . eval_rvalue_into_place ( rvalue, place) . ok ( ) , // both sides are known
605
584
} ;
606
585
607
586
if !matches ! ( const_arg. layout. abi, abi:: Abi :: Scalar ( ..) ) {
608
587
// We cannot handle Scalar Pair stuff.
609
588
// No point in calling `eval_rvalue_into_place`, since only one side is known
610
- throw_machine_stop_str ! ( "cannot optimize this" )
589
+ return None ;
611
590
}
612
591
613
- let arg_value = const_arg. to_scalar ( ) . to_bits ( const_arg. layout . size ) ?;
614
- let dest = this . ecx . eval_place ( place) ?;
592
+ let arg_value = const_arg. to_scalar ( ) . to_bits ( const_arg. layout . size ) . ok ( ) ?;
593
+ let dest = self . ecx . eval_place ( place) . ok ( ) ?;
615
594
616
595
match op {
617
- BinOp :: BitAnd if arg_value == 0 => this. ecx . write_immediate ( * const_arg, & dest) ,
596
+ BinOp :: BitAnd if arg_value == 0 => {
597
+ self . ecx . write_immediate ( * const_arg, & dest) . ok ( )
598
+ }
618
599
BinOp :: BitOr
619
600
if arg_value == const_arg. layout . size . truncate ( u128:: MAX )
620
601
|| ( const_arg. layout . ty . is_bool ( ) && arg_value == 1 ) =>
621
602
{
622
- this . ecx . write_immediate ( * const_arg, & dest)
603
+ self . ecx . write_immediate ( * const_arg, & dest) . ok ( )
623
604
}
624
605
BinOp :: Mul if const_arg. layout . ty . is_integral ( ) && arg_value == 0 => {
625
606
if let Rvalue :: CheckedBinaryOp ( _, _) = rvalue {
626
607
let val = Immediate :: ScalarPair (
627
608
const_arg. to_scalar ( ) ,
628
609
Scalar :: from_bool ( false ) ,
629
610
) ;
630
- this . ecx . write_immediate ( val, & dest)
611
+ self . ecx . write_immediate ( val, & dest) . ok ( )
631
612
} else {
632
- this . ecx . write_immediate ( * const_arg, & dest)
613
+ self . ecx . write_immediate ( * const_arg, & dest) . ok ( )
633
614
}
634
615
}
635
- _ => throw_machine_stop_str ! ( "cannot optimize this" ) ,
616
+ _ => None ,
636
617
}
637
618
}
638
- _ => this . ecx . eval_rvalue_into_place ( rvalue, place) ,
639
- } )
619
+ _ => self . ecx . eval_rvalue_into_place ( rvalue, place) . ok ( ) ,
620
+ }
640
621
}
641
622
642
623
/// Creates a new `Operand::Constant` from a `Scalar` value
@@ -678,7 +659,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
678
659
}
679
660
680
661
// FIXME> figure out what to do when read_immediate_raw fails
681
- let imm = self . use_ecx ( |this| this . ecx . read_immediate_raw ( value) ) ;
662
+ let imm = self . ecx . read_immediate_raw ( value) . ok ( ) ;
682
663
683
664
if let Some ( Right ( imm) ) = imm {
684
665
match * imm {
@@ -698,25 +679,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
698
679
if let ty:: Tuple ( types) = ty. kind ( ) {
699
680
// Only do it if tuple is also a pair with two scalars
700
681
if let [ ty1, ty2] = types[ ..] {
701
- let alloc = self . use_ecx ( |this| {
702
- let ty_is_scalar = |ty| {
703
- this. ecx . layout_of ( ty) . ok ( ) . map ( |layout| layout. abi . is_scalar ( ) )
704
- == Some ( true )
705
- } ;
706
- if ty_is_scalar ( ty1) && ty_is_scalar ( ty2) {
707
- let alloc = this
708
- . ecx
709
- . intern_with_temp_alloc ( value. layout , |ecx, dest| {
710
- ecx. write_immediate ( * imm, dest)
711
- } )
712
- . unwrap ( ) ;
713
- Ok ( Some ( alloc) )
714
- } else {
715
- Ok ( None )
716
- }
717
- } ) ;
718
-
719
- if let Some ( Some ( alloc) ) = alloc {
682
+ let ty_is_scalar = |ty| {
683
+ self . ecx . layout_of ( ty) . ok ( ) . map ( |layout| layout. abi . is_scalar ( ) )
684
+ == Some ( true )
685
+ } ;
686
+ let alloc = if ty_is_scalar ( ty1) && ty_is_scalar ( ty2) {
687
+ let alloc = self
688
+ . ecx
689
+ . intern_with_temp_alloc ( value. layout , |ecx, dest| {
690
+ ecx. write_immediate ( * imm, dest)
691
+ } )
692
+ . unwrap ( ) ;
693
+ Some ( alloc)
694
+ } else {
695
+ None
696
+ } ;
697
+
698
+ if let Some ( alloc) = alloc {
720
699
// Assign entire constant in a single statement.
721
700
// We can't use aggregates, as we run after the aggregate-lowering `MirPhase`.
722
701
let const_val = ConstValue :: ByRef { alloc, offset : Size :: ZERO } ;
@@ -971,7 +950,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
971
950
StatementKind :: SetDiscriminant { ref place, .. } => {
972
951
match self . ecx . machine . can_const_prop [ place. local ] {
973
952
ConstPropMode :: FullConstProp | ConstPropMode :: OnlyInsideOwnBlock => {
974
- if self . use_ecx ( |this| this . ecx . statement ( statement) ) . is_some ( ) {
953
+ if self . ecx . statement ( statement) . is_ok ( ) {
975
954
trace ! ( "propped discriminant into {:?}" , place) ;
976
955
} else {
977
956
Self :: remove_const ( & mut self . ecx , place. local ) ;
@@ -1004,8 +983,6 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
1004
983
match & mut terminator. kind {
1005
984
TerminatorKind :: Assert { expected, ref mut cond, .. } => {
1006
985
if let Some ( ref value) = self . eval_operand ( & cond)
1007
- // FIXME should be used use_ecx rather than a local match... but we have
1008
- // quite a few of these read_scalar/read_immediate that need fixing.
1009
986
&& let Ok ( value_const) = self . ecx . read_scalar ( & value)
1010
987
&& self . should_const_prop ( value)
1011
988
{
0 commit comments