Skip to content

Commit 066f286

Browse files
Extend result_map_or_into_option lint to handle Result::map_or_else(|_| None, Some)
1 parent 6eb935a commit 066f286

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ mod read_line_without_trim;
8080
mod readonly_write_lock;
8181
mod redundant_as_str;
8282
mod repeat_once;
83+
mod result_map_or_else_none;
8384
mod search_is_some;
8485
mod seek_from_current;
8586
mod seek_to_start_instead_of_rewind;
@@ -4291,6 +4292,9 @@ impl Methods {
42914292
option_map_or_none::check(cx, expr, recv, def, map);
42924293
manual_ok_or::check(cx, expr, recv, def, map);
42934294
},
4295+
("map_or_else", [_, map]) => {
4296+
result_map_or_else_none::check(cx, expr, recv, map);
4297+
},
42944298
("next", []) => {
42954299
if let Some((name2, recv2, args2, _, _)) = method_call(recv) {
42964300
match (name2, args2) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet;
3+
use clippy_utils::ty::is_type_diagnostic_item;
4+
use clippy_utils::{is_res_lang_ctor, path_res};
5+
use rustc_errors::Applicability;
6+
use rustc_hir as hir;
7+
use rustc_hir::LangItem::OptionSome;
8+
use rustc_lint::LateContext;
9+
use rustc_span::symbol::sym;
10+
11+
use super::RESULT_MAP_OR_INTO_OPTION;
12+
13+
/// lint use of `_.map_or(None, _)` for `Option`s and `Result`s
14+
pub(super) fn check<'tcx>(
15+
cx: &LateContext<'tcx>,
16+
expr: &'tcx hir::Expr<'_>,
17+
recv: &'tcx hir::Expr<'_>,
18+
map_arg: &'tcx hir::Expr<'_>,
19+
) {
20+
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
21+
22+
if !is_result {
23+
return;
24+
}
25+
26+
let f_arg_is_some = is_res_lang_ctor(cx, path_res(cx, map_arg), OptionSome);
27+
28+
if f_arg_is_some {
29+
// if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind {}
30+
let msg = "called `map_or_else(|_| None, Some)` on a `Result` value";
31+
let self_snippet = snippet(cx, recv.span, "..");
32+
span_lint_and_sugg(
33+
cx,
34+
RESULT_MAP_OR_INTO_OPTION,
35+
expr.span,
36+
msg,
37+
"try using `ok` instead",
38+
format!("{self_snippet}.ok()"),
39+
Applicability::MachineApplicable,
40+
);
41+
}
42+
}

0 commit comments

Comments
 (0)