#![allow( unused, non_local_definitions, clippy::uninlined_format_args, clippy::unnecessary_mut_passed, clippy::unnecessary_to_owned, clippy::unnecessary_literal_unwrap, clippy::needless_lifetimes )] #![warn(clippy::needless_borrow)] fn main() { let a = 5; let ref_a = &a; let _ = x(&a); // no warning let _ = x(&&a); // warn let mut b = 5; mut_ref(&mut b); // no warning mut_ref(&mut &mut b); // warn let s = &String::from("hi"); let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not let g_val = g(&Vec::new()); // should not error, because `&Vec` derefs to `&[T]` let vec = Vec::new(); let vec_val = g(&vec); // should not error, because `&Vec` derefs to `&[T]` h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait` let garbl = match 42 { 44 => &a, 45 => { println!("foo"); &&a }, 46 => &&a, 47 => { println!("foo"); loop { println!("{}", a); if a == 25 { break &ref_a; } } }, _ => panic!(), }; let _ = x(&&&a); let _ = x(&mut &&a); let _ = x(&&&mut b); let _ = x(&&ref_a); { let b = &mut b; x(&b); } // Issue #8191 let mut x = 5; let mut x = &mut x; mut_ref(&mut x); mut_ref(&mut &mut x); let y: &mut i32 = &mut x; let y: &mut i32 = &mut &mut x; let y = match 0 { // Don't lint. Removing the borrow would move 'x' 0 => &mut x, _ => &mut *x, }; let y: &mut i32 = match 0 { // Lint here. The type given above triggers auto-borrow. 0 => &mut x, _ => &mut *x, }; fn ref_mut_i32(_: &mut i32) {} ref_mut_i32(match 0 { // Lint here. The type given above triggers auto-borrow. 0 => &mut x, _ => &mut *x, }); // use 'x' after to make sure it's still usable in the fixed code. *x = 5; let s = String::new(); // let _ = (&s).len(); // let _ = (&s).capacity(); // let _ = (&&s).capacity(); let x = (1, 2); let _ = (&x).0; let x = &x as *const (i32, i32); let _ = unsafe { (&*x).0 }; // Issue #8367 trait Foo { fn foo(self); } impl Foo for &'_ () { fn foo(self) {} } (&()).foo(); // Don't lint. `()` doesn't implement `Foo` (&&()).foo(); impl Foo for i32 { fn foo(self) {} } impl Foo for &'_ i32 { fn foo(self) {} } (&5).foo(); // Don't lint. `5` will call `::foo` (&&5).foo(); trait FooRef { fn foo_ref(&self); } impl FooRef for () { fn foo_ref(&self) {} } impl FooRef for &'_ () { fn foo_ref(&self) {} } (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref` struct S; impl From for u32 { fn from(s: S) -> Self { (&s).into() } } impl From<&S> for u32 { fn from(s: &S) -> Self { 0 } } // issue #11786 let x: (&str,) = (&"",); } #[allow(clippy::needless_borrowed_reference)] fn x(y: &i32) -> i32 { *y } fn mut_ref(y: &mut i32) { *y = 5; } fn f(y: &T) -> T { *y } fn g(y: &[u8]) -> u8 { y[0] } trait Trait {} impl<'a> Trait for &'a str {} fn h(_: &dyn Trait) {} fn check_expect_suppression() { let a = 5; #[expect(clippy::needless_borrow)] let _ = x(&&a); } mod issue9160 { pub struct S { f: F, } impl S where F: Fn() -> T, { fn calls_field(&self) -> T { (&self.f)() } } impl S where F: FnMut() -> T, { fn calls_mut_field(&mut self) -> T { (&mut self.f)() } } } fn issue9383() { // Should not lint because unions need explicit deref when accessing field use std::mem::ManuallyDrop; #[derive(Clone, Copy)] struct Wrap(T); impl core::ops::Deref for Wrap { type Target = T; fn deref(&self) -> &T { &self.0 } } impl core::ops::DerefMut for Wrap { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } union U { u: T, } #[derive(Clone, Copy)] struct Foo { x: u32, } unsafe { let mut x = U { u: ManuallyDrop::new(Foo { x: 0 }), }; let _ = &mut (&mut x.u).x; let _ = &mut (&mut { x.u }).x; let _ = &mut ({ &mut x.u }).x; let mut x = U { u: Wrap(ManuallyDrop::new(Foo { x: 0 })), }; let _ = &mut (&mut x.u).x; let _ = &mut (&mut { x.u }).x; let _ = &mut ({ &mut x.u }).x; let mut x = U { u: Wrap(Foo { x: 0 }) }; let _ = &mut (&mut x.u).x; let _ = &mut (&mut { x.u }).x; let _ = &mut ({ &mut x.u }).x; } } mod issue_10253 { struct S; trait X { fn f(&self); } impl X for &S { fn f(&self) {} } fn f() { (&S).f::<()>(); } } fn issue_12268() { let option = Some((&1,)); let x = (&1,); option.unwrap_or((&x.0,)); //~^ ERROR: this expression creates a reference which is immediately dereferenced by the // compiler }