137137//! [attempt 3]: https://github.com/rust-lang/rust/pull/72632 
138138//! [attempt 4]: https://github.com/rust-lang/rust/pull/96451 
139139
140+ use  rustc_data_structures:: union_find:: UnionFind ; 
140141use  rustc_index:: bit_set:: DenseBitSet ; 
141142use  rustc_index:: interval:: SparseIntervalMatrix ; 
142143use  rustc_index:: { IndexVec ,  newtype_index} ; 
@@ -225,13 +226,12 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
225226                merged_locals. insert ( orig_dst) ; 
226227
227228                // Replace `src` by `dst`. 
228-                 relevant. union ( src,  dst) ; 
229-                 live. union_rows ( /* read */  src,  /* write */  dst) ; 
229+                 let  head = relevant. union ( src,  dst) ; 
230+                 live. union_rows ( /* read */  src,  /* write */  head) ; 
231+                 live. union_rows ( /* read */  dst,  /* write */  head) ; 
230232            } 
231233        } 
232234        trace ! ( ?merged_locals) ; 
233- 
234-         relevant. make_idempotent ( ) ; 
235235        trace ! ( ?relevant. renames) ; 
236236
237237        if  merged_locals. is_empty ( )  { 
@@ -326,7 +326,7 @@ newtype_index! {
326326struct  RelevantLocals  { 
327327    original :  IndexVec < RelevantLocal ,  Local > , 
328328    shrink :  IndexVec < Local ,  Option < RelevantLocal > > , 
329-     renames :  IndexVec < RelevantLocal ,   RelevantLocal > , 
329+     renames :  UnionFind < RelevantLocal > , 
330330} 
331331
332332impl  RelevantLocals  { 
@@ -345,35 +345,21 @@ impl RelevantLocals {
345345            declare ( dest) 
346346        } 
347347
348-         let  renames = IndexVec :: from_fn_n ( |l| l ,   original. len ( ) ) ; 
348+         let  renames = UnionFind :: new ( original. len ( ) ) ; 
349349        RelevantLocals  {  original,  shrink,  renames } 
350350    } 
351351
352-     fn  find ( & self ,  src :  Local )  -> Option < RelevantLocal >  { 
353-         let  mut  src = self . shrink [ src] ?; 
354-         while  let  s2 = self . renames [ src] 
355-             && src != s2
356-         { 
357-             src = s2
358-         } 
352+     fn  find ( & mut  self ,  src :  Local )  -> Option < RelevantLocal >  { 
353+         let  src = self . shrink [ src] ?; 
354+         let  src = self . renames . find ( src) ; 
359355        Some ( src) 
360356    } 
361357
362-     fn  union ( & mut  self ,  lhs :  RelevantLocal ,  rhs :  RelevantLocal )  { 
363-         self . renames [ lhs]  = rhs; 
364-     } 
365- 
366-     fn  make_idempotent ( & mut  self )  { 
367-         for  l in  self . renames . indices ( )  { 
368-             let  mut  h = self . renames [ l] ; 
369-             while  let  h2 = self . renames [ h] 
370-                 && h != h2
371-             { 
372-                 h = h2
373-             } 
374-             self . renames [ l]  = h; 
375-             debug_assert_eq ! ( h,  self . renames[ h] ,  "non-idempotent for {l:?}" ) ; 
376-         } 
358+     fn  union ( & mut  self ,  lhs :  RelevantLocal ,  rhs :  RelevantLocal )  -> RelevantLocal  { 
359+         let  head = self . renames . unify ( lhs,  rhs) ; 
360+         // We need to ensure we keep the original local of the RHS, as it may be a required local. 
361+         self . original [ head]  = self . original [ rhs] ; 
362+         head
377363    } 
378364} 
379365
0 commit comments