Skip to content

Commit 2f0e9f7

Browse files
committed
or_fun_call: fix suggestion for or_insert(vec![])
Applies for `std::collections::hash_map::Entry` and `std::collections::btree_map::Entry` Example: Previously, for the following code: `let _ = hash_map.entry("test".to_owned()).or_insert(vec![]);` clippy would suggest to use: `or_insert_with(vec![])`, which causes a compiler error (E0277). Now clippy suggests: `or_insert_with(Vec::new)`
1 parent 877be18 commit 2f0e9f7

File tree

4 files changed

+46
-8
lines changed

4 files changed

+46
-8
lines changed

clippy_lints/src/methods/mod.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -2005,12 +2005,26 @@ fn lint_or_fun_call<'tcx>(
20052005
if poss.contains(&name);
20062006

20072007
then {
2008+
let macro_expanded_snipped;
20082009
let sugg: Cow<'_, str> = {
20092010
let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) {
20102011
(false, Some(fun_span)) => (fun_span, false),
20112012
_ => (arg.span, true),
20122013
};
2013-
let snippet = snippet_with_macro_callsite(cx, snippet_span, "..");
2014+
let snippet = {
2015+
let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, "..");
2016+
if not_macro_argument_snippet == "vec![]" {
2017+
macro_expanded_snipped = snippet(cx, snippet_span, "..");
2018+
match macro_expanded_snipped.strip_prefix("$crate::vec::") {
2019+
Some(stripped) => Cow::from(stripped),
2020+
None => macro_expanded_snipped
2021+
}
2022+
}
2023+
else {
2024+
not_macro_argument_snippet
2025+
}
2026+
};
2027+
20142028
if use_lambda {
20152029
let l_arg = if fn_has_arguments { "_" } else { "" };
20162030
format!("|{}| {}", l_arg, snippet).into()

tests/ui/or_fun_call.fixed

+6
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,15 @@ fn or_fun_call() {
6262
let mut map = HashMap::<u64, String>::new();
6363
map.entry(42).or_insert_with(String::new);
6464

65+
let mut map_vec = HashMap::<u64, Vec<i32>>::new();
66+
map_vec.entry(42).or_insert_with(Vec::new);
67+
6568
let mut btree = BTreeMap::<u64, String>::new();
6669
btree.entry(42).or_insert_with(String::new);
6770

71+
let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
72+
btree_vec.entry(42).or_insert_with(Vec::new);
73+
6874
let stringy = Some(String::from(""));
6975
let _ = stringy.unwrap_or_else(|| "".to_owned());
7076

tests/ui/or_fun_call.rs

+6
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,15 @@ fn or_fun_call() {
6262
let mut map = HashMap::<u64, String>::new();
6363
map.entry(42).or_insert(String::new());
6464

65+
let mut map_vec = HashMap::<u64, Vec<i32>>::new();
66+
map_vec.entry(42).or_insert(vec![]);
67+
6568
let mut btree = BTreeMap::<u64, String>::new();
6669
btree.entry(42).or_insert(String::new());
6770

71+
let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
72+
btree_vec.entry(42).or_insert(vec![]);
73+
6874
let stringy = Some(String::from(""));
6975
let _ = stringy.unwrap_or("".to_owned());
7076

tests/ui/or_fun_call.stderr

+19-7
Original file line numberDiff line numberDiff line change
@@ -67,40 +67,52 @@ LL | map.entry(42).or_insert(String::new());
6767
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
6868

6969
error: use of `or_insert` followed by a function call
70-
--> $DIR/or_fun_call.rs:66:21
70+
--> $DIR/or_fun_call.rs:66:23
71+
|
72+
LL | map_vec.entry(42).or_insert(vec![]);
73+
| ^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(Vec::new)`
74+
75+
error: use of `or_insert` followed by a function call
76+
--> $DIR/or_fun_call.rs:69:21
7177
|
7278
LL | btree.entry(42).or_insert(String::new());
7379
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
7480

81+
error: use of `or_insert` followed by a function call
82+
--> $DIR/or_fun_call.rs:72:25
83+
|
84+
LL | btree_vec.entry(42).or_insert(vec![]);
85+
| ^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(Vec::new)`
86+
7587
error: use of `unwrap_or` followed by a function call
76-
--> $DIR/or_fun_call.rs:69:21
88+
--> $DIR/or_fun_call.rs:75:21
7789
|
7890
LL | let _ = stringy.unwrap_or("".to_owned());
7991
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())`
8092

8193
error: use of `unwrap_or` followed by a function call
82-
--> $DIR/or_fun_call.rs:77:21
94+
--> $DIR/or_fun_call.rs:83:21
8395
|
8496
LL | let _ = Some(1).unwrap_or(map[&1]);
8597
| ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])`
8698

8799
error: use of `unwrap_or` followed by a function call
88-
--> $DIR/or_fun_call.rs:79:21
100+
--> $DIR/or_fun_call.rs:85:21
89101
|
90102
LL | let _ = Some(1).unwrap_or(map[&1]);
91103
| ^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| map[&1])`
92104

93105
error: use of `or` followed by a function call
94-
--> $DIR/or_fun_call.rs:103:35
106+
--> $DIR/or_fun_call.rs:109:35
95107
|
96108
LL | let _ = Some("a".to_string()).or(Some("b".to_string()));
97109
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))`
98110

99111
error: use of `or` followed by a function call
100-
--> $DIR/or_fun_call.rs:107:10
112+
--> $DIR/or_fun_call.rs:113:10
101113
|
102114
LL | .or(Some(Bar(b, Duration::from_secs(2))));
103115
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(Bar(b, Duration::from_secs(2))))`
104116

105-
error: aborting due to 17 previous errors
117+
error: aborting due to 19 previous errors
106118

0 commit comments

Comments
 (0)