@@ -299,6 +299,34 @@ pub trait Cursor {
299299        self . set_position ( CursorPosition :: After ( block) ) ; 
300300    } 
301301
302+     /// Get the next position that a forwards traversal will move to, but do not 
303+      /// move this cursor. 
304+      fn  next_position ( & self )  -> CursorPosition  { 
305+         self . next_inst_position ( ) 
306+             . unwrap_or_else ( || self . next_block_position ( ) ) 
307+     } 
308+ 
309+     /// Get the next position that a backwards traversal will move to, but do 
310+      /// not move this cursor. 
311+      fn  prev_position ( & self )  -> CursorPosition  { 
312+         self . prev_inst_position ( ) 
313+             . unwrap_or_else ( || self . prev_block_position ( ) ) 
314+     } 
315+ 
316+     /// Get the position that a `cursor.next_block()` call would move this 
317+      /// cursor to, but do not update this cursor's position. 
318+      fn  next_block_position ( & self )  -> CursorPosition  { 
319+         let  next = if  let  Some ( block)  = self . current_block ( )  { 
320+             self . layout ( ) . next_block ( block) 
321+         }  else  { 
322+             self . layout ( ) . entry_block ( ) 
323+         } ; 
324+         match  next { 
325+             Some ( block)  => CursorPosition :: Before ( block) , 
326+             None  => CursorPosition :: Nowhere , 
327+         } 
328+     } 
329+ 
302330    /// Go to the top of the next block in layout order and return it. 
303331     /// 
304332     /// - If the cursor wasn't pointing at anything, go to the top of the first block in the 
@@ -320,16 +348,23 @@ pub trait Cursor {
320348     /// } 
321349     /// ``` 
322350     fn  next_block ( & mut  self )  -> Option < ir:: Block >  { 
323-         let  next = if  let  Some ( block)  = self . current_block ( )  { 
324-             self . layout ( ) . next_block ( block) 
351+         let  pos = self . next_block_position ( ) ; 
352+         self . set_position ( pos) ; 
353+         self . current_block ( ) 
354+     } 
355+ 
356+     /// Get the position that a `cursor.prev_block()` call would move this 
357+      /// cursor to, but do not update this cursor's position. 
358+      fn  prev_block_position ( & self )  -> CursorPosition  { 
359+         let  prev = if  let  Some ( block)  = self . current_block ( )  { 
360+             self . layout ( ) . prev_block ( block) 
325361        }  else  { 
326-             self . layout ( ) . entry_block ( ) 
362+             self . layout ( ) . last_block ( ) 
327363        } ; 
328-         self . set_position ( match  next  { 
329-             Some ( block)  => CursorPosition :: Before ( block) , 
364+         match  prev  { 
365+             Some ( block)  => CursorPosition :: After ( block) , 
330366            None  => CursorPosition :: Nowhere , 
331-         } ) ; 
332-         next
367+         } 
333368    } 
334369
335370    /// Go to the bottom of the previous block in layout order and return it. 
@@ -353,16 +388,36 @@ pub trait Cursor {
353388     /// } 
354389     /// ``` 
355390     fn  prev_block ( & mut  self )  -> Option < ir:: Block >  { 
356-         let  prev = if  let  Some ( block)  = self . current_block ( )  { 
357-             self . layout ( ) . prev_block ( block) 
358-         }  else  { 
359-             self . layout ( ) . last_block ( ) 
360-         } ; 
361-         self . set_position ( match  prev { 
362-             Some ( block)  => CursorPosition :: After ( block) , 
363-             None  => CursorPosition :: Nowhere , 
364-         } ) ; 
365-         prev
391+         let  pos = self . prev_block_position ( ) ; 
392+         self . set_position ( pos) ; 
393+         self . current_block ( ) 
394+     } 
395+ 
396+     /// Get the position that a `cursor.next_inst()` call would move this cursor 
397+      /// to, but do not update this cursor's position. 
398+      fn  next_inst_position ( & self )  -> Option < CursorPosition >  { 
399+         use  self :: CursorPosition :: * ; 
400+         match  self . position ( )  { 
401+             Nowhere  | After ( ..)  => None , 
402+             At ( inst)  => { 
403+                 if  let  Some ( next)  = self . layout ( ) . next_inst ( inst)  { 
404+                     Some ( At ( next) ) 
405+                 }  else  { 
406+                     Some ( After ( 
407+                         self . layout ( ) 
408+                             . inst_block ( inst) 
409+                             . expect ( "current instruction removed?" ) , 
410+                     ) ) 
411+                 } 
412+             } 
413+             Before ( block)  => { 
414+                 if  let  Some ( next)  = self . layout ( ) . first_inst ( block)  { 
415+                     Some ( At ( next) ) 
416+                 }  else  { 
417+                     Some ( After ( block) ) 
418+                 } 
419+             } 
420+         } 
366421    } 
367422
368423    /// Move to the next instruction in the same block and return it. 
@@ -406,30 +461,33 @@ pub trait Cursor {
406461     /// } 
407462     /// ``` 
408463     fn  next_inst ( & mut  self )  -> Option < ir:: Inst >  { 
464+         let  pos = self . next_inst_position ( ) ?; 
465+         self . set_position ( pos) ; 
466+         self . current_inst ( ) 
467+     } 
468+ 
469+     /// Get the position that a `cursor.prev_inst()` call would move this cursor 
470+      /// to, but do not update this cursor's position. 
471+      fn  prev_inst_position ( & self )  -> Option < CursorPosition >  { 
409472        use  self :: CursorPosition :: * ; 
410473        match  self . position ( )  { 
411-             Nowhere  | After ( ..)  => None , 
474+             Nowhere  | Before ( ..)  => None , 
412475            At ( inst)  => { 
413-                 if  let  Some ( next)  = self . layout ( ) . next_inst ( inst)  { 
414-                     self . set_position ( At ( next) ) ; 
415-                     Some ( next) 
476+                 if  let  Some ( prev)  = self . layout ( ) . prev_inst ( inst)  { 
477+                     Some ( At ( prev) ) 
416478                }  else  { 
417-                     let  pos =  After ( 
479+                     Some ( Before ( 
418480                        self . layout ( ) 
419481                            . inst_block ( inst) 
420482                            . expect ( "current instruction removed?" ) , 
421-                     ) ; 
422-                     self . set_position ( pos) ; 
423-                     None 
483+                     ) ) 
424484                } 
425485            } 
426-             Before ( block)  => { 
427-                 if  let  Some ( next)  = self . layout ( ) . first_inst ( block)  { 
428-                     self . set_position ( At ( next) ) ; 
429-                     Some ( next) 
486+             After ( block)  => { 
487+                 if  let  Some ( prev)  = self . layout ( ) . last_inst ( block)  { 
488+                     Some ( At ( prev) ) 
430489                }  else  { 
431-                     self . set_position ( After ( block) ) ; 
432-                     None 
490+                     Some ( Before ( block) ) 
433491                } 
434492            } 
435493        } 
@@ -460,33 +518,9 @@ pub trait Cursor {
460518     /// } 
461519     /// ``` 
462520     fn  prev_inst ( & mut  self )  -> Option < ir:: Inst >  { 
463-         use  self :: CursorPosition :: * ; 
464-         match  self . position ( )  { 
465-             Nowhere  | Before ( ..)  => None , 
466-             At ( inst)  => { 
467-                 if  let  Some ( prev)  = self . layout ( ) . prev_inst ( inst)  { 
468-                     self . set_position ( At ( prev) ) ; 
469-                     Some ( prev) 
470-                 }  else  { 
471-                     let  pos = Before ( 
472-                         self . layout ( ) 
473-                             . inst_block ( inst) 
474-                             . expect ( "current instruction removed?" ) , 
475-                     ) ; 
476-                     self . set_position ( pos) ; 
477-                     None 
478-                 } 
479-             } 
480-             After ( block)  => { 
481-                 if  let  Some ( prev)  = self . layout ( ) . last_inst ( block)  { 
482-                     self . set_position ( At ( prev) ) ; 
483-                     Some ( prev) 
484-                 }  else  { 
485-                     self . set_position ( Before ( block) ) ; 
486-                     None 
487-                 } 
488-             } 
489-         } 
521+         let  pos = self . prev_inst_position ( ) ?; 
522+         self . set_position ( pos) ; 
523+         self . current_inst ( ) 
490524    } 
491525
492526    /// Insert an instruction at the current position. 
0 commit comments