@@ -418,77 +418,123 @@ mod helper {
418
418
pub fn successors ( & self ) -> Successors < ' _ > {
419
419
use self :: TerminatorKind :: * ;
420
420
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
421
429
Call { target : Some ( ref t) , unwind : UnwindAction :: Cleanup ( u) , .. }
422
430
| 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) , .. }
424
433
| Assert { target : ref t, unwind : UnwindAction :: Cleanup ( u) , .. }
425
434
| 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 ) )
427
436
}
437
+ // single successor
428
438
Goto { target : ref t }
429
439
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref t) , .. }
430
440
| Call { target : Some ( ref t) , unwind : _, .. }
431
441
| Yield { resume : ref t, drop : None , .. }
432
442
| Drop { target : ref t, unwind : _, .. }
433
443
| Assert { target : ref t, unwind : _, .. }
434
444
| 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 ) )
436
446
}
447
+ // No successors
437
448
UnwindResume
438
449
| UnwindTerminate ( _)
439
450
| CoroutineDrop
440
451
| Return
441
452
| Unreachable
442
453
| 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
444
458
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 ) )
446
463
}
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 ) )
451
466
}
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 ) ) ,
452
472
}
453
473
}
454
474
455
475
#[ inline]
456
476
pub fn successors_mut ( & mut self ) -> SuccessorsMut < ' _ > {
457
477
use self :: TerminatorKind :: * ;
458
478
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
459
487
Call {
460
488
target : Some ( ref mut t) , unwind : UnwindAction :: Cleanup ( ref mut u) , ..
461
489
}
462
490
| 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) , .. }
464
498
| Assert { target : ref mut t, unwind : UnwindAction :: Cleanup ( ref mut u) , .. }
465
499
| FalseUnwind {
466
500
real_target : ref mut t,
467
501
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
469
504
Goto { target : ref mut t }
470
505
| Call { target : None , unwind : UnwindAction :: Cleanup ( ref mut t) , .. }
471
506
| Call { target : Some ( ref mut t) , unwind : _, .. }
472
507
| Yield { resume : ref mut t, drop : None , .. }
473
508
| Drop { target : ref mut t, unwind : _, .. }
474
509
| Assert { target : ref mut t, unwind : _, .. }
475
510
| 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 ) )
477
512
}
513
+ // No successors
478
514
UnwindResume
479
515
| UnwindTerminate ( _)
480
516
| CoroutineDrop
481
517
| Return
482
518
| Unreachable
483
519
| 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
485
524
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 ) )
487
532
}
488
- InlineAsm { ref mut targets, unwind : _, .. } => targets. iter_mut ( ) . chain ( None ) ,
489
- SwitchInt { ref mut targets, .. } => targets. targets . iter_mut ( ) . chain ( None ) ,
533
+ // FalseEdge
490
534
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 ) )
492
538
}
493
539
}
494
540
}
@@ -619,8 +665,10 @@ impl<'tcx> TerminatorKind<'tcx> {
619
665
620
666
Goto { target } => TerminatorEdges :: Single ( target) ,
621
667
668
+ // FIXME: Maybe we need also TerminatorEdges::Trio for async drop
669
+ // (target + unwind + dropline)
622
670
Assert { target, unwind, expected : _, msg : _, cond : _ }
623
- | Drop { target, unwind, place : _, replace : _ }
671
+ | Drop { target, unwind, place : _, replace : _, drop : _ , async_fut : _ }
624
672
| FalseUnwind { real_target : target, unwind } => match unwind {
625
673
UnwindAction :: Cleanup ( unwind) => TerminatorEdges :: Double ( target, unwind) ,
626
674
UnwindAction :: Continue | UnwindAction :: Terminate ( _) | UnwindAction :: Unreachable => {
0 commit comments