about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Ayoup <chris@achris.net>2020-10-14 23:49:48 -0400
committerChris Ayoup <chris@achris.net>2020-10-14 23:49:48 -0400
commit32e2021b75f5bb5c83bf753de76ec9ed499d12cc (patch)
tree835742111a844d27653cfa84a5fbfc912636df86
parent0cba5e6bd38a5acede81a09795a00bb8ec1ad3f9 (diff)
downloadrust-32e2021b75f5bb5c83bf753de76ec9ed499d12cc.tar.gz
rust-32e2021b75f5bb5c83bf753de76ec9ed499d12cc.zip
Lint items after statements in macro expansions
The items_after_statements lint was skipping all expansions.  Instead
we should still lint local macros.

Fixes #578
-rw-r--r--clippy_lints/src/items_after_statements.rs7
-rw-r--r--tests/ui/item_after_statement.rs5
-rw-r--r--tests/ui/item_after_statement.stderr15
3 files changed, 22 insertions, 5 deletions
diff --git a/clippy_lints/src/items_after_statements.rs b/clippy_lints/src/items_after_statements.rs
index c8576bcfcb4..8998fae09de 100644
--- a/clippy_lints/src/items_after_statements.rs
+++ b/clippy_lints/src/items_after_statements.rs
@@ -2,7 +2,8 @@
 
 use crate::utils::span_lint;
 use rustc_ast::ast::{Block, ItemKind, StmtKind};
-use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
@@ -53,7 +54,7 @@ declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);
 
 impl EarlyLintPass for ItemsAfterStatements {
     fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) {
-        if item.span.from_expansion() {
+        if in_external_macro(cx.sess(), item.span) {
             return;
         }
 
@@ -67,7 +68,7 @@ impl EarlyLintPass for ItemsAfterStatements {
         // lint on all further items
         for stmt in stmts {
             if let StmtKind::Item(ref it) = *stmt {
-                if it.span.from_expansion() {
+                if in_external_macro(cx.sess(), it.span) {
                     return;
                 }
                 if let ItemKind::MacroDef(..) = it.kind {
diff --git a/tests/ui/item_after_statement.rs b/tests/ui/item_after_statement.rs
index c17a7cbc8d9..377e58e4417 100644
--- a/tests/ui/item_after_statement.rs
+++ b/tests/ui/item_after_statement.rs
@@ -28,7 +28,10 @@ fn mac() {
     // do not lint this, because it needs to be after `a`
     macro_rules! b {
         () => {{
-            a = 6
+            a = 6;
+            fn say_something() {
+                println!("something");
+            }
         }};
     }
     b!();
diff --git a/tests/ui/item_after_statement.stderr b/tests/ui/item_after_statement.stderr
index f8f010b5e5c..68a3c81b6a8 100644
--- a/tests/ui/item_after_statement.stderr
+++ b/tests/ui/item_after_statement.stderr
@@ -16,5 +16,18 @@ LL | |         println!("foo");
 LL | |     }
    | |_____^
 
-error: aborting due to 2 previous errors
+error: adding items after statements is confusing, since items exist from the start of the scope
+  --> $DIR/item_after_statement.rs:32:13
+   |
+LL | /             fn say_something() {
+LL | |                 println!("something");
+LL | |             }
+   | |_____________^
+...
+LL |       b!();
+   |       ----- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors