@@ -457,7 +457,7 @@ mod helper {
457
457
#[ cfg_attr( not( bootstrap) , define_opaque( Successors ) ) ]
458
458
pub fn successors_for_value ( & self , value : u128 ) -> Successors < ' _ > {
459
459
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 ) )
461
461
}
462
462
}
463
463
@@ -467,37 +467,57 @@ mod helper {
467
467
pub fn successors ( & self ) -> Successors < ' _ > {
468
468
use self :: TerminatorKind :: * ;
469
469
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
470
478
Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
471
479
| 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) , .. }
473
482
| Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
474
483
| 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 ) )
476
485
}
486
+ // single successor
477
487
Goto { target : ref t }
478
488
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
479
489
| Call { target : Some ( ref t) , unwind : _, .. }
480
490
| Yield { resume : ref t, drop : None , .. }
481
491
| Drop { target : ref t, unwind : _, .. }
482
492
| Assert { target : ref t, unwind : _, .. }
483
493
| 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 ) )
485
495
}
496
+ // No successors
486
497
UnwindResume
487
498
| UnwindTerminate ( _)
488
499
| CoroutineDrop
489
500
| Return
490
501
| Unreachable
491
502
| 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
493
507
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 ) )
495
512
}
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 ) )
500
515
}
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 ) ) ,
501
521
}
502
522
}
503
523
@@ -506,39 +526,65 @@ mod helper {
506
526
pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
507
527
use self :: TerminatorKind :: * ;
508
528
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
509
537
Call {
510
538
target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
511
539
}
512
540
| 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) , .. }
514
548
| Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
515
549
| FalseUnwind {
516
550
real_target : ref mut t,
517
551
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
519
554
Goto { target : ref mut t }
520
555
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
521
556
| Call { target : Some ( ref mut t) , unwind : _, .. }
522
557
| Yield { resume : ref mut t, drop : None , .. }
523
558
| Drop { target : ref mut t, unwind : _, .. }
524
559
| Assert { target : ref mut t, unwind : _, .. }
525
560
| 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 ) )
527
562
}
563
+ // No successors
528
564
UnwindResume
529
565
| UnwindTerminate ( _)
530
566
| CoroutineDrop
531
567
| Return
532
568
| Unreachable
533
569
| 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
535
574
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 ) )
537
582
}
538
- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
539
- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
583
+ // FalseEdge
540
584
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 ) )
542
588
}
543
589
}
544
590
}
@@ -671,8 +717,10 @@ impl<'tcx> TerminatorKind<'tcx> {
671
717
672
718
Goto { target } => TerminatorEdges :: Single ( target) ,
673
719
720
+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
721
+ // (target + unwind + dropline)
674
722
Assert { target, unwind, expected : _, msg : _, cond : _ }
675
- | Drop { target, unwind, place : _, replace : _ }
723
+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
676
724
| FalseUnwind { real_target : target, unwind } => match unwind {
677
725
UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
678
726
UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments