diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-08-22 18:27:00 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-22 18:27:00 +0000 |
| commit | 4bb6a0ebe08068e7b640370a89e5c3417d9bb948 (patch) | |
| tree | 7c5fcdae5faaaee5f2efbcaed9117263b28bab8c | |
| parent | 8a8caeb99c8f4f5460520f411e910e58764ebc09 (diff) | |
| parent | f64fbe118409e29e2e3000c79d2ad2bbafc09788 (diff) | |
| download | rust-4bb6a0ebe08068e7b640370a89e5c3417d9bb948.tar.gz rust-4bb6a0ebe08068e7b640370a89e5c3417d9bb948.zip | |
fix `manual_is_ascii_check`: also add explicit type when linting `matches!` (#15492)
fixes https://github.com/rust-lang/rust-clippy/issues/15326 changelog: [`manual_is_ascii_check`]: also add explicit type when linting `matches!`
| -rw-r--r-- | clippy_lints/src/manual_is_ascii_check.rs | 26 | ||||
| -rw-r--r-- | tests/ui/manual_is_ascii_check.fixed | 4 | ||||
| -rw-r--r-- | tests/ui/manual_is_ascii_check.rs | 4 | ||||
| -rw-r--r-- | tests/ui/manual_is_ascii_check.stderr | 30 |
4 files changed, 50 insertions, 14 deletions
diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index ac8c88f0205..2eebb2430fd 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -97,11 +97,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { return; } - if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) { - if let ExprKind::Match(recv, [arm, ..], _) = expr.kind { - let range = check_pat(&arm.pat.kind); - check_is_ascii(cx, macro_call.span, recv, &range, None); - } + let (arg, span, range) = if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) + && let ExprKind::Match(recv, [arm, ..], _) = expr.kind + { + let recv = peel_ref_operators(cx, recv); + let range = check_pat(&arm.pat.kind); + (recv, macro_call.span, range) } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind && path.ident.name == sym::contains && let Some(higher::Range { @@ -112,10 +113,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck { && !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_)) { let arg = peel_ref_operators(cx, arg); - let ty_sugg = get_ty_sugg(cx, arg); let range = check_expr_range(start, end); - check_is_ascii(cx, expr.span, arg, &range, ty_sugg); - } + (arg, expr.span, range) + } else { + return; + }; + + let ty_sugg = get_ty_sugg(cx, arg); + check_is_ascii(cx, span, arg, &range, ty_sugg); } } @@ -146,9 +151,8 @@ fn check_is_ascii( CharRange::HexDigit => "is_ascii_hexdigit", CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return, }; - let default_snip = ".."; let mut app = Applicability::MachineApplicable; - let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_paren(); + let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), "_", &mut app).maybe_paren(); let mut suggestion = vec![(span, format!("{recv}.{sugg}()"))]; if let Some((ty_span, ty)) = ty_sugg { suggestion.push((ty_span, format!("{recv}: {ty}"))); @@ -182,7 +186,7 @@ fn check_pat(pat_kind: &PatKind<'_>) -> CharRange { CharRange::Otherwise } }, - PatKind::Range(Some(start), Some(end), kind) if *kind == RangeEnd::Included => check_range(start, end), + PatKind::Range(Some(start), Some(end), RangeEnd::Included) => check_range(start, end), _ => CharRange::Otherwise, } } diff --git a/tests/ui/manual_is_ascii_check.fixed b/tests/ui/manual_is_ascii_check.fixed index 7b0d1906834..406336dbd09 100644 --- a/tests/ui/manual_is_ascii_check.fixed +++ b/tests/ui/manual_is_ascii_check.fixed @@ -108,6 +108,8 @@ fn generics() { //~^ manual_is_ascii_check take_while(|c: char| c.is_ascii_uppercase()); //~^ manual_is_ascii_check + take_while(|c: char| c.is_ascii_uppercase()); + //~^ manual_is_ascii_check } fn adds_type_reference() { @@ -115,4 +117,6 @@ fn adds_type_reference() { //~^ manual_is_ascii_check let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); //~^ manual_is_ascii_check + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); + //~^ manual_is_ascii_check } diff --git a/tests/ui/manual_is_ascii_check.rs b/tests/ui/manual_is_ascii_check.rs index e4f7fe9f583..a624497e75e 100644 --- a/tests/ui/manual_is_ascii_check.rs +++ b/tests/ui/manual_is_ascii_check.rs @@ -108,6 +108,8 @@ fn generics() { //~^ manual_is_ascii_check take_while(|c: char| ('A'..='Z').contains(&c)); //~^ manual_is_ascii_check + take_while(|c| matches!(c, 'A'..='Z')); + //~^ manual_is_ascii_check } fn adds_type_reference() { @@ -115,4 +117,6 @@ fn adds_type_reference() { //~^ manual_is_ascii_check let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); //~^ manual_is_ascii_check + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect(); + //~^ manual_is_ascii_check } diff --git a/tests/ui/manual_is_ascii_check.stderr b/tests/ui/manual_is_ascii_check.stderr index 9fd7f457b42..cb2548ea731 100644 --- a/tests/ui/manual_is_ascii_check.stderr +++ b/tests/ui/manual_is_ascii_check.stderr @@ -176,7 +176,19 @@ LL | take_while(|c: char| ('A'..='Z').contains(&c)); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()` error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:114:63 + --> tests/ui/manual_is_ascii_check.rs:111:20 + | +LL | take_while(|c| matches!(c, 'A'..='Z')); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - take_while(|c| matches!(c, 'A'..='Z')); +LL + take_while(|c: char| c.is_ascii_uppercase()); + | + +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:116:63 | LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,7 +200,7 @@ LL + let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ | error: manual check for common ascii range - --> tests/ui/manual_is_ascii_check.rs:116:71 + --> tests/ui/manual_is_ascii_check.rs:118:71 | LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect(); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -199,5 +211,17 @@ LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'. LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); | -error: aborting due to 29 previous errors +error: manual check for common ascii range + --> tests/ui/manual_is_ascii_check.rs:120:71 + | +LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect(); +LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect(); + | + +error: aborting due to 31 previous errors |
