about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCentri3 <114838443+Centri3@users.noreply.github.com>2023-06-15 14:15:10 -0500
committerCatherine <114838443+Centri3@users.noreply.github.com>2023-06-27 05:16:40 -0500
commit8cb6c86996a8ea9e35a4e1c0c38a5a4da00b95dc (patch)
tree56be1a6efd6f9ff97b5d10cc66bbcb315efd66b2
parentcb52d19ce106f2ba2c4e1cca860757170c1db2ed (diff)
downloadrust-8cb6c86996a8ea9e35a4e1c0c38a5a4da00b95dc.tar.gz
rust-8cb6c86996a8ea9e35a4e1c0c38a5a4da00b95dc.zip
change category and refactor
Update raw_strings.rs

Revert "new lints for visibility"

This reverts commit 0e5a537d209727169769dc19cf86aef27122c092.

new lints for visibility
-rw-r--r--CHANGELOG.md4
-rw-r--r--book/src/lint_configuration.md2
-rw-r--r--clippy_lints/src/declared_lints.rs2
-rw-r--r--clippy_lints/src/lib.rs6
-rw-r--r--clippy_lints/src/raw_strings.rs64
-rw-r--r--clippy_lints/src/utils/conf.rs2
-rw-r--r--tests/compile-test.rs2
-rw-r--r--tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs2
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr4
-rw-r--r--tests/ui/needless_raw_string.fixed2
-rw-r--r--tests/ui/needless_raw_string.rs2
-rw-r--r--tests/ui/needless_raw_string.stderr2
-rw-r--r--tests/ui/needless_raw_string_hashes.fixed2
-rw-r--r--tests/ui/needless_raw_string_hashes.rs2
-rw-r--r--tests/ui/regex.rs2
-rw-r--r--tests/ui/single_char_add_str.fixed2
-rw-r--r--tests/ui/single_char_add_str.rs2
-rw-r--r--tests/ui/single_char_pattern.fixed2
-rw-r--r--tests/ui/single_char_pattern.rs2
-rw-r--r--tests/ui/write_literal_2.rs2
-rw-r--r--tests/ui/write_literal_2.stderr2
21 files changed, 75 insertions, 37 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e81e87bf077..a7284a70a1f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5048,8 +5048,8 @@ 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_raw_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_strings
 [`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
 [`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update
@@ -5414,5 +5414,5 @@ Released 2018-09-13
 [`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
 [`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
 [`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes
-[`allow-one-hash-in-raw-string`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-string
+[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
 <!-- end autogenerated links to configuration documentation -->
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index efb48131502..293195e858c 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -717,7 +717,7 @@ Whether to accept a safety comment to be placed above the attributes for the `un
 * [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
 
 
-## `allow-one-hash-in-raw-string`
+## `allow-one-hash-in-raw-strings`
 Whether to allow `r#""#` when `r""` can be used
 
 **Default Value:** `false` (`bool`)
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index c67ed14b3b0..dbd4a53d836 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -540,7 +540,7 @@ 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_STRINGS_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,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index e1a7eedd93e..d926b7b84ea 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -1062,6 +1062,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
             def_id_to_usage: rustc_data_structures::fx::FxHashMap::default(),
         })
     });
+    let needless_raw_string_hashes_allow_one = conf.allow_one_hash_in_raw_strings;
+    store.register_early_pass(move || {
+        Box::new(raw_strings::RawStrings {
+            needless_raw_string_hashes_allow_one,
+        })
+    });
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs
index b465c7566f0..f45bb1ef3e1 100644
--- a/clippy_lints/src/raw_strings.rs
+++ b/clippy_lints/src/raw_strings.rs
@@ -1,3 +1,5 @@
+use std::{iter::once, ops::ControlFlow};
+
 use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet};
 use rustc_ast::{
     ast::{Expr, ExprKind},
@@ -13,7 +15,8 @@ declare_clippy_lint! {
     /// Checks for raw string literals where a string literal can be used instead.
     ///
     /// ### Why is this bad?
-    /// It's just unnecessary.
+    /// It's just unnecessary, but there are many cases where using a raw string literal is more
+    /// idiomatic than a string literal, so it's opt-in.
     ///
     /// ### Example
     /// ```rust
@@ -24,8 +27,8 @@ declare_clippy_lint! {
     /// let r = "Hello, world!";
     /// ```
     #[clippy::version = "1.72.0"]
-    pub NEEDLESS_RAW_STRING,
-    complexity,
+    pub NEEDLESS_RAW_STRINGS,
+    restriction,
     "suggests using a string literal when a raw string literal is unnecessary"
 }
 declare_clippy_lint! {
@@ -46,10 +49,10 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.72.0"]
     pub NEEDLESS_RAW_STRING_HASHES,
-    complexity,
+    style,
     "suggests reducing the number of hashes around a raw string literal"
 }
-impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRING, NEEDLESS_RAW_STRING_HASHES]);
+impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]);
 
 pub struct RawStrings {
     pub needless_raw_string_hashes_allow_one: bool,
@@ -59,8 +62,9 @@ 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 LitKind::StrRaw(max) | LitKind::ByteStrRaw(max) | LitKind::CStrRaw(max) = lit.kind
         {
+            let str = lit.symbol.as_str();
             let prefix = match lit.kind {
                 LitKind::StrRaw(..) => "r",
                 LitKind::ByteStrRaw(..) => "br",
@@ -71,10 +75,10 @@ impl EarlyLintPass for RawStrings {
                 return;
             }
 
-            if !lit.symbol.as_str().contains(['\\', '"']) {
+            if !str.contains(['\\', '"']) {
                 span_lint_and_sugg(
                     cx,
-                    NEEDLESS_RAW_STRING,
+                    NEEDLESS_RAW_STRINGS,
                     expr.span,
                     "unnecessary raw string literal",
                     "try",
@@ -85,15 +89,43 @@ impl EarlyLintPass for RawStrings {
                 return;
             }
 
-            #[expect(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);
+            let req = {
+                let mut following_quote = false;
+                let mut req = 0;
+                // `once` so a raw string ending in hashes is still checked
+                let num = str.as_bytes().iter().chain(once(&0)).try_fold(0u8, |acc, &b| {
+                    match b {
+                        b'"' => (following_quote, req) = (true, 1),
+                        // I'm a bit surprised the compiler didn't optimize this out, there's no
+                        // branch but it still ends up doing an unnecessary comparison, it's:
+                        // - cmp r9b,1h
+                        // - sbb cl,-1h
+                        // which will add 1 if it's true. With this change, it becomes:
+                        // - add cl,r9b
+                        // isn't that so much nicer?
+                        b'#' => req += u8::from(following_quote),
+                        _ => {
+                            if following_quote {
+                                following_quote = false;
+
+                                if req == max {
+                                    return ControlFlow::Break(req);
+                                }
+
+                                return ControlFlow::Continue(acc.max(req));
+                            }
+                        },
+                    }
+
+                    ControlFlow::Continue(acc)
+                });
+
+                match num {
+                    ControlFlow::Continue(num) | ControlFlow::Break(num) => num,
+                }
+            };
 
-            if req < num {
+            if req < max {
                 let hashes = "#".repeat(req as usize);
 
                 span_lint_and_sugg(
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 9f88960f7ce..9be94920f96 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -550,7 +550,7 @@ define_Conf! {
     /// Lint: UNNECESSARY_RAW_STRING_HASHES.
     ///
     /// Whether to allow `r#""#` when `r""` can be used
-    (allow_one_hash_in_raw_string: bool = false),
+    (allow_one_hash_in_raw_strings: bool = false),
 }
 
 /// Search for the configuration file.
diff --git a/tests/compile-test.rs b/tests/compile-test.rs
index c5e8622bc85..13013f646e5 100644
--- a/tests/compile-test.rs
+++ b/tests/compile-test.rs
@@ -50,7 +50,7 @@ fn base_config(test_dir: &str) -> compiletest::Config {
     config.program.args.push("-Dwarnings".into());
 
     // Normalize away slashes in windows paths.
-    config.stderr_filter(r#"\\"#, "/");
+    config.stderr_filter(r"\\", "/");
 
     //config.build_base = profile_path.join("test").join(test_dir);
     config.program.program = profile_path.join(if cfg!(windows) {
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 d26bc72787b..63fdea710cb 100644
--- a/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs
+++ b/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs
@@ -1,6 +1,6 @@
 //@compile-flags: --crate-name conf_disallowed_methods
 
-#![allow(clippy::needless_raw_string)]
+#![allow(clippy::needless_raw_strings)]
 #![warn(clippy::disallowed_methods)]
 #![allow(clippy::useless_vec)]
 
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 8724dc29d29..6ba26e97730 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -4,7 +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-one-hash-in-raw-strings
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
@@ -73,7 +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-one-hash-in-raw-strings
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
diff --git a/tests/ui/needless_raw_string.fixed b/tests/ui/needless_raw_string.fixed
index ffc1644335d..6438e46977b 100644
--- a/tests/ui/needless_raw_string.fixed
+++ b/tests/ui/needless_raw_string.fixed
@@ -1,6 +1,6 @@
 //@run-rustfix
 #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
-#![warn(clippy::needless_raw_string)]
+#![warn(clippy::needless_raw_strings)]
 #![feature(c_str_literals)]
 
 fn main() {
diff --git a/tests/ui/needless_raw_string.rs b/tests/ui/needless_raw_string.rs
index b06b9a0ec85..f7ddc68265e 100644
--- a/tests/ui/needless_raw_string.rs
+++ b/tests/ui/needless_raw_string.rs
@@ -1,6 +1,6 @@
 //@run-rustfix
 #![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
-#![warn(clippy::needless_raw_string)]
+#![warn(clippy::needless_raw_strings)]
 #![feature(c_str_literals)]
 
 fn main() {
diff --git a/tests/ui/needless_raw_string.stderr b/tests/ui/needless_raw_string.stderr
index 3eb699dea36..0179978b7b0 100644
--- a/tests/ui/needless_raw_string.stderr
+++ b/tests/ui/needless_raw_string.stderr
@@ -4,7 +4,7 @@ error: unnecessary raw string literal
 LL |     r#"aaa"#;
    |     ^^^^^^^^ help: try: `"aaa"`
    |
-   = note: `-D clippy::needless-raw-string` implied by `-D warnings`
+   = note: `-D clippy::needless-raw-strings` implied by `-D warnings`
 
 error: unnecessary raw string literal
   --> $DIR/needless_raw_string.rs:10:5
diff --git a/tests/ui/needless_raw_string_hashes.fixed b/tests/ui/needless_raw_string_hashes.fixed
index 8d443dabcb7..e4d7d8fb017 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::needless_raw_string, clippy::no_effect, unused)]
+#![allow(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 dedd774ea0a..e2d85c52e78 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::needless_raw_string, clippy::no_effect, unused)]
+#![allow(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 850c9813462..89d1d949454 100644
--- a/tests/ui/regex.rs
+++ b/tests/ui/regex.rs
@@ -1,6 +1,6 @@
 #![allow(
     unused,
-    clippy::needless_raw_string,
+    clippy::needless_raw_strings,
     clippy::needless_raw_string_hashes,
     clippy::needless_borrow
 )]
diff --git a/tests/ui/single_char_add_str.fixed b/tests/ui/single_char_add_str.fixed
index ee0177776bf..cb301c8bc15 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, clippy::needless_raw_string_hashes)]
+#![allow(clippy::needless_raw_strings, 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 e3b7d8597c2..99baf35ac29 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, clippy::needless_raw_string_hashes)]
+#![allow(clippy::needless_raw_strings, 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 920d43318ae..7ae62231acc 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, clippy::needless_raw_string_hashes, unused_must_use)]
+#![allow(clippy::needless_raw_strings, 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 3a53084e30b..0604624e767 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, clippy::needless_raw_string_hashes, unused_must_use)]
+#![allow(clippy::needless_raw_strings, 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 1d9b9603bd8..805127e2750 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::needless_raw_string, clippy::write_literal)]
+#![warn(clippy::needless_raw_strings, clippy::write_literal)]
 
 use std::io::Write;
 
diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr
index a69d031b011..18591250aad 100644
--- a/tests/ui/write_literal_2.stderr
+++ b/tests/ui/write_literal_2.stderr
@@ -4,7 +4,7 @@ error: unnecessary raw string literal
 LL |     writeln!(v, r"{}", r"{hello}");
    |                        ^^^^^^^^^^ help: try: `"{hello}"`
    |
-   = note: `-D clippy::needless-raw-string` implied by `-D warnings`
+   = note: `-D clippy::needless-raw-strings` implied by `-D warnings`
 
 error: literal with an empty format string
   --> $DIR/write_literal_2.rs:9:23