@@ -433,7 +433,7 @@ mod helper {
433
433
#[ inline]
434
434
pub fn successors_for_value ( & self , value : u128 ) -> Successors < ' _ > {
435
435
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 ) )
437
437
}
438
438
}
439
439
@@ -442,77 +442,123 @@ mod helper {
442
442
pub fn successors ( & self ) -> Successors < ' _ > {
443
443
use self :: TerminatorKind :: * ;
444
444
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
445
453
Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
446
454
| 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) , .. }
448
457
| Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
449
458
| 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 ) )
451
460
}
461
+ // single successor
452
462
Goto { target : ref t }
453
463
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
454
464
| Call { target : Some ( ref t) , unwind : _, .. }
455
465
| Yield { resume : ref t, drop : None , .. }
456
466
| Drop { target : ref t, unwind : _, .. }
457
467
| Assert { target : ref t, unwind : _, .. }
458
468
| 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 ) )
460
470
}
471
+ // No successors
461
472
UnwindResume
462
473
| UnwindTerminate ( _)
463
474
| CoroutineDrop
464
475
| Return
465
476
| Unreachable
466
477
| 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
468
482
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 ) )
470
487
}
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 ) )
475
490
}
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 ) ) ,
476
496
}
477
497
}
478
498
479
499
#[ inline]
480
500
pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
481
501
use self :: TerminatorKind :: * ;
482
502
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
483
511
Call {
484
512
target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
485
513
}
486
514
| 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) , .. }
488
522
| Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
489
523
| FalseUnwind {
490
524
real_target : ref mut t,
491
525
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
493
528
Goto { target : ref mut t }
494
529
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
495
530
| Call { target : Some ( ref mut t) , unwind : _, .. }
496
531
| Yield { resume : ref mut t, drop : None , .. }
497
532
| Drop { target : ref mut t, unwind : _, .. }
498
533
| Assert { target : ref mut t, unwind : _, .. }
499
534
| 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 ) )
501
536
}
537
+ // No successors
502
538
UnwindResume
503
539
| UnwindTerminate ( _)
504
540
| CoroutineDrop
505
541
| Return
506
542
| Unreachable
507
543
| 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
509
548
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 ) )
511
556
}
512
- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
513
- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
557
+ // FalseEdge
514
558
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 ) )
516
562
}
517
563
}
518
564
}
@@ -645,8 +691,10 @@ impl<'tcx> TerminatorKind<'tcx> {
645
691
646
692
Goto { target } => TerminatorEdges :: Single ( target) ,
647
693
694
+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
695
+ // (target + unwind + dropline)
648
696
Assert { target, unwind, expected : _, msg : _, cond : _ }
649
- | Drop { target, unwind, place : _, replace : _ }
697
+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
650
698
| FalseUnwind { real_target : target, unwind } => match unwind {
651
699
UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
652
700
UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments