Deprecate redundant lint option_map_or_err_ok and take manual_ok_or out of pedantic (#14027)
While extending the `option_map_or_err_ok` lint (warn by default,
"style") to recognize η-expanded forms of `Ok`, as in
```rust
// Should suggest `opt.ok_or("foobar")`
let _ = opt.map_or(Err("foobar"), |x| Ok(x));
```
I discovered that the `manual_ok_or` lint (allow by default, "pedantic")
already covered exactly the cases handled by `option_map_or_err_ok`,
including the one I was adding. Apparently, `option_map_or_err_ok` was
added without realizing that the lint already existed under the
`manual_ok_or` name. As a matter of fact, artifacts of this second lint
were even present in the first lint `stderr` file and went unnoticed for
more than a year.
This PR:
- deprecates `option_map_or_err_ok` with a message saying to use
`manual_ok_or`
- moves `manual_ok_or` from "pedantic" to "style" (the category in which
`option_map_or_err_ok` was)
In addition, I think that this lint, which is short, machine applicable,
and leads to shorter and clearer code with less arguments (`Ok`
disappears) and the removal of one level of call (`Err(x)` is replaced
by `x`), is a reason by itself to be in "style".
changelog: [`option_map_or_err_ok` and `manual_ok_or`]: move
`manual_ok_or` from "pedantic" to "style", and deprecate the redundant
style lint `option_map_or_err_ok`.
This commit is contained in:
commit
4e5d00a0a7
10 changed files with 12 additions and 107 deletions
|
|
@ -452,7 +452,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::methods::OPTION_AS_REF_CLONED_INFO,
|
||||
crate::methods::OPTION_AS_REF_DEREF_INFO,
|
||||
crate::methods::OPTION_FILTER_MAP_INFO,
|
||||
crate::methods::OPTION_MAP_OR_ERR_OK_INFO,
|
||||
crate::methods::OPTION_MAP_OR_NONE_INFO,
|
||||
crate::methods::OR_FUN_CALL_INFO,
|
||||
crate::methods::OR_THEN_UNWRAP_INFO,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION): &[(&str, &str)] = &[
|
|||
("clippy::pub_enum_variant_names", "`clippy::enum_variant_names` now covers this case via the `avoid-breaking-exported-api` config"),
|
||||
#[clippy::version = "1.54.0"]
|
||||
("clippy::wrong_pub_self_convention", "`clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config"),
|
||||
#[clippy::version = "1.86.0"]
|
||||
("clippy::option_map_or_err_ok", "`clippy::manual_ok_or` covers this case"),
|
||||
// end deprecated lints. used by `cargo dev deprecate_lint`
|
||||
]}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ mod ok_expect;
|
|||
mod open_options;
|
||||
mod option_as_ref_cloned;
|
||||
mod option_as_ref_deref;
|
||||
mod option_map_or_err_ok;
|
||||
mod option_map_or_none;
|
||||
mod option_map_unwrap_or;
|
||||
mod or_fun_call;
|
||||
|
|
@ -2641,7 +2640,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
#[clippy::version = "1.49.0"]
|
||||
pub MANUAL_OK_OR,
|
||||
pedantic,
|
||||
style,
|
||||
"finds patterns that can be encoded more concisely with `Option::ok_or`"
|
||||
}
|
||||
|
||||
|
|
@ -3783,31 +3782,6 @@ declare_clippy_lint! {
|
|||
"calls to `Path::join` which will overwrite the original path"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for usage of `_.map_or(Err(_), Ok)`.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Readability, this can be written more concisely as
|
||||
/// `_.ok_or(_)`.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// # let opt = Some(1);
|
||||
/// opt.map_or(Err("error"), Ok);
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// # let opt = Some(1);
|
||||
/// opt.ok_or("error");
|
||||
/// ```
|
||||
#[clippy::version = "1.76.0"]
|
||||
pub OPTION_MAP_OR_ERR_OK,
|
||||
style,
|
||||
"using `Option.map_or(Err(_), Ok)`, which is more succinctly expressed as `Option.ok_or(_)`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may
|
||||
|
|
@ -4579,7 +4553,6 @@ impl_lint_pass!(Methods => [
|
|||
WAKER_CLONE_WAKE,
|
||||
UNNECESSARY_FALLIBLE_CONVERSIONS,
|
||||
JOIN_ABSOLUTE_PATHS,
|
||||
OPTION_MAP_OR_ERR_OK,
|
||||
RESULT_FILTER_MAP,
|
||||
ITER_FILTER_IS_SOME,
|
||||
ITER_FILTER_IS_OK,
|
||||
|
|
@ -5146,7 +5119,6 @@ impl Methods {
|
|||
("map_or", [def, map]) => {
|
||||
option_map_or_none::check(cx, expr, recv, def, map);
|
||||
manual_ok_or::check(cx, expr, recv, def, map);
|
||||
option_map_or_err_ok::check(cx, expr, recv, def, map);
|
||||
unnecessary_map_or::check(cx, expr, recv, def, map, span, &self.msrv);
|
||||
},
|
||||
("map_or_else", [def, map]) => {
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{is_res_lang_ctor, path_res};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{ResultErr, ResultOk};
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
use super::OPTION_MAP_OR_ERR_OK;
|
||||
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &'tcx Expr<'tcx>,
|
||||
recv: &'tcx Expr<'_>,
|
||||
or_expr: &'tcx Expr<'_>,
|
||||
map_expr: &'tcx Expr<'_>,
|
||||
) {
|
||||
// We check that it's called on an `Option` type.
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option)
|
||||
// We check that first we pass an `Err`.
|
||||
&& let ExprKind::Call(call, &[arg]) = or_expr.kind
|
||||
&& is_res_lang_ctor(cx, path_res(cx, call), ResultErr)
|
||||
// And finally we check that it is mapped as `Ok`.
|
||||
&& is_res_lang_ctor(cx, path_res(cx, map_expr), ResultOk)
|
||||
{
|
||||
let msg = "called `map_or(Err(_), Ok)` on an `Option` value";
|
||||
let self_snippet = snippet(cx, recv.span, "..");
|
||||
let err_snippet = snippet(cx, arg.span, "..");
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
OPTION_MAP_OR_ERR_OK,
|
||||
expr.span,
|
||||
msg,
|
||||
"consider using `ok_or`",
|
||||
format!("{self_snippet}.ok_or({err_snippet})"),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -15,5 +15,6 @@
|
|||
#![warn(clippy::regex_macro)] //~ ERROR: lint `clippy::regex_macro`
|
||||
#![warn(clippy::pub_enum_variant_names)] //~ ERROR: lint `clippy::pub_enum_variant_names`
|
||||
#![warn(clippy::wrong_pub_self_convention)] //~ ERROR: lint `clippy::wrong_pub_self_convention`
|
||||
#![warn(clippy::option_map_or_err_ok)] //~ ERROR: lint `clippy::option_map_or_err_ok`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -79,5 +79,11 @@ error: lint `clippy::wrong_pub_self_convention` has been removed: `clippy::wrong
|
|||
LL | #![warn(clippy::wrong_pub_self_convention)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error: lint `clippy::option_map_or_err_ok` has been removed: `clippy::manual_ok_or` covers this case
|
||||
--> tests/ui/deprecated.rs:18:9
|
||||
|
|
||||
LL | #![warn(clippy::option_map_or_err_ok)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -13,15 +13,6 @@ error: this pattern reimplements `Option::ok_or`
|
|||
LL | foo.map_or(Err("error"), Ok);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or("error")`
|
||||
|
||||
error: called `map_or(Err(_), Ok)` on an `Option` value
|
||||
--> tests/ui/manual_ok_or.rs:14:5
|
||||
|
|
||||
LL | foo.map_or(Err("error"), Ok);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `foo.ok_or("error")`
|
||||
|
|
||||
= note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
|
||||
|
||||
error: this pattern reimplements `Option::ok_or`
|
||||
--> tests/ui/manual_ok_or.rs:17:5
|
||||
|
|
||||
|
|
@ -47,5 +38,5 @@ LL + "{}{}{}{}{}{}{}",
|
|||
LL ~ "Alice", "Bob", "Sarah", "Marc", "Sandra", "Eric", "Jenifer"));
|
||||
|
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#![warn(clippy::option_map_or_err_ok)]
|
||||
|
||||
fn main() {
|
||||
let x = Some("a");
|
||||
let _ = x.ok_or("a");
|
||||
//~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
#![warn(clippy::option_map_or_err_ok)]
|
||||
|
||||
fn main() {
|
||||
let x = Some("a");
|
||||
let _ = x.map_or(Err("a"), Ok);
|
||||
//~^ ERROR: called `map_or(Err(_), Ok)` on an `Option` value
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
error: called `map_or(Err(_), Ok)` on an `Option` value
|
||||
--> tests/ui/option_map_or_err_ok.rs:5:13
|
||||
|
|
||||
LL | let _ = x.map_or(Err("a"), Ok);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `x.ok_or("a")`
|
||||
|
|
||||
= note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue