#![warn(clippy::needless_borrows_for_generic_args)] #![allow( clippy::unnecessary_to_owned, clippy::unnecessary_literal_unwrap, clippy::needless_borrow )] use core::ops::Deref; use std::any::Any; use std::ffi::OsStr; use std::fmt::{Debug, Display}; use std::path::Path; use std::process::Command; fn main() { let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap(); let _ = Path::new(".").join("."); let _ = Any::type_id(&""); // Don't lint. `Any` is only bound let _ = Box::new(&""); // Don't lint. Type parameter appears in return type let _ = Some("").unwrap_or(&""); let _ = std::fs::write("x", "".to_string()); { #[derive(Clone, Copy)] struct X; impl Deref for X { type Target = X; fn deref(&self) -> &Self::Target { self } } fn deref_target_is_x>(_: T) {} deref_target_is_x(X); } { fn multiple_constraints(_: T) where T: IntoIterator + IntoIterator, U: IntoIterator, V: AsRef, X: IntoIterator, Y: AsRef, { } multiple_constraints([[""]]); } { #[derive(Clone, Copy)] struct X; impl Deref for X { type Target = X; fn deref(&self) -> &Self::Target { self } } fn multiple_constraints_normalizes_to_same(_: T, _: V) where T: Deref, U: Deref, { } multiple_constraints_normalizes_to_same(X, X); } { fn only_sized(_: T) {} only_sized(&""); // Don't lint. `Sized` is only bound } { fn ref_as_ref_path(_: &'static T) where &'static T: AsRef, { } ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter } { trait RefsOnly { type Referent; } impl RefsOnly for &T { type Referent = T; } fn refs_only(_: T) where T: RefsOnly, { } refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't } { fn multiple_constraints_normalizes_to_different(_: T, _: U) where T: IntoIterator, U: IntoIterator, V: AsRef, { } multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments } // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321 { #[derive(Clone, Copy)] struct Iter; impl Iterator for Iter { type Item = (); fn next(&mut self) -> Option { None } } fn takes_iter(_: impl Iterator) {} fn dont_warn(mut x: Iter) { takes_iter(&mut x); } #[allow(unused_mut)] fn warn(mut x: &mut Iter) { takes_iter(x) } } #[clippy::msrv = "1.52.0"] { let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap(); }; #[clippy::msrv = "1.53.0"] { let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap(); }; { let env = "env".to_owned(); let arg = "arg".to_owned(); let f = |arg| { let loc = "loc".to_owned(); let _ = std::fs::write("x", &env); // Don't lint. In environment let _ = std::fs::write("x", &arg); let _ = std::fs::write("x", &loc); }; let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f` f(arg); } { #[derive(Debug)] struct X; impl Drop for X { fn drop(&mut self) {} } fn f(_: impl Debug) {} let x = X; f(&x); // Don't lint, not copy, passed by a reference to a variable } { fn f(_: impl AsRef) {} let x = String::new(); f(&x); } { fn f(_: impl AsRef) {} fn f2(_: impl AsRef) {} let x = String::new(); f(&x); f2(&x); } // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280 // issue 9111 { struct A; impl Extend for A { fn extend>(&mut self, _: T) { unimplemented!() } } impl<'a> Extend<&'a u8> for A { fn extend>(&mut self, _: T) { unimplemented!() } } let mut a = A; a.extend(&[]); // vs a.extend([]); } // issue 9710 { fn f(_: impl AsRef) {} let x = String::new(); for _ in 0..10 { f(&x); } } // issue 9739 { fn foo(_it: impl IntoIterator) {} foo(if std::env::var_os("HI").is_some() { &[0] } else { &[] as &[u32] }); } { struct S; impl S { fn foo(&self, _it: impl IntoIterator) {} } S.foo(if std::env::var_os("HI").is_some() { &[0] } else { &[] as &[u32] }); } // issue 9782 { fn foo>(t: T) { println!("{}", std::mem::size_of::()); let _t: &[u8] = t.as_ref(); } let a: [u8; 100] = [0u8; 100]; // 100 foo::<[u8; 100]>(a); foo(a); // 16 foo::<&[u8]>(&a); foo(a.as_slice()); // 8 foo::<&[u8; 100]>(&a); foo(a); } { struct S; impl S { fn foo>(t: T) { println!("{}", std::mem::size_of::()); let _t: &[u8] = t.as_ref(); } } let a: [u8; 100] = [0u8; 100]; S::foo::<&[u8; 100]>(&a); } { struct S; impl S { fn foo>(&self, t: T) { println!("{}", std::mem::size_of::()); let _t: &[u8] = t.as_ref(); } } let a: [u8; 100] = [0u8; 100]; S.foo::<&[u8; 100]>(&a); } // issue 10535 { static SOME_STATIC: String = String::new(); static UNIT: () = compute(&SOME_STATIC); pub const fn compute(_: T) where T: Copy, { } } // address of field when operand impl Drop { struct CustomDrop(String); impl Drop for CustomDrop { fn drop(&mut self) {} } fn check_str>(_to: P) {} fn test() { let owner = CustomDrop(String::default()); check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop } } { #[derive(Debug)] struct X(Vec); fn f(_: impl Debug) {} let x = X(vec![]); f(&x); // Don't lint, makes x unavailable later } { #[derive(Debug)] struct X; impl Drop for X { fn drop(&mut self) {} } fn f(_: impl Debug) {} #[derive(Debug)] struct Y(X); let y = Y(X); f(&y); // Don't lint. Not copy, passed by a reference to value } { fn f(_: impl AsRef) {} let x = String::new(); f(&x); // Don't lint, not a copy, makes it unavailable later f(String::new()); // Lint, makes no difference let y = "".to_owned(); f(&y); // Don't lint f("".to_owned()); // Lint } }