Auto merge of #7216 - ThibsG:OptionIfLetElse7006, r=llogiq

Stop linting `else if let` pattern in [`option_if_let_else`] lint

For readability concerns, it is counterproductive to lint `else if let` pattern.
Unfortunately the suggested code is much less readable.

Fixes: #7006

changelog: stop linting `else if let` pattern in [`option_if_let_else`] lint
This commit is contained in:
bors 2021-05-17 05:45:24 +00:00
commit 44e0747664
3 changed files with 9 additions and 14 deletions

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::usage::contains_return_break_continue_macro;
use clippy_utils::{eager_or_lazy, get_enclosing_block, in_macro, is_lang_ctor};
use clippy_utils::{eager_or_lazy, get_enclosing_block, in_macro, is_else_clause, is_lang_ctor};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::LangItem::OptionSome;
@ -161,6 +161,7 @@ fn detect_option_if_let_else<'tcx>(
if_chain! {
if !in_macro(expr.span); // Don't lint macros, because it behaves weirdly
if let ExprKind::Match(cond_expr, arms, MatchSource::IfLetDesugar{contains_else_clause: true}) = &expr.kind;
if !is_else_clause(cx.tcx, expr);
if arms.len() == 2;
if !is_result_ok(cx, cond_expr); // Don't lint on Result::ok because a different lint does it already
if let PatKind::TupleStruct(struct_qpath, &[inner_pat], _) = &arms[0].pat.kind;
@ -168,6 +169,7 @@ fn detect_option_if_let_else<'tcx>(
if let PatKind::Binding(bind_annotation, _, id, _) = &inner_pat.kind;
if !contains_return_break_continue_macro(arms[0].body);
if !contains_return_break_continue_macro(arms[1].body);
then {
let capture_mut = if bind_annotation == &BindingAnnotation::Mutable { "mut " } else { "" };
let some_body = extract_body_from_arm(&arms[0])?;

View file

@ -10,7 +10,11 @@ fn bad1(string: Option<&str>) -> (bool, &str) {
fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> {
if string.is_none() {
None
} else { string.map_or(Some((false, "")), |x| Some((true, x))) }
} else if let Some(x) = string {
Some((true, x))
} else {
Some((false, ""))
}
}
fn unop_bad(string: &Option<&str>, mut num: Option<i32>) {

View file

@ -10,17 +10,6 @@ LL | | }
|
= note: `-D clippy::option-if-let-else` implied by `-D warnings`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:17:12
|
LL | } else if let Some(x) = string {
| ____________^
LL | | Some((true, x))
LL | | } else {
LL | | Some((false, ""))
LL | | }
| |_____^ help: try: `{ string.map_or(Some((false, "")), |x| Some((true, x))) }`
error: use Option::map_or instead of an if let/else
--> $DIR/option_if_let_else.rs:25:13
|
@ -159,5 +148,5 @@ error: use Option::map_or instead of an if let/else
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
error: aborting due to 12 previous errors
error: aborting due to 11 previous errors