@@ -54,36 +54,35 @@ declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);
54
54
55
55
impl LateLintPass < ' _ > for ItemsAfterStatements {
56
56
fn check_block ( & mut self , cx : & LateContext < ' _ > , block : & Block < ' _ > ) {
57
- if in_external_macro ( cx. sess ( ) , block. span ) {
58
- return ;
59
- }
60
-
61
- // skip initial items
62
- let stmts = block
63
- . stmts
64
- . iter ( )
65
- . skip_while ( |stmt| matches ! ( stmt. kind, StmtKind :: Item ( ..) ) ) ;
66
-
67
- // lint on all further items
68
- for stmt in stmts {
69
- if let StmtKind :: Item ( item_id) = stmt. kind {
70
- let item = cx. tcx . hir ( ) . item ( item_id) ;
71
- if in_external_macro ( cx. sess ( ) , item. span ) || !item. span . eq_ctxt ( block. span ) {
72
- return ;
73
- }
74
- if let ItemKind :: Macro ( ..) = item. kind {
75
- // do not lint `macro_rules`, but continue processing further statements
76
- continue ;
77
- }
78
- span_lint_hir (
79
- cx,
80
- ITEMS_AFTER_STATEMENTS ,
81
- item. hir_id ( ) ,
82
- item. span ,
83
- "adding items after statements is confusing, since items exist from the \
84
- start of the scope",
85
- ) ;
86
- }
57
+ if block. stmts . len ( ) > 1 {
58
+ let ctxt = block. span . ctxt ( ) ;
59
+ let mut in_external = None ;
60
+ block
61
+ . stmts
62
+ . iter ( )
63
+ . skip_while ( |stmt| matches ! ( stmt. kind, StmtKind :: Item ( ..) ) )
64
+ . filter_map ( |stmt| match stmt. kind {
65
+ StmtKind :: Item ( id) => Some ( cx. tcx . hir ( ) . item ( id) ) ,
66
+ _ => None ,
67
+ } )
68
+ // Ignore macros since they can only see previously defined locals.
69
+ . filter ( |item| !matches ! ( item. kind, ItemKind :: Macro ( ..) ) )
70
+ // Stop linting if macros define items.
71
+ . take_while ( |item| item. span . ctxt ( ) == ctxt)
72
+ // Don't use `next` due to the complex filter chain.
73
+ . for_each ( |item| {
74
+ // Only do the macro check once, but delay it until it's needed.
75
+ if !* in_external. get_or_insert_with ( || in_external_macro ( cx. sess ( ) , block. span ) ) {
76
+ span_lint_hir (
77
+ cx,
78
+ ITEMS_AFTER_STATEMENTS ,
79
+ item. hir_id ( ) ,
80
+ item. span ,
81
+ "adding items after statements is confusing, since items exist from the \
82
+ start of the scope",
83
+ ) ;
84
+ }
85
+ } ) ;
87
86
}
88
87
}
89
88
}
0 commit comments