mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
redundant_closure_for_method_calls fixes:
lint does not trigger when there is a difference in mutability lint does not trigger when the method belongs to a trait which is not implemebted directly (Deref)
This commit is contained in:
parent
bd33a97cc4
commit
d4ad23bb3f
3 changed files with 47 additions and 6 deletions
|
@ -6,7 +6,9 @@ use rustc::ty::{self, Ty};
|
|||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_errors::Applicability;
|
||||
|
||||
use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function};
|
||||
use crate::utils::{
|
||||
implements_trait, is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then, type_is_unsafe_function,
|
||||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for closures which just call another function where
|
||||
|
@ -152,7 +154,9 @@ fn get_ufcs_type_name(
|
|||
let actual_type_of_self = &cx.tables.node_type(self_arg.hir_id);
|
||||
|
||||
if let Some(trait_id) = cx.tcx.trait_of_item(method_def_id) {
|
||||
if match_borrow_depth(expected_type_of_self, &actual_type_of_self) {
|
||||
if match_borrow_depth(expected_type_of_self, &actual_type_of_self)
|
||||
&& implements_trait(cx, actual_type_of_self, trait_id, &[])
|
||||
{
|
||||
return Some(cx.tcx.def_path_str(trait_id));
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +172,7 @@ fn get_ufcs_type_name(
|
|||
|
||||
fn match_borrow_depth(lhs: Ty<'_>, rhs: Ty<'_>) -> bool {
|
||||
match (&lhs.sty, &rhs.sty) {
|
||||
(ty::Ref(_, t1, _), ty::Ref(_, t2, _)) => match_borrow_depth(&t1, &t2),
|
||||
(ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_borrow_depth(&t1, &t2),
|
||||
(l, r) => match (l, r) {
|
||||
(ty::Ref(_, _, _), _) | (_, ty::Ref(_, _, _)) => false,
|
||||
(_, _) => true,
|
||||
|
@ -183,9 +187,8 @@ fn match_types(lhs: Ty<'_>, rhs: Ty<'_>) -> bool {
|
|||
| (ty::Int(_), ty::Int(_))
|
||||
| (ty::Uint(_), ty::Uint(_))
|
||||
| (ty::Str, ty::Str) => true,
|
||||
(ty::Ref(_, t1, _), ty::Ref(_, t2, _))
|
||||
| (ty::Array(t1, _), ty::Array(t2, _))
|
||||
| (ty::Slice(t1), ty::Slice(t2)) => match_types(t1, t2),
|
||||
(ty::Ref(_, t1, mut1), ty::Ref(_, t2, mut2)) => mut1 == mut2 && match_types(t1, t2),
|
||||
(ty::Array(t1, _), ty::Array(t2, _)) | (ty::Slice(t1), ty::Slice(t2)) => match_types(t1, t2),
|
||||
(ty::Adt(def1, _), ty::Adt(def2, _)) => def1 == def2,
|
||||
(_, _) => false,
|
||||
}
|
||||
|
|
|
@ -184,3 +184,22 @@ fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {
|
|||
// called. This changes semantics, so the closure must stay.
|
||||
Box::new(move |x| f()(x))
|
||||
}
|
||||
|
||||
fn call<F: FnOnce(&mut String) -> String>(f: F) -> String {
|
||||
f(&mut "Hello".to_owned())
|
||||
}
|
||||
fn test_difference_in_mutability() {
|
||||
call(|s| s.clone());
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
impl std::ops::Deref for Bar {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &str {
|
||||
"hi"
|
||||
}
|
||||
}
|
||||
|
||||
fn test_deref_with_trait_method() {
|
||||
let _ = [Bar].iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
}
|
||||
|
|
|
@ -184,3 +184,22 @@ fn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {
|
|||
// called. This changes semantics, so the closure must stay.
|
||||
Box::new(move |x| f()(x))
|
||||
}
|
||||
|
||||
fn call<F: FnOnce(&mut String) -> String>(f: F) -> String {
|
||||
f(&mut "Hello".to_owned())
|
||||
}
|
||||
fn test_difference_in_mutability() {
|
||||
call(|s| s.clone());
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
impl std::ops::Deref for Bar {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &str {
|
||||
"hi"
|
||||
}
|
||||
}
|
||||
|
||||
fn test_deref_with_trait_method() {
|
||||
let _ = [Bar].iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue