Skip to content

Commit 32e2021

Browse files
committed
Lint items after statements in macro expansions
The items_after_statements lint was skipping all expansions. Instead we should still lint local macros. Fixes rust-lang#578
1 parent 0cba5e6 commit 32e2021

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

clippy_lints/src/items_after_statements.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use crate::utils::span_lint;
44
use rustc_ast::ast::{Block, ItemKind, StmtKind};
5-
use rustc_lint::{EarlyContext, EarlyLintPass};
5+
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
6+
use rustc_middle::lint::in_external_macro;
67
use rustc_session::{declare_lint_pass, declare_tool_lint};
78

89
declare_clippy_lint! {
@@ -53,7 +54,7 @@ declare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);
5354

5455
impl EarlyLintPass for ItemsAfterStatements {
5556
fn check_block(&mut self, cx: &EarlyContext<'_>, item: &Block) {
56-
if item.span.from_expansion() {
57+
if in_external_macro(cx.sess(), item.span) {
5758
return;
5859
}
5960

@@ -67,7 +68,7 @@ impl EarlyLintPass for ItemsAfterStatements {
6768
// lint on all further items
6869
for stmt in stmts {
6970
if let StmtKind::Item(ref it) = *stmt {
70-
if it.span.from_expansion() {
71+
if in_external_macro(cx.sess(), it.span) {
7172
return;
7273
}
7374
if let ItemKind::MacroDef(..) = it.kind {

tests/ui/item_after_statement.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ fn mac() {
2828
// do not lint this, because it needs to be after `a`
2929
macro_rules! b {
3030
() => {{
31-
a = 6
31+
a = 6;
32+
fn say_something() {
33+
println!("something");
34+
}
3235
}};
3336
}
3437
b!();

tests/ui/item_after_statement.stderr

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,18 @@ LL | | println!("foo");
1616
LL | | }
1717
| |_____^
1818

19-
error: aborting due to 2 previous errors
19+
error: adding items after statements is confusing, since items exist from the start of the scope
20+
--> $DIR/item_after_statement.rs:32:13
21+
|
22+
LL | / fn say_something() {
23+
LL | | println!("something");
24+
LL | | }
25+
| |_____________^
26+
...
27+
LL | b!();
28+
| ----- in this macro invocation
29+
|
30+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
31+
32+
error: aborting due to 3 previous errors
2033

0 commit comments

Comments
 (0)