@@ -21,7 +21,7 @@ use rustc_span::source_map::{self, Span, DUMMY_SP};
2121
2222use super :: {
2323 Immediate , MPlaceTy , Machine , MemPlace , MemPlaceMeta , Memory , OpTy , Operand , Place , PlaceTy ,
24- ScalarMaybeUndef , StackPopInfo ,
24+ ScalarMaybeUndef , StackPopJump ,
2525} ;
2626
2727pub struct InterpCx < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > {
@@ -623,31 +623,24 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
623623
624624 :: log_settings:: settings ( ) . indentation -= 1 ;
625625 let frame = self . stack . pop ( ) . expect ( "tried to pop a stack frame, but there were none" ) ;
626- let stack_pop_info = M :: stack_pop ( self , frame. extra , unwinding) ?;
627- if let ( false , StackPopInfo :: StopUnwinding ) = ( unwinding, stack_pop_info) {
628- bug ! ( "Attempted to stop unwinding while there is no unwinding!" ) ;
629- }
630626
631627 // Now where do we jump next?
632628
633- // Determine if we leave this function normally or via unwinding.
634- let cur_unwinding =
635- if let StackPopInfo :: StopUnwinding = stack_pop_info { false } else { unwinding } ;
636-
637629 // Usually we want to clean up (deallocate locals), but in a few rare cases we don't.
638630 // In that case, we return early. We also avoid validation in that case,
639631 // because this is CTFE and the final value will be thoroughly validated anyway.
640632 let ( cleanup, next_block) = match frame. return_to_block {
641633 StackPopCleanup :: Goto { ret, unwind } => {
642- ( true , Some ( if cur_unwinding { unwind } else { ret } ) )
634+ ( true , Some ( if unwinding { unwind } else { ret } ) )
643635 }
644636 StackPopCleanup :: None { cleanup, .. } => ( cleanup, None ) ,
645637 } ;
646638
647639 if !cleanup {
648640 assert ! ( self . stack. is_empty( ) , "only the topmost frame should ever be leaked" ) ;
649641 assert ! ( next_block. is_none( ) , "tried to skip cleanup when we have a next block!" ) ;
650- // Leak the locals, skip validation.
642+ assert ! ( !unwinding, "tried to skip cleanup during unwinding" ) ;
643+ // Leak the locals, skip validation, skip machine hook.
651644 return Ok ( ( ) ) ;
652645 }
653646
@@ -656,13 +649,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
656649 self . deallocate_local ( local. value ) ?;
657650 }
658651
659- trace ! (
660- "StackPopCleanup: {:?} StackPopInfo: {:?} cur_unwinding = {:?}" ,
661- frame . return_to_block ,
662- stack_pop_info ,
663- cur_unwinding
664- ) ;
665- if cur_unwinding {
652+ if M :: stack_pop ( self , frame . extra , unwinding ) ? == StackPopJump :: NoJump {
653+ // The hook already did everything.
654+ // We want to skip the `info!` below, hence early return.
655+ return Ok ( ( ) ) ;
656+ }
657+ // Normal return.
658+ if unwinding {
666659 // Follow the unwind edge.
667660 let unwind = next_block. expect ( "Encountered StackPopCleanup::None when unwinding!" ) ;
668661 self . unwind_to_block ( unwind) ;
@@ -697,7 +690,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
697690 "CONTINUING({}) {} (unwinding = {})" ,
698691 self . cur_frame( ) ,
699692 self . frame( ) . instance,
700- cur_unwinding
693+ unwinding
701694 ) ;
702695 }
703696
0 commit comments