Only allow {declare,impl}_lint_pass macros for implementing LintPass
This commit is contained in:
parent
7d0a952e46
commit
37f09cb237
4 changed files with 57 additions and 11 deletions
|
@ -9,6 +9,7 @@ use errors::Applicability;
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use syntax::ast::{Ident, Item, ItemKind};
|
||||
use syntax::symbol::{sym, Symbol};
|
||||
use syntax_pos::ExpnInfo;
|
||||
|
||||
declare_lint! {
|
||||
pub DEFAULT_HASH_TYPES,
|
||||
|
@ -225,9 +226,11 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
|
|||
impl EarlyLintPass for LintPassImpl {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
|
||||
if !lint_pass.path.span.ctxt().outer_expn_info().is_some() {
|
||||
if let Some(last) = lint_pass.path.segments.last() {
|
||||
if last.ident.as_str() == "LintPass" {
|
||||
if last.ident.name == sym::LintPass {
|
||||
match &lint_pass.path.span.ctxt().outer_expn_info() {
|
||||
Some(info) if is_lint_pass_expansion(info) => {}
|
||||
_ => {
|
||||
cx.struct_span_lint(
|
||||
LINT_PASS_IMPL_WITHOUT_MACRO,
|
||||
lint_pass.path.span,
|
||||
|
@ -240,4 +243,15 @@ impl EarlyLintPass for LintPassImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
|
||||
if expn_info.format.name() == sym::impl_lint_pass {
|
||||
true
|
||||
} else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
|
||||
info.format.name() == sym::declare_lint_pass
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -214,6 +214,7 @@ symbols! {
|
|||
custom_inner_attributes,
|
||||
custom_test_frameworks,
|
||||
c_variadic,
|
||||
declare_lint_pass,
|
||||
decl_macro,
|
||||
Default,
|
||||
default_lib_allocator,
|
||||
|
@ -324,6 +325,7 @@ symbols! {
|
|||
if_while_or_patterns,
|
||||
ignore,
|
||||
impl_header_lifetime_elision,
|
||||
impl_lint_pass,
|
||||
impl_trait_in_bindings,
|
||||
import_shadowing,
|
||||
index,
|
||||
|
@ -365,6 +367,7 @@ symbols! {
|
|||
link_llvm_intrinsics,
|
||||
link_name,
|
||||
link_section,
|
||||
LintPass,
|
||||
lint_reasons,
|
||||
literal,
|
||||
local_inner_macros,
|
||||
|
|
|
@ -26,6 +26,24 @@ impl LintPass for Foo { //~ERROR implementing `LintPass` by hand
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! custom_lint_pass_macro {
|
||||
() => {
|
||||
struct Custom;
|
||||
|
||||
impl LintPass for Custom { //~ERROR implementing `LintPass` by hand
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(TEST_LINT)
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Custom"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
custom_lint_pass_macro!();
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl_lint_pass!(Bar => [TEST_LINT]);
|
||||
|
|
|
@ -11,5 +11,16 @@ LL | #![deny(lint_pass_impl_without_macro)]
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
|
||||
error: aborting due to previous error
|
||||
error: implementing `LintPass` by hand
|
||||
--> $DIR/lint_pass_impl_without_macro.rs:33:14
|
||||
|
|
||||
LL | impl LintPass for Custom {
|
||||
| ^^^^^^^^
|
||||
...
|
||||
LL | custom_lint_pass_macro!();
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue