From: flip1995 Date: Thu, 13 Jun 2019 13:49:33 +0000 (+0200) Subject: Only allow {declare,impl}_lint_pass macros for implementing LintPass X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=37f09cb237ebbabdd6889d3c3d707075b8acc29d;p=rust.git Only allow {declare,impl}_lint_pass macros for implementing LintPass --- diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs index d3996c4e37a..9763801f0d9 100644 --- a/src/librustc/lint/internal.rs +++ b/src/librustc/lint/internal.rs @@ -9,6 +9,7 @@ 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,19 +226,32 @@ fn gen_args(segment: &PathSegment) -> String { 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" { - cx.struct_span_lint( - LINT_PASS_IMPL_WITHOUT_MACRO, - lint_pass.path.span, - "implementing `LintPass` by hand", - ) - .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead") - .emit(); + if let Some(last) = lint_pass.path.segments.last() { + 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, + "implementing `LintPass` by hand", + ) + .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead") + .emit(); + } } } } } } } + +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 + } +} diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 756bc8c29d8..4b8535fa625 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -214,6 +214,7 @@ custom_inner_attributes, custom_test_frameworks, c_variadic, + declare_lint_pass, decl_macro, Default, default_lib_allocator, @@ -324,6 +325,7 @@ if_while_or_patterns, ignore, impl_header_lifetime_elision, + impl_lint_pass, impl_trait_in_bindings, import_shadowing, index, @@ -365,6 +367,7 @@ link_llvm_intrinsics, link_name, link_section, + LintPass, lint_reasons, literal, local_inner_macros, diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index 92f8e8364a7..89fa838768e 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -26,6 +26,24 @@ fn name(&self) -> &'static str { } } +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]); diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index 9ddd6af472a..a033b0a07e0 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -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