mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-24 12:54:00 +00:00
add tests, add base bone for the new lint
This commit is contained in:
parent
7b2896a8fc
commit
30fb8229e1
@ -3348,6 +3348,7 @@ Released 2018-09-13
|
||||
[`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool
|
||||
[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
|
||||
[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
|
||||
[`nop_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#nop_match
|
||||
[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref
|
||||
[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/master/index.html#octal_escapes
|
||||
[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect
|
||||
|
@ -134,6 +134,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::NOP_MATCH),
|
||||
LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
|
||||
LintId::of(matches::SINGLE_MATCH),
|
||||
LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
|
||||
|
@ -37,6 +37,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
|
||||
LintId::of(loops::NEVER_LOOP),
|
||||
LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
|
||||
LintId::of(match_str_case_mismatch::MATCH_STR_CASE_MISMATCH),
|
||||
LintId::of(matches::NOP_MATCH),
|
||||
LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
|
||||
LintId::of(methods::CLONE_DOUBLE_REF),
|
||||
LintId::of(methods::ITERATOR_STEP_BY_ZERO),
|
||||
|
@ -253,6 +253,7 @@ store.register_lints(&[
|
||||
matches::MATCH_SINGLE_BINDING,
|
||||
matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
|
||||
matches::MATCH_WILD_ERR_ARM,
|
||||
matches::NOP_MATCH,
|
||||
matches::REDUNDANT_PATTERN_MATCHING,
|
||||
matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
|
||||
matches::SINGLE_MATCH,
|
||||
|
@ -21,6 +21,7 @@ mod redundant_pattern_match;
|
||||
mod rest_pat_in_fully_bound_struct;
|
||||
mod single_match;
|
||||
mod wild_in_or_pats;
|
||||
mod nop_match;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
@ -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 NOP_MATCH,
|
||||
correctness,
|
||||
"`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,
|
||||
NOP_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);
|
||||
nop_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);
|
||||
nop_match::check(cx, expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
34
clippy_lints/src/matches/nop_match.rs
Normal file
34
clippy_lints/src/matches/nop_match.rs
Normal file
@ -0,0 +1,34 @@
|
||||
#![allow(unused_variables)]
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_hir::{Arm, Expr};
|
||||
use rustc_errors::Applicability;
|
||||
use super::NOP_MATCH;
|
||||
|
||||
pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>) {
|
||||
if false {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NOP_MATCH,
|
||||
ex.span,
|
||||
"this if-let expression is unnecessary",
|
||||
"replace it with",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
|
||||
if false {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
NOP_MATCH,
|
||||
ex.span,
|
||||
"this match expression is unnecessary",
|
||||
"replace it with",
|
||||
"".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
83
tests/ui/nop_match.fixed
Normal file
83
tests/ui/nop_match.fixed
Normal file
@ -0,0 +1,83 @@
|
||||
// run-rustfix
|
||||
#![warn(clippy::nop_match)]
|
||||
#![allow(clippy::manual_map)]
|
||||
#![allow(clippy::question_mark)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn option_match() -> Option<i32> {
|
||||
match Some(1) {
|
||||
Some(a) => Some(a),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
fn result_match() -> Result<i32, i32> {
|
||||
match Ok(1) {
|
||||
Ok(a) => Ok(a),
|
||||
Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
fn option_check() -> Option<i32> {
|
||||
if let Some(a) = Some(1) {
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn option_check_no_else() -> Option<i32> {
|
||||
if let Some(a) = Some(1) {
|
||||
return Some(a);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn func_ret_err<T>(err: T) -> Result<(), T> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
fn result_check_no_else() -> Result<(), i32> {
|
||||
if let Err(e) = func_ret_err(0_i32) {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn result_check_a() -> Result<(), i32> {
|
||||
if let Err(e) = func_ret_err(0_i32) {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trigger
|
||||
fn result_check_b() -> Result<(), i32> {
|
||||
if let Err(e) = Ok(1) {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn result_check_c() -> Result<(), i32> {
|
||||
let example = Ok(());
|
||||
if let Err(e) = example {
|
||||
Err(e)
|
||||
} else {
|
||||
example
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trigger
|
||||
fn result_check_d() -> Result<(), i32> {
|
||||
let example = Ok(1);
|
||||
if let Err(e) = example {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
83
tests/ui/nop_match.rs
Normal file
83
tests/ui/nop_match.rs
Normal file
@ -0,0 +1,83 @@
|
||||
// run-rustfix
|
||||
#![warn(clippy::nop_match)]
|
||||
#![allow(clippy::manual_map)]
|
||||
#![allow(clippy::question_mark)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn option_match() -> Option<i32> {
|
||||
match Some(1) {
|
||||
Some(a) => Some(a),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
|
||||
fn result_match() -> Result<i32, i32> {
|
||||
match Ok(1) {
|
||||
Ok(a) => Ok(a),
|
||||
Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
fn option_check() -> Option<i32> {
|
||||
if let Some(a) = Some(1) {
|
||||
Some(a)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn option_check_no_else() -> Option<i32> {
|
||||
if let Some(a) = Some(1) {
|
||||
return Some(a);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn func_ret_err<T>(err: T) -> Result<(), T> {
|
||||
Err(err)
|
||||
}
|
||||
|
||||
fn result_check_no_else() -> Result<(), i32> {
|
||||
if let Err(e) = func_ret_err(0_i32) {
|
||||
return Err(e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn result_check_a() -> Result<(), i32> {
|
||||
if let Err(e) = func_ret_err(0_i32) {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trigger
|
||||
fn result_check_b() -> Result<(), i32> {
|
||||
if let Err(e) = Ok(1) {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn result_check_c() -> Result<(), i32> {
|
||||
let example = Ok(());
|
||||
if let Err(e) = example {
|
||||
Err(e)
|
||||
} else {
|
||||
example
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trigger
|
||||
fn result_check_d() -> Result<(), i32> {
|
||||
let example = Ok(1);
|
||||
if let Err(e) = example {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
0
tests/ui/nop_match.stderr
Normal file
0
tests/ui/nop_match.stderr
Normal file
Loading…
Reference in New Issue
Block a user