#![warn(clippy::manual_map)] #![allow(clippy::toplevel_ref_arg)] fn main() { // Lint. `y` is declared within the arm, so it isn't captured by the map closure let _ = Some(0).map(|x| { let y = (String::new(), String::new()); (x, y.0) }); // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map // closure let s = Some(String::new()); let _ = match &s { Some(x) => Some((x.clone(), s)), None => None, }; // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map // closure let s = Some(String::new()); let _ = match &s { Some(x) => Some({ let clone = x.clone(); let s = || s; (clone, s()) }), None => None, }; // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured as a mutable // reference by the map closure let mut s = Some(String::new()); let _ = match &s { Some(x) => Some({ let clone = x.clone(); let ref mut s = s; (clone, s) }), None => None, }; let s = Some(String::new()); // Lint. `s` is captured by reference, so no lifetime issues. let _ = s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }); // Don't lint this, type of `s` is coercioned from `&String` to `&str` let x: Option<(String, &str)> = match &s { Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; // Issue #7820 unsafe fn f(x: u32) -> u32 { x } unsafe { let _ = Some(0).map(|x| f(x)); } let _ = Some(0).map(|x| unsafe { f(x) }); let _ = Some(0).map(|x| unsafe { f(x) }); } // issue #12659 mod with_type_coercion { trait DummyTrait {} fn foo Result>(f: F) { // Don't lint let _: Option, ()>> = match Some(0) { Some(_) => Some(match f() { Ok(res) => Ok(Box::new(res)), _ => Err(()), }), None => None, }; let _: Option> = match Some(()) { Some(_) => Some(Box::new(b"1234")), None => None, }; let x = String::new(); let _: Option> = match Some(()) { Some(_) => Some(Box::new(&x)), None => None, }; let _: Option<&str> = match Some(()) { Some(_) => Some(&x), None => None, }; let _ = Some(0).map(|_| match f() { Ok(res) => Ok(Box::new(res)), _ => Err(()), }); } #[allow(clippy::redundant_allocation)] fn bar() { fn f(_: Option>) {} fn g(b: &[u8]) -> Box<&[u8]> { Box::new(b) } let x: &[u8; 4] = b"1234"; f(match Some(()) { Some(_) => Some(Box::new(x)), None => None, }); let _: Option> = Some(0).map(|_| g(x)); } fn with_fn_ret(s: &Option) -> Option<(String, &str)> { // Don't lint, `map` doesn't work as the return type is adjusted. match s { Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, } } fn with_fn_ret_2(s: &Option) -> Option<(String, &str)> { if true { // Don't lint, `map` doesn't work as the return type is adjusted. return match s { Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, }; } None } #[allow(clippy::needless_late_init)] fn with_fn_ret_3<'a>(s: &'a Option) -> Option<(String, &'a str)> { let x: Option<(String, &'a str)>; x = { match s { Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }), None => None, } }; x } }