Skip to content

Commit 37f09cb

Browse files
committed
Only allow {declare,impl}_lint_pass macros for implementing LintPass
1 parent 7d0a952 commit 37f09cb

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed

src/librustc/lint/internal.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use errors::Applicability;
99
use rustc_data_structures::fx::FxHashMap;
1010
use syntax::ast::{Ident, Item, ItemKind};
1111
use syntax::symbol::{sym, Symbol};
12+
use syntax_pos::ExpnInfo;
1213

1314
declare_lint! {
1415
pub DEFAULT_HASH_TYPES,
@@ -225,19 +226,32 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
225226
impl EarlyLintPass for LintPassImpl {
226227
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
227228
if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
228-
if !lint_pass.path.span.ctxt().outer_expn_info().is_some() {
229-
if let Some(last) = lint_pass.path.segments.last() {
230-
if last.ident.as_str() == "LintPass" {
231-
cx.struct_span_lint(
232-
LINT_PASS_IMPL_WITHOUT_MACRO,
233-
lint_pass.path.span,
234-
"implementing `LintPass` by hand",
235-
)
236-
.help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
237-
.emit();
229+
if let Some(last) = lint_pass.path.segments.last() {
230+
if last.ident.name == sym::LintPass {
231+
match &lint_pass.path.span.ctxt().outer_expn_info() {
232+
Some(info) if is_lint_pass_expansion(info) => {}
233+
_ => {
234+
cx.struct_span_lint(
235+
LINT_PASS_IMPL_WITHOUT_MACRO,
236+
lint_pass.path.span,
237+
"implementing `LintPass` by hand",
238+
)
239+
.help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
240+
.emit();
241+
}
238242
}
239243
}
240244
}
241245
}
242246
}
243247
}
248+
249+
fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
250+
if expn_info.format.name() == sym::impl_lint_pass {
251+
true
252+
} else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
253+
info.format.name() == sym::declare_lint_pass
254+
} else {
255+
false
256+
}
257+
}

src/libsyntax_pos/symbol.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ symbols! {
214214
custom_inner_attributes,
215215
custom_test_frameworks,
216216
c_variadic,
217+
declare_lint_pass,
217218
decl_macro,
218219
Default,
219220
default_lib_allocator,
@@ -324,6 +325,7 @@ symbols! {
324325
if_while_or_patterns,
325326
ignore,
326327
impl_header_lifetime_elision,
328+
impl_lint_pass,
327329
impl_trait_in_bindings,
328330
import_shadowing,
329331
index,
@@ -365,6 +367,7 @@ symbols! {
365367
link_llvm_intrinsics,
366368
link_name,
367369
link_section,
370+
LintPass,
368371
lint_reasons,
369372
literal,
370373
local_inner_macros,

src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ impl LintPass for Foo { //~ERROR implementing `LintPass` by hand
2626
}
2727
}
2828

29+
macro_rules! custom_lint_pass_macro {
30+
() => {
31+
struct Custom;
32+
33+
impl LintPass for Custom { //~ERROR implementing `LintPass` by hand
34+
fn get_lints(&self) -> LintArray {
35+
lint_array!(TEST_LINT)
36+
}
37+
38+
fn name(&self) -> &'static str {
39+
"Custom"
40+
}
41+
}
42+
};
43+
}
44+
45+
custom_lint_pass_macro!();
46+
2947
struct Bar;
3048

3149
impl_lint_pass!(Bar => [TEST_LINT]);

src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,16 @@ LL | #![deny(lint_pass_impl_without_macro)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
1313

14-
error: aborting due to previous error
14+
error: implementing `LintPass` by hand
15+
--> $DIR/lint_pass_impl_without_macro.rs:33:14
16+
|
17+
LL | impl LintPass for Custom {
18+
| ^^^^^^^^
19+
...
20+
LL | custom_lint_pass_macro!();
21+
| -------------------------- in this macro invocation
22+
|
23+
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
24+
25+
error: aborting due to 2 previous errors
1526

0 commit comments

Comments
 (0)