@@ -418,77 +418,123 @@ mod helper {
418418 pub fn successors ( & self ) -> Successors < ' _ > {
419419 use self :: TerminatorKind :: * ;
420420 match * self {
421+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
422+ Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : Some ( d) , .. } => {
423+ slice:: from_ref ( t)
424+ . into_iter ( )
425+ . copied ( )
426+ . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) )
427+ }
428+ // 2-successors
421429 Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
422430 | Yield { resume : ref t, drop : Some ( u) , .. }
423- | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
431+ | Drop { target : ref t, unwind : UnwindAction :: Cleanup ( u) , drop : None , .. }
432+ | Drop { target : ref t, unwind : _, drop : Some ( u) , .. }
424433 | Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
425434 | FalseUnwind { real_target : ref t, unwind : UnwindAction :: Cleanup ( u) } => {
426- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) )
435+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
427436 }
437+ // single successor
428438 Goto { target : ref t }
429439 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
430440 | Call { target : Some ( ref t) , unwind : _, .. }
431441 | Yield { resume : ref t, drop : None , .. }
432442 | Drop { target : ref t, unwind : _, .. }
433443 | Assert { target : ref t, unwind : _, .. }
434444 | FalseUnwind { real_target : ref t, unwind : _ } => {
435- slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None )
445+ slice:: from_ref ( t) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
436446 }
447+ // No successors
437448 UnwindResume
438449 | UnwindTerminate ( _)
439450 | CoroutineDrop
440451 | Return
441452 | Unreachable
442453 | TailCall { .. }
443- | Call { target : None , unwind : _, .. } => ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None ) ,
454+ | Call { target : None , unwind : _, .. } => {
455+ ( & [ ] ) . into_iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
456+ }
457+ // Multiple successors
444458 InlineAsm { ref targets, unwind : UnwindAction :: Cleanup ( u) , .. } => {
445- targets. iter ( ) . copied ( ) . chain ( Some ( u) )
459+ targets. iter ( ) . copied ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
460+ }
461+ InlineAsm { ref targets, unwind : _, .. } => {
462+ targets. iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
446463 }
447- InlineAsm { ref targets, unwind : _, .. } => targets. iter ( ) . copied ( ) . chain ( None ) ,
448- SwitchInt { ref targets, .. } => targets. targets . iter ( ) . copied ( ) . chain ( None ) ,
449- FalseEdge { ref real_target, imaginary_target } => {
450- slice:: from_ref ( real_target) . into_iter ( ) . copied ( ) . chain ( Some ( imaginary_target) )
464+ SwitchInt { ref targets, .. } => {
465+ targets. targets . iter ( ) . copied ( ) . chain ( None . into_iter ( ) . chain ( None ) )
451466 }
467+ // FalseEdge
468+ FalseEdge { ref real_target, imaginary_target } => slice:: from_ref ( real_target)
469+ . into_iter ( )
470+ . copied ( )
471+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) ) ,
452472 }
453473 }
454474
455475 #[ inline]
456476 pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
457477 use self :: TerminatorKind :: * ;
458478 match * self {
479+ // 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
480+ Drop {
481+ target : ref mut t,
482+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
483+ drop : Some ( ref mut d) ,
484+ ..
485+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( Some ( d) ) ) ,
486+ // 2-successors
459487 Call {
460488 target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
461489 }
462490 | Yield { resume : ref mut t, drop : Some ( ref mut u) , .. }
463- | Drop { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
491+ | Drop {
492+ target : ref mut t,
493+ unwind : UnwindAction :: Cleanup ( ref mut u) ,
494+ drop : None ,
495+ ..
496+ }
497+ | Drop { target : ref mut t, unwind : _, drop : Some ( ref mut u) , .. }
464498 | Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
465499 | FalseUnwind {
466500 real_target : ref mut t,
467501 unwind : UnwindAction :: Cleanup ( ref mut u) ,
468- } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) ) ,
502+ } => slice:: from_mut ( t) . into_iter ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) ) ,
503+ // single successor
469504 Goto { target : ref mut t }
470505 | Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
471506 | Call { target : Some ( ref mut t) , unwind : _, .. }
472507 | Yield { resume : ref mut t, drop : None , .. }
473508 | Drop { target : ref mut t, unwind : _, .. }
474509 | Assert { target : ref mut t, unwind : _, .. }
475510 | FalseUnwind { real_target : ref mut t, unwind : _ } => {
476- slice:: from_mut ( t) . into_iter ( ) . chain ( None )
511+ slice:: from_mut ( t) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
477512 }
513+ // No successors
478514 UnwindResume
479515 | UnwindTerminate ( _)
480516 | CoroutineDrop
481517 | Return
482518 | Unreachable
483519 | TailCall { .. }
484- | Call { target : None , unwind : _, .. } => ( & mut [ ] ) . into_iter ( ) . chain ( None ) ,
520+ | Call { target : None , unwind : _, .. } => {
521+ ( & mut [ ] ) . into_iter ( ) . chain ( None . into_iter ( ) . chain ( None ) )
522+ }
523+ // Multiple successors
485524 InlineAsm { ref mut targets, unwind : UnwindAction :: Cleanup ( ref mut u) , .. } => {
486- targets. iter_mut ( ) . chain ( Some ( u) )
525+ targets. iter_mut ( ) . chain ( Some ( u) . into_iter ( ) . chain ( None ) )
526+ }
527+ InlineAsm { ref mut targets, unwind : _, .. } => {
528+ targets. iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
529+ }
530+ SwitchInt { ref mut targets, .. } => {
531+ targets. targets . iter_mut ( ) . chain ( None . into_iter ( ) . chain ( None ) )
487532 }
488- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
489- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
533+ // FalseEdge
490534 FalseEdge { ref mut real_target, ref mut imaginary_target } => {
491- slice:: from_mut ( real_target) . into_iter ( ) . chain ( Some ( imaginary_target) )
535+ slice:: from_mut ( real_target)
536+ . into_iter ( )
537+ . chain ( Some ( imaginary_target) . into_iter ( ) . chain ( None ) )
492538 }
493539 }
494540 }
@@ -619,8 +665,10 @@ impl<'tcx> TerminatorKind<'tcx> {
619665
620666 Goto { target } => TerminatorEdges :: Single ( target) ,
621667
668+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
669+ // (target + unwind + dropline)
622670 Assert { target, unwind, expected : _, msg : _, cond : _ }
623- | Drop { target, unwind, place : _, replace : _ }
671+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
624672 | FalseUnwind { real_target : target, unwind } => match unwind {
625673 UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
626674 UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments