#![warn(clippy::unwrap_or_default)] #![allow(dead_code)] #![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)] /// Checks implementation of the `UNWRAP_OR_DEFAULT` lint. fn unwrap_or_else_default() { struct Foo; impl Foo { fn new() -> Foo { Foo } // fake default, we should not trigger on this fn default() -> Foo { Foo } } struct HasDefaultAndDuplicate; impl HasDefaultAndDuplicate { fn default() -> Self { HasDefaultAndDuplicate } } impl Default for HasDefaultAndDuplicate { fn default() -> Self { HasDefaultAndDuplicate } } enum Enum { A(), } fn make<T, V>(_: V) -> T { unimplemented!(); } let with_enum = Some(Enum::A()); with_enum.unwrap_or_else(Enum::A); let with_new = Some(vec![1]); with_new.unwrap_or_default(); let with_err: Result<_, ()> = Ok(vec![1]); with_err.unwrap_or_else(make); // should not be changed let with_fake_default = None::<Foo>; with_fake_default.unwrap_or_else(Foo::default); // should not be changed let with_fake_default2 = None::<HasDefaultAndDuplicate>; with_fake_default2.unwrap_or_else(<HasDefaultAndDuplicate>::default); let with_real_default = None::<HasDefaultAndDuplicate>; with_real_default.unwrap_or_default(); 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 with_default_type: Option<Vec<u64>> = None; with_default_type.unwrap_or_default(); let empty_string = None::<String>; empty_string.unwrap_or_default(); } fn type_certainty(option: Option<Vec<u64>>) { option.unwrap_or_default().push(1); let option: std::option::Option<std::vec::Vec<u64>> = None; option.unwrap_or_default().push(1); let option: Option<Vec<u64>> = None; option.unwrap_or_default().push(1); let option = std::option::Option::<std::vec::Vec<u64>>::None; option.unwrap_or_default().push(1); let option = Option::<Vec<u64>>::None; option.unwrap_or_default().push(1); let option = std::option::Option::None::<std::vec::Vec<u64>>; option.unwrap_or_default().push(1); let option = Option::None::<Vec<u64>>; option.unwrap_or_default().push(1); let option = None::<Vec<u64>>; option.unwrap_or_default().push(1); // should not be changed: type annotation with infer, unconcretized initializer let option: Option<Vec<_>> = None; option.unwrap_or_else(Vec::new).push(1); // should not be changed: no type annotation, unconcretized initializer let option = Option::None; option.unwrap_or_else(Vec::new).push(1); // should not be changed: no type annotation, unconcretized initializer let option = None; option.unwrap_or_else(Vec::new).push(1); type Alias = Option<Vec<u32>>; let option: Alias = Option::<Vec<u32>>::Some(Vec::new()); option.unwrap_or_default().push(1); } fn method_call_with_deref() { use std::cell::RefCell; use std::collections::HashMap; let cell = RefCell::new(HashMap::<u64, HashMap<u64, String>>::new()); let mut outer_map = cell.borrow_mut(); #[allow(unused_assignments)] let mut option = None; option = Some(0); let inner_map = outer_map.get_mut(&option.unwrap()).unwrap(); let _ = inner_map.entry(0).or_default(); } fn missing_suggested_method() { #[derive(Copy, Clone)] struct S<T>(T); impl<T> S<T> { fn or_insert_with(&mut self, default: impl FnOnce() -> T) -> &mut T { &mut self.0 } fn or_insert(&mut self, default: T) -> &mut T { &mut self.0 } fn unwrap_or_else(self, default: impl FnOnce() -> T) -> T { self.0 } fn unwrap_or(self, default: T) -> T { self.0 } } // Don't lint when or_default/unwrap_or_default do not exist on the type let mut s = S(1); s.or_insert_with(Default::default); s.or_insert(Default::default()); s.unwrap_or_else(Default::default); s.unwrap_or(Default::default()); } fn main() {}