33//! Currently, this pass only propagates scalar values.
44
55use rustc_const_eval:: const_eval:: { DummyMachine , throw_machine_stop_str} ;
6- use rustc_const_eval:: interpret:: { ImmTy , Immediate , InterpCx , OpTy , PlaceTy , Projectable } ;
6+ use rustc_const_eval:: interpret:: {
7+ DiscardInterpError , ImmTy , Immediate , InterpCx , OpTy , PlaceTy , Projectable ,
8+ } ;
79use rustc_data_structures:: fx:: FxHashMap ;
810use rustc_hir:: def:: DefKind ;
911use rustc_middle:: bug;
@@ -364,8 +366,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
364366 }
365367 }
366368 Operand :: Constant ( box constant) => {
367- if let Ok ( constant) =
368- self . ecx . eval_mir_constant ( & constant. const_ , constant. span , None )
369+ if let Some ( constant) = self
370+ . ecx
371+ . eval_mir_constant ( & constant. const_ , constant. span , None )
372+ . discard_interp_error ( )
369373 {
370374 self . assign_constant ( state, place, constant, & [ ] ) ;
371375 }
@@ -387,15 +391,17 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
387391 for & ( mut proj_elem) in projection {
388392 if let PlaceElem :: Index ( index) = proj_elem {
389393 if let FlatSet :: Elem ( index) = state. get ( index. into ( ) , & self . map )
390- && let Ok ( offset) = index. to_target_usize ( & self . tcx )
394+ && let Some ( offset) = index. to_target_usize ( & self . tcx ) . discard_interp_error ( )
391395 && let Some ( min_length) = offset. checked_add ( 1 )
392396 {
393397 proj_elem = PlaceElem :: ConstantIndex { offset, min_length, from_end : false } ;
394398 } else {
395399 return ;
396400 }
397401 }
398- operand = if let Ok ( operand) = self . ecx . project ( & operand, proj_elem) {
402+ operand = if let Some ( operand) =
403+ self . ecx . project ( & operand, proj_elem) . discard_interp_error ( )
404+ {
399405 operand
400406 } else {
401407 return ;
@@ -406,24 +412,30 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
406412 place,
407413 operand,
408414 & mut |elem, op| match elem {
409- TrackElem :: Field ( idx) => self . ecx . project_field ( op, idx. as_usize ( ) ) . ok ( ) ,
410- TrackElem :: Variant ( idx) => self . ecx . project_downcast ( op, idx) . ok ( ) ,
415+ TrackElem :: Field ( idx) => {
416+ self . ecx . project_field ( op, idx. as_usize ( ) ) . discard_interp_error ( )
417+ }
418+ TrackElem :: Variant ( idx) => {
419+ self . ecx . project_downcast ( op, idx) . discard_interp_error ( )
420+ }
411421 TrackElem :: Discriminant => {
412- let variant = self . ecx . read_discriminant ( op) . ok ( ) ?;
413- let discr_value =
414- self . ecx . discriminant_for_variant ( op. layout . ty , variant) . ok ( ) ?;
422+ let variant = self . ecx . read_discriminant ( op) . discard_interp_error ( ) ?;
423+ let discr_value = self
424+ . ecx
425+ . discriminant_for_variant ( op. layout . ty , variant)
426+ . discard_interp_error ( ) ?;
415427 Some ( discr_value. into ( ) )
416428 }
417429 TrackElem :: DerefLen => {
418- let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . ok ( ) ?. into ( ) ;
419- let len_usize = op. len ( & self . ecx ) . ok ( ) ?;
430+ let op: OpTy < ' _ > = self . ecx . deref_pointer ( op) . discard_interp_error ( ) ?. into ( ) ;
431+ let len_usize = op. len ( & self . ecx ) . discard_interp_error ( ) ?;
420432 let layout =
421433 self . tcx . layout_of ( self . param_env . and ( self . tcx . types . usize ) ) . unwrap ( ) ;
422434 Some ( ImmTy :: from_uint ( len_usize, layout) . into ( ) )
423435 }
424436 } ,
425437 & mut |place, op| {
426- if let Ok ( imm) = self . ecx . read_immediate_raw ( op)
438+ if let Some ( imm) = self . ecx . read_immediate_raw ( op) . discard_interp_error ( )
427439 && let Some ( imm) = imm. right ( )
428440 {
429441 let elem = self . wrap_immediate ( * imm) ;
@@ -447,11 +459,11 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
447459 ( FlatSet :: Bottom , _) | ( _, FlatSet :: Bottom ) => ( FlatSet :: Bottom , FlatSet :: Bottom ) ,
448460 // Both sides are known, do the actual computation.
449461 ( FlatSet :: Elem ( left) , FlatSet :: Elem ( right) ) => {
450- match self . ecx . binary_op ( op, & left, & right) {
462+ match self . ecx . binary_op ( op, & left, & right) . discard_interp_error ( ) {
451463 // Ideally this would return an Immediate, since it's sometimes
452464 // a pair and sometimes not. But as a hack we always return a pair
453465 // and just make the 2nd component `Bottom` when it does not exist.
454- Ok ( val) => {
466+ Some ( val) => {
455467 if matches ! ( val. layout. abi, Abi :: ScalarPair ( ..) ) {
456468 let ( val, overflow) = val. to_scalar_pair ( ) ;
457469 ( FlatSet :: Elem ( val) , FlatSet :: Elem ( overflow) )
@@ -470,7 +482,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
470482 }
471483
472484 let arg_scalar = const_arg. to_scalar ( ) ;
473- let Ok ( arg_value) = arg_scalar. to_bits ( layout. size ) else {
485+ let Some ( arg_value) = arg_scalar. to_bits ( layout. size ) . discard_interp_error ( ) else {
474486 return ( FlatSet :: Top , FlatSet :: Top ) ;
475487 } ;
476488
@@ -518,8 +530,10 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
518530 return None ;
519531 }
520532 let enum_ty_layout = self . tcx . layout_of ( self . param_env . and ( enum_ty) ) . ok ( ) ?;
521- let discr_value =
522- self . ecx . discriminant_for_variant ( enum_ty_layout. ty , variant_index) . ok ( ) ?;
533+ let discr_value = self
534+ . ecx
535+ . discriminant_for_variant ( enum_ty_layout. ty , variant_index)
536+ . discard_interp_error ( ) ?;
523537 Some ( discr_value. to_scalar ( ) )
524538 }
525539
@@ -573,7 +587,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
573587 map : & Map < ' tcx > ,
574588 ) -> Option < Const < ' tcx > > {
575589 let ty = place. ty ( self . local_decls , self . patch . tcx ) . ty ;
576- let layout = ecx. layout_of ( ty) . ok ( ) ?;
590+ let layout = ecx. layout_of ( ty) . discard_interp_error ( ) ?;
577591
578592 if layout. is_zst ( ) {
579593 return Some ( Const :: zero_sized ( ty) ) ;
@@ -595,7 +609,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> {
595609 . intern_with_temp_alloc ( layout, |ecx, dest| {
596610 try_write_constant ( ecx, dest, place, ty, state, map)
597611 } )
598- . ok ( ) ?;
612+ . discard_interp_error ( ) ?;
599613 return Some ( Const :: Val ( ConstValue :: Indirect { alloc_id, offset : Size :: ZERO } , ty) ) ;
600614 }
601615
@@ -830,7 +844,7 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> {
830844 if let PlaceElem :: Index ( local) = elem {
831845 let offset = self . before_effect . get ( & ( location, local. into ( ) ) ) ?;
832846 let offset = offset. try_to_scalar ( ) ?;
833- let offset = offset. to_target_usize ( & self . tcx ) . ok ( ) ?;
847+ let offset = offset. to_target_usize ( & self . tcx ) . discard_interp_error ( ) ?;
834848 let min_length = offset. checked_add ( 1 ) ?;
835849 Some ( PlaceElem :: ConstantIndex { offset, min_length, from_end : false } )
836850 } else {
0 commit comments