@@ -457,7 +457,7 @@ mod helper {
457457 #[ cfg_attr( not( bootstrap) , define_opaque( Successors ) ) ]
458458 pub fn successors_for_value ( & self , value : u128 ) -> Successors < ' _ > {
459459 let target = self . target_for_value ( value) ;
460- ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( Some ( target) )
460+ ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( Some ( target) . into_iter ( ) . chain ( None ) )
461461 }
462462 }
463463
@@ -467,37 +467,57 @@ mod helper {
467467 pub fn successors ( & self ) -> Successors < ' _ > {
468468 use self :: TerminatorKind :: * ;
469469 match * self {
470+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
471+ Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : Some ( d) , .. } => {
472+ slice:: from_ref ( t)
473+ . into_iter ( )
474+ . copied ( )
475+ . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) )
476+ }
477+ // 2-successors
470478 Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
471479 | Yield { resume : ref t, drop : Some ( u) , .. }
472- | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
480+ | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : None , .. }
481+ | Drop { target : ref t, unwind : _, drop : Some ( u) , .. }
473482 | Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
474483 | FalseUnwind { real_target : ref t, unwind : UnwindAction :: Cleanup ( u) } => {
475- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) )
484+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
476485 }
486+ // single successor
477487 Goto { target : ref t }
478488 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
479489 | Call { target : Some ( ref t) , unwind : _, .. }
480490 | Yield { resume : ref t, drop : None , .. }
481491 | Drop { target : ref t, unwind : _, .. }
482492 | Assert { target : ref t, unwind : _, .. }
483493 | FalseUnwind { real_target : ref t, unwind : _ } => {
484- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None )
494+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
485495 }
496+ // No successors
486497 UnwindResume
487498 | UnwindTerminate ( _)
488499 | CoroutineDrop
489500 | Return
490501 | Unreachable
491502 | TailCall { .. }
492- | Call { target : None , unwind : _, .. } => ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None ) ,
503+ | Call { target : None , unwind : _, .. } => {
504+ ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
505+ }
506+ // Multiple successors
493507 InlineAsm { ref targets, unwind : UnwindAction :: Cleanup ( u) , .. } => {
494- targets. iter ( ) . copied ( ) . chain ( Some ( u) )
508+ targets. iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
509+ }
510+ InlineAsm { ref targets, unwind : _, .. } => {
511+ targets. iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
495512 }
496- InlineAsm { ref targets, unwind : _, .. } => targets. iter ( ) . copied ( ) . chain ( None ) ,
497- SwitchInt { ref targets, .. } => targets. targets . iter ( ) . copied ( ) . chain ( None ) ,
498- FalseEdge { ref real_target, imaginary_target } => {
499- slice:: from_ref ( real_target) . into_iter ( ) . copied ( ) . chain ( Some ( imaginary_target) )
513+ SwitchInt { ref targets, .. } => {
514+ targets. targets . iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
500515 }
516+ // FalseEdge
517+ FalseEdge { ref real_target, imaginary_target } => slice:: from_ref ( real_target)
518+ . into_iter ( )
519+ . copied ( )
520+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) ) ,
501521 }
502522 }
503523
@@ -506,39 +526,65 @@ mod helper {
506526 pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
507527 use self :: TerminatorKind :: * ;
508528 match * self {
529+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
530+ Drop {
531+ target : ref mut t,
532+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
533+ drop : Some ( ref mut d) ,
534+ ..
535+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) ) ,
536+ // 2-successors
509537 Call {
510538 target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
511539 }
512540 | Yield { resume : ref mut t, drop : Some ( ref mut u) , .. }
513- | Drop { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
541+ | Drop {
542+ target : ref mut t,
543+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
544+ drop : None ,
545+ ..
546+ }
547+ | Drop { target : ref mut t, unwind : _, drop : Some ( ref mut u) , .. }
514548 | Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
515549 | FalseUnwind {
516550 real_target : ref mut t,
517551 unwind : UnwindAction :: Cleanup ( ref mut u) ,
518- } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) ) ,
552+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) ) ,
553+ // single successor
519554 Goto { target : ref mut t }
520555 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
521556 | Call { target : Some ( ref mut t) , unwind : _, .. }
522557 | Yield { resume : ref mut t, drop : None , .. }
523558 | Drop { target : ref mut t, unwind : _, .. }
524559 | Assert { target : ref mut t, unwind : _, .. }
525560 | FalseUnwind { real_target : ref mut t, unwind : _ } => {
526- slice:: from_mut ( t) . into_iter ( ) . chain ( None )
561+ slice:: from_mut ( t) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
527562 }
563+ // No successors
528564 UnwindResume
529565 | UnwindTerminate ( _)
530566 | CoroutineDrop
531567 | Return
532568 | Unreachable
533569 | TailCall { .. }
534- | Call { target : None , unwind : _, .. } => ( & mut [ ] ) . into_iter ( ) . chain ( None ) ,
570+ | Call { target : None , unwind : _, .. } => {
571+ ( & mut [ ] ) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
572+ }
573+ // Multiple successors
535574 InlineAsm { ref mut targets, unwind : UnwindAction :: Cleanup ( ref mut u) , .. } => {
536- targets. iter_mut ( ) . chain ( Some ( u) )
575+ targets. iter_mut ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
576+ }
577+ InlineAsm { ref mut targets, unwind : _, .. } => {
578+ targets. iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
579+ }
580+ SwitchInt { ref mut targets, .. } => {
581+ targets. targets . iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
537582 }
538- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
539- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
583+ // FalseEdge
540584 FalseEdge { ref mut real_target, ref mut imaginary_target } => {
541- slice:: from_mut ( real_target) . into_iter ( ) . chain ( Some ( imaginary_target) )
585+ slice:: from_mut ( real_target)
586+ . into_iter ( )
587+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) )
542588 }
543589 }
544590 }
@@ -671,8 +717,10 @@ impl<'tcx> TerminatorKind<'tcx> {
671717
672718 Goto { target } => TerminatorEdges :: Single ( target) ,
673719
720+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
721+ // (target + unwind + dropline)
674722 Assert { target, unwind, expected : _, msg : _, cond : _ }
675- | Drop { target, unwind, place : _, replace : _ }
723+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
676724 | FalseUnwind { real_target : target, unwind } => match unwind {
677725 UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
678726 UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments