mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Auto merge of #8471 - J-ZhengLi:master-issue7040, r=llogiq
new lint that detects useless match expression fixes #7040 changelog: Add new lint [`needless_match`] under complexity lint group
This commit is contained in:
commit
75b616e92f
@ -3331,6 +3331,7 @@ Released 2018-09-13
|
||||
[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each
|
||||
[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
|
||||
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
|
||||
[`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match
|
||||
[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref
|
||||
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
|
||||
[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark
|
||||
|
@ -138,6 +138,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
|
||||
LintId::of(matches::MATCH_OVERLAPPING_ARM),
|
||||
LintId::of(matches::MATCH_REF_PATS),
|
||||
LintId::of(matches::MATCH_SINGLE_BINDING),
|
||||
LintId::of(matches::NEEDLESS_MATCH),
|
||||
LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
|
||||
LintId::of(matches::SINGLE_MATCH),
|
||||
LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
|
||||
|
@ -30,6 +30,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
|
||||
LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
|
||||
LintId::of(matches::MATCH_AS_REF),
|
||||
LintId::of(matches::MATCH_SINGLE_BINDING),
|
||||
LintId::of(matches::NEEDLESS_MATCH),
|
||||
LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
|
||||
LintId::of(methods::BIND_INSTEAD_OF_MAP),
|
||||
LintId::of(methods::CLONE_ON_COPY),
|
||||
|
@ -260,6 +260,7 @@ store.register_lints(&[
|
||||
matches::MATCH_SINGLE_BINDING,
|
||||
matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
|
||||
matches::MATCH_WILD_ERR_ARM,
|
||||
matches::NEEDLESS_MATCH,
|
||||
matches::REDUNDANT_PATTERN_MATCHING,
|
||||
matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
|
||||
matches::SINGLE_MATCH,
|
||||
|
@ -16,6 +16,7 @@ mod match_same_arms;
|
||||
mod match_single_binding;
|
||||
mod match_wild_enum;
|
||||
mod match_wild_err_arm;
|
||||
mod needless_match;
|
||||
mod overlapping_arms;
|
||||
mod redundant_pattern_match;
|
||||
mod rest_pat_in_fully_bound_struct;
|
||||
@ -566,6 +567,49 @@ declare_clippy_lint! {
|
||||
"`match` with identical arm bodies"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`
|
||||
/// when function signatures are the same.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// This `match` block does nothing and might not be what the coder intended.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```rust,ignore
|
||||
/// fn foo() -> Result<(), i32> {
|
||||
/// match result {
|
||||
/// Ok(val) => Ok(val),
|
||||
/// Err(err) => Err(err),
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn bar() -> Option<i32> {
|
||||
/// if let Some(val) = option {
|
||||
/// Some(val)
|
||||
/// } else {
|
||||
/// None
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Could be replaced as
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// fn foo() -> Result<(), i32> {
|
||||
/// result
|
||||
/// }
|
||||
///
|
||||
/// fn bar() -> Option<i32> {
|
||||
/// option
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.61.0"]
|
||||
pub NEEDLESS_MATCH,
|
||||
complexity,
|
||||
"`match` or match-like `if let` that are unnecessary"
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Matches {
|
||||
msrv: Option<RustcVersion>,
|
||||
@ -599,6 +643,7 @@ impl_lint_pass!(Matches => [
|
||||
REDUNDANT_PATTERN_MATCHING,
|
||||
MATCH_LIKE_MATCHES_MACRO,
|
||||
MATCH_SAME_ARMS,
|
||||
NEEDLESS_MATCH,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||
@ -622,6 +667,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||
overlapping_arms::check(cx, ex, arms);
|
||||
match_wild_enum::check(cx, ex, arms);
|
||||
match_as_ref::check(cx, ex, arms, expr);
|
||||
needless_match::check_match(cx, ex, arms);
|
||||
|
||||
if self.infallible_destructuring_match_linted {
|
||||
self.infallible_destructuring_match_linted = false;
|
||||
@ -640,6 +686,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
|
||||
match_like_matches::check(cx, expr);
|
||||
}
|
||||
redundant_pattern_match::check(cx, expr);
|
||||
needless_match::check(cx, expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
197
clippy_lints/src/matches/needless_match.rs
Normal file
197
clippy_lints/src/matches/needless_match.rs
Normal file
@ -0,0 +1,197 @@
|
||||
use super::NEEDLESS_MATCH;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{eq_expr_value, get_parent_expr, higher, is_else_clause, is_lang_ctor, peel_blocks_with_stmt};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::{Arm, BindingAnnotation, Expr, ExprKind, Pat, PatKind, Path, PathSegment, QPath, UnOp};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::sym;
|
||||
|
||||
pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
|
||||
// This is for avoiding collision with `match_single_binding`.
|
||||
if arms.len() < 2 {
|
||||
return;
|
||||
}
|
||||
|
||||
for arm in arms {
|
||||
if let PatKind::Wild = arm.pat.kind {
|
||||
let ret_expr = strip_return(arm.body);
|
||||
if !eq_expr_value(cx, ex, ret_expr) {
|
||||
return;
|
||||
}
|
||||
} else if !pat_same_as_expr(arm.pat, arm.body) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(match_expr) = get_parent_expr(cx, ex) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NEEDLESS_MATCH,
|
||||
match_expr.span,
|
||||
"this match expression is unnecessary",
|
||||
"replace it with",
|
||||
snippet_with_applicability(cx, ex.span, "..", &mut applicability).to_string(),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check for nop `if let` expression that assembled as unnecessary match
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// if let Some(a) = option {
|
||||
/// Some(a)
|
||||
/// } else {
|
||||
/// None
|
||||
/// }
|
||||
/// ```
|
||||
/// OR
|
||||
/// ```rust,ignore
|
||||
/// if let SomeEnum::A = some_enum {
|
||||
/// SomeEnum::A
|
||||
/// } else if let SomeEnum::B = some_enum {
|
||||
/// SomeEnum::B
|
||||
/// } else {
|
||||
/// some_enum
|
||||
/// }
|
||||
/// ```
|
||||
pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>) {
|
||||
if_chain! {
|
||||
if let Some(ref if_let) = higher::IfLet::hir(cx, ex);
|
||||
if !is_else_clause(cx.tcx, ex);
|
||||
if check_if_let(cx, if_let);
|
||||
then {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NEEDLESS_MATCH,
|
||||
ex.span,
|
||||
"this if-let expression is unnecessary",
|
||||
"replace it with",
|
||||
snippet_with_applicability(cx, if_let.let_expr.span, "..", &mut applicability).to_string(),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_if_let(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {
|
||||
if let Some(if_else) = if_let.if_else {
|
||||
if !pat_same_as_expr(if_let.let_pat, peel_blocks_with_stmt(if_let.if_then)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recurrsively check for each `else if let` phrase,
|
||||
if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else) {
|
||||
return check_if_let(cx, nested_if_let);
|
||||
}
|
||||
|
||||
if matches!(if_else.kind, ExprKind::Block(..)) {
|
||||
let else_expr = peel_blocks_with_stmt(if_else);
|
||||
let ret = strip_return(else_expr);
|
||||
let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);
|
||||
if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) {
|
||||
if let ExprKind::Path(ref qpath) = ret.kind {
|
||||
return is_lang_ctor(cx, qpath, OptionNone) || eq_expr_value(cx, if_let.let_expr, ret);
|
||||
}
|
||||
} else {
|
||||
return eq_expr_value(cx, if_let.let_expr, ret);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Strip `return` keyword if the expression type is `ExprKind::Ret`.
|
||||
fn strip_return<'hir>(expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
|
||||
if let ExprKind::Ret(Some(ret)) = expr.kind {
|
||||
ret
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
}
|
||||
|
||||
fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
|
||||
let expr = strip_return(expr);
|
||||
match (&pat.kind, &expr.kind) {
|
||||
// Example: `Some(val) => Some(val)`
|
||||
(
|
||||
PatKind::TupleStruct(QPath::Resolved(_, path), [first_pat, ..], _),
|
||||
ExprKind::Call(call_expr, [first_param, ..]),
|
||||
) => {
|
||||
if let ExprKind::Path(QPath::Resolved(_, call_path)) = call_expr.kind {
|
||||
if has_identical_segments(path.segments, call_path.segments)
|
||||
&& has_same_non_ref_symbol(first_pat, first_param)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
// Example: `val => val`, or `ref val => *val`
|
||||
(PatKind::Binding(annot, _, pat_ident, _), _) => {
|
||||
let new_expr = if let (
|
||||
BindingAnnotation::Ref | BindingAnnotation::RefMut,
|
||||
ExprKind::Unary(UnOp::Deref, operand_expr),
|
||||
) = (annot, &expr.kind)
|
||||
{
|
||||
operand_expr
|
||||
} else {
|
||||
expr
|
||||
};
|
||||
|
||||
if let ExprKind::Path(QPath::Resolved(
|
||||
_,
|
||||
Path {
|
||||
segments: [first_seg, ..],
|
||||
..
|
||||
},
|
||||
)) = new_expr.kind
|
||||
{
|
||||
return pat_ident.name == first_seg.ident.name;
|
||||
}
|
||||
},
|
||||
// Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
|
||||
(PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {
|
||||
return has_identical_segments(p_path.segments, e_path.segments);
|
||||
},
|
||||
// Example: `5 => 5`
|
||||
(PatKind::Lit(pat_lit_expr), ExprKind::Lit(expr_spanned)) => {
|
||||
if let ExprKind::Lit(pat_spanned) = &pat_lit_expr.kind {
|
||||
return pat_spanned.node == expr_spanned.node;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn has_identical_segments(left_segs: &[PathSegment<'_>], right_segs: &[PathSegment<'_>]) -> bool {
|
||||
if left_segs.len() != right_segs.len() {
|
||||
return false;
|
||||
}
|
||||
for i in 0..left_segs.len() {
|
||||
if left_segs[i].ident.name != right_segs[i].ident.name {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn has_same_non_ref_symbol(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let PatKind::Binding(annot, _, pat_ident, _) = pat.kind;
|
||||
if !matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
|
||||
if let ExprKind::Path(QPath::Resolved(_, Path {segments: [first_seg, ..], .. })) = expr.kind;
|
||||
then {
|
||||
return pat_ident.name == first_seg.ident.name;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
@ -148,6 +148,7 @@ fn main() {
|
||||
|
||||
// #7077
|
||||
let s = &String::new();
|
||||
#[allow(clippy::needless_match)]
|
||||
let _: Option<&str> = match Some(s) {
|
||||
Some(s) => Some(s),
|
||||
None => None,
|
||||
|
@ -214,6 +214,7 @@ fn main() {
|
||||
|
||||
// #7077
|
||||
let s = &String::new();
|
||||
#[allow(clippy::needless_match)]
|
||||
let _: Option<&str> = match Some(s) {
|
||||
Some(s) => Some(s),
|
||||
None => None,
|
||||
|
83
tests/ui/needless_match.fixed
Normal file
83
tests/ui/needless_match.fixed
Normal file
@ -0,0 +1,83 @@
|
||||
// run-rustfix
|
||||
#![warn(clippy::needless_match)]
|
||||
#![allow(clippy::manual_map)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Choice {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
}
|
||||
|
||||
#[allow(unused_mut)]
|
||||
fn useless_match() {
|
||||
let mut i = 10;
|
||||
let _: i32 = i;
|
||||
let _: i32 = i;
|
||||
let mut _i_mut = i;
|
||||
|
||||
let s = "test";
|
||||
let _: &str = s;
|
||||
}
|
||||
|
||||
fn custom_type_match(se: Choice) {
|
||||
let _: Choice = se;
|
||||
// Don't trigger
|
||||
let _: Choice = match se {
|
||||
Choice::A => Choice::A,
|
||||
Choice::B => Choice::B,
|
||||
_ => Choice::C,
|
||||
};
|
||||
// Mingled, don't trigger
|
||||
let _: Choice = match se {
|
||||
Choice::A => Choice::B,
|
||||
Choice::B => Choice::C,
|
||||
Choice::C => Choice::D,
|
||||
Choice::D => Choice::A,
|
||||
};
|
||||
}
|
||||
|
||||
fn option_match(x: Option<i32>) {
|
||||
let _: Option<i32> = x;
|
||||
// Don't trigger, this is the case for manual_map_option
|
||||
let _: Option<i32> = match x {
|
||||
Some(a) => Some(-a),
|
||||
None => None,
|
||||
};
|
||||
}
|
||||
|
||||
fn func_ret_err<T>(err: T) -> Result<i32, T> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
fn result_match() {
|
||||
let _: Result<i32, i32> = Ok(1);
|
||||
let _: Result<i32, i32> = func_ret_err(0_i32);
|
||||
}
|
||||
|
||||
fn if_let_option() -> Option<i32> {
|
||||
Some(1)
|
||||
}
|
||||
|
||||
fn if_let_result(x: Result<(), i32>) {
|
||||
let _: Result<(), i32> = x;
|
||||
let _: Result<(), i32> = x;
|
||||
// Input type mismatch, don't trigger
|
||||
let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
|
||||
}
|
||||
|
||||
fn if_let_custom_enum(x: Choice) {
|
||||
let _: Choice = x;
|
||||
// Don't trigger
|
||||
let _: Choice = if let Choice::A = x {
|
||||
Choice::A
|
||||
} else if true {
|
||||
Choice::B
|
||||
} else {
|
||||
x
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
122
tests/ui/needless_match.rs
Normal file
122
tests/ui/needless_match.rs
Normal file
@ -0,0 +1,122 @@
|
||||
// run-rustfix
|
||||
#![warn(clippy::needless_match)]
|
||||
#![allow(clippy::manual_map)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Choice {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
}
|
||||
|
||||
#[allow(unused_mut)]
|
||||
fn useless_match() {
|
||||
let mut i = 10;
|
||||
let _: i32 = match i {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
_ => i,
|
||||
};
|
||||
let _: i32 = match i {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
ref i => *i,
|
||||
};
|
||||
let mut _i_mut = match i {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
ref mut i => *i,
|
||||
};
|
||||
|
||||
let s = "test";
|
||||
let _: &str = match s {
|
||||
"a" => "a",
|
||||
"b" => "b",
|
||||
s => s,
|
||||
};
|
||||
}
|
||||
|
||||
fn custom_type_match(se: Choice) {
|
||||
let _: Choice = match se {
|
||||
Choice::A => Choice::A,
|
||||
Choice::B => Choice::B,
|
||||
Choice::C => Choice::C,
|
||||
Choice::D => Choice::D,
|
||||
};
|
||||
// Don't trigger
|
||||
let _: Choice = match se {
|
||||
Choice::A => Choice::A,
|
||||
Choice::B => Choice::B,
|
||||
_ => Choice::C,
|
||||
};
|
||||
// Mingled, don't trigger
|
||||
let _: Choice = match se {
|
||||
Choice::A => Choice::B,
|
||||
Choice::B => Choice::C,
|
||||
Choice::C => Choice::D,
|
||||
Choice::D => Choice::A,
|
||||
};
|
||||
}
|
||||
|
||||
fn option_match(x: Option<i32>) {
|
||||
let _: Option<i32> = match x {
|
||||
Some(a) => Some(a),
|
||||
None => None,
|
||||
};
|
||||
// Don't trigger, this is the case for manual_map_option
|
||||
let _: Option<i32> = match x {
|
||||
Some(a) => Some(-a),
|
||||
None => None,
|
||||
};
|
||||
}
|
||||
|
||||
fn func_ret_err<T>(err: T) -> Result<i32, T> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
fn result_match() {
|
||||
let _: Result<i32, i32> = match Ok(1) {
|
||||
Ok(a) => Ok(a),
|
||||
Err(err) => Err(err),
|
||||
};
|
||||
let _: Result<i32, i32> = match func_ret_err(0_i32) {
|
||||
Err(err) => Err(err),
|
||||
Ok(a) => Ok(a),
|
||||
};
|
||||
}
|
||||
|
||||
fn if_let_option() -> Option<i32> {
|
||||
if let Some(a) = Some(1) { Some(a) } else { None }
|
||||
}
|
||||
|
||||
fn if_let_result(x: Result<(), i32>) {
|
||||
let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
|
||||
let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
|
||||
// Input type mismatch, don't trigger
|
||||
let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
|
||||
}
|
||||
|
||||
fn if_let_custom_enum(x: Choice) {
|
||||
let _: Choice = if let Choice::A = x {
|
||||
Choice::A
|
||||
} else if let Choice::B = x {
|
||||
Choice::B
|
||||
} else if let Choice::C = x {
|
||||
Choice::C
|
||||
} else {
|
||||
x
|
||||
};
|
||||
// Don't trigger
|
||||
let _: Choice = if let Choice::A = x {
|
||||
Choice::A
|
||||
} else if true {
|
||||
Choice::B
|
||||
} else {
|
||||
x
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
122
tests/ui/needless_match.stderr
Normal file
122
tests/ui/needless_match.stderr
Normal file
@ -0,0 +1,122 @@
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:17:18
|
||||
|
|
||||
LL | let _: i32 = match i {
|
||||
| __________________^
|
||||
LL | | 0 => 0,
|
||||
LL | | 1 => 1,
|
||||
LL | | 2 => 2,
|
||||
LL | | _ => i,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `i`
|
||||
|
|
||||
= note: `-D clippy::needless-match` implied by `-D warnings`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:23:18
|
||||
|
|
||||
LL | let _: i32 = match i {
|
||||
| __________________^
|
||||
LL | | 0 => 0,
|
||||
LL | | 1 => 1,
|
||||
LL | | ref i => *i,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `i`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:28:22
|
||||
|
|
||||
LL | let mut _i_mut = match i {
|
||||
| ______________________^
|
||||
LL | | 0 => 0,
|
||||
LL | | 1 => 1,
|
||||
LL | | ref mut i => *i,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `i`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:35:19
|
||||
|
|
||||
LL | let _: &str = match s {
|
||||
| ___________________^
|
||||
LL | | "a" => "a",
|
||||
LL | | "b" => "b",
|
||||
LL | | s => s,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `s`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:43:21
|
||||
|
|
||||
LL | let _: Choice = match se {
|
||||
| _____________________^
|
||||
LL | | Choice::A => Choice::A,
|
||||
LL | | Choice::B => Choice::B,
|
||||
LL | | Choice::C => Choice::C,
|
||||
LL | | Choice::D => Choice::D,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `se`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:65:26
|
||||
|
|
||||
LL | let _: Option<i32> = match x {
|
||||
| __________________________^
|
||||
LL | | Some(a) => Some(a),
|
||||
LL | | None => None,
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `x`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:81:31
|
||||
|
|
||||
LL | let _: Result<i32, i32> = match Ok(1) {
|
||||
| _______________________________^
|
||||
LL | | Ok(a) => Ok(a),
|
||||
LL | | Err(err) => Err(err),
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `Ok(1)`
|
||||
|
||||
error: this match expression is unnecessary
|
||||
--> $DIR/needless_match.rs:85:31
|
||||
|
|
||||
LL | let _: Result<i32, i32> = match func_ret_err(0_i32) {
|
||||
| _______________________________^
|
||||
LL | | Err(err) => Err(err),
|
||||
LL | | Ok(a) => Ok(a),
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `func_ret_err(0_i32)`
|
||||
|
||||
error: this if-let expression is unnecessary
|
||||
--> $DIR/needless_match.rs:92:5
|
||||
|
|
||||
LL | if let Some(a) = Some(1) { Some(a) } else { None }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
|
||||
|
||||
error: this if-let expression is unnecessary
|
||||
--> $DIR/needless_match.rs:96:30
|
||||
|
|
||||
LL | let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
|
||||
|
||||
error: this if-let expression is unnecessary
|
||||
--> $DIR/needless_match.rs:97:30
|
||||
|
|
||||
LL | let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
|
||||
|
||||
error: this if-let expression is unnecessary
|
||||
--> $DIR/needless_match.rs:103:21
|
||||
|
|
||||
LL | let _: Choice = if let Choice::A = x {
|
||||
| _____________________^
|
||||
LL | | Choice::A
|
||||
LL | | } else if let Choice::B = x {
|
||||
LL | | Choice::B
|
||||
... |
|
||||
LL | | x
|
||||
LL | | };
|
||||
| |_____^ help: replace it with: `x`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user