From db80ef1795d34822877a38186f75c62ff68c6603 Mon Sep 17 00:00:00 2001 From: Teodoro Freund Date: Sat, 8 Nov 2025 10:42:06 +0000 Subject: [PATCH 1/2] Added new lint for `map_or(..., identity)` --- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/methods/map_or_identity.rs | 42 +++++++++ clippy_lints/src/methods/mod.rs | 26 ++++++ tests/ui/manual_ok_or.fixed | 1 + tests/ui/manual_ok_or.rs | 1 + tests/ui/manual_ok_or.stderr | 8 +- tests/ui/map_or_identity.fixed | 17 ++++ tests/ui/map_or_identity.rs | 17 ++++ tests/ui/map_or_identity.stderr | 17 ++++ tests/ui/option_if_let_else.fixed | 3 +- tests/ui/option_if_let_else.rs | 3 +- tests/ui/option_if_let_else.stderr | 58 ++++++------ tests/ui/or_fun_call.fixed | 1 + tests/ui/or_fun_call.rs | 1 + tests/ui/or_fun_call.stderr | 98 ++++++++++----------- 15 files changed, 210 insertions(+), 84 deletions(-) create mode 100644 clippy_lints/src/methods/map_or_identity.rs create mode 100644 tests/ui/map_or_identity.fixed create mode 100644 tests/ui/map_or_identity.rs create mode 100644 tests/ui/map_or_identity.stderr diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index a754eea31165..f630f9b2494f 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -420,6 +420,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[ crate::methods::MAP_ERR_IGNORE_INFO, crate::methods::MAP_FLATTEN_INFO, crate::methods::MAP_IDENTITY_INFO, + crate::methods::MAP_OR_IDENTITY_INFO, crate::methods::MAP_UNWRAP_OR_INFO, crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES_INFO, crate::methods::MUT_MUTEX_LOCK_INFO, diff --git a/clippy_lints/src/methods/map_or_identity.rs b/clippy_lints/src/methods/map_or_identity.rs new file mode 100644 index 000000000000..1b3d1cebdaae --- /dev/null +++ b/clippy_lints/src/methods/map_or_identity.rs @@ -0,0 +1,42 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_expr_identity_function; +use clippy_utils::res::MaybeDef; +use clippy_utils::source::snippet_with_applicability; +use rustc_errors::Applicability; +use rustc_hir::Expr; + +use rustc_lint::LateContext; +use rustc_span::Symbol; +use rustc_span::symbol::sym; + +use super::MAP_OR_IDENTITY; + +/// Emit a lint for an unnecessary `map_or` over `Option` or `Result` +/// +/// Note: `symbol` can only be `sym::Option` or `sym::Result` +fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>, symbol: Symbol) { + assert!(symbol == sym::Option || symbol == sym::Result); + let msg = format!("unused \"map closure\" when calling `{symbol}::map_or` value"); + let mut applicability = Applicability::MachineApplicable; + let self_snippet = snippet_with_applicability(cx, recv.span, "_", &mut applicability); + let err_snippet = snippet_with_applicability(cx, def_arg.span, "..", &mut applicability); + span_lint_and_sugg( + cx, + MAP_OR_IDENTITY, + expr.span, + msg, + "consider using `unwrap_or`", + format!("{self_snippet}.unwrap_or({err_snippet})"), + applicability, + ); +} + +/// lint use of `_.map_or(err, |n| n)` for `Result`s and `Option`s. +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>, map_arg: &Expr<'_>) { + // lint if the caller of `map_or()` is a `Result` or an `Option` + if let Some(x @ (sym::Result | sym::Option)) = cx.typeck_results().expr_ty(recv).opt_diag_name(cx) + && is_expr_identity_function(cx, map_arg) + { + emit_lint(cx, expr, recv, def_arg, x); + } +} diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 5b917e2bfefa..8fea4c2ea11c 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -73,6 +73,7 @@ mod map_collect_result_unit; mod map_err_ignore; mod map_flatten; mod map_identity; +mod map_or_identity; mod map_unwrap_or; mod map_with_unused_argument_over_ranges; mod mut_mutex_lock; @@ -4714,6 +4715,29 @@ declare_clippy_lint! { "filtering `std::io::Lines` with `filter_map()`, `flat_map()`, or `flatten()` might cause an infinite loop" } +declare_clippy_lint! { + /// ### What it does + /// Checks the usage of `.map_or(...)` with an identity function for `Option` and `Result` types. + /// + /// ### Why is this bad? + /// This can be written more concisely by using `unwrap_or()`. + /// + /// ### Example + /// ```no_run + /// let opt = Some(1); + /// opt.map_or(42, |v| v); + /// ``` + /// Use instead: + /// ```no_run + /// let opt = Some(1); + /// opt.unwrap_or(42); + /// ``` + #[clippy::version = "1.93.0"] + pub MAP_OR_IDENTITY, + suspicious, + "using an identity function when mapping with `.map_or(|err| ..., |x| x)`" +} + #[expect(clippy::struct_excessive_bools)] pub struct Methods { avoid_breaking_exported_api: bool, @@ -4897,6 +4921,7 @@ impl_lint_pass!(Methods => [ REDUNDANT_ITER_CLONED, UNNECESSARY_OPTION_MAP_OR_ELSE, LINES_FILTER_MAP_OK, + MAP_OR_IDENTITY, ]); /// Extracts a method call name, args, and `Span` of the method name. @@ -5368,6 +5393,7 @@ impl Methods { option_map_or_none::check(cx, expr, recv, def, map); manual_ok_or::check(cx, expr, recv, def, map); unnecessary_map_or::check(cx, expr, recv, def, map, span, self.msrv); + map_or_identity::check(cx, expr, recv, def, map); }, (sym::map_or_else, [def, map]) => { result_map_or_else_none::check(cx, expr, recv, def, map); diff --git a/tests/ui/manual_ok_or.fixed b/tests/ui/manual_ok_or.fixed index f326822149cd..58510fc9f022 100644 --- a/tests/ui/manual_ok_or.fixed +++ b/tests/ui/manual_ok_or.fixed @@ -4,6 +4,7 @@ #![allow(clippy::redundant_closure)] #![allow(dead_code)] #![allow(unused_must_use)] +#![allow(clippy::map_or_identity)] fn main() { // basic case diff --git a/tests/ui/manual_ok_or.rs b/tests/ui/manual_ok_or.rs index 7d065eda0ea1..813c982cf248 100644 --- a/tests/ui/manual_ok_or.rs +++ b/tests/ui/manual_ok_or.rs @@ -4,6 +4,7 @@ #![allow(clippy::redundant_closure)] #![allow(dead_code)] #![allow(unused_must_use)] +#![allow(clippy::map_or_identity)] fn main() { // basic case diff --git a/tests/ui/manual_ok_or.stderr b/tests/ui/manual_ok_or.stderr index e8176f4c31fa..8303d6c0d99b 100644 --- a/tests/ui/manual_ok_or.stderr +++ b/tests/ui/manual_ok_or.stderr @@ -1,5 +1,5 @@ error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:11:5 + --> tests/ui/manual_ok_or.rs:12:5 | LL | foo.map_or(Err("error"), |v| Ok(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")` @@ -8,19 +8,19 @@ LL | foo.map_or(Err("error"), |v| Ok(v)); = help: to override `-D warnings` add `#[allow(clippy::manual_ok_or)]` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:15:5 + --> tests/ui/manual_ok_or.rs:16:5 | LL | foo.map_or(Err("error"), Ok); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:19:5 + --> tests/ui/manual_ok_or.rs:20:5 | LL | None::.map_or(Err("error"), |v| Ok(v)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `None::.ok_or("error")` error: this pattern reimplements `Option::ok_or` - --> tests/ui/manual_ok_or.rs:24:5 + --> tests/ui/manual_ok_or.rs:25:5 | LL | / foo.map_or(Err::( LL | | diff --git a/tests/ui/map_or_identity.fixed b/tests/ui/map_or_identity.fixed new file mode 100644 index 000000000000..6f1c28e7ea8a --- /dev/null +++ b/tests/ui/map_or_identity.fixed @@ -0,0 +1,17 @@ +#![warn(clippy::map_or_identity)] + +mod issue15801 { + + fn foo(opt: Option, default: i32) -> i32 { + opt.unwrap_or(default) + //~^ map_or_identity + } + + fn bar(res: Result, default: i32) -> i32 { + res.unwrap_or(default) + //~^ map_or_identity + } +} +fn main() { + // test code goes here +} diff --git a/tests/ui/map_or_identity.rs b/tests/ui/map_or_identity.rs new file mode 100644 index 000000000000..1af85db810b4 --- /dev/null +++ b/tests/ui/map_or_identity.rs @@ -0,0 +1,17 @@ +#![warn(clippy::map_or_identity)] + +mod issue15801 { + + fn foo(opt: Option, default: i32) -> i32 { + opt.map_or(default, |o| o) + //~^ map_or_identity + } + + fn bar(res: Result, default: i32) -> i32 { + res.map_or(default, |o| o) + //~^ map_or_identity + } +} +fn main() { + // test code goes here +} diff --git a/tests/ui/map_or_identity.stderr b/tests/ui/map_or_identity.stderr new file mode 100644 index 000000000000..502f052bd6cf --- /dev/null +++ b/tests/ui/map_or_identity.stderr @@ -0,0 +1,17 @@ +error: unused "map closure" when calling `Option::map_or` value + --> tests/ui/map_or_identity.rs:6:9 + | +LL | opt.map_or(default, |o| o) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or`: `opt.unwrap_or(default)` + | + = note: `-D clippy::map-or-identity` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::map_or_identity)]` + +error: unused "map closure" when calling `Result::map_or` value + --> tests/ui/map_or_identity.rs:11:9 + | +LL | res.map_or(default, |o| o) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or`: `res.unwrap_or(default)` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed index a2ecea773efe..2c13ce5dae2a 100644 --- a/tests/ui/option_if_let_else.fixed +++ b/tests/ui/option_if_let_else.fixed @@ -7,7 +7,8 @@ clippy::manual_midpoint, clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::unnecessary_option_map_or_else + clippy::unnecessary_option_map_or_else, + clippy::map_or_identity )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs index 3adbc785237f..c41394a1e35e 100644 --- a/tests/ui/option_if_let_else.rs +++ b/tests/ui/option_if_let_else.rs @@ -7,7 +7,8 @@ clippy::manual_midpoint, clippy::manual_unwrap_or_default, clippy::manual_unwrap_or, - clippy::unnecessary_option_map_or_else + clippy::unnecessary_option_map_or_else, + clippy::map_or_identity )] fn bad1(string: Option<&str>) -> (bool, &str) { diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr index f5578f63c946..7e5df7c53110 100644 --- a/tests/ui/option_if_let_else.stderr +++ b/tests/ui/option_if_let_else.stderr @@ -1,5 +1,5 @@ error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:14:5 + --> tests/ui/option_if_let_else.rs:15:5 | LL | / if let Some(x) = string { LL | | @@ -13,19 +13,19 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:33:13 + --> tests/ui/option_if_let_else.rs:34:13 | LL | let _ = if let Some(s) = *string { s.len() } else { 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:35:13 + --> tests/ui/option_if_let_else.rs:36:13 | LL | let _ = if let Some(s) = &num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:37:13 + --> tests/ui/option_if_let_else.rs:38:13 | LL | let _ = if let Some(s) = &mut num { | _____________^ @@ -47,13 +47,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:44:13 + --> tests/ui/option_if_let_else.rs:45:13 | LL | let _ = if let Some(ref s) = num { s } else { &0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:46:13 + --> tests/ui/option_if_let_else.rs:47:13 | LL | let _ = if let Some(mut s) = num { | _____________^ @@ -75,7 +75,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:53:13 + --> tests/ui/option_if_let_else.rs:54:13 | LL | let _ = if let Some(ref mut s) = num { | _____________^ @@ -97,7 +97,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:63:5 + --> tests/ui/option_if_let_else.rs:64:5 | LL | / if let Some(x) = arg { LL | | @@ -118,7 +118,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:77:13 + --> tests/ui/option_if_let_else.rs:78:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -131,7 +131,7 @@ LL | | }; | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:87:13 + --> tests/ui/option_if_let_else.rs:88:13 | LL | let _ = if let Some(x) = arg { | _____________^ @@ -154,7 +154,7 @@ LL ~ }, |x| x * x * x * x); | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:121:13 + --> tests/ui/option_if_let_else.rs:122:13 | LL | / if let Some(idx) = s.find('.') { LL | | @@ -165,7 +165,7 @@ LL | | } | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:133:5 + --> tests/ui/option_if_let_else.rs:134:5 | LL | / if let Ok(binding) = variable { LL | | @@ -189,7 +189,7 @@ LL + }) | error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:158:5 + --> tests/ui/option_if_let_else.rs:159:5 | LL | / match r { LL | | @@ -199,7 +199,7 @@ LL | | } | |_____^ help: try: `r.map_or_else(|_| Vec::new(), |s| s.to_owned())` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:167:5 + --> tests/ui/option_if_let_else.rs:168:5 | LL | / if let Ok(s) = r { s.to_owned() } LL | | @@ -207,13 +207,13 @@ LL | | else { Vec::new() } | |_______________________^ help: try: `r.map_or_else(|_| Vec::new(), |s| s.to_owned())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:174:13 + --> tests/ui/option_if_let_else.rs:175:13 | LL | let _ = if let Some(x) = optional { x + 2 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:185:13 + --> tests/ui/option_if_let_else.rs:186:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -235,13 +235,13 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:214:13 + --> tests/ui/option_if_let_else.rs:215:13 | LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:219:13 + --> tests/ui/option_if_let_else.rs:220:13 | LL | let _ = if let Some(x) = Some(0) { | _____________^ @@ -263,7 +263,7 @@ LL ~ }); | error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:259:13 + --> tests/ui/option_if_let_else.rs:260:13 | LL | let _ = match s { | _____________^ @@ -274,7 +274,7 @@ LL | | }; | |_____^ help: try: `s.map_or(1, |string| string.len())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:264:13 + --> tests/ui/option_if_let_else.rs:265:13 | LL | let _ = match Some(10) { | _____________^ @@ -285,7 +285,7 @@ LL | | }; | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:271:13 + --> tests/ui/option_if_let_else.rs:272:13 | LL | let _ = match res { | _____________^ @@ -296,7 +296,7 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:276:13 + --> tests/ui/option_if_let_else.rs:277:13 | LL | let _ = match res { | _____________^ @@ -307,13 +307,13 @@ LL | | }; | |_____^ help: try: `res.map_or(1, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:281:13 + --> tests/ui/option_if_let_else.rs:282:13 | LL | let _ = if let Ok(a) = res { a + 1 } else { 5 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:299:17 + --> tests/ui/option_if_let_else.rs:300:17 | LL | let _ = match initial { | _________________^ @@ -324,7 +324,7 @@ LL | | }; | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:307:17 + --> tests/ui/option_if_let_else.rs:308:17 | LL | let _ = match initial { | _________________^ @@ -335,7 +335,7 @@ LL | | }; | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:331:24 + --> tests/ui/option_if_let_else.rs:332:24 | LL | let mut _hashmap = if let Some(hm) = &opt { | ________________________^ @@ -347,19 +347,19 @@ LL | | }; | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:338:19 + --> tests/ui/option_if_let_else.rs:339:19 | LL | let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())` error: use Option::map_or instead of an if let/else - --> tests/ui/option_if_let_else.rs:389:22 + --> tests/ui/option_if_let_else.rs:390:22 | LL | let _ = unsafe { if let Some(o) = *opt_raw_ptr { o } else { 1 } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*opt_raw_ptr).map_or(1, |o| o)` error: use Option::map_or_else instead of an if let/else - --> tests/ui/option_if_let_else.rs:395:13 + --> tests/ui/option_if_let_else.rs:396:13 | LL | let _ = match res { | _____________^ diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed index 314da0804a5f..6fadf61f1174 100644 --- a/tests/ui/or_fun_call.fixed +++ b/tests/ui/or_fun_call.fixed @@ -6,6 +6,7 @@ clippy::unnecessary_literal_unwrap, clippy::unnecessary_result_map_or_else, clippy::unnecessary_option_map_or_else, + clippy::map_or_identity, clippy::useless_vec )] diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs index 2a19614026ec..06ad7f266d5a 100644 --- a/tests/ui/or_fun_call.rs +++ b/tests/ui/or_fun_call.rs @@ -6,6 +6,7 @@ clippy::unnecessary_literal_unwrap, clippy::unnecessary_result_map_or_else, clippy::unnecessary_option_map_or_else, + clippy::map_or_identity, clippy::useless_vec )] diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr index 3d55f2cd1f9f..934af4656ea3 100644 --- a/tests/ui/or_fun_call.stderr +++ b/tests/ui/or_fun_call.stderr @@ -1,5 +1,5 @@ error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:53:22 + --> tests/ui/or_fun_call.rs:54:22 | LL | with_constructor.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(make)` @@ -8,7 +8,7 @@ LL | with_constructor.unwrap_or(make()); = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:57:14 + --> tests/ui/or_fun_call.rs:58:14 | LL | with_new.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` @@ -17,205 +17,205 @@ LL | with_new.unwrap_or(Vec::new()); = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:61:21 + --> tests/ui/or_fun_call.rs:62:21 | LL | with_const_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:65:14 + --> tests/ui/or_fun_call.rs:66:14 | LL | with_err.unwrap_or(make()); | ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:69:19 + --> tests/ui/or_fun_call.rs:70:19 | LL | with_err_args.unwrap_or(Vec::with_capacity(12)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:73:24 + --> tests/ui/or_fun_call.rs:74:24 | LL | with_default_trait.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:77:23 + --> tests/ui/or_fun_call.rs:78:23 | LL | with_default_type.unwrap_or(u64::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:97:18 + --> tests/ui/or_fun_call.rs:98:18 | LL | self_default.unwrap_or(::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(::default)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:101:18 + --> tests/ui/or_fun_call.rs:102:18 | LL | real_default.unwrap_or(::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:105:14 + --> tests/ui/or_fun_call.rs:106:14 | LL | with_vec.unwrap_or(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:109:21 + --> tests/ui/or_fun_call.rs:110:21 | LL | without_default.unwrap_or(Foo::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:113:19 + --> tests/ui/or_fun_call.rs:114:19 | LL | map.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:117:23 + --> tests/ui/or_fun_call.rs:118:23 | LL | map_vec.entry(42).or_insert(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:121:21 + --> tests/ui/or_fun_call.rs:122:21 | LL | btree.entry(42).or_insert(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert` to construct default value - --> tests/ui/or_fun_call.rs:125:25 + --> tests/ui/or_fun_call.rs:126:25 | LL | btree_vec.entry(42).or_insert(Vec::new()); | ^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:129:21 + --> tests/ui/or_fun_call.rs:130:21 | LL | let _ = stringy.unwrap_or(String::new()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `ok_or` - --> tests/ui/or_fun_call.rs:134:17 + --> tests/ui/or_fun_call.rs:135:17 | LL | let _ = opt.ok_or(format!("{} world.", hello)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ok_or_else(|| format!("{} world.", hello))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:139:21 + --> tests/ui/or_fun_call.rs:140:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:142:21 + --> tests/ui/or_fun_call.rs:143:21 | LL | let _ = Some(1).unwrap_or(map[&1]); | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])` error: function call inside of `or` - --> tests/ui/or_fun_call.rs:167:35 + --> tests/ui/or_fun_call.rs:168:35 | LL | let _ = Some("a".to_string()).or(Some("b".to_string())); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some("b".to_string()))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:210:18 + --> tests/ui/or_fun_call.rs:211:18 | LL | None.unwrap_or(ptr_to_ref(s)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:218:14 + --> tests/ui/or_fun_call.rs:219:14 | LL | None.unwrap_or(unsafe { ptr_to_ref(s) }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:221:14 + --> tests/ui/or_fun_call.rs:222:14 | LL | None.unwrap_or( unsafe { ptr_to_ref(s) } ); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:297:25 + --> tests/ui/or_fun_call.rs:298:25 | LL | let _ = Some(4).map_or(g(), |v| v); | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:299:25 + --> tests/ui/or_fun_call.rs:300:25 | LL | let _ = Some(4).map_or(g(), f); | ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:302:25 + --> tests/ui/or_fun_call.rs:303:25 | LL | let _ = Some(4).map_or("asd".to_string().len() as i32, f); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| "asd".to_string().len() as i32, f)` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:333:18 + --> tests/ui/or_fun_call.rs:334:18 | LL | with_new.unwrap_or_else(Vec::new); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:337:28 + --> tests/ui/or_fun_call.rs:338:28 | LL | with_default_trait.unwrap_or_else(Default::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:341:27 + --> tests/ui/or_fun_call.rs:342:27 | LL | with_default_type.unwrap_or_else(u64::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:345:22 + --> tests/ui/or_fun_call.rs:346:22 | LL | real_default.unwrap_or_else(::default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:349:23 + --> tests/ui/or_fun_call.rs:350:23 | LL | map.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `or_insert_with` to construct default value - --> tests/ui/or_fun_call.rs:353:25 + --> tests/ui/or_fun_call.rs:354:25 | LL | btree.entry(42).or_insert_with(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()` error: use of `unwrap_or_else` to construct default value - --> tests/ui/or_fun_call.rs:357:25 + --> tests/ui/or_fun_call.rs:358:25 | LL | let _ = stringy.unwrap_or_else(String::new); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:399:17 + --> tests/ui/or_fun_call.rs:400:17 | LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:404:17 + --> tests/ui/or_fun_call.rs:405:17 | LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)` | ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:409:17 + --> tests/ui/or_fun_call.rs:410:17 | LL | let _ = opt.unwrap_or({ | _________________^ @@ -235,79 +235,79 @@ LL ~ }); | error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:415:17 + --> tests/ui/or_fun_call.rs:416:17 | LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:420:17 + --> tests/ui/or_fun_call.rs:421:17 | LL | let _ = opt.unwrap_or({ i32::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:427:21 + --> tests/ui/or_fun_call.rs:428:21 | LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:442:19 + --> tests/ui/or_fun_call.rs:443:19 | LL | let _ = x.map_or(g(), |v| v); | ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), |v| v)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:444:19 + --> tests/ui/or_fun_call.rs:445:19 | LL | let _ = x.map_or(g(), f); | ^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), f)` error: function call inside of `map_or` - --> tests/ui/or_fun_call.rs:447:19 + --> tests/ui/or_fun_call.rs:448:19 | LL | let _ = x.map_or("asd".to_string().len() as i32, f); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| "asd".to_string().len() as i32, f)` error: function call inside of `get_or_insert` - --> tests/ui/or_fun_call.rs:458:15 + --> tests/ui/or_fun_call.rs:459:15 | LL | let _ = x.get_or_insert(g()); | ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)` error: function call inside of `and` - --> tests/ui/or_fun_call.rs:468:15 + --> tests/ui/or_fun_call.rs:469:15 | LL | let _ = x.and(g()); | ^^^^^^^^ help: try: `and_then(|_| g())` error: function call inside of `and` - --> tests/ui/or_fun_call.rs:478:15 + --> tests/ui/or_fun_call.rs:479:15 | LL | let _ = x.and(g()); | ^^^^^^^^ help: try: `and_then(|_| g())` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:484:17 + --> tests/ui/or_fun_call.rs:485:17 | LL | let _ = opt.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: function call inside of `unwrap_or` - --> tests/ui/or_fun_call.rs:486:17 + --> tests/ui/or_fun_call.rs:487:17 | LL | let _ = res.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Default::default())` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:492:17 + --> tests/ui/or_fun_call.rs:493:17 | LL | let _ = opt.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` error: use of `unwrap_or` to construct default value - --> tests/ui/or_fun_call.rs:494:17 + --> tests/ui/or_fun_call.rs:495:17 | LL | let _ = res.unwrap_or(Default::default()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()` From 6d20f77f3597a43088d4bdd3a880b09bd3caae90 Mon Sep 17 00:00:00 2001 From: Teodoro Freund Date: Sat, 8 Nov 2025 10:45:50 +0000 Subject: [PATCH 2/2] Forgot changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb2755be0ee..be2aa8cce549 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6585,6 +6585,7 @@ Released 2018-09-13 [`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_err_ignore [`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten [`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity +[`map_or_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_or_identity [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or [`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref