//@ check-pass #![warn(dropping_references)] struct SomeStruct; fn main() { drop(&SomeStruct); //~ WARN calls to `std::mem::drop` let mut owned1 = SomeStruct; drop(&owned1); //~ WARN calls to `std::mem::drop` drop(&&owned1); //~ WARN calls to `std::mem::drop` drop(&mut owned1); //~ WARN calls to `std::mem::drop` drop(owned1); let reference1 = &SomeStruct; drop(reference1); //~ WARN calls to `std::mem::drop` let reference2 = &mut SomeStruct; drop(reference2); //~ WARN calls to `std::mem::drop` let ref reference3 = SomeStruct; drop(reference3); //~ WARN calls to `std::mem::drop` } #[allow(dead_code)] fn test_generic_fn_drop(val: T) { drop(&val); //~ WARN calls to `std::mem::drop` drop(val); } #[allow(dead_code)] fn test_similarly_named_function() { fn drop(_val: T) {} drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name std::mem::drop(&SomeStruct); //~ WARN calls to `std::mem::drop` } #[derive(Copy, Clone)] pub struct Error; fn produce_half_owl_error() -> Result<(), Error> { Ok(()) } fn produce_half_owl_ok() -> Result { Ok(true) } #[allow(dead_code)] fn test_owl_result() -> Result<(), ()> { produce_half_owl_error().map_err(|_| ())?; produce_half_owl_ok().map(|_| ())?; // the following should not be linted, // we should not force users to use toilet closures // to produce owl results when drop is more convenient produce_half_owl_error().map_err(drop)?; produce_half_owl_ok().map_err(drop)?; Ok(()) } #[allow(dead_code)] fn test_owl_result_2() -> Result { produce_half_owl_error().map_err(|_| ())?; produce_half_owl_ok().map(|_| ())?; // the following should not be linted, // we should not force users to use toilet closures // to produce owl results when drop is more convenient produce_half_owl_error().map_err(drop)?; produce_half_owl_ok().map(drop)?; Ok(1) } #[allow(unused)] #[allow(clippy::unit_cmp)] fn issue10122(x: u8) { // This is a function which returns a reference and has a side-effect, which means // that calling drop() on the function is considered an idiomatic way of achieving // the side-effect in a match arm. fn println_and(t: &T) -> &T { println!("foo"); t } match x { // Don't lint (copy type), we only care about side-effects 0 => drop(println_and(&12)), // Don't lint (no copy type), we only care about side-effects 1 => drop(println_and(&String::new())), 2 => { // Lint, even if we only care about the side-effect, it's already in a block drop(println_and(&13)); //~ WARN calls to `std::mem::drop` }, // Lint, idiomatic use is only in body of `Arm` 3 if drop(println_and(&14)) == () => (), //~ WARN calls to `std::mem::drop` // Lint, not a fn/method call 4 => drop(&2), //~ WARN calls to `std::mem::drop` _ => (), } } fn issue112653() { fn foo() -> Result<&'static u8, ()> { println!("doing foo"); Ok(&0) // result is not always useful, the side-effect matters } fn bar() { println!("doing bar"); } fn stuff() -> Result<(), ()> { match 42 { 0 => drop(foo()?), // drop is needed because we only care about side-effects 1 => bar(), _ => (), // doing nothing (no side-effects needed here) } Ok(()) } }