Skip to content

Commit 4bb6a0e

Browse files
fix manual_is_ascii_check: also add explicit type when linting matches! (#15492)
fixes rust-lang/rust-clippy#15326 changelog: [`manual_is_ascii_check`]: also add explicit type when linting `matches!`
2 parents 8a8caeb + f64fbe1 commit 4bb6a0e

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

clippy_lints/src/manual_is_ascii_check.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
9797
return;
9898
}
9999

100-
if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) {
101-
if let ExprKind::Match(recv, [arm, ..], _) = expr.kind {
102-
let range = check_pat(&arm.pat.kind);
103-
check_is_ascii(cx, macro_call.span, recv, &range, None);
104-
}
100+
let (arg, span, range) = if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro)
101+
&& let ExprKind::Match(recv, [arm, ..], _) = expr.kind
102+
{
103+
let recv = peel_ref_operators(cx, recv);
104+
let range = check_pat(&arm.pat.kind);
105+
(recv, macro_call.span, range)
105106
} else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind
106107
&& path.ident.name == sym::contains
107108
&& let Some(higher::Range {
@@ -112,10 +113,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
112113
&& !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_))
113114
{
114115
let arg = peel_ref_operators(cx, arg);
115-
let ty_sugg = get_ty_sugg(cx, arg);
116116
let range = check_expr_range(start, end);
117-
check_is_ascii(cx, expr.span, arg, &range, ty_sugg);
118-
}
117+
(arg, expr.span, range)
118+
} else {
119+
return;
120+
};
121+
122+
let ty_sugg = get_ty_sugg(cx, arg);
123+
check_is_ascii(cx, span, arg, &range, ty_sugg);
119124
}
120125
}
121126

@@ -146,9 +151,8 @@ fn check_is_ascii(
146151
CharRange::HexDigit => "is_ascii_hexdigit",
147152
CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return,
148153
};
149-
let default_snip = "..";
150154
let mut app = Applicability::MachineApplicable;
151-
let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_paren();
155+
let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), "_", &mut app).maybe_paren();
152156
let mut suggestion = vec![(span, format!("{recv}.{sugg}()"))];
153157
if let Some((ty_span, ty)) = ty_sugg {
154158
suggestion.push((ty_span, format!("{recv}: {ty}")));
@@ -182,7 +186,7 @@ fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
182186
CharRange::Otherwise
183187
}
184188
},
185-
PatKind::Range(Some(start), Some(end), kind) if *kind == RangeEnd::Included => check_range(start, end),
189+
PatKind::Range(Some(start), Some(end), RangeEnd::Included) => check_range(start, end),
186190
_ => CharRange::Otherwise,
187191
}
188192
}

tests/ui/manual_is_ascii_check.fixed

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,15 @@ fn generics() {
108108
//~^ manual_is_ascii_check
109109
take_while(|c: char| c.is_ascii_uppercase());
110110
//~^ manual_is_ascii_check
111+
take_while(|c: char| c.is_ascii_uppercase());
112+
//~^ manual_is_ascii_check
111113
}
112114

113115
fn adds_type_reference() {
114116
let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect();
115117
//~^ manual_is_ascii_check
116118
let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
117119
//~^ manual_is_ascii_check
120+
let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
121+
//~^ manual_is_ascii_check
118122
}

tests/ui/manual_is_ascii_check.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,15 @@ fn generics() {
108108
//~^ manual_is_ascii_check
109109
take_while(|c: char| ('A'..='Z').contains(&c));
110110
//~^ manual_is_ascii_check
111+
take_while(|c| matches!(c, 'A'..='Z'));
112+
//~^ manual_is_ascii_check
111113
}
112114

113115
fn adds_type_reference() {
114116
let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();
115117
//~^ manual_is_ascii_check
116118
let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();
117119
//~^ manual_is_ascii_check
120+
let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
121+
//~^ manual_is_ascii_check
118122
}

tests/ui/manual_is_ascii_check.stderr

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,19 @@ LL | take_while(|c: char| ('A'..='Z').contains(&c));
176176
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()`
177177

178178
error: manual check for common ascii range
179-
--> tests/ui/manual_is_ascii_check.rs:114:63
179+
--> tests/ui/manual_is_ascii_check.rs:111:20
180+
|
181+
LL | take_while(|c| matches!(c, 'A'..='Z'));
182+
| ^^^^^^^^^^^^^^^^^^^^^^
183+
|
184+
help: try
185+
|
186+
LL - take_while(|c| matches!(c, 'A'..='Z'));
187+
LL + take_while(|c: char| c.is_ascii_uppercase());
188+
|
189+
190+
error: manual check for common ascii range
191+
--> tests/ui/manual_is_ascii_check.rs:116:63
180192
|
181193
LL | let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();
182194
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -188,7 +200,7 @@ LL + let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_
188200
|
189201

190202
error: manual check for common ascii range
191-
--> tests/ui/manual_is_ascii_check.rs:116:71
203+
--> tests/ui/manual_is_ascii_check.rs:118:71
192204
|
193205
LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();
194206
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,5 +211,17 @@ LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'.
199211
LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
200212
|
201213

202-
error: aborting due to 29 previous errors
214+
error: manual check for common ascii range
215+
--> tests/ui/manual_is_ascii_check.rs:120:71
216+
|
217+
LL | let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
218+
| ^^^^^^^^^^^^^^^^^^^^^^
219+
|
220+
help: try
221+
|
222+
LL - let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
223+
LL + let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
224+
|
225+
226+
error: aborting due to 31 previous errors
203227

0 commit comments

Comments
 (0)