@@ -64,6 +64,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
6464 tcx,
6565 param_env,
6666 mir_phase,
67+ unwind_edge_count : 0 ,
6768 reachable_blocks : traversal:: reachable_as_bitset ( body) ,
6869 storage_liveness,
6970 place_cache : Vec :: new ( ) ,
@@ -80,6 +81,7 @@ struct TypeChecker<'a, 'tcx> {
8081 tcx : TyCtxt < ' tcx > ,
8182 param_env : ParamEnv < ' tcx > ,
8283 mir_phase : MirPhase ,
84+ unwind_edge_count : usize ,
8385 reachable_blocks : BitSet < BasicBlock > ,
8486 storage_liveness : ResultsCursor < ' a , ' tcx , MaybeStorageLive < ' static > > ,
8587 place_cache : Vec < PlaceRef < ' tcx > > ,
@@ -104,7 +106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
104106 ) ;
105107 }
106108
107- fn check_edge ( & self , location : Location , bb : BasicBlock , edge_kind : EdgeKind ) {
109+ fn check_edge ( & mut self , location : Location , bb : BasicBlock , edge_kind : EdgeKind ) {
108110 if bb == START_BLOCK {
109111 self . fail ( location, "start block must not have predecessors" )
110112 }
@@ -113,10 +115,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
113115 match ( src. is_cleanup , bb. is_cleanup , edge_kind) {
114116 // Non-cleanup blocks can jump to non-cleanup blocks along non-unwind edges
115117 ( false , false , EdgeKind :: Normal )
116- // Non-cleanup blocks can jump to cleanup blocks along unwind edges
117- | ( false , true , EdgeKind :: Unwind )
118118 // Cleanup blocks can jump to cleanup blocks along non-unwind edges
119119 | ( true , true , EdgeKind :: Normal ) => { }
120+ // Non-cleanup blocks can jump to cleanup blocks along unwind edges
121+ ( false , true , EdgeKind :: Unwind ) => {
122+ self . unwind_edge_count += 1 ;
123+ }
120124 // All other jumps are invalid
121125 _ => {
122126 self . fail (
@@ -137,6 +141,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
137141 }
138142
139143 fn check_cleanup_control_flow ( & self ) {
144+ if self . unwind_edge_count <= 1 {
145+ return ;
146+ }
140147 let doms = self . body . basic_blocks . dominators ( ) ;
141148 let mut post_contract_node = FxHashMap :: default ( ) ;
142149 // Reusing the allocation across invocations of the closure
@@ -196,7 +203,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
196203 stack. clear ( ) ;
197204 stack. insert ( bb) ;
198205 loop {
199- let Some ( parent ) = parent[ bb] . take ( ) else {
206+ let Some ( parent) = parent[ bb] . take ( ) else {
200207 break
201208 } ;
202209 let no_cycle = stack. insert ( parent) ;
0 commit comments