reduce single_char_pattern to only lint on ascii chars

This commit is contained in:
Andre Bogus 2023-11-21 14:35:02 +01:00
parent 6b1c828d91
commit 58c53e8ea9
7 changed files with 28 additions and 17 deletions

View File

@ -1145,11 +1145,14 @@ declare_clippy_lint! {
/// `str` as an argument, e.g., `_.split("x")`.
///
/// ### Why is this bad?
/// Performing these methods using a `char` is faster than
/// using a `str`.
/// Performing these methods using a `char` can be faster than
/// using a `str` because it needs one less indirection.
///
/// ### Known problems
/// Does not catch multi-byte unicode characters.
/// Does not catch multi-byte unicode characters. This is by
/// design, on many machines, splitting by a non-ascii char is
/// actually slower. Please do your own measurements instead of
/// relying solely on the results of this lint.
///
/// ### Example
/// ```rust,ignore

View File

@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR;
/// lint for length-1 `str`s as argument for `insert_str`
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let mut applicability = Applicability::MachineApplicable;
if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability) {
if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[1], &mut applicability, false) {
let base_string_snippet =
snippet_with_applicability(cx, receiver.span.source_callsite(), "_", &mut applicability);
let pos_arg = snippet_with_applicability(cx, args[0].span, "..", &mut applicability);

View File

@ -8,7 +8,7 @@ use rustc_span::symbol::Symbol;
use super::SINGLE_CHAR_PATTERN;
const PATTERN_METHODS: [(&str, usize); 24] = [
const PATTERN_METHODS: [(&str, usize); 22] = [
("contains", 0),
("starts_with", 0),
("ends_with", 0),
@ -27,8 +27,6 @@ const PATTERN_METHODS: [(&str, usize); 24] = [
("rmatches", 0),
("match_indices", 0),
("rmatch_indices", 0),
("strip_prefix", 0),
("strip_suffix", 0),
("trim_start_matches", 0),
("trim_end_matches", 0),
("replace", 0),
@ -50,7 +48,7 @@ pub(super) fn check(
&& args.len() > pos
&& let arg = &args[pos]
&& let mut applicability = Applicability::MachineApplicable
&& let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability)
&& let Some(hint) = get_hint_if_single_char_arg(cx, arg, &mut applicability, true)
{
span_lint_and_sugg(
cx,

View File

@ -10,7 +10,7 @@ use super::SINGLE_CHAR_ADD_STR;
/// lint for length-1 `str`s as argument for `push_str`
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
let mut applicability = Applicability::MachineApplicable;
if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability) {
if let Some(extension_string) = get_hint_if_single_char_arg(cx, &args[0], &mut applicability, false) {
let base_string_snippet =
snippet_with_applicability(cx, receiver.span.source_callsite(), "..", &mut applicability);
let sugg = format!("{base_string_snippet}.push({extension_string})");

View File

@ -52,11 +52,17 @@ pub(super) fn get_hint_if_single_char_arg(
cx: &LateContext<'_>,
arg: &Expr<'_>,
applicability: &mut Applicability,
ascii_only: bool,
) -> Option<String> {
if let ExprKind::Lit(lit) = &arg.kind
&& let ast::LitKind::Str(r, style) = lit.node
&& let string = r.as_str()
&& string.chars().count() == 1
&& let len = if ascii_only {
string.len()
} else {
string.chars().count()
}
&& len == 1
{
let snip = snippet_with_applicability(cx, arg.span, string, applicability);
let ch = if let ast::StrStyle::Raw(nhash) = style {

View File

@ -10,9 +10,9 @@ fn main() {
let y = "x";
x.split(y);
x.split('ß');
x.split('');
x.split('💣');
x.split("ß");
x.split("");
x.split("💣");
// Can't use this lint for unicode code points which don't fit in a char
x.split("❤️");
x.split_inclusive('x');
@ -34,8 +34,6 @@ fn main() {
x.rmatch_indices('x');
x.trim_start_matches('x');
x.trim_end_matches('x');
x.strip_prefix('x');
x.strip_suffix('x');
x.replace('x', "y");
x.replacen('x', "y", 3);
// Make sure we escape characters correctly.
@ -64,4 +62,8 @@ fn main() {
// Must escape backslash in raw strings when converting to char #8060
x.split('\\');
x.split('\\');
// should not warn, the char versions are actually slower in some cases
x.strip_prefix("x");
x.strip_suffix("x");
}

View File

@ -34,8 +34,6 @@ fn main() {
x.rmatch_indices("x");
x.trim_start_matches("x");
x.trim_end_matches("x");
x.strip_prefix("x");
x.strip_suffix("x");
x.replace("x", "y");
x.replacen("x", "y", 3);
// Make sure we escape characters correctly.
@ -64,4 +62,8 @@ fn main() {
// Must escape backslash in raw strings when converting to char #8060
x.split(r#"\"#);
x.split(r"\");
// should not warn, the char versions are actually slower in some cases
x.strip_prefix("x");
x.strip_suffix("x");
}