about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/items_after_statements.rs31
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--tests/ui/items_after_statement.rs (renamed from tests/ui/item_after_statement.rs)17
-rw-r--r--tests/ui/items_after_statement.stderr (renamed from tests/ui/item_after_statement.stderr)6
4 files changed, 37 insertions, 19 deletions
diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs
index 46d439b4497..a7ec57e2850 100644
--- a/clippy_lints/src/items_after_statements.rs
+++ b/clippy_lints/src/items_after_statements.rs
@@ -1,8 +1,8 @@
 //! lint when items are used after statements
 
-use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast::{Block, ItemKind, StmtKind};
-use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use clippy_utils::diagnostics::span_lint_hir;
+use rustc_hir::{Block, ItemKind, StmtKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
@@ -52,33 +52,34 @@ declare_clippy_lint! {
 
 declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);
 
-impl EarlyLintPass for ItemsAfterStatements {
-    fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) {
-        if in_external_macro(cx.sess(), item.span) {
+impl LateLintPass<'_> for ItemsAfterStatements {
+    fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {
+        if in_external_macro(cx.sess(), block.span) {
             return;
         }
 
-        // skip initial items and trailing semicolons
-        let stmts = item
+        // skip initial items
+        let stmts = block
             .stmts
             .iter()
-            .map(|stmt| &stmt.kind)
-            .skip_while(|s| matches!(**s, StmtKind::Item(..) | StmtKind::Empty));
+            .skip_while(|stmt| matches!(stmt.kind, StmtKind::Item(..)));
 
         // lint on all further items
         for stmt in stmts {
-            if let StmtKind::Item(ref it) = *stmt {
-                if in_external_macro(cx.sess(), it.span) {
+            if let StmtKind::Item(item_id) = stmt.kind {
+                let item = cx.tcx.hir().item(item_id);
+                if in_external_macro(cx.sess(), item.span) || !item.span.eq_ctxt(block.span) {
                     return;
                 }
-                if let ItemKind::MacroDef(..) = it.kind {
+                if let ItemKind::Macro(..) = item.kind {
                     // do not lint `macro_rules`, but continue processing further statements
                     continue;
                 }
-                span_lint(
+                span_lint_hir(
                     cx,
                     ITEMS_AFTER_STATEMENTS,
-                    it.span,
+                    item.hir_id(),
+                    item.span,
                     "adding items after statements is confusing, since items exist from the \
                      start of the scope",
                 );
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index c9210bf73f8..f6cea7e2daf 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -747,7 +747,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(|| Box::new(unused_unit::UnusedUnit));
     store.register_late_pass(|_| Box::new(returns::Return));
     store.register_early_pass(|| Box::new(collapsible_if::CollapsibleIf));
-    store.register_early_pass(|| Box::new(items_after_statements::ItemsAfterStatements));
+    store.register_late_pass(|_| Box::new(items_after_statements::ItemsAfterStatements));
     store.register_early_pass(|| Box::new(precedence::Precedence));
     store.register_late_pass(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals));
     store.register_early_pass(|| Box::new(needless_continue::NeedlessContinue));
diff --git a/tests/ui/item_after_statement.rs b/tests/ui/items_after_statement.rs
index 5e92dcab1f5..f12cb8f22e2 100644
--- a/tests/ui/item_after_statement.rs
+++ b/tests/ui/items_after_statement.rs
@@ -51,3 +51,20 @@ fn semicolon() {
 
     let _ = S::new(3);
 }
+
+fn item_from_macro() {
+    macro_rules! static_assert_size {
+        ($ty:ty, $size:expr) => {
+            const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
+        };
+    }
+
+    let _ = 1;
+    static_assert_size!(u32, 4);
+}
+
+fn allow_attribute() {
+    let _ = 1;
+    #[allow(clippy::items_after_statements)]
+    const _: usize = 1;
+}
diff --git a/tests/ui/item_after_statement.stderr b/tests/ui/items_after_statement.stderr
index 2523c53ac53..f69635a977b 100644
--- a/tests/ui/item_after_statement.stderr
+++ b/tests/ui/items_after_statement.stderr
@@ -1,5 +1,5 @@
 error: adding items after statements is confusing, since items exist from the start of the scope
-  --> $DIR/item_after_statement.rs:13:5
+  --> $DIR/items_after_statement.rs:13:5
    |
 LL | /     fn foo() {
 LL | |         println!("foo");
@@ -9,7 +9,7 @@ LL | |     }
    = note: `-D clippy::items-after-statements` implied by `-D warnings`
 
 error: adding items after statements is confusing, since items exist from the start of the scope
-  --> $DIR/item_after_statement.rs:20:5
+  --> $DIR/items_after_statement.rs:20:5
    |
 LL | /     fn foo() {
 LL | |         println!("foo");
@@ -17,7 +17,7 @@ LL | |     }
    | |_____^
 
 error: adding items after statements is confusing, since items exist from the start of the scope
-  --> $DIR/item_after_statement.rs:33:13
+  --> $DIR/items_after_statement.rs:33:13
    |
 LL | /             fn say_something() {
 LL | |                 println!("something");