-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add new lint that disallow renaming parameters in trait functions
- Loading branch information
Showing
6 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
use clippy_utils::diagnostics::span_lint_and_help; | ||
use rustc_hir::def_id::DefId; | ||
use rustc_hir::hir_id::OwnerId; | ||
use rustc_hir::{ImplItem, ImplItemKind, ItemKind, Node}; | ||
use rustc_lint::LateContext; | ||
use rustc_span::symbol::{Ident, Symbol}; | ||
use rustc_span::Span; | ||
|
||
use super::RENAMED_FUNCTION_PARAMS; | ||
|
||
pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>) { | ||
if let ImplItemKind::Fn(_, body_id) = item.kind && | ||
let Some(did) = impled_item_def_id(cx, item.owner_id) | ||
{ | ||
let mut param_idents_iter = cx.tcx.hir().body_param_names(body_id); | ||
let mut default_param_idents_iter = cx.tcx.fn_arg_names(did).iter().copied(); | ||
|
||
let renames = renamed_params(&mut default_param_idents_iter, &mut param_idents_iter); | ||
// FIXME: Should we use `MultiSpan` to combine output together? | ||
// But how should we display help message if so. | ||
for rename in renames { | ||
span_lint_and_help( | ||
cx, | ||
RENAMED_FUNCTION_PARAMS, | ||
rename.renamed_span, | ||
"function parameter name was renamed from its trait default", | ||
None, | ||
&format!("consider changing the name to: '{}'", rename.default_name.as_str()) | ||
); | ||
} | ||
} | ||
} | ||
|
||
struct RenamedParam { | ||
renamed_span: Span, | ||
default_name: Symbol, | ||
} | ||
|
||
fn renamed_params<I, T>(default_names: &mut I, current_names: &mut T) -> Vec<RenamedParam> | ||
where | ||
I: Iterator<Item = Ident>, | ||
T: Iterator<Item = Ident>, | ||
{ | ||
let mut renamed = vec![]; | ||
// FIXME: Should we stop if they have different length? | ||
while let (Some(def_name), Some(cur_name)) = (default_names.next(), current_names.next()) { | ||
let current_name = cur_name.name; | ||
let default_name = def_name.name; | ||
if is_ignored_or_empty_symbol(current_name) || is_ignored_or_empty_symbol(default_name) { | ||
continue; | ||
} | ||
if current_name != default_name { | ||
renamed.push(RenamedParam { | ||
renamed_span: cur_name.span, | ||
default_name, | ||
}); | ||
} | ||
} | ||
renamed | ||
} | ||
|
||
fn is_ignored_or_empty_symbol(symbol: Symbol) -> bool { | ||
let s = symbol.as_str(); | ||
s.is_empty() || s.starts_with('_') | ||
} | ||
|
||
fn impled_item_def_id(cx: &LateContext<'_>, impl_item_id: OwnerId) -> Option<DefId> { | ||
let trait_node = cx.tcx.hir().find_parent(impl_item_id.into())?; | ||
if let Node::Item(item) = trait_node && | ||
let ItemKind::Impl(impl_) = &item.kind | ||
{ | ||
impl_.items.iter().find_map(|item| { | ||
if item.id.owner_id == impl_item_id { | ||
item.trait_item_def_id | ||
} else { | ||
None | ||
} | ||
}) | ||
} else { | ||
None | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#![warn(clippy::renamed_function_params)] | ||
#![allow(clippy::partialeq_ne_impl)] | ||
#![allow(unused)] | ||
|
||
use std::hash::{Hash, Hasher}; | ||
|
||
struct A; | ||
impl From<A> for String { | ||
fn from(_value: A) -> Self { | ||
String::new() | ||
} | ||
} | ||
impl ToString for A { | ||
fn to_string(&self) -> String { | ||
String::new() | ||
} | ||
} | ||
|
||
struct B(u32); | ||
impl From<B> for String { | ||
fn from(b: B) -> Self { | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
b.0.to_string() | ||
} | ||
} | ||
impl PartialEq for B { | ||
fn eq(&self, rhs: &Self) -> bool { | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
self.0 == rhs.0 | ||
} | ||
fn ne(&self, rhs: &Self) -> bool { | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
self.0 != rhs.0 | ||
} | ||
} | ||
|
||
trait MyTrait { | ||
fn foo(&self, val: u8); | ||
fn bar(a: u8, b: u8); | ||
fn baz(self, _val: u8); | ||
} | ||
|
||
impl MyTrait for B { | ||
fn foo(&self, i_dont_wanna_use_your_name: u8) {} | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
fn bar(_a: u8, _b: u8) {} | ||
fn baz(self, val: u8) {} | ||
} | ||
|
||
impl Hash for B { | ||
fn hash<H: Hasher>(&self, states: &mut H) { | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
self.0.hash(states); | ||
} | ||
fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { | ||
//~^ ERROR: function parameter name was renamed from its trait default | ||
for d in date { | ||
d.hash(states); | ||
} | ||
} | ||
} | ||
|
||
impl B { | ||
fn totally_irrelevant(&self, right: bool) {} | ||
fn some_fn(&self, other: impl MyTrait) {} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:21:13 | ||
| | ||
LL | fn from(b: B) -> Self { | ||
| ^ | ||
| | ||
= help: consider changing the name to: 'value' | ||
= note: `-D clippy::renamed-function-params` implied by `-D warnings` | ||
= help: to override `-D warnings` add `#[allow(clippy::renamed_function_params)]` | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:27:18 | ||
| | ||
LL | fn eq(&self, rhs: &Self) -> bool { | ||
| ^^^ | ||
| | ||
= help: consider changing the name to: 'other' | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:31:18 | ||
| | ||
LL | fn ne(&self, rhs: &Self) -> bool { | ||
| ^^^ | ||
| | ||
= help: consider changing the name to: 'other' | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:44:19 | ||
| | ||
LL | fn foo(&self, i_dont_wanna_use_your_name: u8) {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= help: consider changing the name to: 'val' | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:51:31 | ||
| | ||
LL | fn hash<H: Hasher>(&self, states: &mut H) { | ||
| ^^^^^^ | ||
| | ||
= help: consider changing the name to: 'state' | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:55:30 | ||
| | ||
LL | fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { | ||
| ^^^^ | ||
| | ||
= help: consider changing the name to: 'data' | ||
|
||
error: function parameter name was renamed from its trait default | ||
--> $DIR/renamed_function_params.rs:55:45 | ||
| | ||
LL | fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) { | ||
| ^^^^^^ | ||
| | ||
= help: consider changing the name to: 'state' | ||
|
||
error: aborting due to 7 previous errors | ||
|