@@ -36,10 +36,35 @@ pub fn walk_expr(expr: &ast::Expr, cb: &mut dyn FnMut(ast::Expr)) {
36
36
} )
37
37
}
38
38
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
+
39
56
/// Preorder walk all the expression's child expressions preserving events.
40
57
/// If the callback returns true on an [`WalkEvent::Enter`], the subtree of the expression will be skipped.
41
58
/// Note that the subtree may already be skipped due to the context analysis this function does.
42
59
pub 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
+ ) {
43
68
let mut preorder = start. syntax ( ) . preorder ( ) ;
44
69
while let Some ( event) = preorder. next ( ) {
45
70
let node = match event {
@@ -71,20 +96,7 @@ pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent<ast::Expr>)
71
96
if ast:: GenericArg :: can_cast ( node. kind ( ) ) {
72
97
preorder. skip_subtree ( ) ;
73
98
} 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 ( ) ;
88
100
let skip = cb ( WalkEvent :: Enter ( expr) ) ;
89
101
if skip || is_different_context {
90
102
preorder. skip_subtree ( ) ;
@@ -394,7 +406,7 @@ fn for_each_break_expr(
394
406
}
395
407
}
396
408
397
- fn eq_label_lt ( lt1 : & Option < ast:: Lifetime > , lt2 : & Option < ast:: Lifetime > ) -> bool {
409
+ pub fn eq_label_lt ( lt1 : & Option < ast:: Lifetime > , lt2 : & Option < ast:: Lifetime > ) -> bool {
398
410
lt1. as_ref ( ) . zip ( lt2. as_ref ( ) ) . map_or ( false , |( lt, lbl) | lt. text ( ) == lbl. text ( ) )
399
411
}
400
412
0 commit comments