Fix needless_borrow
false positive
This commit is contained in:
parent
70187c7d11
commit
83771c5242
@ -1049,7 +1049,7 @@ fn visit_generic_arg(&mut self, arg: &GenericArg<'_>) {
|
|||||||
// If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
|
// If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
|
||||||
// The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
|
// The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
|
||||||
// be moved, but it cannot be.
|
// be moved, but it cannot be.
|
||||||
#[expect(clippy::too_many_arguments)]
|
#[expect(clippy::too_many_arguments, clippy::too_many_lines)]
|
||||||
fn needless_borrow_impl_arg_position<'tcx>(
|
fn needless_borrow_impl_arg_position<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
||||||
@ -1092,7 +1092,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
|||||||
.iter()
|
.iter()
|
||||||
.filter_map(|predicate| {
|
.filter_map(|predicate| {
|
||||||
if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
if let PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder()
|
||||||
&& trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
|
&& trait_predicate.self_ty() == param_ty.to_ty(cx.tcx)
|
||||||
{
|
{
|
||||||
Some(trait_predicate.trait_ref.def_id)
|
Some(trait_predicate.trait_ref.def_id)
|
||||||
} else {
|
} else {
|
||||||
@ -1111,6 +1111,16 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
|||||||
return Position::Other(precedence);
|
return Position::Other(precedence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See:
|
||||||
|
// - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
|
||||||
|
// - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
|
||||||
|
if projection_predicates
|
||||||
|
.iter()
|
||||||
|
.any(|projection_predicate| is_mixed_projection_predicate(cx, callee_def_id, projection_predicate))
|
||||||
|
{
|
||||||
|
return Position::Other(precedence);
|
||||||
|
}
|
||||||
|
|
||||||
// `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
|
// `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
|
||||||
// elements are modified each time `check_referent` is called.
|
// elements are modified each time `check_referent` is called.
|
||||||
let mut substs_with_referent_ty = substs_with_expr_ty.to_vec();
|
let mut substs_with_referent_ty = substs_with_expr_ty.to_vec();
|
||||||
@ -1190,8 +1200,39 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn referent_used_exactly_once<'tcx>(
|
fn is_mixed_projection_predicate<'tcx>(
|
||||||
cx: &LateContext<'tcx>,
|
cx: &LateContext<'tcx>,
|
||||||
|
callee_def_id: DefId,
|
||||||
|
projection_predicate: &ProjectionPredicate<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
let generics = cx.tcx.generics_of(callee_def_id);
|
||||||
|
// The predicate requires the projected type to equal a type parameter from the parent context.
|
||||||
|
if let Some(term_ty) = projection_predicate.term.ty()
|
||||||
|
&& let ty::Param(term_param_ty) = term_ty.kind()
|
||||||
|
&& (term_param_ty.index as usize) < generics.parent_count
|
||||||
|
{
|
||||||
|
// The inner-most self type is a type parameter from the current function.
|
||||||
|
let mut projection_ty = projection_predicate.projection_ty;
|
||||||
|
loop {
|
||||||
|
match projection_ty.self_ty().kind() {
|
||||||
|
ty::Projection(inner_projection_ty) => {
|
||||||
|
projection_ty = *inner_projection_ty;
|
||||||
|
}
|
||||||
|
ty::Param(param_ty) => {
|
||||||
|
return (param_ty.index as usize) >= generics.parent_count;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn referent_used_exactly_once<'a, 'tcx>(
|
||||||
|
cx: &'a LateContext<'tcx>,
|
||||||
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
|
||||||
reference: &Expr<'tcx>,
|
reference: &Expr<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -385,3 +385,26 @@ mod used_more_than_once {
|
|||||||
fn use_x(_: impl AsRef<str>) {}
|
fn use_x(_: impl AsRef<str>) {}
|
||||||
fn use_x_again(_: impl AsRef<str>) {}
|
fn use_x_again(_: impl AsRef<str>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
|
||||||
|
#[allow(dead_code)]
|
||||||
|
mod issue_9111 {
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
impl Extend<u8> for A {
|
||||||
|
fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Extend<&'a u8> for A {
|
||||||
|
fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut a = A;
|
||||||
|
a.extend(&[]); // vs a.extend([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -385,3 +385,26 @@ fn foo(x: String) {
|
|||||||
fn use_x(_: impl AsRef<str>) {}
|
fn use_x(_: impl AsRef<str>) {}
|
||||||
fn use_x_again(_: impl AsRef<str>) {}
|
fn use_x_again(_: impl AsRef<str>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
|
||||||
|
#[allow(dead_code)]
|
||||||
|
mod issue_9111 {
|
||||||
|
struct A;
|
||||||
|
|
||||||
|
impl Extend<u8> for A {
|
||||||
|
fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Extend<&'a u8> for A {
|
||||||
|
fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut a = A;
|
||||||
|
a.extend(&[]); // vs a.extend([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user