2019-04-11 00:47:04 -05:00
|
|
|
#![warn(clippy::or_fun_call)]
|
2019-08-22 00:41:00 -05:00
|
|
|
#![allow(dead_code)]
|
2023-06-06 15:56:57 -05:00
|
|
|
#![allow(
|
|
|
|
clippy::borrow_as_ptr,
|
|
|
|
clippy::uninlined_format_args,
|
|
|
|
clippy::unnecessary_wraps,
|
2023-05-31 12:47:10 -05:00
|
|
|
clippy::unnecessary_literal_unwrap,
|
2023-06-06 15:56:57 -05:00
|
|
|
clippy::useless_vec
|
|
|
|
)]
|
2019-04-11 00:47:04 -05:00
|
|
|
|
2023-07-03 12:42:48 -05:00
|
|
|
use std::collections::{BTreeMap, HashMap};
|
2019-05-12 03:18:38 -05:00
|
|
|
use std::time::Duration;
|
2019-04-11 00:47:04 -05:00
|
|
|
|
|
|
|
/// Checks implementation of the `OR_FUN_CALL` lint.
|
|
|
|
fn or_fun_call() {
|
|
|
|
struct Foo;
|
|
|
|
|
|
|
|
impl Foo {
|
|
|
|
fn new() -> Foo {
|
|
|
|
Foo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-30 01:56:47 -05:00
|
|
|
struct FakeDefault;
|
|
|
|
impl FakeDefault {
|
|
|
|
fn default() -> Self {
|
|
|
|
FakeDefault
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for FakeDefault {
|
|
|
|
fn default() -> Self {
|
|
|
|
FakeDefault
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-11 00:47:04 -05:00
|
|
|
enum Enum {
|
|
|
|
A(i32),
|
|
|
|
}
|
|
|
|
|
|
|
|
fn make<T>() -> T {
|
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
|
|
|
|
let with_enum = Some(Enum::A(1));
|
|
|
|
with_enum.unwrap_or(Enum::A(5));
|
|
|
|
|
2019-05-12 03:18:38 -05:00
|
|
|
let with_const_fn = Some(Duration::from_secs(1));
|
|
|
|
with_const_fn.unwrap_or(Duration::from_secs(5));
|
2019-04-11 00:47:04 -05:00
|
|
|
|
|
|
|
let with_constructor = Some(vec![1]);
|
|
|
|
with_constructor.unwrap_or(make());
|
|
|
|
|
|
|
|
let with_new = Some(vec![1]);
|
|
|
|
with_new.unwrap_or(Vec::new());
|
|
|
|
|
|
|
|
let with_const_args = Some(vec![1]);
|
|
|
|
with_const_args.unwrap_or(Vec::with_capacity(12));
|
|
|
|
|
|
|
|
let with_err: Result<_, ()> = Ok(vec![1]);
|
|
|
|
with_err.unwrap_or(make());
|
|
|
|
|
|
|
|
let with_err_args: Result<_, ()> = Ok(vec![1]);
|
|
|
|
with_err_args.unwrap_or(Vec::with_capacity(12));
|
|
|
|
|
|
|
|
let with_default_trait = Some(1);
|
|
|
|
with_default_trait.unwrap_or(Default::default());
|
|
|
|
|
|
|
|
let with_default_type = Some(1);
|
|
|
|
with_default_type.unwrap_or(u64::default());
|
|
|
|
|
2021-07-30 01:56:47 -05:00
|
|
|
let self_default = None::<FakeDefault>;
|
|
|
|
self_default.unwrap_or(<FakeDefault>::default());
|
|
|
|
|
|
|
|
let real_default = None::<FakeDefault>;
|
|
|
|
real_default.unwrap_or(<FakeDefault as Default>::default());
|
|
|
|
|
2019-04-11 00:47:04 -05:00
|
|
|
let with_vec = Some(vec![1]);
|
|
|
|
with_vec.unwrap_or(vec![]);
|
|
|
|
|
|
|
|
let without_default = Some(Foo);
|
|
|
|
without_default.unwrap_or(Foo::new());
|
|
|
|
|
2020-09-22 17:34:56 -05:00
|
|
|
let mut map = HashMap::<u64, String>::new();
|
|
|
|
map.entry(42).or_insert(String::new());
|
|
|
|
|
2021-02-24 14:06:26 -06:00
|
|
|
let mut map_vec = HashMap::<u64, Vec<i32>>::new();
|
|
|
|
map_vec.entry(42).or_insert(vec![]);
|
|
|
|
|
2020-09-22 17:34:56 -05:00
|
|
|
let mut btree = BTreeMap::<u64, String>::new();
|
|
|
|
btree.entry(42).or_insert(String::new());
|
|
|
|
|
2021-02-24 14:06:26 -06:00
|
|
|
let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
|
|
|
|
btree_vec.entry(42).or_insert(vec![]);
|
|
|
|
|
2022-08-05 18:59:50 -05:00
|
|
|
let stringy = Some(String::new());
|
|
|
|
let _ = stringy.unwrap_or(String::new());
|
2019-04-24 01:11:20 -05:00
|
|
|
|
|
|
|
let opt = Some(1);
|
|
|
|
let hello = "Hello";
|
|
|
|
let _ = opt.ok_or(format!("{} world.", hello));
|
2020-10-29 15:30:20 -05:00
|
|
|
|
|
|
|
// index
|
|
|
|
let map = HashMap::<u64, u64>::new();
|
|
|
|
let _ = Some(1).unwrap_or(map[&1]);
|
|
|
|
let map = BTreeMap::<u64, u64>::new();
|
|
|
|
let _ = Some(1).unwrap_or(map[&1]);
|
|
|
|
// don't lint index vec
|
|
|
|
let vec = vec![1];
|
|
|
|
let _ = Some(1).unwrap_or(vec[1]);
|
2019-04-11 00:47:04 -05:00
|
|
|
}
|
|
|
|
|
2019-05-12 02:32:39 -05:00
|
|
|
struct Foo(u8);
|
2019-05-12 03:18:38 -05:00
|
|
|
struct Bar(String, Duration);
|
2019-05-12 02:32:39 -05:00
|
|
|
#[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));
|
2019-05-12 03:18:38 -05:00
|
|
|
|
|
|
|
let _ = Some("a".to_string()).or(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))));
|
2019-08-21 14:18:43 -05:00
|
|
|
|
|
|
|
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());
|
2021-03-22 14:34:20 -05:00
|
|
|
|
|
|
|
let string = "foo";
|
|
|
|
let _ = opt.ok_or(string.len());
|
2019-05-12 02:32:39 -05:00
|
|
|
}
|
|
|
|
|
2019-09-08 04:03:45 -05:00
|
|
|
// 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(())
|
|
|
|
}
|
|
|
|
|
2021-03-17 14:29:31 -05:00
|
|
|
mod issue6675 {
|
2021-08-17 15:22:48 -05:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-03-17 14:29:31 -05:00
|
|
|
unsafe fn foo() {
|
2021-08-17 15:22:48 -05:00
|
|
|
let s = "test".to_owned();
|
|
|
|
let s = &s as *const _;
|
|
|
|
None.unwrap_or(ptr_to_ref(s));
|
2021-03-17 14:29:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn bar() {
|
2021-08-17 15:22:48 -05:00
|
|
|
let s = "test".to_owned();
|
|
|
|
let s = &s as *const _;
|
|
|
|
None.unwrap_or(unsafe { ptr_to_ref(s) });
|
2021-03-17 14:29:31 -05:00
|
|
|
#[rustfmt::skip]
|
2021-08-17 15:22:48 -05:00
|
|
|
None.unwrap_or( unsafe { ptr_to_ref(s) } );
|
2021-03-17 14:29:31 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-15 15:19:01 -06:00
|
|
|
mod issue8239 {
|
2022-01-17 05:34:03 -06:00
|
|
|
fn more_than_max_suggestion_highest_lines_0() {
|
2022-01-15 15:19:01 -06:00
|
|
|
let frames = Vec::new();
|
|
|
|
frames
|
|
|
|
.iter()
|
|
|
|
.map(|f: &String| f.to_lowercase())
|
|
|
|
.reduce(|mut acc, f| {
|
|
|
|
acc.push_str(&f);
|
|
|
|
acc
|
|
|
|
})
|
|
|
|
.unwrap_or(String::new());
|
|
|
|
}
|
|
|
|
|
2022-01-17 05:34:03 -06:00
|
|
|
fn more_to_max_suggestion_highest_lines_1() {
|
2022-01-15 15:19:01 -06:00
|
|
|
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(String::new());
|
|
|
|
}
|
|
|
|
|
2022-01-17 05:34:03 -06:00
|
|
|
fn equal_to_max_suggestion_highest_lines() {
|
2022-01-15 15:19:01 -06:00
|
|
|
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(String::new());
|
|
|
|
}
|
|
|
|
|
2022-01-17 05:34:03 -06:00
|
|
|
fn less_than_max_suggestion_highest_lines() {
|
2022-01-15 15:19:01 -06:00
|
|
|
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(String::new());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-08 10:23:05 -05:00
|
|
|
mod issue9608 {
|
|
|
|
fn sig_drop() {
|
|
|
|
enum X {
|
|
|
|
X(std::fs::File),
|
|
|
|
Y(u32),
|
|
|
|
}
|
|
|
|
|
|
|
|
let _ = None.unwrap_or(X::Y(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 02:36:36 -05:00
|
|
|
mod issue8993 {
|
|
|
|
fn g() -> i32 {
|
|
|
|
3
|
|
|
|
}
|
|
|
|
|
|
|
|
fn f(n: i32) -> i32 {
|
|
|
|
n
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_map_or() {
|
|
|
|
let _ = Some(4).map_or(g(), |v| v);
|
|
|
|
let _ = Some(4).map_or(g(), f);
|
|
|
|
let _ = Some(4).map_or(0, f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-19 19:05:16 -05:00
|
|
|
mod lazy {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
fn foo() {
|
|
|
|
struct Foo;
|
|
|
|
|
|
|
|
impl Foo {
|
|
|
|
fn new() -> Foo {
|
|
|
|
Foo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct FakeDefault;
|
|
|
|
impl FakeDefault {
|
|
|
|
fn default() -> Self {
|
|
|
|
FakeDefault
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for FakeDefault {
|
|
|
|
fn default() -> Self {
|
|
|
|
FakeDefault
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let with_new = Some(vec![1]);
|
|
|
|
with_new.unwrap_or_else(Vec::new);
|
|
|
|
|
|
|
|
let with_default_trait = Some(1);
|
|
|
|
with_default_trait.unwrap_or_else(Default::default);
|
|
|
|
|
|
|
|
let with_default_type = Some(1);
|
|
|
|
with_default_type.unwrap_or_else(u64::default);
|
|
|
|
|
|
|
|
let real_default = None::<FakeDefault>;
|
|
|
|
real_default.unwrap_or_else(<FakeDefault as Default>::default);
|
|
|
|
|
|
|
|
let mut map = HashMap::<u64, String>::new();
|
|
|
|
map.entry(42).or_insert_with(String::new);
|
|
|
|
|
|
|
|
let mut btree = BTreeMap::<u64, String>::new();
|
|
|
|
btree.entry(42).or_insert_with(String::new);
|
|
|
|
|
|
|
|
let stringy = Some(String::new());
|
|
|
|
let _ = stringy.unwrap_or_else(String::new);
|
|
|
|
|
|
|
|
// negative tests
|
|
|
|
let self_default = None::<FakeDefault>;
|
|
|
|
self_default.unwrap_or_else(<FakeDefault>::default);
|
|
|
|
|
|
|
|
let without_default = Some(Foo);
|
|
|
|
without_default.unwrap_or_else(Foo::new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-01 13:10:48 -05:00
|
|
|
fn host_effect() {
|
|
|
|
// #12877 - make sure we don't ICE in type_certainty
|
|
|
|
use std::ops::Add;
|
|
|
|
|
|
|
|
Add::<i32>::add(1, 1).add(i32::MIN);
|
|
|
|
}
|
|
|
|
|
2024-07-12 04:23:08 -05:00
|
|
|
mod issue_10228 {
|
|
|
|
struct Entry;
|
|
|
|
|
|
|
|
impl Entry {
|
|
|
|
fn or_insert(self, _default: i32) {}
|
|
|
|
fn or_default(self) {
|
|
|
|
// Don't lint, suggested code is an infinite recursion
|
|
|
|
self.or_insert(Default::default())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 02:08:22 -05:00
|
|
|
// issue #12973
|
|
|
|
fn fn_call_in_nested_expr() {
|
|
|
|
struct Foo {
|
|
|
|
val: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn f() -> i32 {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
let opt: Option<i32> = Some(1);
|
|
|
|
|
2024-10-10 03:05:41 -05:00
|
|
|
//~v ERROR: function call inside of `unwrap_or`
|
2024-07-11 02:08:22 -05:00
|
|
|
let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`
|
|
|
|
//
|
2024-10-10 03:05:41 -05:00
|
|
|
//~v ERROR: function call inside of `unwrap_or`
|
2024-07-11 02:08:22 -05:00
|
|
|
let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
|
|
|
|
//
|
2024-10-10 03:05:41 -05:00
|
|
|
//~v ERROR: function call inside of `unwrap_or`
|
2024-07-11 02:08:22 -05:00
|
|
|
let _ = opt.unwrap_or({
|
|
|
|
let x = f();
|
|
|
|
x + 1
|
|
|
|
});
|
2024-10-10 03:05:41 -05:00
|
|
|
//~v ERROR: function call inside of `map_or`
|
2024-07-11 02:08:22 -05:00
|
|
|
let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
|
|
|
|
//
|
|
|
|
//~v ERROR: use of `unwrap_or` to construct default value
|
|
|
|
let _ = opt.unwrap_or({ i32::default() });
|
|
|
|
|
|
|
|
let opt_foo = Some(Foo {
|
|
|
|
val: String::from("123"),
|
|
|
|
});
|
2024-10-10 03:05:41 -05:00
|
|
|
//~v ERROR: function call inside of `unwrap_or`
|
2024-07-11 02:08:22 -05:00
|
|
|
let _ = opt_foo.unwrap_or(Foo { val: String::default() });
|
|
|
|
}
|
|
|
|
|
2019-04-11 00:47:04 -05:00
|
|
|
fn main() {}
|