Skip to content

Commit b34bf8b

Browse files
committed
Lint against Self as an arbitrary self type
Fixes rust-lang#5861
1 parent 8012178 commit b34bf8b

File tree

7 files changed

+115
-1
lines changed

7 files changed

+115
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,6 +1622,7 @@ Released 2018-09-13
16221622
[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
16231623
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
16241624
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
1625+
[`needless_fn_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_fn_self_type
16251626
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
16261627
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
16271628
[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop

clippy_lints/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ mod needless_bool;
254254
mod needless_borrow;
255255
mod needless_borrowed_ref;
256256
mod needless_continue;
257+
mod needless_fn_self_type;
257258
mod needless_pass_by_value;
258259
mod needless_update;
259260
mod neg_cmp_op_on_partial_ord;
@@ -721,6 +722,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
721722
&needless_borrow::NEEDLESS_BORROW,
722723
&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
723724
&needless_continue::NEEDLESS_CONTINUE,
725+
&needless_fn_self_type::NEEDLESS_FN_SELF_TYPE,
724726
&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
725727
&needless_update::NEEDLESS_UPDATE,
726728
&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
@@ -1025,6 +1027,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10251027
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
10261028
store.register_early_pass(|| box precedence::Precedence);
10271029
store.register_early_pass(|| box needless_continue::NeedlessContinue);
1030+
store.register_early_pass(|| box needless_fn_self_type::NeedlessFnSelfType);
10281031
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
10291032
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
10301033
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
@@ -1371,6 +1374,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13711374
LintId::of(&needless_bool::BOOL_COMPARISON),
13721375
LintId::of(&needless_bool::NEEDLESS_BOOL),
13731376
LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
1377+
LintId::of(&needless_fn_self_type::NEEDLESS_FN_SELF_TYPE),
13741378
LintId::of(&needless_update::NEEDLESS_UPDATE),
13751379
LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
13761380
LintId::of(&neg_multiply::NEG_MULTIPLY),
@@ -1530,6 +1534,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15301534
LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
15311535
LintId::of(&misc_early::REDUNDANT_PATTERN),
15321536
LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
1537+
LintId::of(&needless_fn_self_type::NEEDLESS_FN_SELF_TYPE),
15331538
LintId::of(&neg_multiply::NEG_MULTIPLY),
15341539
LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
15351540
LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use crate::utils::span_lint_and_help;
2+
use if_chain::if_chain;
3+
use rustc_ast::ast::{Param, TyKind};
4+
use rustc_lint::{EarlyContext, EarlyLintPass};
5+
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** The lint checks for `self` fn fn parameters that explicitly
9+
/// specify the `Self`-type explicitly
10+
/// **Why is this bad?** Increases the amount and decreases the readability of code
11+
///
12+
/// **Known problems:** None
13+
///
14+
/// **Example:**
15+
/// ```rust
16+
/// impl ValType {
17+
/// pub fn bytes(self: Self) -> usize {
18+
/// match self {
19+
/// Self::I32 | Self::F32 => 4,
20+
/// Self::I64 | Self::F64 => 8,
21+
/// }
22+
/// }
23+
/// }
24+
/// ```
25+
///
26+
/// Could be rewritten as
27+
///
28+
/// ```rust
29+
/// impl ValType {
30+
/// pub fn bytes(self) -> usize {
31+
/// match self {
32+
/// Self::I32 | Self::F32 => 4,
33+
/// Self::I64 | Self::F64 => 8,
34+
/// }
35+
/// }
36+
/// }
37+
/// ```
38+
pub NEEDLESS_FN_SELF_TYPE,
39+
style,
40+
"type of `self` parameter is already by default `Self`"
41+
}
42+
43+
declare_lint_pass!(NeedlessFnSelfType => [NEEDLESS_FN_SELF_TYPE]);
44+
45+
impl EarlyLintPass for NeedlessFnSelfType {
46+
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
47+
if_chain! {
48+
if p.is_self();
49+
if let TyKind::Path(None, path) = &p.ty.kind;
50+
if let Some(segment) = path.segments.first();
51+
if segment.ident.as_str() == sym!(Self).as_str();
52+
then {
53+
span_lint_and_help(
54+
cx,
55+
NEEDLESS_FN_SELF_TYPE,
56+
p.ty.span,
57+
"the type of the `self` parameter is already by default `Self`",
58+
None,
59+
"consider removing the type specification",
60+
);
61+
}
62+
}
63+
}
64+
}

clippy_lints/src/trait_bounds.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ declare_clippy_lint! {
5050
/// fn func<T: Clone + Default>(arg: T) {}
5151
/// ```
5252
/// or
53-
/// ///
53+
///
5454
/// ```rust
5555
/// fn func<T>(arg: T) where T: Clone + Default {}
5656
/// ```

src/lintlist/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
15011501
deprecation: None,
15021502
module: "doc",
15031503
},
1504+
Lint {
1505+
name: "needless_fn_self_type",
1506+
group: "style",
1507+
desc: "type of `self` parameter is already by default `Self`",
1508+
deprecation: None,
1509+
module: "needless_fn_self_type",
1510+
},
15041511
Lint {
15051512
name: "needless_lifetimes",
15061513
group: "complexity",

tests/ui/needless_fn_self_type.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![warn(clippy::style, clippy::needless_fn_self_type)]
2+
3+
pub enum ValType {
4+
I32,
5+
I64,
6+
F32,
7+
F64,
8+
}
9+
10+
impl ValType {
11+
pub fn bytes_bad(self: Self) -> usize {
12+
match self {
13+
Self::I32 | Self::F32 => 4,
14+
Self::I64 | Self::F64 => 8,
15+
}
16+
}
17+
18+
pub fn bytes_good(self) -> usize {
19+
match self {
20+
Self::I32 | Self::F32 => 4,
21+
Self::I64 | Self::F64 => 8,
22+
}
23+
}
24+
}
25+
26+
fn main() {}

tests/ui/needless_fn_self_type.stderr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: the type of the `self` parameter is already by default `Self`
2+
--> $DIR/needless_fn_self_type.rs:11:28
3+
|
4+
LL | pub fn bytes_bad(self: Self) -> usize {
5+
| ^^^^
6+
|
7+
= note: `-D clippy::needless-fn-self-type` implied by `-D warnings`
8+
= help: consider removing the type specification
9+
10+
error: aborting due to previous error
11+

0 commit comments

Comments
 (0)