@@ -452,27 +452,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
452452 } ;
453453 }
454454
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-
476455 /// Returns the value, if any, of evaluating `c`.
477456 fn eval_constant ( & mut self , c : & Constant < ' tcx > ) -> Option < OpTy < ' tcx > > {
478457 // FIXME we need to revisit this for #67176
@@ -487,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
487466 /// Returns the value, if any, of evaluating `place`.
488467 fn eval_place ( & mut self , place : Place < ' tcx > ) -> Option < OpTy < ' tcx > > {
489468 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 ( )
491470 }
492471
493472 /// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant`
@@ -591,52 +570,54 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
591570 rvalue : & Rvalue < ' tcx > ,
592571 place : Place < ' tcx > ,
593572 ) -> Option < ( ) > {
594- self . use_ecx ( |this| match rvalue {
573+ match rvalue {
595574 Rvalue :: BinaryOp ( op, box ( left, right) )
596575 | 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) ) ;
598577 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) ) ;
600579
601580 let const_arg = match ( l, r) {
602581 ( 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
605584 } ;
606585
607586 if !matches ! ( const_arg. layout. abi, abi:: Abi :: Scalar ( ..) ) {
608587 // We cannot handle Scalar Pair stuff.
609588 // 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 ;
611590 }
612591
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 ( ) ?;
615594
616595 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+ }
618599 BinOp :: BitOr
619600 if arg_value == const_arg. layout . size . truncate ( u128:: MAX )
620601 || ( const_arg. layout . ty . is_bool ( ) && arg_value == 1 ) =>
621602 {
622- this . ecx . write_immediate ( * const_arg, & dest)
603+ self . ecx . write_immediate ( * const_arg, & dest) . ok ( )
623604 }
624605 BinOp :: Mul if const_arg. layout . ty . is_integral ( ) && arg_value == 0 => {
625606 if let Rvalue :: CheckedBinaryOp ( _, _) = rvalue {
626607 let val = Immediate :: ScalarPair (
627608 const_arg. to_scalar ( ) ,
628609 Scalar :: from_bool ( false ) ,
629610 ) ;
630- this . ecx . write_immediate ( val, & dest)
611+ self . ecx . write_immediate ( val, & dest) . ok ( )
631612 } else {
632- this . ecx . write_immediate ( * const_arg, & dest)
613+ self . ecx . write_immediate ( * const_arg, & dest) . ok ( )
633614 }
634615 }
635- _ => throw_machine_stop_str ! ( "cannot optimize this" ) ,
616+ _ => None ,
636617 }
637618 }
638- _ => this . ecx . eval_rvalue_into_place ( rvalue, place) ,
639- } )
619+ _ => self . ecx . eval_rvalue_into_place ( rvalue, place) . ok ( ) ,
620+ }
640621 }
641622
642623 /// Creates a new `Operand::Constant` from a `Scalar` value
@@ -678,7 +659,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
678659 }
679660
680661 // 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 ( ) ;
682663
683664 if let Some ( Right ( imm) ) = imm {
684665 match * imm {
@@ -698,25 +679,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
698679 if let ty:: Tuple ( types) = ty. kind ( ) {
699680 // Only do it if tuple is also a pair with two scalars
700681 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 {
720699 // Assign entire constant in a single statement.
721700 // We can't use aggregates, as we run after the aggregate-lowering `MirPhase`.
722701 let const_val = ConstValue :: ByRef { alloc, offset : Size :: ZERO } ;
@@ -971,7 +950,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
971950 StatementKind :: SetDiscriminant { ref place, .. } => {
972951 match self . ecx . machine . can_const_prop [ place. local ] {
973952 ConstPropMode :: FullConstProp | ConstPropMode :: OnlyInsideOwnBlock => {
974- if self . use_ecx ( |this| this . ecx . statement ( statement) ) . is_some ( ) {
953+ if self . ecx . statement ( statement) . is_ok ( ) {
975954 trace ! ( "propped discriminant into {:?}" , place) ;
976955 } else {
977956 Self :: remove_const ( & mut self . ecx , place. local ) ;
@@ -1004,8 +983,6 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
1004983 match & mut terminator. kind {
1005984 TerminatorKind :: Assert { expected, ref mut cond, .. } => {
1006985 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.
1009986 && let Ok ( value_const) = self . ecx . read_scalar ( & value)
1010987 && self . should_const_prop ( value)
1011988 {
0 commit comments