From bc744eb82bdf9c4ecb21ade5d7b3516f14da29ad Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Thu, 8 Jun 2023 06:55:47 -0500 Subject: [PATCH] new lint `needless_raw_string` + refactor a bit Thanks, #112373, for the snippet at line 75! --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 3 +- clippy_lints/src/lib.rs | 2 +- .../src/needless_raw_string_hashes.rs | 73 ------------ clippy_lints/src/raw_strings.rs | 109 ++++++++++++++++++ clippy_lints/src/utils/conf.rs | 6 +- .../almost_standard_lint_formulation.rs | 2 +- src/main.rs | 2 +- tests/lint_message_convention.rs | 30 ++--- .../conf_disallowed_methods.rs | 1 + .../conf_disallowed_methods.stderr | 28 ++--- .../toml_unknown_key/conf_unknown_key.stderr | 2 + tests/ui/format.stderr | 30 ++--- tests/ui/needless_raw_string.fixed | 16 +++ tests/ui/needless_raw_string.rs | 16 +++ tests/ui/needless_raw_string.stderr | 22 ++++ tests/ui/needless_raw_string_hashes.fixed | 2 +- tests/ui/needless_raw_string_hashes.rs | 2 +- tests/ui/regex.rs | 7 +- tests/ui/regex.stderr | 48 ++++---- tests/ui/single_char_add_str.fixed | 2 +- tests/ui/single_char_add_str.rs | 2 +- tests/ui/single_char_pattern.fixed | 2 +- tests/ui/single_char_pattern.rs | 2 +- tests/ui/write_literal_2.rs | 2 +- tests/ui/write_literal_2.stderr | 10 +- 26 files changed, 267 insertions(+), 155 deletions(-) delete mode 100644 clippy_lints/src/needless_raw_string_hashes.rs create mode 100644 clippy_lints/src/raw_strings.rs create mode 100644 tests/ui/needless_raw_string.fixed create mode 100644 tests/ui/needless_raw_string.rs create mode 100644 tests/ui/needless_raw_string.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb820b0c43..5b17072df40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5048,6 +5048,7 @@ Released 2018-09-13 [`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value [`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark [`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop +[`needless_raw_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string [`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes [`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return [`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 8753bcee5ce..c67ed14b3b0 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -469,7 +469,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO, crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO, crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO, - crate::needless_raw_string_hashes::NEEDLESS_RAW_STRING_HASHES_INFO, crate::needless_update::NEEDLESS_UPDATE_INFO, crate::neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD_INFO, crate::neg_multiply::NEG_MULTIPLY_INFO, @@ -541,6 +540,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::ranges::RANGE_MINUS_ONE_INFO, crate::ranges::RANGE_PLUS_ONE_INFO, crate::ranges::REVERSED_EMPTY_RANGES_INFO, + crate::raw_strings::NEEDLESS_RAW_STRING_INFO, + crate::raw_strings::NEEDLESS_RAW_STRING_HASHES_INFO, crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO, crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO, crate::redundant_async_block::REDUNDANT_ASYNC_BLOCK_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index aadba6581a1..e1a7eedd93e 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -230,7 +230,6 @@ mod needless_late_init; mod needless_parens_on_range_literals; mod needless_pass_by_value; mod needless_question_mark; -mod needless_raw_string_hashes; mod needless_update; mod neg_cmp_op_on_partial_ord; mod neg_multiply; @@ -263,6 +262,7 @@ mod pub_use; mod question_mark; mod question_mark_used; mod ranges; +mod raw_strings; mod rc_clone_in_vec_init; mod read_zero_byte_vec; mod redundant_async_block; diff --git a/clippy_lints/src/needless_raw_string_hashes.rs b/clippy_lints/src/needless_raw_string_hashes.rs deleted file mode 100644 index 85dffa5613d..00000000000 --- a/clippy_lints/src/needless_raw_string_hashes.rs +++ /dev/null @@ -1,73 +0,0 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; -use rustc_ast::{ - ast::{Expr, ExprKind}, - token::LitKind, -}; -use rustc_errors::Applicability; -use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; -use rustc_middle::lint::in_external_macro; -use rustc_session::{declare_lint_pass, declare_tool_lint}; - -declare_clippy_lint! { - /// ### What it does - /// Checks for raw string literals with an unnecessary amount of hashes around them. - /// - /// ### Why is this bad? - /// It's just unnecessary, and makes it look like there's more escaping needed than is actually - /// necessary. - /// - /// ### Example - /// ```rust - /// let r = r###"Hello, "world"!"###; - /// ``` - /// Use instead: - /// ```rust - /// let r = r#"Hello, "world"!"#; - /// ``` - #[clippy::version = "1.72.0"] - pub NEEDLESS_RAW_STRING_HASHES, - complexity, - "suggests reducing the number of hashes around a raw string literal" -} -declare_lint_pass!(NeedlessRawStringHashes => [NEEDLESS_RAW_STRING_HASHES]); - -impl EarlyLintPass for NeedlessRawStringHashes { - fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { - if_chain! { - if !in_external_macro(cx.sess(), expr.span); - if let ExprKind::Lit(lit) = expr.kind; - if let LitKind::StrRaw(num) | LitKind::ByteStrRaw(num) | LitKind::CStrRaw(num) = lit.kind; - then { - let str = lit.symbol.as_str(); - let mut lowest = 0; - - for i in (0..num).rev() { - if str.contains(&format!("\"{}", "#".repeat(i as usize))) { - lowest = i + 1; - break; - } - } - - if lowest < num { - let hashes = "#".repeat(lowest as usize); - let prefix = match lit.kind { - LitKind::StrRaw(..) => "r", - LitKind::ByteStrRaw(..) => "br", - LitKind::CStrRaw(..) => "cr", - _ => unreachable!(), - }; - - span_lint_and_sugg( - cx, - NEEDLESS_RAW_STRING_HASHES, - expr.span, - "unnecessary hashes around raw string literal", - "try", - format!(r#"{prefix}{hashes}"{}"{hashes}"#, lit.symbol), - Applicability::MachineApplicable, - ); - } - } - } - } -} diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs new file mode 100644 index 00000000000..52814693f3c --- /dev/null +++ b/clippy_lints/src/raw_strings.rs @@ -0,0 +1,109 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; +use rustc_ast::{ + ast::{Expr, ExprKind}, + token::LitKind, +}; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for raw string literals where a string literal can be used instead. + /// + /// ### Why is this bad? + /// It's just unnecessary. + /// + /// ### Example + /// ```rust + /// let r = r"Hello, world!"; + /// ``` + /// Use instead: + /// ```rust + /// let r = "Hello, world!"; + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_RAW_STRING, + complexity, + "suggests using a string literal when a raw string literal is unnecessary" +} +declare_clippy_lint! { + /// ### What it does + /// Checks for raw string literals with an unnecessary amount of hashes around them. + /// + /// ### Why is this bad? + /// It's just unnecessary, and makes it look like there's more escaping needed than is actually + /// necessary. + /// + /// ### Example + /// ```rust + /// let r = r###"Hello, "world"!"###; + /// ``` + /// Use instead: + /// ```rust + /// let r = r#"Hello, "world"!"#; + /// ``` + #[clippy::version = "1.72.0"] + pub NEEDLESS_RAW_STRING_HASHES, + complexity, + "suggests reducing the number of hashes around a raw string literal" +} +impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRING, NEEDLESS_RAW_STRING_HASHES]); + +pub struct RawStrings { + pub needless_raw_string_hashes_allow_one: bool, +} + +impl EarlyLintPass for RawStrings { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if !in_external_macro(cx.sess(), expr.span) + && let ExprKind::Lit(lit) = expr.kind + && let LitKind::StrRaw(num) | LitKind::ByteStrRaw(num) | LitKind::CStrRaw(num) = lit.kind + { + let prefix = match lit.kind { + LitKind::StrRaw(..) => "r", + LitKind::ByteStrRaw(..) => "br", + LitKind::CStrRaw(..) => "cr", + _ => unreachable!(), + }; + if !snippet(cx, expr.span, prefix).trim().starts_with(prefix) { + return; + } + + #[allow(clippy::cast_possible_truncation)] + let req = lit.symbol.as_str().as_bytes() + .split(|&b| b == b'"') + .skip(1) + .map(|bs| 1 + bs.iter().take_while(|&&b| b == b'#').count() as u8) + .max() + .unwrap_or(0); + + if req < num { + let hashes = "#".repeat(req as usize); + + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRING_HASHES, + expr.span, + "unnecessary hashes around raw string literal", + "try", + format!(r#"{prefix}{hashes}"{}"{hashes}"#, lit.symbol), + Applicability::MachineApplicable, + ); + } + + if !lit.symbol.as_str().contains(['\\', '"']) { + span_lint_and_sugg( + cx, + NEEDLESS_RAW_STRING, + expr.span, + "unnecessary raw string literal", + "try", + format!("{}\"{}\"", prefix.replace('r', ""), lit.symbol), + Applicability::MachineApplicable, + ); + } + } + } +} diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 12197666b30..9f88960f7ce 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -543,10 +543,14 @@ define_Conf! { /// /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block (accept_comment_above_statement: bool = false), - /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. /// /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block (accept_comment_above_attributes: bool = false), + /// Lint: UNNECESSARY_RAW_STRING_HASHES. + /// + /// Whether to allow `r#""#` when `r""` can be used + (allow_one_hash_in_raw_string: bool = false), } /// Search for the configuration file. diff --git a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs index e4cb5316a98..570a88a0ed2 100644 --- a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs +++ b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs @@ -35,7 +35,7 @@ struct StandardFormulations<'a> { impl AlmostStandardFormulation { pub fn new() -> Self { let standard_formulations = vec![StandardFormulations { - wrong_pattern: Regex::new(r"^(Check for|Detects? uses?)").unwrap(), + wrong_pattern: Regex::new("^(Check for|Detects? uses?)").unwrap(), correction: "Checks for", }]; Self { standard_formulations } diff --git a/src/main.rs b/src/main.rs index fd0da5a170b..cdc85cb33ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::env; use std::path::PathBuf; use std::process::{self, Command}; -const CARGO_CLIPPY_HELP: &str = r"Checks a package to catch common mistakes and improve your Rust code. +const CARGO_CLIPPY_HELP: &str = "Checks a package to catch common mistakes and improve your Rust code. Usage: cargo clippy [options] [--] [...] diff --git a/tests/lint_message_convention.rs b/tests/lint_message_convention.rs index 8feea800fdb..15e5cdd6992 100644 --- a/tests/lint_message_convention.rs +++ b/tests/lint_message_convention.rs @@ -20,16 +20,16 @@ impl Message { // also no punctuation (except for "?" ?) at the end of a line static REGEX_SET: LazyLock = LazyLock::new(|| { RegexSet::new([ - r"error: [A-Z]", - r"help: [A-Z]", - r"warning: [A-Z]", - r"note: [A-Z]", - r"try this: [A-Z]", - r"error: .*[.!]$", - r"help: .*[.!]$", - r"warning: .*[.!]$", - r"note: .*[.!]$", - r"try this: .*[.!]$", + "error: [A-Z]", + "help: [A-Z]", + "warning: [A-Z]", + "note: [A-Z]", + "try this: [A-Z]", + "error: .*[.!]$", + "help: .*[.!]$", + "warning: .*[.!]$", + "note: .*[.!]$", + "try this: .*[.!]$", ]) .unwrap() }); @@ -39,11 +39,11 @@ impl Message { static EXCEPTIONS_SET: LazyLock = LazyLock::new(|| { RegexSet::new([ r"\.\.\.$", - r".*C-like enum variant discriminant is not portable to 32-bit targets", - r".*Intel x86 assembly syntax used", - r".*AT&T x86 assembly syntax used", - r"note: Clippy version: .*", - r"the compiler unexpectedly panicked. this is a bug.", + ".*C-like enum variant discriminant is not portable to 32-bit targets", + ".*Intel x86 assembly syntax used", + ".*AT&T x86 assembly syntax used", + "note: Clippy version: .*", + "the compiler unexpectedly panicked. this is a bug.", ]) .unwrap() }); diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index ebbc7fea328..d26bc72787b 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -1,5 +1,6 @@ //@compile-flags: --crate-name conf_disallowed_methods +#![allow(clippy::needless_raw_string)] #![warn(clippy::disallowed_methods)] #![allow(clippy::useless_vec)] diff --git a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr index 3dc83a40780..fc137c225d8 100644 --- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr +++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr @@ -1,5 +1,5 @@ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:34:14 + --> $DIR/conf_disallowed_methods.rs:35:14 | LL | let re = Regex::new(r"ab.*c").unwrap(); | ^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | let re = Regex::new(r"ab.*c").unwrap(); = note: `-D clippy::disallowed-methods` implied by `-D warnings` error: use of a disallowed method `regex::Regex::is_match` - --> $DIR/conf_disallowed_methods.rs:35:5 + --> $DIR/conf_disallowed_methods.rs:36:5 | LL | re.is_match("abc"); | ^^^^^^^^^^^^^^^^^^ @@ -15,73 +15,73 @@ LL | re.is_match("abc"); = note: no matching allowed (from clippy.toml) error: use of a disallowed method `std::iter::Iterator::sum` - --> $DIR/conf_disallowed_methods.rs:38:5 + --> $DIR/conf_disallowed_methods.rs:39:5 | LL | a.iter().sum::(); | ^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `slice::sort_unstable` - --> $DIR/conf_disallowed_methods.rs:40:5 + --> $DIR/conf_disallowed_methods.rs:41:5 | LL | a.sort_unstable(); | ^^^^^^^^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> $DIR/conf_disallowed_methods.rs:42:13 + --> $DIR/conf_disallowed_methods.rs:43:13 | LL | let _ = 2.0f32.clamp(3.0f32, 4.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:45:61 + --> $DIR/conf_disallowed_methods.rs:46:61 | LL | let indirect: fn(&str) -> Result = Regex::new; | ^^^^^^^^^^ error: use of a disallowed method `f32::clamp` - --> $DIR/conf_disallowed_methods.rs:48:28 + --> $DIR/conf_disallowed_methods.rs:49:28 | LL | let in_call = Box::new(f32::clamp); | ^^^^^^^^^^ error: use of a disallowed method `regex::Regex::new` - --> $DIR/conf_disallowed_methods.rs:49:53 + --> $DIR/conf_disallowed_methods.rs:50:53 | LL | let in_method_call = ["^", "$"].into_iter().map(Regex::new); | ^^^^^^^^^^ error: use of a disallowed method `futures::stream::select_all` - --> $DIR/conf_disallowed_methods.rs:52:31 + --> $DIR/conf_disallowed_methods.rs:53:31 | LL | let same_name_as_module = select_all(vec![empty::<()>()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_fn` - --> $DIR/conf_disallowed_methods.rs:54:5 + --> $DIR/conf_disallowed_methods.rs:55:5 | LL | local_fn(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::local_mod::f` - --> $DIR/conf_disallowed_methods.rs:55:5 + --> $DIR/conf_disallowed_methods.rs:56:5 | LL | local_mod::f(); | ^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Struct::method` - --> $DIR/conf_disallowed_methods.rs:57:5 + --> $DIR/conf_disallowed_methods.rs:58:5 | LL | s.method(); | ^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::provided_method` - --> $DIR/conf_disallowed_methods.rs:58:5 + --> $DIR/conf_disallowed_methods.rs:59:5 | LL | s.provided_method(); | ^^^^^^^^^^^^^^^^^^^ error: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method` - --> $DIR/conf_disallowed_methods.rs:59:5 + --> $DIR/conf_disallowed_methods.rs:60:5 | LL | s.implemented_method(); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 69678057917..8724dc29d29 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -4,6 +4,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect allow-dbg-in-tests allow-expect-in-tests allow-mixed-uninlined-format-args + allow-one-hash-in-raw-string allow-print-in-tests allow-private-module-inception allow-unwrap-in-tests @@ -72,6 +73,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect allow-dbg-in-tests allow-expect-in-tests allow-mixed-uninlined-format-args + allow-one-hash-in-raw-string allow-print-in-tests allow-private-module-inception allow-unwrap-in-tests diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr index f456c11924e..78a11a3354f 100644 --- a/tests/ui/format.stderr +++ b/tests/ui/format.stderr @@ -1,5 +1,5 @@ error: useless use of `format!` - --> $DIR/format.rs:20:5 + --> $DIR/format.rs:21:5 | LL | format!("foo"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` @@ -7,19 +7,19 @@ LL | format!("foo"); = note: `-D clippy::useless-format` implied by `-D warnings` error: useless use of `format!` - --> $DIR/format.rs:21:5 + --> $DIR/format.rs:22:5 | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:22:5 + --> $DIR/format.rs:23:5 | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:23:5 + --> $DIR/format.rs:24:5 | LL | / format!( LL | | r##"foo {{}} @@ -34,67 +34,67 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> $DIR/format.rs:28:13 + --> $DIR/format.rs:29:13 | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> $DIR/format.rs:30:5 + --> $DIR/format.rs:31:5 | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> $DIR/format.rs:38:5 + --> $DIR/format.rs:39:5 | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> $DIR/format.rs:68:5 + --> $DIR/format.rs:69:5 | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> $DIR/format.rs:70:5 + --> $DIR/format.rs:71:5 | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> $DIR/format.rs:74:18 + --> $DIR/format.rs:75:18 | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> $DIR/format.rs:78:22 + --> $DIR/format.rs:79:22 | LL | let _s: String = format!("{}", &*v.join("/n")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()` error: useless use of `format!` - --> $DIR/format.rs:84:13 + --> $DIR/format.rs:85:13 | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:86:13 + --> $DIR/format.rs:87:13 | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:90:13 + --> $DIR/format.rs:91:13 | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> $DIR/format.rs:92:13 + --> $DIR/format.rs:93:13 | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/tests/ui/needless_raw_string.fixed b/tests/ui/needless_raw_string.fixed new file mode 100644 index 00000000000..ffc1644335d --- /dev/null +++ b/tests/ui/needless_raw_string.fixed @@ -0,0 +1,16 @@ +//@run-rustfix +#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] +#![warn(clippy::needless_raw_string)] +#![feature(c_str_literals)] + +fn main() { + "aaa"; + r#""aaa""#; + r#"\s"#; + b"aaa"; + br#""aaa""#; + br#"\s"#; + c"aaa"; + cr#""aaa""#; + cr#"\s"#; +} diff --git a/tests/ui/needless_raw_string.rs b/tests/ui/needless_raw_string.rs new file mode 100644 index 00000000000..b06b9a0ec85 --- /dev/null +++ b/tests/ui/needless_raw_string.rs @@ -0,0 +1,16 @@ +//@run-rustfix +#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)] +#![warn(clippy::needless_raw_string)] +#![feature(c_str_literals)] + +fn main() { + r#"aaa"#; + r#""aaa""#; + r#"\s"#; + br#"aaa"#; + br#""aaa""#; + br#"\s"#; + cr#"aaa"#; + cr#""aaa""#; + cr#"\s"#; +} diff --git a/tests/ui/needless_raw_string.stderr b/tests/ui/needless_raw_string.stderr new file mode 100644 index 00000000000..3eb699dea36 --- /dev/null +++ b/tests/ui/needless_raw_string.stderr @@ -0,0 +1,22 @@ +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:7:5 + | +LL | r#"aaa"#; + | ^^^^^^^^ help: try: `"aaa"` + | + = note: `-D clippy::needless-raw-string` implied by `-D warnings` + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:10:5 + | +LL | br#"aaa"#; + | ^^^^^^^^^ help: try: `b"aaa"` + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:13:5 + | +LL | cr#"aaa"#; + | ^^^^^^^^^ help: try: `c"aaa"` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/needless_raw_string_hashes.fixed b/tests/ui/needless_raw_string_hashes.fixed index 43616860a2e..1bfb573719d 100644 --- a/tests/ui/needless_raw_string_hashes.fixed +++ b/tests/ui/needless_raw_string_hashes.fixed @@ -1,5 +1,5 @@ //@run-rustfix -#![allow(clippy::no_effect, unused)] +#![allow(clippy::needless_raw_string, clippy::no_effect, unused)] #![warn(clippy::needless_raw_string_hashes)] #![feature(c_str_literals)] diff --git a/tests/ui/needless_raw_string_hashes.rs b/tests/ui/needless_raw_string_hashes.rs index e2d85c52e78..dedd774ea0a 100644 --- a/tests/ui/needless_raw_string_hashes.rs +++ b/tests/ui/needless_raw_string_hashes.rs @@ -1,5 +1,5 @@ //@run-rustfix -#![allow(clippy::no_effect, unused)] +#![allow(clippy::needless_raw_string, clippy::no_effect, unused)] #![warn(clippy::needless_raw_string_hashes)] #![feature(c_str_literals)] diff --git a/tests/ui/regex.rs b/tests/ui/regex.rs index 3b208651946..850c9813462 100644 --- a/tests/ui/regex.rs +++ b/tests/ui/regex.rs @@ -1,4 +1,9 @@ -#![allow(unused, clippy::needless_raw_string_hashes, clippy::needless_borrow)] +#![allow( + unused, + clippy::needless_raw_string, + clippy::needless_raw_string_hashes, + clippy::needless_borrow +)] #![warn(clippy::invalid_regex, clippy::trivial_regex)] extern crate regex; diff --git a/tests/ui/regex.stderr b/tests/ui/regex.stderr index c74dc8108fe..21f1cb44460 100644 --- a/tests/ui/regex.stderr +++ b/tests/ui/regex.stderr @@ -1,5 +1,5 @@ error: trivial regex - --> $DIR/regex.rs:13:45 + --> $DIR/regex.rs:18:45 | LL | let pipe_in_wrong_position = Regex::new("|"); | ^^^ @@ -8,7 +8,7 @@ LL | let pipe_in_wrong_position = Regex::new("|"); = note: `-D clippy::trivial-regex` implied by `-D warnings` error: trivial regex - --> $DIR/regex.rs:14:60 + --> $DIR/regex.rs:19:60 | LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); | ^^^ @@ -16,7 +16,7 @@ LL | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); = help: the regex is unlikely to be useful as it is error: regex syntax error: invalid character class range, the start must be <= the end - --> $DIR/regex.rs:15:42 + --> $DIR/regex.rs:20:42 | LL | let wrong_char_ranice = Regex::new("[z-a]"); | ^^^ @@ -24,7 +24,7 @@ LL | let wrong_char_ranice = Regex::new("[z-a]"); = note: `-D clippy::invalid-regex` implied by `-D warnings` error: regex syntax error: invalid character class range, the start must be <= the end - --> $DIR/regex.rs:16:37 + --> $DIR/regex.rs:21:37 | LL | let some_unicode = Regex::new("[é-è]"); | ^^^ @@ -33,13 +33,13 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:18:33 + --> $DIR/regex.rs:23:33 | LL | let some_regex = Regex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ error: trivial regex - --> $DIR/regex.rs:20:53 + --> $DIR/regex.rs:25:53 | LL | let binary_pipe_in_wrong_position = BRegex::new("|"); | ^^^ @@ -50,7 +50,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:21:41 + --> $DIR/regex.rs:26:41 | LL | let some_binary_regex = BRegex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:22:56 + --> $DIR/regex.rs:27:56 | LL | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); | ^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:34:37 + --> $DIR/regex.rs:39:37 | LL | let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); | ^^^^^^^^^^^^^ @@ -77,7 +77,7 @@ error: regex parse error: ( ^ error: unclosed group - --> $DIR/regex.rs:35:39 + --> $DIR/regex.rs:40:39 | LL | let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+/.(com|org|net)"]); | ^^^^^^^^^^^^^ @@ -86,7 +86,7 @@ error: regex parse error: /b/c ^^ error: unrecognized escape sequence - --> $DIR/regex.rs:42:42 + --> $DIR/regex.rs:47:42 | LL | let escaped_string_span = Regex::new("//b//c"); | ^^^^^^^^ @@ -94,19 +94,19 @@ LL | let escaped_string_span = Regex::new("//b//c"); = help: consider using a raw string literal: `r".."` error: regex syntax error: duplicate flag - --> $DIR/regex.rs:44:34 + --> $DIR/regex.rs:49:34 | LL | let aux_span = Regex::new("(?ixi)"); | ^ ^ error: regex syntax error: pattern can match invalid UTF-8 - --> $DIR/regex.rs:49:53 + --> $DIR/regex.rs:54:53 | LL | let invalid_utf8_should_lint = Regex::new("(?-u)."); | ^ error: trivial regex - --> $DIR/regex.rs:53:33 + --> $DIR/regex.rs:58:33 | LL | let trivial_eq = Regex::new("^foobar$"); | ^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | let trivial_eq = Regex::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:55:48 + --> $DIR/regex.rs:60:48 | LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); | ^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | let trivial_eq_builder = RegexBuilder::new("^foobar$"); = help: consider using `==` on `str`s error: trivial regex - --> $DIR/regex.rs:57:42 + --> $DIR/regex.rs:62:42 | LL | let trivial_starts_with = Regex::new("^foobar"); | ^^^^^^^^^ @@ -130,7 +130,7 @@ LL | let trivial_starts_with = Regex::new("^foobar"); = help: consider using `str::starts_with` error: trivial regex - --> $DIR/regex.rs:59:40 + --> $DIR/regex.rs:64:40 | LL | let trivial_ends_with = Regex::new("foobar$"); | ^^^^^^^^^ @@ -138,7 +138,7 @@ LL | let trivial_ends_with = Regex::new("foobar$"); = help: consider using `str::ends_with` error: trivial regex - --> $DIR/regex.rs:61:39 + --> $DIR/regex.rs:66:39 | LL | let trivial_contains = Regex::new("foobar"); | ^^^^^^^^ @@ -146,7 +146,7 @@ LL | let trivial_contains = Regex::new("foobar"); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:63:39 + --> $DIR/regex.rs:68:39 | LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); | ^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:65:40 + --> $DIR/regex.rs:70:40 | LL | let trivial_backslash = Regex::new("a//.b"); | ^^^^^^^ @@ -162,7 +162,7 @@ LL | let trivial_backslash = Regex::new("a//.b"); = help: consider using `str::contains` error: trivial regex - --> $DIR/regex.rs:68:36 + --> $DIR/regex.rs:73:36 | LL | let trivial_empty = Regex::new(""); | ^^ @@ -170,7 +170,7 @@ LL | let trivial_empty = Regex::new(""); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:70:36 + --> $DIR/regex.rs:75:36 | LL | let trivial_empty = Regex::new("^"); | ^^^ @@ -178,7 +178,7 @@ LL | let trivial_empty = Regex::new("^"); = help: the regex is unlikely to be useful as it is error: trivial regex - --> $DIR/regex.rs:72:36 + --> $DIR/regex.rs:77:36 | LL | let trivial_empty = Regex::new("^$"); | ^^^^ @@ -186,7 +186,7 @@ LL | let trivial_empty = Regex::new("^$"); = help: consider using `str::is_empty` error: trivial regex - --> $DIR/regex.rs:74:44 + --> $DIR/regex.rs:79:44 | LL | let binary_trivial_empty = BRegex::new("^$"); | ^^^^ diff --git a/tests/ui/single_char_add_str.fixed b/tests/ui/single_char_add_str.fixed index 2d4c0841219..ee0177776bf 100644 --- a/tests/ui/single_char_add_str.fixed +++ b/tests/ui/single_char_add_str.fixed @@ -1,6 +1,6 @@ //@run-rustfix #![warn(clippy::single_char_add_str)] -#![allow(clippy::needless_raw_string_hashes)] +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes)] macro_rules! get_string { () => { diff --git a/tests/ui/single_char_add_str.rs b/tests/ui/single_char_add_str.rs index 463b19da09e..e3b7d8597c2 100644 --- a/tests/ui/single_char_add_str.rs +++ b/tests/ui/single_char_add_str.rs @@ -1,6 +1,6 @@ //@run-rustfix #![warn(clippy::single_char_add_str)] -#![allow(clippy::needless_raw_string_hashes)] +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes)] macro_rules! get_string { () => { diff --git a/tests/ui/single_char_pattern.fixed b/tests/ui/single_char_pattern.fixed index f1dc3ea9894..920d43318ae 100644 --- a/tests/ui/single_char_pattern.fixed +++ b/tests/ui/single_char_pattern.fixed @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(clippy::needless_raw_string_hashes, unused_must_use)] +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes, unused_must_use)] use std::collections::HashSet; diff --git a/tests/ui/single_char_pattern.rs b/tests/ui/single_char_pattern.rs index 00b38498001..3a53084e30b 100644 --- a/tests/ui/single_char_pattern.rs +++ b/tests/ui/single_char_pattern.rs @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(clippy::needless_raw_string_hashes, unused_must_use)] +#![allow(clippy::needless_raw_string, clippy::needless_raw_string_hashes, unused_must_use)] use std::collections::HashSet; diff --git a/tests/ui/write_literal_2.rs b/tests/ui/write_literal_2.rs index 55a11daa1d3..1d9b9603bd8 100644 --- a/tests/ui/write_literal_2.rs +++ b/tests/ui/write_literal_2.rs @@ -1,5 +1,5 @@ #![allow(unused_must_use)] -#![warn(clippy::write_literal)] +#![warn(clippy::needless_raw_string, clippy::write_literal)] use std::io::Write; diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr index bf22738480d..a69d031b011 100644 --- a/tests/ui/write_literal_2.stderr +++ b/tests/ui/write_literal_2.stderr @@ -1,3 +1,11 @@ +error: unnecessary raw string literal + --> $DIR/write_literal_2.rs:10:24 + | +LL | writeln!(v, r"{}", r"{hello}"); + | ^^^^^^^^^^ help: try: `"{hello}"` + | + = note: `-D clippy::needless-raw-string` implied by `-D warnings` + error: literal with an empty format string --> $DIR/write_literal_2.rs:9:23 | @@ -186,5 +194,5 @@ error: literal with an empty format string LL | writeln!(v, r#"{}{}"#, '#', '"'); // hard mode | ^^^ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors