Skip to content

Commit a5d5976

Browse files
committed
Auto merge of rust-lang#8077 - nixxquality:single_char_pattern-false-negatives, r=camsteffen
Fix some false negatives for [`single_char_pattern`] *Please write a short comment explaining your change (or "none" for internal only changes)* changelog: Fix some false negatives for [`single_char_pattern`] I noticed that clippy wasn't complaining about my usage of `split_once("x")` in a personal project so I updated the list of functions. I had to update the test case for an unrelated issue because replace is now included in the list of functions to be linted.
2 parents 476d609 + 01e302b commit a5d5976

9 files changed

+88
-43
lines changed

clippy_lints/src/map_unit_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ fn unit_closure<'tcx>(
190190
/// Anything else will return `a`.
191191
fn let_binding_name(cx: &LateContext<'_>, var_arg: &hir::Expr<'_>) -> String {
192192
match &var_arg.kind {
193-
hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, "_").replace(".", "_"),
193+
hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, "_").replace('.', "_"),
194194
hir::ExprKind::Path(_) => format!("_{}", snippet(cx, var_arg.span, "")),
195195
_ => "a".to_string(),
196196
}

clippy_lints/src/methods/single_char_pattern.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,21 @@ use rustc_span::symbol::Symbol;
99

1010
use super::SINGLE_CHAR_PATTERN;
1111

12-
const PATTERN_METHODS: [(&str, usize); 19] = [
12+
const PATTERN_METHODS: [(&str, usize); 24] = [
1313
("contains", 1),
1414
("starts_with", 1),
1515
("ends_with", 1),
1616
("find", 1),
1717
("rfind", 1),
1818
("split", 1),
19+
("split_inclusive", 1),
1920
("rsplit", 1),
2021
("split_terminator", 1),
2122
("rsplit_terminator", 1),
2223
("splitn", 2),
2324
("rsplitn", 2),
25+
("split_once", 1),
26+
("rsplit_once", 1),
2427
("matches", 1),
2528
("rmatches", 1),
2629
("match_indices", 1),
@@ -29,6 +32,8 @@ const PATTERN_METHODS: [(&str, usize); 19] = [
2932
("strip_suffix", 1),
3033
("trim_start_matches", 1),
3134
("trim_end_matches", 1),
35+
("replace", 1),
36+
("replacen", 1),
3237
];
3338

3439
/// lint for length-1 `str`s for methods in `PATTERN_METHODS`

clippy_lints/src/nonstandard_macro_braces.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, mac_braces: &'a Mac
112112
if snip.starts_with(&format!("{}!", name));
113113
if unnested_or_local();
114114
// make formatting consistent
115-
let c = snip.replace(" ", "");
115+
let c = snip.replace(' ', "");
116116
if !c.starts_with(&format!("{}!{}", name, braces.0));
117117
if !mac_braces.done.contains(&span.ctxt().outer_expn_data().call_site);
118118
then {

clippy_lints/src/self_named_constructors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
7676
let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
7777
if let Some(Node::Item(x)) = cx.tcx.hir().find(self_id);
7878
let type_name = x.ident.name.as_str().to_lowercase();
79-
if impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace("_", "") == type_name;
79+
if impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace('_', "") == type_name;
8080

8181
then {
8282
span_lint(

clippy_lints/src/unicode.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {
106106
"invisible character detected",
107107
"consider replacing the string with",
108108
string
109-
.replace("\u{200B}", "\\u{200B}")
110-
.replace("\u{ad}", "\\u{AD}")
111-
.replace("\u{2060}", "\\u{2060}"),
109+
.replace('\u{200B}', "\\u{200B}")
110+
.replace('\u{ad}', "\\u{AD}")
111+
.replace('\u{2060}', "\\u{2060}"),
112112
Applicability::MachineApplicable,
113113
);
114114
}

clippy_lints/src/write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,10 @@ impl Write {
583583
let replacement: String = match lit.token.kind {
584584
LitKind::Integer | LitKind::Float | LitKind::Err => continue,
585585
LitKind::StrRaw(_) | LitKind::ByteStrRaw(_) if matches!(fmtstr.style, StrStyle::Raw(_)) => {
586-
lit.token.symbol.as_str().replace("{", "{{").replace("}", "}}")
586+
lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
587587
},
588588
LitKind::Str | LitKind::ByteStr if matches!(fmtstr.style, StrStyle::Cooked) => {
589-
lit.token.symbol.as_str().replace("{", "{{").replace("}", "}}")
589+
lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
590590
},
591591
LitKind::StrRaw(_) | LitKind::Str | LitKind::ByteStrRaw(_) | LitKind::ByteStr => continue,
592592
LitKind::Byte | LitKind::Char => match &*lit.token.symbol.as_str() {

tests/ui/single_char_pattern.fixed

+6-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn main() {
1717
x.split('💣');
1818
// Can't use this lint for unicode code points which don't fit in a char
1919
x.split("❤️");
20+
x.split_inclusive('x');
2021
x.contains('x');
2122
x.starts_with('x');
2223
x.ends_with('x');
@@ -27,6 +28,8 @@ fn main() {
2728
x.rsplit_terminator('x');
2829
x.splitn(2, 'x');
2930
x.rsplitn(2, 'x');
31+
x.split_once('x');
32+
x.rsplit_once('x');
3033
x.matches('x');
3134
x.rmatches('x');
3235
x.match_indices('x');
@@ -35,6 +38,8 @@ fn main() {
3538
x.trim_end_matches('x');
3639
x.strip_prefix('x');
3740
x.strip_suffix('x');
41+
x.replace('x', "y");
42+
x.replacen('x', "y", 3);
3843
// Make sure we escape characters correctly.
3944
x.split('\n');
4045
x.split('\'');
@@ -43,7 +48,7 @@ fn main() {
4348
let h = HashSet::<String>::new();
4449
h.contains("X"); // should not warn
4550

46-
x.replace(";", ",").split(','); // issue #2978
51+
x.replace(';', ",").split(','); // issue #2978
4752
x.starts_with('\x03'); // issue #2996
4853

4954
// Issue #3204

tests/ui/single_char_pattern.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn main() {
1717
x.split("💣");
1818
// Can't use this lint for unicode code points which don't fit in a char
1919
x.split("❤️");
20+
x.split_inclusive("x");
2021
x.contains("x");
2122
x.starts_with("x");
2223
x.ends_with("x");
@@ -27,6 +28,8 @@ fn main() {
2728
x.rsplit_terminator("x");
2829
x.splitn(2, "x");
2930
x.rsplitn(2, "x");
31+
x.split_once("x");
32+
x.rsplit_once("x");
3033
x.matches("x");
3134
x.rmatches("x");
3235
x.match_indices("x");
@@ -35,6 +38,8 @@ fn main() {
3538
x.trim_end_matches("x");
3639
x.strip_prefix("x");
3740
x.strip_suffix("x");
41+
x.replace("x", "y");
42+
x.replacen("x", "y", 3);
3843
// Make sure we escape characters correctly.
3944
x.split("\n");
4045
x.split("'");
@@ -43,7 +48,7 @@ fn main() {
4348
let h = HashSet::<String>::new();
4449
h.contains("X"); // should not warn
4550

46-
x.replace(";", ",").split(","); // issue #2978
51+
x.replace(';', ",").split(","); // issue #2978
4752
x.starts_with("\x03"); // issue #2996
4853

4954
// Issue #3204

0 commit comments

Comments
 (0)