Use correct substitutions when checking if needless_borrow can apply to a method receiver

This commit is contained in:
Jason Newcomb 2022-07-02 15:32:29 -04:00
parent 8c341d66a1
commit 988b813649
3 changed files with 32 additions and 3 deletions

View file

@ -756,9 +756,14 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
} else if let Some(trait_id) = cx.tcx.trait_of_item(id)
&& let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
&& let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
&& let subs = cx.typeck_results().node_substs_opt(child_id).unwrap_or_else(
|| cx.tcx.mk_substs([].iter())
) && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
&& let subs = match cx
.typeck_results()
.node_substs_opt(parent.hir_id)
.and_then(|subs| subs.get(1..))
{
Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
None => cx.tcx.mk_substs([].iter()),
} && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
// Trait methods taking `&self`
sub_ty
} else {

View file

@ -115,6 +115,18 @@ fn main() {
fn foo_ref(&self) {}
}
(&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
struct S;
impl From<S> for u32 {
fn from(s: S) -> Self {
(&s).into()
}
}
impl From<&S> for u32 {
fn from(s: &S) -> Self {
0
}
}
}
#[allow(clippy::needless_borrowed_reference)]

View file

@ -115,6 +115,18 @@ fn main() {
fn foo_ref(&self) {}
}
(&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
struct S;
impl From<S> for u32 {
fn from(s: S) -> Self {
(&s).into()
}
}
impl From<&S> for u32 {
fn from(s: &S) -> Self {
0
}
}
}
#[allow(clippy::needless_borrowed_reference)]