@@ -41,6 +41,12 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
4141    } 
4242} 
4343
44+ /// Preorder traversal of a graph. 
45+ /// 
46+ /// This function creates an iterator over the `Body`'s basic blocks, that 
47+ /// returns basic blocks in a preorder. 
48+ /// 
49+ /// See [`Preorder`]'s docs to learn what is preorder traversal. 
4450pub  fn  preorder < ' a ,  ' tcx > ( body :  & ' a  Body < ' tcx > )  -> Preorder < ' a ,  ' tcx >  { 
4551    Preorder :: new ( body,  START_BLOCK ) 
4652} 
@@ -178,7 +184,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
178184        // When we yield `C` and call `traverse_successor`, we push `B` to the stack, but 
179185        // since we've already visited `E`, that child isn't added to the stack. The last 
180186        // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A] 
181-         while  let  Some ( & mut   ( _ ,   ref   mut  iter ) )  = self . visit_stack . last_mut ( )  &&  let   Some ( bb )  =  iter. next_back ( )  { 
187+         while  let  Some ( bb )  = self . visit_stack . last_mut ( ) . and_then ( | ( _ ,  iter ) |  iter. next_back ( ) )  { 
182188            if  self . visited . insert ( bb)  { 
183189                if  let  Some ( term)  = & self . basic_blocks [ bb] . terminator  { 
184190                    self . visit_stack . push ( ( bb,  term. successors ( ) ) ) ; 
@@ -188,16 +194,14 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
188194    } 
189195} 
190196
191- impl < ' a ,   ' tcx >  Iterator  for  Postorder < ' a ,  ' tcx >  { 
192-     type  Item  = ( BasicBlock ,   & ' a   BasicBlockData < ' tcx > ) ; 
197+ impl < ' tcx >  Iterator  for  Postorder < ' _ ,  ' tcx >  { 
198+     type  Item  = BasicBlock ; 
193199
194-     fn  next ( & mut  self )  -> Option < ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  { 
195-         let  next = self . visit_stack . pop ( ) ; 
196-         if  next. is_some ( )  { 
197-             self . traverse_successor ( ) ; 
198-         } 
200+     fn  next ( & mut  self )  -> Option < BasicBlock >  { 
201+         let  ( bb,  _)  = self . visit_stack . pop ( ) ?; 
202+         self . traverse_successor ( ) ; 
199203
200-         next . map ( | ( bb ,  _ ) |  ( bb ,   & self . basic_blocks [ bb ] ) ) 
204+         Some ( bb ) 
201205    } 
202206
203207    fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
@@ -215,18 +219,43 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
215219    } 
216220} 
217221
218- /// Creates an iterator over the `Body`'s basic blocks, that: 
222+ /// Postorder traversal of a graph. 
223+ /// 
224+ /// This function creates an iterator over the `Body`'s basic blocks, that: 
219225/// - returns basic blocks in a postorder, 
220226/// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the 
221227///   postorder itself. 
228+ /// 
229+ /// See [`Postorder`]'s docs to learn what is postorder traversal. 
222230pub  fn  postorder < ' a ,  ' tcx > ( 
223231    body :  & ' a  Body < ' tcx > , 
224232)  -> impl  Iterator < Item  = ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  + ExactSizeIterator  + DoubleEndedIterator 
225233{ 
226234    reverse_postorder ( body) . rev ( ) 
227235} 
228236
229- /// Reverse postorder traversal of a graph 
237+ /// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular 
238+ /// order. 
239+ /// 
240+ /// This is clearer than writing `preorder` in cases where the order doesn't matter. 
241+ pub  fn  reachable < ' a ,  ' tcx > ( 
242+     body :  & ' a  Body < ' tcx > , 
243+ )  -> impl  ' a  + Iterator < Item  = ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  { 
244+     preorder ( body) 
245+ } 
246+ 
247+ /// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`. 
248+ pub  fn  reachable_as_bitset ( body :  & Body < ' _ > )  -> BitSet < BasicBlock >  { 
249+     let  mut  iter = preorder ( body) ; 
250+     iter. by_ref ( ) . for_each ( drop) ; 
251+     iter. visited 
252+ } 
253+ 
254+ /// Reverse postorder traversal of a graph. 
255+ /// 
256+ /// This function creates an iterator over the `Body`'s basic blocks, that: 
257+ /// - returns basic blocks in a reverse postorder, 
258+ /// - makes use of the `BasicBlocks` CFG cache's reverse postorder. 
230259/// 
231260/// Reverse postorder is the reverse order of a postorder traversal. 
232261/// This is different to a preorder traversal and represents a natural 
@@ -246,65 +275,6 @@ pub fn postorder<'a, 'tcx>(
246275/// A reverse postorder traversal of this graph is either `A B C D` or `A C B D` 
247276/// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to 
248277/// a topological sort. 
249- /// 
250- /// Construction of a `ReversePostorder` traversal requires doing a full 
251- /// postorder traversal of the graph, therefore this traversal should be 
252- /// constructed as few times as possible. Use the `reset` method to be able 
253- /// to re-use the traversal 
254- #[ derive( Clone ) ]  
255- pub  struct  ReversePostorder < ' a ,  ' tcx >  { 
256-     body :  & ' a  Body < ' tcx > , 
257-     blocks :  Vec < BasicBlock > , 
258-     idx :  usize , 
259- } 
260- 
261- impl < ' a ,  ' tcx >  ReversePostorder < ' a ,  ' tcx >  { 
262-     pub  fn  new ( body :  & ' a  Body < ' tcx > ,  root :  BasicBlock )  -> ReversePostorder < ' a ,  ' tcx >  { 
263-         let  blocks:  Vec < _ >  = Postorder :: new ( & body. basic_blocks ,  root) . map ( |( bb,  _) | bb) . collect ( ) ; 
264-         let  len = blocks. len ( ) ; 
265-         ReversePostorder  {  body,  blocks,  idx :  len } 
266-     } 
267- } 
268- 
269- impl < ' a ,  ' tcx >  Iterator  for  ReversePostorder < ' a ,  ' tcx >  { 
270-     type  Item  = ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) ; 
271- 
272-     fn  next ( & mut  self )  -> Option < ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  { 
273-         if  self . idx  == 0  { 
274-             return  None ; 
275-         } 
276-         self . idx  -= 1 ; 
277- 
278-         self . blocks . get ( self . idx ) . map ( |& bb| ( bb,  & self . body [ bb] ) ) 
279-     } 
280- 
281-     fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
282-         ( self . idx ,  Some ( self . idx ) ) 
283-     } 
284- } 
285- 
286- impl < ' a ,  ' tcx >  ExactSizeIterator  for  ReversePostorder < ' a ,  ' tcx >  { } 
287- 
288- /// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular 
289- /// order. 
290- /// 
291- /// This is clearer than writing `preorder` in cases where the order doesn't matter. 
292- pub  fn  reachable < ' a ,  ' tcx > ( 
293-     body :  & ' a  Body < ' tcx > , 
294- )  -> impl  ' a  + Iterator < Item  = ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  { 
295-     preorder ( body) 
296- } 
297- 
298- /// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`. 
299- pub  fn  reachable_as_bitset ( body :  & Body < ' _ > )  -> BitSet < BasicBlock >  { 
300-     let  mut  iter = preorder ( body) ; 
301-     ( & mut  iter) . for_each ( drop) ; 
302-     iter. visited 
303- } 
304- 
305- /// Creates an iterator over the `Body`'s basic blocks, that: 
306- /// - returns basic blocks in a reverse postorder, 
307- /// - makes use of the `BasicBlocks` CFG cache's reverse postorder. 
308278pub  fn  reverse_postorder < ' a ,  ' tcx > ( 
309279    body :  & ' a  Body < ' tcx > , 
310280)  -> impl  Iterator < Item  = ( BasicBlock ,  & ' a  BasicBlockData < ' tcx > ) >  + ExactSizeIterator  + DoubleEndedIterator 
0 commit comments