]> git.lizzy.rs Git - rust.git/commitdiff
Implement initernal lint LINT_PASS_IMPL_WITHOUT_MACRO
authorflip1995 <hello@philkrones.com>
Thu, 2 May 2019 14:53:12 +0000 (16:53 +0200)
committerflip1995 <hello@philkrones.com>
Mon, 24 Jun 2019 08:45:20 +0000 (10:45 +0200)
src/librustc/lint/context.rs
src/librustc/lint/internal.rs
src/librustc_lint/lib.rs
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs [new file with mode: 0644]
src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr [new file with mode: 0644]

index 7f09120bbdd5eac48618102eb20bafe5bb6f2509..7203dd9beaae452c2b093df881ebb16ec744b325 100644 (file)
@@ -1341,6 +1341,7 @@ struct LateLintPassObjects<'a> {
     lints: &'a mut [LateLintPassObject],
 }
 
+#[cfg_attr(not(stage0), allow(lint_pass_impl_without_macro))]
 impl LintPass for LateLintPassObjects<'_> {
     fn name(&self) -> &'static str {
         panic!()
@@ -1510,6 +1511,7 @@ struct EarlyLintPassObjects<'a> {
     lints: &'a mut [EarlyLintPassObject],
 }
 
+#[cfg_attr(not(stage0), allow(lint_pass_impl_without_macro))]
 impl LintPass for EarlyLintPassObjects<'_> {
     fn name(&self) -> &'static str {
         panic!()
index 86dae579ca753d859b3dc04a320a503b53f9e2c5..d3996c4e37a9fb146440a2c0f16598eadfdb3009 100644 (file)
@@ -7,7 +7,7 @@
 };
 use errors::Applicability;
 use rustc_data_structures::fx::FxHashMap;
-use syntax::ast::Ident;
+use syntax::ast::{Ident, Item, ItemKind};
 use syntax::symbol::{sym, Symbol};
 
 declare_lint! {
@@ -36,10 +36,7 @@ pub fn new() -> Self {
 impl EarlyLintPass for DefaultHashTypes {
     fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
         if let Some(replace) = self.map.get(&ident.name) {
-            let msg = format!(
-                "Prefer {} over {}, it has better performance",
-                replace, ident
-            );
+            let msg = format!("Prefer {} over {}, it has better performance", replace, ident);
             let mut db = cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, &msg);
             db.span_suggestion(
                 ident.span,
@@ -47,11 +44,8 @@ fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
                 replace.to_string(),
                 Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
             );
-            db.note(&format!(
-                "a `use rustc_data_structures::fx::{}` may be necessary",
-                replace
-            ))
-            .emit();
+            db.note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace))
+                .emit();
         }
     }
 }
@@ -137,13 +131,7 @@ fn check_ty(&mut self, cx: &LateContext<'_, '_>, ty: &'tcx Ty) {
                     }
                 }
             }
-            TyKind::Rptr(
-                _,
-                MutTy {
-                    ty: inner_ty,
-                    mutbl: Mutability::MutImmutable,
-                },
-            ) => {
+            TyKind::Rptr(_, MutTy { ty: inner_ty, mutbl: Mutability::MutImmutable }) => {
                 if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) {
                     if cx.tcx.impl_trait_ref(impl_did).is_some() {
                         return;
@@ -225,3 +213,31 @@ fn gen_args(segment: &PathSegment) -> String {
 
     String::new()
 }
+
+declare_lint! {
+    pub LINT_PASS_IMPL_WITHOUT_MACRO,
+    Allow,
+    "`impl LintPass` without the `declare_lint_pass!` or `impl_lint_pass!` macros"
+}
+
+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" {
+                        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();
+                    }
+                }
+            }
+        }
+    }
+}
index ec8a9c6fbb2a8639dc7539f6e469eccb3a0830af..8a5fde322b2a76e39edac08239ff8c5bffc6e112 100644 (file)
@@ -493,6 +493,7 @@ macro_rules! register_passes {
 
 pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
     store.register_early_pass(sess, false, false, box DefaultHashTypes::new());
+    store.register_early_pass(sess, false, false, box LintPassImpl);
     store.register_late_pass(sess, false, false, false, box TyTyKind);
     store.register_group(
         sess,
@@ -502,6 +503,7 @@ pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
         vec![
             LintId::of(DEFAULT_HASH_TYPES),
             LintId::of(USAGE_OF_TY_TYKIND),
+            LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
             LintId::of(TY_PASS_BY_REFERENCE),
             LintId::of(USAGE_OF_QUALIFIED_TY),
         ],
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
new file mode 100644 (file)
index 0000000..92f8e83
--- /dev/null
@@ -0,0 +1,35 @@
+// compile-flags: -Z unstable-options
+
+#![feature(rustc_private)]
+#![deny(lint_pass_impl_without_macro)]
+
+extern crate rustc;
+
+use rustc::lint::{LintArray, LintPass};
+use rustc::{declare_lint, declare_lint_pass, impl_lint_pass, lint_array};
+
+declare_lint! {
+    pub TEST_LINT,
+    Allow,
+    "test"
+}
+
+struct Foo;
+
+impl LintPass for Foo { //~ERROR implementing `LintPass` by hand
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT)
+    }
+
+    fn name(&self) -> &'static str {
+        "Foo"
+    }
+}
+
+struct Bar;
+
+impl_lint_pass!(Bar => [TEST_LINT]);
+
+declare_lint_pass!(Baz => [TEST_LINT]);
+
+fn main() {}
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
new file mode 100644 (file)
index 0000000..9ddd6af
--- /dev/null
@@ -0,0 +1,15 @@
+error: implementing `LintPass` by hand
+  --> $DIR/lint_pass_impl_without_macro.rs:19:6
+   |
+LL | impl LintPass for Foo {
+   |      ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint_pass_impl_without_macro.rs:4:9
+   |
+LL | #![deny(lint_pass_impl_without_macro)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead
+
+error: aborting due to previous error
+