//@run-rustfix #![warn(clippy::or_fun_call)] #![allow(dead_code)] #![allow( clippy::borrow_as_ptr, clippy::uninlined_format_args, clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap, clippy::useless_vec )] use std::collections::{BTreeMap, HashMap}; use std::time::Duration; /// Checks implementation of the `OR_FUN_CALL` lint. fn or_fun_call() { struct Foo; impl Foo { fn new() -> Foo { Foo } } struct FakeDefault; impl FakeDefault { fn default() -> Self { FakeDefault } } impl Default for FakeDefault { fn default() -> Self { FakeDefault } } enum Enum { A(i32), } fn make() -> T { unimplemented!(); } let with_enum = Some(Enum::A(1)); with_enum.unwrap_or(Enum::A(5)); let with_const_fn = Some(Duration::from_secs(1)); with_const_fn.unwrap_or(Duration::from_secs(5)); let with_constructor = Some(vec![1]); with_constructor.unwrap_or_else(make); let with_new = Some(vec![1]); with_new.unwrap_or_default(); let with_const_args = Some(vec![1]); with_const_args.unwrap_or_else(|| Vec::with_capacity(12)); let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or_else(|_| make()); let with_err_args: Result<_, ()> = Ok(vec![1]); with_err_args.unwrap_or_else(|_| Vec::with_capacity(12)); let with_default_trait = Some(1); with_default_trait.unwrap_or_default(); let with_default_type = Some(1); with_default_type.unwrap_or_default(); let self_default = None::; self_default.unwrap_or_else(::default); let real_default = None::; real_default.unwrap_or_default(); let with_vec = Some(vec![1]); with_vec.unwrap_or_default(); let without_default = Some(Foo); without_default.unwrap_or_else(Foo::new); let mut map = HashMap::::new(); map.entry(42).or_default(); let mut map_vec = HashMap::>::new(); map_vec.entry(42).or_default(); let mut btree = BTreeMap::::new(); btree.entry(42).or_default(); let mut btree_vec = BTreeMap::>::new(); btree_vec.entry(42).or_default(); let stringy = Some(String::new()); let _ = stringy.unwrap_or_default(); let opt = Some(1); let hello = "Hello"; let _ = opt.ok_or(format!("{} world.", hello)); // index let map = HashMap::::new(); let _ = Some(1).unwrap_or_else(|| map[&1]); let map = BTreeMap::::new(); let _ = Some(1).unwrap_or_else(|| map[&1]); // don't lint index vec let vec = vec![1]; let _ = Some(1).unwrap_or(vec[1]); } struct Foo(u8); struct Bar(String, Duration); #[rustfmt::skip] fn test_or_with_ctors() { let opt = Some(1); let opt_opt = Some(Some(1)); // we also test for const promotion, this makes sure we don't hit that let two = 2; let _ = opt_opt.unwrap_or(Some(2)); let _ = opt_opt.unwrap_or(Some(two)); let _ = opt.ok_or(Some(2)); let _ = opt.ok_or(Some(two)); let _ = opt.ok_or(Foo(2)); let _ = opt.ok_or(Foo(two)); let _ = opt.or(Some(2)); let _ = opt.or(Some(two)); let _ = Some("a".to_string()).or_else(|| Some("b".to_string())); let b = "b".to_string(); let _ = Some(Bar("a".to_string(), Duration::from_secs(1))) .or(Some(Bar(b, Duration::from_secs(2)))); let vec = vec!["foo"]; let _ = opt.ok_or(vec.len()); let array = ["foo"]; let _ = opt.ok_or(array.len()); let slice = &["foo"][..]; let _ = opt.ok_or(slice.len()); let string = "foo"; let _ = opt.ok_or(string.len()); } // Issue 4514 - early return fn f() -> Option<()> { let a = Some(1); let b = 1i32; let _ = a.unwrap_or(b.checked_mul(3)?.min(240)); Some(()) } mod issue6675 { unsafe fn ptr_to_ref<'a, T>(p: *const T) -> &'a T { #[allow(unused)] let x = vec![0; 1000]; // future-proofing, make this function expensive. &*p } unsafe fn foo() { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or_else(|| ptr_to_ref(s)); } fn bar() { let s = "test".to_owned(); let s = &s as *const _; None.unwrap_or_else(|| unsafe { ptr_to_ref(s) }); #[rustfmt::skip] None.unwrap_or_else(|| unsafe { ptr_to_ref(s) }); } } mod issue8239 { fn more_than_max_suggestion_highest_lines_0() { let frames = Vec::new(); frames .iter() .map(|f: &String| f.to_lowercase()) .reduce(|mut acc, f| { acc.push_str(&f); acc }) .unwrap_or_default(); } fn more_to_max_suggestion_highest_lines_1() { let frames = Vec::new(); let iter = frames.iter(); iter.map(|f: &String| f.to_lowercase()) .reduce(|mut acc, f| { let _ = ""; let _ = ""; acc.push_str(&f); acc }) .unwrap_or_default(); } fn equal_to_max_suggestion_highest_lines() { let frames = Vec::new(); let iter = frames.iter(); iter.map(|f: &String| f.to_lowercase()) .reduce(|mut acc, f| { let _ = ""; acc.push_str(&f); acc }) .unwrap_or_default(); } fn less_than_max_suggestion_highest_lines() { let frames = Vec::new(); let iter = frames.iter(); let map = iter.map(|f: &String| f.to_lowercase()); map.reduce(|mut acc, f| { acc.push_str(&f); acc }) .unwrap_or_default(); } } mod issue9608 { fn sig_drop() { enum X { X(std::fs::File), Y(u32), } let _ = None.unwrap_or(X::Y(0)); } } mod issue8993 { fn g() -> i32 { 3 } fn f(n: i32) -> i32 { n } fn test_map_or() { let _ = Some(4).map_or_else(g, |v| v); let _ = Some(4).map_or_else(g, f); let _ = Some(4).map_or(0, f); } } fn main() {}