@@ -433,7 +433,7 @@ mod helper {
433433 #[ inline]
434434 pub fn successors_for_value ( & self , value : u128 ) -> Successors < ' _ > {
435435 let target = self . target_for_value ( value) ;
436- ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( Some ( target) )
436+ ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( Some ( target) . into_iter ( ) . chain ( None ) )
437437 }
438438 }
439439
@@ -442,77 +442,123 @@ mod helper {
442442 pub fn successors ( & self ) -> Successors < ' _ > {
443443 use self :: TerminatorKind :: * ;
444444 match * self {
445+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
446+ Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : Some ( d) , .. } => {
447+ slice:: from_ref ( t)
448+ . into_iter ( )
449+ . copied ( )
450+ . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) )
451+ }
452+ // 2-successors
445453 Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
446454 | Yield { resume : ref t, drop : Some ( u) , .. }
447- | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
455+ | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : None , .. }
456+ | Drop { target : ref t, unwind : _, drop : Some ( u) , .. }
448457 | Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
449458 | FalseUnwind { real_target : ref t, unwind : UnwindAction :: Cleanup ( u) } => {
450- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) )
459+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
451460 }
461+ // single successor
452462 Goto { target : ref t }
453463 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
454464 | Call { target : Some ( ref t) , unwind : _, .. }
455465 | Yield { resume : ref t, drop : None , .. }
456466 | Drop { target : ref t, unwind : _, .. }
457467 | Assert { target : ref t, unwind : _, .. }
458468 | FalseUnwind { real_target : ref t, unwind : _ } => {
459- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None )
469+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
460470 }
471+ // No successors
461472 UnwindResume
462473 | UnwindTerminate ( _)
463474 | CoroutineDrop
464475 | Return
465476 | Unreachable
466477 | TailCall { .. }
467- | Call { target : None , unwind : _, .. } => ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None ) ,
478+ | Call { target : None , unwind : _, .. } => {
479+ ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
480+ }
481+ // Multiple successors
468482 InlineAsm { ref targets, unwind : UnwindAction :: Cleanup ( u) , .. } => {
469- targets. iter ( ) . copied ( ) . chain ( Some ( u) )
483+ targets. iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
484+ }
485+ InlineAsm { ref targets, unwind : _, .. } => {
486+ targets. iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
470487 }
471- InlineAsm { ref targets, unwind : _, .. } => targets. iter ( ) . copied ( ) . chain ( None ) ,
472- SwitchInt { ref targets, .. } => targets. targets . iter ( ) . copied ( ) . chain ( None ) ,
473- FalseEdge { ref real_target, imaginary_target } => {
474- slice:: from_ref ( real_target) . into_iter ( ) . copied ( ) . chain ( Some ( imaginary_target) )
488+ SwitchInt { ref targets, .. } => {
489+ targets. targets . iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
475490 }
491+ // FalseEdge
492+ FalseEdge { ref real_target, imaginary_target } => slice:: from_ref ( real_target)
493+ . into_iter ( )
494+ . copied ( )
495+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) ) ,
476496 }
477497 }
478498
479499 #[ inline]
480500 pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
481501 use self :: TerminatorKind :: * ;
482502 match * self {
503+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
504+ Drop {
505+ target : ref mut t,
506+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
507+ drop : Some ( ref mut d) ,
508+ ..
509+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) ) ,
510+ // 2-successors
483511 Call {
484512 target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
485513 }
486514 | Yield { resume : ref mut t, drop : Some ( ref mut u) , .. }
487- | Drop { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
515+ | Drop {
516+ target : ref mut t,
517+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
518+ drop : None ,
519+ ..
520+ }
521+ | Drop { target : ref mut t, unwind : _, drop : Some ( ref mut u) , .. }
488522 | Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
489523 | FalseUnwind {
490524 real_target : ref mut t,
491525 unwind : UnwindAction :: Cleanup ( ref mut u) ,
492- } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) ) ,
526+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) ) ,
527+ // single successor
493528 Goto { target : ref mut t }
494529 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
495530 | Call { target : Some ( ref mut t) , unwind : _, .. }
496531 | Yield { resume : ref mut t, drop : None , .. }
497532 | Drop { target : ref mut t, unwind : _, .. }
498533 | Assert { target : ref mut t, unwind : _, .. }
499534 | FalseUnwind { real_target : ref mut t, unwind : _ } => {
500- slice:: from_mut ( t) . into_iter ( ) . chain ( None )
535+ slice:: from_mut ( t) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
501536 }
537+ // No successors
502538 UnwindResume
503539 | UnwindTerminate ( _)
504540 | CoroutineDrop
505541 | Return
506542 | Unreachable
507543 | TailCall { .. }
508- | Call { target : None , unwind : _, .. } => ( & mut [ ] ) . into_iter ( ) . chain ( None ) ,
544+ | Call { target : None , unwind : _, .. } => {
545+ ( & mut [ ] ) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
546+ }
547+ // Multiple successors
509548 InlineAsm { ref mut targets, unwind : UnwindAction :: Cleanup ( ref mut u) , .. } => {
510- targets. iter_mut ( ) . chain ( Some ( u) )
549+ targets. iter_mut ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
550+ }
551+ InlineAsm { ref mut targets, unwind : _, .. } => {
552+ targets. iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
553+ }
554+ SwitchInt { ref mut targets, .. } => {
555+ targets. targets . iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
511556 }
512- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
513- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
557+ // FalseEdge
514558 FalseEdge { ref mut real_target, ref mut imaginary_target } => {
515- slice:: from_mut ( real_target) . into_iter ( ) . chain ( Some ( imaginary_target) )
559+ slice:: from_mut ( real_target)
560+ . into_iter ( )
561+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) )
516562 }
517563 }
518564 }
@@ -645,8 +691,10 @@ impl<'tcx> TerminatorKind<'tcx> {
645691
646692 Goto { target } => TerminatorEdges :: Single ( target) ,
647693
694+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
695+ // (target + unwind + dropline)
648696 Assert { target, unwind, expected : _, msg : _, cond : _ }
649- | Drop { target, unwind, place : _, replace : _ }
697+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
650698 | FalseUnwind { real_target : target, unwind } => match unwind {
651699 UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
652700 UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments