refactor(needless_arbitrary_self_type): give suggestions with finer diffs
This commit is contained in:
parent
ee4390f070
commit
a4a88ea592
3 changed files with 109 additions and 69 deletions
|
|
@ -1,10 +1,9 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, Path, TyKind};
|
||||
use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Param, PatKind, TyKind};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::declare_lint_pass;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
@ -65,52 +64,6 @@ enum Mode {
|
|||
Value,
|
||||
}
|
||||
|
||||
fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mode: &Mode, mutbl: Mutability) {
|
||||
if let [segment] = &path.segments[..]
|
||||
&& segment.ident.name == kw::SelfUpper
|
||||
{
|
||||
// In case we have a named lifetime, we check if the name comes from expansion.
|
||||
// If it does, at this point we know the rest of the parameter was written by the user,
|
||||
// so let them decide what the name of the lifetime should be.
|
||||
// See #6089 for more details.
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let self_param = match (binding_mode, mutbl) {
|
||||
(Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(),
|
||||
(Mode::Ref(Some(lifetime)), Mutability::Mut) => {
|
||||
if lifetime.ident.span.from_expansion() {
|
||||
applicability = Applicability::HasPlaceholders;
|
||||
"&'_ mut self".to_string()
|
||||
} else {
|
||||
let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability);
|
||||
format!("&{lt_name} mut self")
|
||||
}
|
||||
},
|
||||
(Mode::Ref(None), Mutability::Not) => "&self".to_string(),
|
||||
(Mode::Ref(Some(lifetime)), Mutability::Not) => {
|
||||
if lifetime.ident.span.from_expansion() {
|
||||
applicability = Applicability::HasPlaceholders;
|
||||
"&'_ self".to_string()
|
||||
} else {
|
||||
let lt_name = snippet_with_applicability(cx, lifetime.ident.span, "..", &mut applicability);
|
||||
format!("&{lt_name} self")
|
||||
}
|
||||
},
|
||||
(Mode::Value, Mutability::Mut) => "mut self".to_string(),
|
||||
(Mode::Value, Mutability::Not) => "self".to_string(),
|
||||
};
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NEEDLESS_ARBITRARY_SELF_TYPE,
|
||||
span,
|
||||
"the type of the `self` parameter does not need to be arbitrary",
|
||||
"consider to change this parameter to",
|
||||
self_param,
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for NeedlessArbitrarySelfType {
|
||||
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
|
||||
// Bail out if the parameter it's not a receiver or was not written by the user
|
||||
|
|
@ -118,20 +71,55 @@ impl EarlyLintPass for NeedlessArbitrarySelfType {
|
|||
return;
|
||||
}
|
||||
|
||||
match &p.ty.kind {
|
||||
TyKind::Path(None, path) => {
|
||||
if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind {
|
||||
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Value, mutbl);
|
||||
}
|
||||
let (path, binding_mode, mutbl) = match &p.ty.kind {
|
||||
TyKind::Path(None, path) if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind => {
|
||||
(path, Mode::Value, mutbl)
|
||||
},
|
||||
TyKind::Ref(lifetime, mut_ty) => {
|
||||
TyKind::Ref(lifetime, mut_ty)
|
||||
if let TyKind::Path(None, path) = &mut_ty.ty.kind
|
||||
&& let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind
|
||||
{
|
||||
check_param_inner(cx, path, p.span.to(p.ty.span), &Mode::Ref(*lifetime), mut_ty.mutbl);
|
||||
}
|
||||
&& let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind =>
|
||||
{
|
||||
(path, Mode::Ref(*lifetime), mut_ty.mutbl)
|
||||
},
|
||||
_ => {},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let span = p.span.to(p.ty.span);
|
||||
if let [segment] = &path.segments[..]
|
||||
&& segment.ident.name == kw::SelfUpper
|
||||
{
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
NEEDLESS_ARBITRARY_SELF_TYPE,
|
||||
span,
|
||||
"the type of the `self` parameter does not need to be arbitrary",
|
||||
|diag| {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let add = match binding_mode {
|
||||
Mode::Value => String::new(),
|
||||
Mode::Ref(None) => mutbl.ref_prefix_str().to_string(),
|
||||
Mode::Ref(Some(lifetime)) => {
|
||||
// In case we have a named lifetime, we check if the name comes from expansion.
|
||||
// If it does, at this point we know the rest of the parameter was written by the user,
|
||||
// so let them decide what the name of the lifetime should be.
|
||||
// See #6089 for more details.
|
||||
let lt_name = if lifetime.ident.span.from_expansion() {
|
||||
applicability = Applicability::HasPlaceholders;
|
||||
"'_".into()
|
||||
} else {
|
||||
snippet_with_applicability(cx, lifetime.ident.span, "'_", &mut applicability)
|
||||
};
|
||||
format!("&{lt_name} {mut_}", mut_ = mutbl.prefix_str())
|
||||
},
|
||||
};
|
||||
|
||||
let mut sugg = vec![(p.ty.span.with_lo(p.span.hi()), String::new())];
|
||||
if !add.is_empty() {
|
||||
sugg.push((p.span.shrink_to_lo(), add));
|
||||
}
|
||||
diag.multipart_suggestion_verbose("remove the type", sugg, applicability);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,52 +2,99 @@ error: the type of the `self` parameter does not need to be arbitrary
|
|||
--> tests/ui/needless_arbitrary_self_type.rs:10:16
|
||||
|
|
||||
LL | pub fn bad(self: Self) {
|
||||
| ^^^^^^^^^^ help: consider to change this parameter to: `self`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn bad(self: Self) {
|
||||
LL + pub fn bad(self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:19:20
|
||||
|
|
||||
LL | pub fn mut_bad(mut self: Self) {
|
||||
| ^^^^^^^^^^^^^^ help: consider to change this parameter to: `mut self`
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn mut_bad(mut self: Self) {
|
||||
LL + pub fn mut_bad(mut self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:28:20
|
||||
|
|
||||
LL | pub fn ref_bad(self: &Self) {
|
||||
| ^^^^^^^^^^^ help: consider to change this parameter to: `&self`
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn ref_bad(self: &Self) {
|
||||
LL + pub fn ref_bad(&self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:37:38
|
||||
|
|
||||
LL | pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {
|
||||
| ^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a self`
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {
|
||||
LL + pub fn ref_bad_with_lifetime<'a>(&'a self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:46:24
|
||||
|
|
||||
LL | pub fn mut_ref_bad(self: &mut Self) {
|
||||
| ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self`
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn mut_ref_bad(self: &mut Self) {
|
||||
LL + pub fn mut_ref_bad(&mut self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:55:42
|
||||
|
|
||||
LL | pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {
|
||||
| ^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'a mut self`
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {
|
||||
LL + pub fn mut_ref_bad_with_lifetime<'a>(&'a mut self) {
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:74:11
|
||||
|
|
||||
LL | fn f1(self: &'r#struct Self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct self`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - fn f1(self: &'r#struct Self) {}
|
||||
LL + fn f1(&'r#struct self) {}
|
||||
|
|
||||
|
||||
error: the type of the `self` parameter does not need to be arbitrary
|
||||
--> tests/ui/needless_arbitrary_self_type.rs:76:11
|
||||
|
|
||||
LL | fn f2(self: &'r#struct mut Self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'r#struct mut self`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: remove the type
|
||||
|
|
||||
LL - fn f2(self: &'r#struct mut Self) {}
|
||||
LL + fn f2(&'r#struct mut self) {}
|
||||
|
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,15 @@ error: the type of the `self` parameter does not need to be arbitrary
|
|||
--> tests/ui/needless_arbitrary_self_type_unfixable.rs:42:31
|
||||
|
|
||||
LL | fn call_with_mut_self(self: &mut Self) {}
|
||||
| ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self`
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`
|
||||
help: remove the type
|
||||
|
|
||||
LL - fn call_with_mut_self(self: &mut Self) {}
|
||||
LL + fn call_with_mut_self(&mut self) {}
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue