]> git.lizzy.rs Git - rust.git/commitdiff
Only allow {declare,impl}_lint_pass macros for implementing LintPass
authorflip1995 <hello@philkrones.com>
Thu, 13 Jun 2019 13:49:33 +0000 (15:49 +0200)
committerflip1995 <hello@philkrones.com>
Mon, 24 Jun 2019 08:45:20 +0000 (10:45 +0200)
src/librustc/lint/internal.rs
src/libsyntax_pos/symbol.rs
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr

index d3996c4e37a9fb146440a2c0f16598eadfdb3009..9763801f0d9a8de599333b1952527994f0f76dd5 100644 (file)
@@ -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
+    }
+}
index 756bc8c29d8287b739ffe87528a64970f434ffd4..4b8535fa625b96aa80118e4ba1cba6304f49df41 100644 (file)
         custom_inner_attributes,
         custom_test_frameworks,
         c_variadic,
+        declare_lint_pass,
         decl_macro,
         Default,
         default_lib_allocator,
         if_while_or_patterns,
         ignore,
         impl_header_lifetime_elision,
+        impl_lint_pass,
         impl_trait_in_bindings,
         import_shadowing,
         index,
         link_llvm_intrinsics,
         link_name,
         link_section,
+        LintPass,
         lint_reasons,
         literal,
         local_inner_macros,
index 92f8e8364a77558cb4c32dcea546f8b166bc29de..89fa838768e8ef2febfcecfd72170389764792a3 100644 (file)
@@ -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]);
index 9ddd6af472a8b189ef9b41fabd7fe62bfc8516ce..a033b0a07e0065c57a9c1ca96a07e104351b4288 100644 (file)
@@ -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