2 #![feature(custom_inner_attributes, lint_reasons)]
4 #[warn(clippy::all, clippy::needless_borrow)]
5 #[allow(unused_variables)]
6 #[allow(clippy::uninlined_format_args, clippy::unnecessary_mut_passed)]
10 let _ = x(&a); // no warning
11 let _ = x(&&a); // warn
14 mut_ref(&mut b); // no warning
15 mut_ref(&mut &mut b); // warn
17 let s = &String::from("hi");
18 let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not
19 let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`
21 let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`
22 h(&"foo"); // should not error, because the `&&str` is required, due to `&Trait`
23 let garbl = match 42 {
57 let y: &mut i32 = &mut x;
58 let y: &mut i32 = &mut &mut x;
61 // Don't lint. Removing the borrow would move 'x'
65 let y: &mut i32 = match 0 {
66 // Lint here. The type given above triggers auto-borrow.
70 fn ref_mut_i32(_: &mut i32) {}
72 // Lint here. The type given above triggers auto-borrow.
76 // use 'x' after to make sure it's still usable in the fixed code.
79 let s = String::new();
80 // let _ = (&s).len();
81 // let _ = (&s).capacity();
82 // let _ = (&&s).capacity();
86 let x = &x as *const (i32, i32);
87 let _ = unsafe { (&*x).0 };
96 (&()).foo(); // Don't lint. `()` doesn't implement `Foo`
102 impl Foo for &'_ i32 {
105 (&5).foo(); // Don't lint. `5` will call `<i32 as Foo>::foo`
114 impl FooRef for &'_ () {
117 (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
120 impl From<S> for u32 {
121 fn from(s: S) -> Self {
125 impl From<&S> for u32 {
126 fn from(s: &S) -> Self {
131 let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
132 let _ = std::path::Path::new(".").join(&&".");
133 deref_target_is_x(&X);
134 multiple_constraints(&[[""]]);
135 multiple_constraints_normalizes_to_same(&X, X);
136 let _ = Some("").unwrap_or(&"");
138 only_sized(&""); // Don't lint. `Sized` is only bound
139 let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
140 let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
141 ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
142 refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
143 multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
146 #[allow(clippy::needless_borrowed_reference)]
147 fn x(y: &i32) -> i32 {
151 fn mut_ref(y: &mut i32) {
155 fn f<T: Copy>(y: &T) -> T {
159 fn g(y: &[u8]) -> u8 {
165 impl<'a> Trait for &'a str {}
167 fn h(_: &dyn Trait) {}
170 fn check_expect_suppression() {
172 #[expect(clippy::needless_borrow)]
186 fn calls_field(&self) -> T {
195 fn calls_mut_field(&mut self) -> T {
201 #[derive(Clone, Copy)]
204 impl std::ops::Deref for X {
206 fn deref(&self) -> &Self::Target {
211 fn deref_target_is_x<T>(_: T)
213 T: std::ops::Deref<Target = X>,
217 fn multiple_constraints<T, U, V, X, Y>(_: T)
219 T: IntoIterator<Item = U> + IntoIterator<Item = X>,
220 U: IntoIterator<Item = V>,
222 X: IntoIterator<Item = Y>,
223 Y: AsRef<std::ffi::OsStr>,
227 fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
229 T: std::ops::Deref<Target = U>,
230 U: std::ops::Deref<Target = V>,
234 fn only_sized<T>(_: T) {}
236 fn ref_as_ref_path<T: 'static>(_: &'static T)
238 &'static T: AsRef<std::path::Path>,
246 impl<T> RefsOnly for &T {
250 fn refs_only<T, U>(_: T)
252 T: RefsOnly<Referent = U>,
256 fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
258 T: IntoIterator<Item = U>,
259 U: IntoIterator<Item = V>,
264 // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
266 mod copyable_iterator {
267 #[derive(Clone, Copy)]
269 impl Iterator for Iter {
271 fn next(&mut self) -> Option<Self::Item> {
275 fn takes_iter(_: impl Iterator) {}
276 fn dont_warn(mut x: Iter) {
279 fn warn(mut x: &mut Iter) {
286 #![clippy::msrv = "1.52.0"]
289 let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
295 #![clippy::msrv = "1.53.0"]
298 let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
304 // Should not lint because unions need explicit deref when accessing field
305 use std::mem::ManuallyDrop;
308 crab: ManuallyDrop<Vec<i32>>,
312 coral: ManuallyDrop<Coral>,
315 let mut ocean = Ocean {
316 coral: ManuallyDrop::new(Coral {
317 crab: ManuallyDrop::new(vec![1, 2, 3]),
322 ManuallyDrop::drop(&mut (&mut ocean.coral).crab);
324 (*ocean.coral).crab = ManuallyDrop::new(vec![4, 5, 6]);
325 ManuallyDrop::drop(&mut (*ocean.coral).crab);
327 ManuallyDrop::drop(&mut ocean.coral);