Skip to content

Commit 8ee57ee

Browse files
authored
Rollup merge of rust-lang#5869 - wiomoc:feature/implicit-self, r=ebroto,flip1995
New lint against `Self` as an arbitrary self type Fixes rust-lang#5861 changelog: * [`needless_arbitrary_self_type`] [rust-lang#5869](rust-lang/rust-clippy#5869)
2 parents 9da5b6d + bfe610c commit 8ee57ee

18 files changed

+373
-58
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ Released 2018-09-13
16161616
[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic
16171617
[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
16181618
[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount
1619+
[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
16191620
[`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool
16201621
[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
16211622
[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference

clippy_lints/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ mod mut_mut;
250250
mod mut_reference;
251251
mod mutable_debug_assertion;
252252
mod mutex_atomic;
253+
mod needless_arbitrary_self_type;
253254
mod needless_bool;
254255
mod needless_borrow;
255256
mod needless_borrowed_ref;
@@ -718,6 +719,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
718719
&mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
719720
&mutex_atomic::MUTEX_ATOMIC,
720721
&mutex_atomic::MUTEX_INTEGER,
722+
&needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
721723
&needless_bool::BOOL_COMPARISON,
722724
&needless_bool::NEEDLESS_BOOL,
723725
&needless_borrow::NEEDLESS_BORROW,
@@ -1028,6 +1030,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10281030
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
10291031
store.register_early_pass(|| box precedence::Precedence);
10301032
store.register_early_pass(|| box needless_continue::NeedlessContinue);
1033+
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
10311034
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
10321035
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
10331036
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
@@ -1373,6 +1376,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
13731376
LintId::of(&mut_key::MUTABLE_KEY_TYPE),
13741377
LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
13751378
LintId::of(&mutex_atomic::MUTEX_ATOMIC),
1379+
LintId::of(&needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
13761380
LintId::of(&needless_bool::BOOL_COMPARISON),
13771381
LintId::of(&needless_bool::NEEDLESS_BOOL),
13781382
LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
@@ -1605,6 +1609,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16051609
LintId::of(&misc::SHORT_CIRCUIT_STATEMENT),
16061610
LintId::of(&misc_early::UNNEEDED_WILDCARD_PATTERN),
16071611
LintId::of(&misc_early::ZERO_PREFIXED_LITERAL),
1612+
LintId::of(&needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
16081613
LintId::of(&needless_bool::BOOL_COMPARISON),
16091614
LintId::of(&needless_bool::NEEDLESS_BOOL),
16101615
LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use crate::utils::span_lint_and_sugg;
2+
use if_chain::if_chain;
3+
use rustc_ast::ast::{BindingMode, Lifetime, Mutability, Param, PatKind, Path, TyKind};
4+
use rustc_errors::Applicability;
5+
use rustc_lint::{EarlyContext, EarlyLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
use rustc_span::symbol::kw;
8+
use rustc_span::Span;
9+
10+
declare_clippy_lint! {
11+
/// **What it does:** The lint checks for `self` in fn parameters that
12+
/// specify the `Self`-type explicitly
13+
/// **Why is this bad?** Increases the amount and decreases the readability of code
14+
///
15+
/// **Known problems:** None
16+
///
17+
/// **Example:**
18+
/// ```rust
19+
/// enum ValType {
20+
/// I32,
21+
/// I64,
22+
/// F32,
23+
/// F64,
24+
/// }
25+
///
26+
/// impl ValType {
27+
/// pub fn bytes(self: Self) -> usize {
28+
/// match self {
29+
/// Self::I32 | Self::F32 => 4,
30+
/// Self::I64 | Self::F64 => 8,
31+
/// }
32+
/// }
33+
/// }
34+
/// ```
35+
///
36+
/// Could be rewritten as
37+
///
38+
/// ```rust
39+
/// enum ValType {
40+
/// I32,
41+
/// I64,
42+
/// F32,
43+
/// F64,
44+
/// }
45+
///
46+
/// impl ValType {
47+
/// pub fn bytes(self) -> usize {
48+
/// match self {
49+
/// Self::I32 | Self::F32 => 4,
50+
/// Self::I64 | Self::F64 => 8,
51+
/// }
52+
/// }
53+
/// }
54+
/// ```
55+
pub NEEDLESS_ARBITRARY_SELF_TYPE,
56+
complexity,
57+
"type of `self` parameter is already by default `Self`"
58+
}
59+
60+
declare_lint_pass!(NeedlessArbitrarySelfType => [NEEDLESS_ARBITRARY_SELF_TYPE]);
61+
62+
enum Mode {
63+
Ref(Option<Lifetime>),
64+
Value,
65+
}
66+
67+
fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mode: &Mode, mutbl: Mutability) {
68+
if_chain! {
69+
if let [segment] = &path.segments[..];
70+
if segment.ident.name == kw::SelfUpper;
71+
then {
72+
let self_param = match (binding_mode, mutbl) {
73+
(Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(),
74+
(Mode::Ref(Some(lifetime)), Mutability::Mut) => format!("&{} mut self", &lifetime.ident.name),
75+
(Mode::Ref(None), Mutability::Not) => "&self".to_string(),
76+
(Mode::Ref(Some(lifetime)), Mutability::Not) => format!("&{} self", &lifetime.ident.name),
77+
(Mode::Value, Mutability::Mut) => "mut self".to_string(),
78+
(Mode::Value, Mutability::Not) => "self".to_string(),
79+
};
80+
81+
span_lint_and_sugg(
82+
cx,
83+
NEEDLESS_ARBITRARY_SELF_TYPE,
84+
span,
85+
"the type of the `self` parameter does not need to be arbitrary",
86+
"consider to change this parameter to",
87+
self_param,
88+
Applicability::MachineApplicable,
89+
)
90+
}
91+
}
92+
}
93+
94+
impl EarlyLintPass for NeedlessArbitrarySelfType {
95+
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
96+
if !p.is_self() {
97+
return;
98+
}
99+
100+
match &p.ty.kind {
101+
TyKind::Path(None, path) => {
102+
if let PatKind::Ident(BindingMode::ByValue(mutbl), _, _) = p.pat.kind {
103+
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl)
104+
}
105+
},
106+
TyKind::Rptr(lifetime, mut_ty) => {
107+
if_chain! {
108+
if let TyKind::Path(None, path) = &mut_ty.ty.kind;
109+
if let PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, _) = p.pat.kind;
110+
then {
111+
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl)
112+
}
113+
}
114+
},
115+
_ => {},
116+
}
117+
}
118+
}

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
@@ -1459,6 +1459,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
14591459
deprecation: None,
14601460
module: "bytecount",
14611461
},
1462+
Lint {
1463+
name: "needless_arbitrary_self_type",
1464+
group: "complexity",
1465+
desc: "type of `self` parameter is already by default `Self`",
1466+
deprecation: None,
1467+
module: "needless_arbitrary_self_type",
1468+
},
14621469
Lint {
14631470
name: "needless_bool",
14641471
group: "complexity",

tests/ui/extra_unused_lifetimes.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
#![allow(unused, dead_code, clippy::needless_lifetimes, clippy::needless_pass_by_value)]
1+
#![allow(
2+
unused,
3+
dead_code,
4+
clippy::needless_lifetimes,
5+
clippy::needless_pass_by_value,
6+
clippy::needless_arbitrary_self_type
7+
)]
28
#![warn(clippy::extra_unused_lifetimes)]
39

410
fn empty() {}

tests/ui/extra_unused_lifetimes.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
error: this lifetime isn't used in the function definition
2-
--> $DIR/extra_unused_lifetimes.rs:8:14
2+
--> $DIR/extra_unused_lifetimes.rs:14:14
33
|
44
LL | fn unused_lt<'a>(x: u8) {}
55
| ^^
66
|
77
= note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings`
88

99
error: this lifetime isn't used in the function definition
10-
--> $DIR/extra_unused_lifetimes.rs:10:25
10+
--> $DIR/extra_unused_lifetimes.rs:16:25
1111
|
1212
LL | fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) {
1313
| ^^
1414

1515
error: this lifetime isn't used in the function definition
16-
--> $DIR/extra_unused_lifetimes.rs:35:10
16+
--> $DIR/extra_unused_lifetimes.rs:41:10
1717
|
1818
LL | fn x<'a>(&self) {}
1919
| ^^
2020

2121
error: this lifetime isn't used in the function definition
22-
--> $DIR/extra_unused_lifetimes.rs:61:22
22+
--> $DIR/extra_unused_lifetimes.rs:67:22
2323
|
2424
LL | fn unused_lt<'a>(x: u8) {}
2525
| ^^

tests/ui/len_without_is_empty.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
pub struct PubOne;
55

66
impl PubOne {
7-
pub fn len(self: &Self) -> isize {
7+
pub fn len(&self) -> isize {
88
1
99
}
1010
}
1111

1212
impl PubOne {
1313
// A second impl for this struct -- the error span shouldn't mention this.
14-
pub fn irrelevant(self: &Self) -> bool {
14+
pub fn irrelevant(&self) -> bool {
1515
false
1616
}
1717
}
@@ -21,57 +21,57 @@ pub struct PubAllowed;
2121

2222
#[allow(clippy::len_without_is_empty)]
2323
impl PubAllowed {
24-
pub fn len(self: &Self) -> isize {
24+
pub fn len(&self) -> isize {
2525
1
2626
}
2727
}
2828

2929
// No `allow` attribute on this impl block, but that doesn't matter -- we only require one on the
3030
// impl containing `len`.
3131
impl PubAllowed {
32-
pub fn irrelevant(self: &Self) -> bool {
32+
pub fn irrelevant(&self) -> bool {
3333
false
3434
}
3535
}
3636

3737
pub trait PubTraitsToo {
38-
fn len(self: &Self) -> isize;
38+
fn len(&self) -> isize;
3939
}
4040

4141
impl PubTraitsToo for One {
42-
fn len(self: &Self) -> isize {
42+
fn len(&self) -> isize {
4343
0
4444
}
4545
}
4646

4747
pub struct HasIsEmpty;
4848

4949
impl HasIsEmpty {
50-
pub fn len(self: &Self) -> isize {
50+
pub fn len(&self) -> isize {
5151
1
5252
}
5353

54-
fn is_empty(self: &Self) -> bool {
54+
fn is_empty(&self) -> bool {
5555
false
5656
}
5757
}
5858

5959
pub struct HasWrongIsEmpty;
6060

6161
impl HasWrongIsEmpty {
62-
pub fn len(self: &Self) -> isize {
62+
pub fn len(&self) -> isize {
6363
1
6464
}
6565

66-
pub fn is_empty(self: &Self, x: u32) -> bool {
66+
pub fn is_empty(&self, x: u32) -> bool {
6767
false
6868
}
6969
}
7070

7171
struct NotPubOne;
7272

7373
impl NotPubOne {
74-
pub fn len(self: &Self) -> isize {
74+
pub fn len(&self) -> isize {
7575
// No error; `len` is pub but `NotPubOne` is not exported anyway.
7676
1
7777
}
@@ -80,48 +80,48 @@ impl NotPubOne {
8080
struct One;
8181

8282
impl One {
83-
fn len(self: &Self) -> isize {
83+
fn len(&self) -> isize {
8484
// No error; `len` is private; see issue #1085.
8585
1
8686
}
8787
}
8888

8989
trait TraitsToo {
90-
fn len(self: &Self) -> isize;
90+
fn len(&self) -> isize;
9191
// No error; `len` is private; see issue #1085.
9292
}
9393

9494
impl TraitsToo for One {
95-
fn len(self: &Self) -> isize {
95+
fn len(&self) -> isize {
9696
0
9797
}
9898
}
9999

100100
struct HasPrivateIsEmpty;
101101

102102
impl HasPrivateIsEmpty {
103-
pub fn len(self: &Self) -> isize {
103+
pub fn len(&self) -> isize {
104104
1
105105
}
106106

107-
fn is_empty(self: &Self) -> bool {
107+
fn is_empty(&self) -> bool {
108108
false
109109
}
110110
}
111111

112112
struct Wither;
113113

114114
pub trait WithIsEmpty {
115-
fn len(self: &Self) -> isize;
116-
fn is_empty(self: &Self) -> bool;
115+
fn len(&self) -> isize;
116+
fn is_empty(&self) -> bool;
117117
}
118118

119119
impl WithIsEmpty for Wither {
120-
fn len(self: &Self) -> isize {
120+
fn len(&self) -> isize {
121121
1
122122
}
123123

124-
fn is_empty(self: &Self) -> bool {
124+
fn is_empty(&self) -> bool {
125125
false
126126
}
127127
}

0 commit comments

Comments
 (0)