]> git.lizzy.rs Git - rust.git/commitdiff
Lint against `Self` as an arbitrary self type
authorChristoph Walcher <christoph-wa@gmx.de>
Tue, 4 Aug 2020 18:23:14 +0000 (20:23 +0200)
committerChristoph Walcher <christoph-wa@gmx.de>
Fri, 7 Aug 2020 16:08:51 +0000 (18:08 +0200)
Fixes #5861

CHANGELOG.md
clippy_lints/src/lib.rs
clippy_lints/src/needless_fn_self_type.rs [new file with mode: 0644]
clippy_lints/src/trait_bounds.rs
src/lintlist/mod.rs
tests/ui/needless_fn_self_type.rs [new file with mode: 0644]
tests/ui/needless_fn_self_type.stderr [new file with mode: 0644]

index bfe896d5efaf31d9ef529974655355d89e37671a..179ecee03da66f866d1ddb758ccef15842f619e2 100644 (file)
@@ -1622,6 +1622,7 @@ Released 2018-09-13
 [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
 [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
 [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
+[`needless_fn_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_fn_self_type
 [`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
 [`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
 [`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
index 81864340f1a531b0505972359ab234f96651ab06..80c85e70e898ccb666e43a7d586df3375a48a1bd 100644 (file)
@@ -254,6 +254,7 @@ macro_rules! declare_clippy_lint {
 mod needless_borrow;
 mod needless_borrowed_ref;
 mod needless_continue;
+mod needless_fn_self_type;
 mod needless_pass_by_value;
 mod needless_update;
 mod neg_cmp_op_on_partial_ord;
@@ -722,6 +723,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &needless_borrow::NEEDLESS_BORROW,
         &needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
         &needless_continue::NEEDLESS_CONTINUE,
+        &needless_fn_self_type::NEEDLESS_FN_SELF_TYPE,
         &needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
         &needless_update::NEEDLESS_UPDATE,
         &neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
@@ -1027,6 +1029,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
     store.register_early_pass(|| box precedence::Precedence);
     store.register_early_pass(|| box needless_continue::NeedlessContinue);
+    store.register_early_pass(|| box needless_fn_self_type::NeedlessFnSelfType);
     store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
     store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
     store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
@@ -1374,6 +1377,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&needless_bool::BOOL_COMPARISON),
         LintId::of(&needless_bool::NEEDLESS_BOOL),
         LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
+        LintId::of(&needless_fn_self_type::NEEDLESS_FN_SELF_TYPE),
         LintId::of(&needless_update::NEEDLESS_UPDATE),
         LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
         LintId::of(&neg_multiply::NEG_MULTIPLY),
@@ -1534,6 +1538,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
         LintId::of(&misc_early::REDUNDANT_PATTERN),
         LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
+        LintId::of(&needless_fn_self_type::NEEDLESS_FN_SELF_TYPE),
         LintId::of(&neg_multiply::NEG_MULTIPLY),
         LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
         LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
diff --git a/clippy_lints/src/needless_fn_self_type.rs b/clippy_lints/src/needless_fn_self_type.rs
new file mode 100644 (file)
index 0000000..050a034
--- /dev/null
@@ -0,0 +1,64 @@
+use crate::utils::span_lint_and_help;
+use if_chain::if_chain;
+use rustc_ast::ast::{Param, TyKind};
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// **What it does:** The lint checks for `self` fn fn parameters that explicitly
+    /// specify the `Self`-type explicitly
+    /// **Why is this bad?** Increases the amount and decreases the readability of code
+    ///
+    /// **Known problems:** None
+    ///
+    /// **Example:**
+    /// ```rust
+    /// impl ValType {
+    ///     pub fn bytes(self: Self) -> usize {
+    ///         match self {
+    ///             Self::I32 | Self::F32 => 4,
+    ///             Self::I64 | Self::F64 => 8,
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// Could be rewritten as
+    ///
+    /// ```rust
+    /// impl ValType {
+    ///     pub fn bytes(self) -> usize {
+    ///         match self {
+    ///             Self::I32 | Self::F32 => 4,
+    ///             Self::I64 | Self::F64 => 8,
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    pub NEEDLESS_FN_SELF_TYPE,
+    style,
+    "type of `self` parameter is already by default `Self`"
+}
+
+declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);
+
+impl EarlyLintPass for NeedlessFnSelfType {
+    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
+        if_chain! {
+            if p.is_self();
+            if let TyKind::Path(None, path) = &p.ty.kind;
+            if let Some(segment) = path.segments.first();
+            if segment.ident.as_str() == sym!(Self).as_str();
+            then {
+                span_lint_and_help(
+                    cx,
+                    NEEDLESS_FN_SELF_TYPE,
+                    p.ty.span,
+                    "the type of the `self` parameter is already by default `Self`",
+                    None,
+                    "consider removing the type specification",
+                );
+            }
+        }
+    }
+}
index 06631f89f27ddf5633f80b62ca095547c1c55bf7..d4acf8df46d8a5323d64613c38de7ef7abbb8dd1 100644 (file)
@@ -50,7 +50,7 @@
     /// fn func<T: Clone + Default>(arg: T) {}
     /// ```
     /// or
-    ///  ///
+    ///
     /// ```rust
     /// fn func<T>(arg: T) where T: Clone + Default {}
     /// ```
index b64c6e5440953afa3e97778eb436c547a17bec46..a20e410f79b17a2caf714a7d2b864a05239efd93 100644 (file)
         deprecation: None,
         module: "doc",
     },
+    Lint {
+        name: "needless_fn_self_type",
+        group: "style",
+        desc: "type of `self` parameter is already by default `Self`",
+        deprecation: None,
+        module: "needless_fn_self_type",
+    },
     Lint {
         name: "needless_lifetimes",
         group: "complexity",
diff --git a/tests/ui/needless_fn_self_type.rs b/tests/ui/needless_fn_self_type.rs
new file mode 100644 (file)
index 0000000..12bb845
--- /dev/null
@@ -0,0 +1,26 @@
+#![warn(clippy::style, clippy::needless_fn_self_type)]
+
+pub enum ValType {
+    I32,
+    I64,
+    F32,
+    F64,
+}
+
+impl ValType {
+    pub fn bytes_bad(self: Self) -> usize {
+        match self {
+            Self::I32 | Self::F32 => 4,
+            Self::I64 | Self::F64 => 8,
+        }
+    }
+
+    pub fn bytes_good(self) -> usize {
+        match self {
+            Self::I32 | Self::F32 => 4,
+            Self::I64 | Self::F64 => 8,
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/needless_fn_self_type.stderr b/tests/ui/needless_fn_self_type.stderr
new file mode 100644 (file)
index 0000000..703705c
--- /dev/null
@@ -0,0 +1,11 @@
+error: the type of the `self` parameter is already by default `Self`
+  --> $DIR/needless_fn_self_type.rs:11:28
+   |
+LL |     pub fn bytes_bad(self: Self) -> usize {
+   |                            ^^^^
+   |
+   = note: `-D clippy::needless-fn-self-type` implied by `-D warnings`
+   = help: consider removing the type specification
+
+error: aborting due to previous error
+