@@ -16,7 +16,7 @@ use rustc_middle::ty::layout::{self, TyAndLayout};
1616use  rustc_middle:: ty:: { 
1717    self ,  query:: TyCtxtAt ,  subst:: SubstsRef ,  ParamEnv ,  Ty ,  TyCtxt ,  TypeFoldable , 
1818} ; 
19- use  rustc_span:: { source_map :: DUMMY_SP ,   Pos ,  Span } ; 
19+ use  rustc_span:: { Pos ,  Span } ; 
2020use  rustc_target:: abi:: { Align ,  HasDataLayout ,  LayoutOf ,  Size ,  TargetDataLayout } ; 
2121
2222use  super :: { 
@@ -83,9 +83,11 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> {
8383    //////////////////////////////////////////////////////////////////////////////// 
8484    // Current position within the function 
8585    //////////////////////////////////////////////////////////////////////////////// 
86-     /// If this is `None`, we are unwinding and this function doesn't need any clean-up. 
87- /// Just continue the same as with `Resume`. 
88- pub  loc :  Option < mir:: Location > , 
86+     /// If this is `Err`, we are not currently executing any particular statement in 
87+ /// this frame (can happen e.g. during frame initialization, and during unwinding on 
88+ /// frames without cleanup code). 
89+ /// We basically abuse `Result` as `Either`. 
90+ pub ( super )  loc :  Result < mir:: Location ,  Span > , 
8991} 
9092
9193/// What we store about a frame in an interpreter backtrace. 
@@ -189,7 +191,14 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
189191impl < ' mir ,  ' tcx ,  Tag ,  Extra >  Frame < ' mir ,  ' tcx ,  Tag ,  Extra >  { 
190192    /// Return the `SourceInfo` of the current instruction. 
191193pub  fn  current_source_info ( & self )  -> Option < & mir:: SourceInfo >  { 
192-         self . loc . map ( |loc| self . body . source_info ( loc) ) 
194+         self . loc . ok ( ) . map ( |loc| self . body . source_info ( loc) ) 
195+     } 
196+ 
197+     pub  fn  current_span ( & self )  -> Span  { 
198+         match  self . loc  { 
199+             Ok ( loc)  => self . body . source_info ( loc) . span , 
200+             Err ( span)  => span, 
201+         } 
193202    } 
194203} 
195204
@@ -324,11 +333,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
324333
325334    #[ inline( always) ]  
326335    pub  fn  cur_span ( & self )  -> Span  { 
327-         self . stack ( ) 
328-             . last ( ) 
329-             . and_then ( |f| f. current_source_info ( ) ) 
330-             . map ( |si| si. span ) 
331-             . unwrap_or ( self . tcx . span ) 
336+         self . stack ( ) . last ( ) . map ( |f| f. current_span ( ) ) . unwrap_or ( self . tcx . span ) 
332337    } 
333338
334339    #[ inline( always) ]  
@@ -640,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
640645        // first push a stack frame so we have access to the local substs 
641646        let  pre_frame = Frame  { 
642647            body, 
643-             loc :  Some ( mir :: Location :: START ) , 
648+             loc :  Err ( body . span ) ,   // Span used for errors caused during preamble. 
644649            return_to_block, 
645650            return_place, 
646651            // empty local array, we fill it in below, after we are inside the stack frame and 
@@ -654,9 +659,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
654659
655660        // Make sure all the constants required by this frame evaluate successfully (post-monomorphization check). 
656661        for  const_ in  & body. required_consts  { 
662+             let  span = const_. span ; 
657663            let  const_ =
658664                self . subst_from_current_frame_and_normalize_erasing_regions ( const_. literal ) ; 
659-             self . const_to_op ( const_,  None ) ?; 
665+             self . const_to_op ( const_,  None ) . map_err ( |err| { 
666+                 // If there was an error, set the span of the current frame to this constant. 
667+                 // Avoiding doing this when evaluation succeeds. 
668+                 self . frame_mut ( ) . loc  = Err ( span) ; 
669+                 err
670+             } ) ?; 
660671        } 
661672
662673        // Locals are initially uninitialized. 
@@ -683,8 +694,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
683694        } 
684695        // done 
685696        self . frame_mut ( ) . locals  = locals; 
686- 
687697        M :: after_stack_push ( self ) ?; 
698+         self . frame_mut ( ) . loc  = Ok ( mir:: Location :: START ) ; 
688699        info ! ( "ENTERING({}) {}" ,  self . frame_idx( ) ,  self . frame( ) . instance) ; 
689700
690701        Ok ( ( ) ) 
@@ -693,7 +704,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
693704    /// Jump to the given block. 
694705#[ inline]  
695706    pub  fn  go_to_block ( & mut  self ,  target :  mir:: BasicBlock )  { 
696-         self . frame_mut ( ) . loc  = Some ( mir:: Location  {  block :  target,  statement_index :  0  } ) ; 
707+         self . frame_mut ( ) . loc  = Ok ( mir:: Location  {  block :  target,  statement_index :  0  } ) ; 
697708    } 
698709
699710    /// *Return* to the given `target` basic block. 
@@ -715,7 +726,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
715726/// If `target` is `None`, that indicates the function does not need cleanup during 
716727/// unwinding, and we will just keep propagating that upwards. 
717728pub  fn  unwind_to_block ( & mut  self ,  target :  Option < mir:: BasicBlock > )  { 
718-         self . frame_mut ( ) . loc  = target. map ( |block| mir:: Location  {  block,  statement_index :  0  } ) ; 
729+         self . frame_mut ( ) . loc  = match  target { 
730+             Some ( block)  => Ok ( mir:: Location  {  block,  statement_index :  0  } ) , 
731+             None  => Err ( self . frame_mut ( ) . body . span ) , 
732+         } ; 
719733    } 
720734
721735    /// Pops the current frame from the stack, deallocating the 
@@ -743,8 +757,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
743757        assert_eq ! ( 
744758            unwinding, 
745759            match  self . frame( ) . loc { 
746-                 None  => true , 
747-                 Some ( loc )  => self . body ( ) . basic_blocks ( ) [ loc . block ] . is_cleanup , 
760+                 Ok ( loc )  => self . body ( ) . basic_blocks ( ) [ loc . block ] . is_cleanup , 
761+                 Err ( _ )  => true , 
748762            } 
749763        ) ; 
750764
@@ -920,14 +934,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
920934    pub  fn  generate_stacktrace ( & self )  -> Vec < FrameInfo < ' tcx > >  { 
921935        let  mut  frames = Vec :: new ( ) ; 
922936        for  frame in  self . stack ( ) . iter ( ) . rev ( )  { 
923-             let  source_info = frame. current_source_info ( ) ; 
924-             let  lint_root = source_info. and_then ( |source_info| { 
937+             let  lint_root = frame. current_source_info ( ) . and_then ( |source_info| { 
925938                match  & frame. body . source_scopes [ source_info. scope ] . local_data  { 
926939                    mir:: ClearCrossCrate :: Set ( data)  => Some ( data. lint_root ) , 
927940                    mir:: ClearCrossCrate :: Clear  => None , 
928941                } 
929942            } ) ; 
930-             let  span = source_info . map_or ( DUMMY_SP ,  |source_info| source_info . span ) ; 
943+             let  span = frame . current_span ( ) ; 
931944
932945            frames. push ( FrameInfo  {  span,  instance :  frame. instance ,  lint_root } ) ; 
933946        } 
0 commit comments