@@ -36,10 +36,35 @@ pub fn walk_expr(expr: &ast::Expr, cb: &mut dyn FnMut(ast::Expr)) {
3636 } )
3737}
3838
39+ pub fn is_closure_or_blk_with_modif ( expr : & ast:: Expr ) -> bool {
40+ match expr {
41+ ast:: Expr :: BlockExpr ( block_expr) => {
42+ matches ! (
43+ block_expr. modifier( ) ,
44+ Some (
45+ ast:: BlockModifier :: Async ( _)
46+ | ast:: BlockModifier :: Try ( _)
47+ | ast:: BlockModifier :: Const ( _)
48+ )
49+ )
50+ }
51+ ast:: Expr :: ClosureExpr ( _) => true ,
52+ _ => false ,
53+ }
54+ }
55+
3956/// Preorder walk all the expression's child expressions preserving events.
4057/// If the callback returns true on an [`WalkEvent::Enter`], the subtree of the expression will be skipped.
4158/// Note that the subtree may already be skipped due to the context analysis this function does.
4259pub fn preorder_expr ( start : & ast:: Expr , cb : & mut dyn FnMut ( WalkEvent < ast:: Expr > ) -> bool ) {
60+ preorder_expr_with_ctx_checker ( start, & is_closure_or_blk_with_modif, cb) ;
61+ }
62+
63+ pub fn preorder_expr_with_ctx_checker (
64+ start : & ast:: Expr ,
65+ check_ctx : & dyn Fn ( & ast:: Expr ) -> bool ,
66+ cb : & mut dyn FnMut ( WalkEvent < ast:: Expr > ) -> bool ,
67+ ) {
4368 let mut preorder = start. syntax ( ) . preorder ( ) ;
4469 while let Some ( event) = preorder. next ( ) {
4570 let node = match event {
@@ -71,20 +96,7 @@ pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent<ast::Expr>)
7196 if ast:: GenericArg :: can_cast ( node. kind ( ) ) {
7297 preorder. skip_subtree ( ) ;
7398 } else if let Some ( expr) = ast:: Expr :: cast ( node) {
74- let is_different_context = match & expr {
75- ast:: Expr :: BlockExpr ( block_expr) => {
76- matches ! (
77- block_expr. modifier( ) ,
78- Some (
79- ast:: BlockModifier :: Async ( _)
80- | ast:: BlockModifier :: Try ( _)
81- | ast:: BlockModifier :: Const ( _)
82- )
83- )
84- }
85- ast:: Expr :: ClosureExpr ( _) => true ,
86- _ => false ,
87- } && expr. syntax ( ) != start. syntax ( ) ;
99+ let is_different_context = check_ctx ( & expr) && expr. syntax ( ) != start. syntax ( ) ;
88100 let skip = cb ( WalkEvent :: Enter ( expr) ) ;
89101 if skip || is_different_context {
90102 preorder. skip_subtree ( ) ;
@@ -392,7 +404,7 @@ fn for_each_break_expr(
392404 }
393405}
394406
395- fn eq_label_lt ( lt1 : & Option < ast:: Lifetime > , lt2 : & Option < ast:: Lifetime > ) -> bool {
407+ pub fn eq_label_lt ( lt1 : & Option < ast:: Lifetime > , lt2 : & Option < ast:: Lifetime > ) -> bool {
396408 lt1. as_ref ( ) . zip ( lt2. as_ref ( ) ) . map_or ( false , |( lt, lbl) | lt. text ( ) == lbl. text ( ) )
397409}
398410
0 commit comments