From 6cdff107782be2c00ce37267bc5b2181dc1f12f7 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Tue, 26 Sep 2023 11:40:10 +0000 Subject: [PATCH] Describe the type of string in raw_strings lints --- clippy_lints/src/raw_strings.rs | 30 +++++++------ tests/ui/needless_raw_string.fixed | 4 ++ tests/ui/needless_raw_string.rs | 4 ++ tests/ui/needless_raw_string.stderr | 46 +++++++++++++++++--- tests/ui/needless_raw_string_hashes.stderr | 30 ++++++------- tests/ui/write_literal_2.rs | 10 ++--- tests/ui/write_literal_2.stderr | 49 ++++++++-------------- 7 files changed, 100 insertions(+), 73 deletions(-) diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs index 2895595e039..4b46cbc4d89 100644 --- a/clippy_lints/src/raw_strings.rs +++ b/clippy_lints/src/raw_strings.rs @@ -75,6 +75,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { if !snippet(cx, expr.span, prefix).trim().starts_with(prefix) { return; } + let descr = lit.kind.descr(); if !str.contains(['\\', '"']) { span_lint_and_then( @@ -89,20 +90,17 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { let r_pos = expr.span.lo() + BytePos::from_usize(prefix.len() - 1); let start = start.with_lo(r_pos); - if end.is_empty() { - diag.span_suggestion( - start, - "use a string literal instead", - format!("\"{str}\""), - Applicability::MachineApplicable, - ); - } else { - diag.multipart_suggestion( - "try", - vec![(start, String::new()), (end, String::new())], - Applicability::MachineApplicable, - ); + let mut remove = vec![(start, String::new())]; + // avoid debug ICE from empty suggestions + if !end.is_empty() { + remove.push((end, String::new())); } + + diag.multipart_suggestion_verbose( + format!("use a plain {descr} literal instead"), + remove, + Applicability::MachineApplicable, + ); }, ); if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) { @@ -149,9 +147,9 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { let (start, end) = hash_spans(expr.span, prefix, req, max); let message = match max - req { - _ if req == 0 => "remove all the hashes around the literal".to_string(), - 1 => "remove one hash from both sides of the literal".to_string(), - n => format!("remove {n} hashes from both sides of the literal"), + _ if req == 0 => format!("remove all the hashes around the {descr} literal"), + 1 => format!("remove one hash from both sides of the {descr} literal"), + n => format!("remove {n} hashes from both sides of the {descr} literal"), }; diag.multipart_suggestion( diff --git a/tests/ui/needless_raw_string.fixed b/tests/ui/needless_raw_string.fixed index 85549810513..4ea711fd67a 100644 --- a/tests/ui/needless_raw_string.fixed +++ b/tests/ui/needless_raw_string.fixed @@ -18,4 +18,8 @@ fn main() { multiline string "; + + "no hashes"; + b"no hashes"; + c"no hashes"; } diff --git a/tests/ui/needless_raw_string.rs b/tests/ui/needless_raw_string.rs index 06d49730387..b6239f9b1f0 100644 --- a/tests/ui/needless_raw_string.rs +++ b/tests/ui/needless_raw_string.rs @@ -18,4 +18,8 @@ fn main() { multiline string "#; + + r"no hashes"; + br"no hashes"; + cr"no hashes"; } diff --git a/tests/ui/needless_raw_string.stderr b/tests/ui/needless_raw_string.stderr index e6806b31b1d..276bc84c6c3 100644 --- a/tests/ui/needless_raw_string.stderr +++ b/tests/ui/needless_raw_string.stderr @@ -6,7 +6,7 @@ LL | r#"aaa"#; | = note: `-D clippy::needless-raw-strings` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]` -help: try +help: use a plain string literal instead | LL - r#"aaa"#; LL + "aaa"; @@ -18,7 +18,7 @@ error: unnecessary raw string literal LL | br#"aaa"#; | ^^^^^^^^^ | -help: try +help: use a plain byte string literal instead | LL - br#"aaa"#; LL + b"aaa"; @@ -30,7 +30,7 @@ error: unnecessary raw string literal LL | cr#"aaa"#; | ^^^^^^^^^ | -help: try +help: use a plain C string literal instead | LL - cr#"aaa"#; LL + c"aaa"; @@ -46,7 +46,7 @@ LL | | string LL | | "#; | |______^ | -help: try +help: use a plain string literal instead | LL ~ " LL | a @@ -55,5 +55,41 @@ LL | string LL ~ "; | -error: aborting due to 4 previous errors +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:22:5 + | +LL | r"no hashes"; + | ^^^^^^^^^^^^ + | +help: use a plain string literal instead + | +LL - r"no hashes"; +LL + "no hashes"; + | + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:23:5 + | +LL | br"no hashes"; + | ^^^^^^^^^^^^^ + | +help: use a plain byte string literal instead + | +LL - br"no hashes"; +LL + b"no hashes"; + | + +error: unnecessary raw string literal + --> $DIR/needless_raw_string.rs:24:5 + | +LL | cr"no hashes"; + | ^^^^^^^^^^^^^ + | +help: use a plain C string literal instead + | +LL - cr"no hashes"; +LL + c"no hashes"; + | + +error: aborting due to 7 previous errors diff --git a/tests/ui/needless_raw_string_hashes.stderr b/tests/ui/needless_raw_string_hashes.stderr index 4399c6555c2..017160b1a42 100644 --- a/tests/ui/needless_raw_string_hashes.stderr +++ b/tests/ui/needless_raw_string_hashes.stderr @@ -6,7 +6,7 @@ LL | r#"\aaa"#; | = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]` -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r#"\aaa"#; LL + r"\aaa"; @@ -18,7 +18,7 @@ error: unnecessary hashes around raw string literal LL | r##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the string literal | LL - r##"Hello "world"!"##; LL + r#"Hello "world"!"#; @@ -30,7 +30,7 @@ error: unnecessary hashes around raw string literal LL | r######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the string literal | LL - r######" "### "## "# "######; LL + r####" "### "## "# "####; @@ -42,7 +42,7 @@ error: unnecessary hashes around raw string literal LL | r######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the string literal | LL - r######" "aa" "# "## "######; LL + r###" "aa" "# "## "###; @@ -54,7 +54,7 @@ error: unnecessary hashes around raw string literal LL | br#"\aaa"#; | ^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the byte string literal | LL - br#"\aaa"#; LL + br"\aaa"; @@ -66,7 +66,7 @@ error: unnecessary hashes around raw string literal LL | br##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the byte string literal | LL - br##"Hello "world"!"##; LL + br#"Hello "world"!"#; @@ -78,7 +78,7 @@ error: unnecessary hashes around raw string literal LL | br######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the byte string literal | LL - br######" "### "## "# "######; LL + br####" "### "## "# "####; @@ -90,7 +90,7 @@ error: unnecessary hashes around raw string literal LL | br######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the byte string literal | LL - br######" "aa" "# "## "######; LL + br###" "aa" "# "## "###; @@ -102,7 +102,7 @@ error: unnecessary hashes around raw string literal LL | cr#"\aaa"#; | ^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the C string literal | LL - cr#"\aaa"#; LL + cr"\aaa"; @@ -114,7 +114,7 @@ error: unnecessary hashes around raw string literal LL | cr##"Hello "world"!"##; | ^^^^^^^^^^^^^^^^^^^^^^ | -help: remove one hash from both sides of the literal +help: remove one hash from both sides of the C string literal | LL - cr##"Hello "world"!"##; LL + cr#"Hello "world"!"#; @@ -126,7 +126,7 @@ error: unnecessary hashes around raw string literal LL | cr######" "### "## "# "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 2 hashes from both sides of the literal +help: remove 2 hashes from both sides of the C string literal | LL - cr######" "### "## "# "######; LL + cr####" "### "## "# "####; @@ -138,7 +138,7 @@ error: unnecessary hashes around raw string literal LL | cr######" "aa" "# "## "######; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -help: remove 3 hashes from both sides of the literal +help: remove 3 hashes from both sides of the C string literal | LL - cr######" "aa" "# "## "######; LL + cr###" "aa" "# "## "###; @@ -154,7 +154,7 @@ LL | | string LL | | "#; | |______^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL ~ r" LL | \a @@ -169,7 +169,7 @@ error: unnecessary hashes around raw string literal LL | r###"rust"###; | ^^^^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r###"rust"###; LL + r"rust"; @@ -181,7 +181,7 @@ error: unnecessary hashes around raw string literal LL | r#"hello world"#; | ^^^^^^^^^^^^^^^^ | -help: remove all the hashes around the literal +help: remove all the hashes around the string literal | LL - r#"hello world"#; LL + r"hello world"; diff --git a/tests/ui/write_literal_2.rs b/tests/ui/write_literal_2.rs index aa0c13c1340..197e01149e0 100644 --- a/tests/ui/write_literal_2.rs +++ b/tests/ui/write_literal_2.rs @@ -1,6 +1,6 @@ //@no-rustfix: overlapping suggestions #![allow(unused_must_use)] -#![warn(clippy::needless_raw_strings, clippy::write_literal)] +#![warn(clippy::write_literal)] use std::io::Write; @@ -11,9 +11,7 @@ fn main() { //~^ ERROR: literal with an empty format string //~| NOTE: `-D clippy::write-literal` implied by `-D warnings` writeln!(v, r"{}", r"{hello}"); - //~^ ERROR: unnecessary raw string literal - //~| NOTE: `-D clippy::needless-raw-strings` implied by `-D warnings` - //~| ERROR: literal with an empty format string + //~^ ERROR: literal with an empty format string writeln!(v, "{}", '\''); //~^ ERROR: literal with an empty format string writeln!(v, "{}", '"'); @@ -26,8 +24,8 @@ fn main() { v, "some {}", "hello \ - //~^ ERROR: literal with an empty format string - world!" + world!", + //~^^ ERROR: literal with an empty format string ); writeln!( v, diff --git a/tests/ui/write_literal_2.stderr b/tests/ui/write_literal_2.stderr index 6d382a267ad..9a16d2f240d 100644 --- a/tests/ui/write_literal_2.stderr +++ b/tests/ui/write_literal_2.stderr @@ -1,14 +1,3 @@ -error: unnecessary raw string literal - --> $DIR/write_literal_2.rs:13:24 - | -LL | writeln!(v, r"{}", r"{hello}"); - | -^^^^^^^^^ - | | - | help: use a string literal instead: `"{hello}"` - | - = note: `-D clippy::needless-raw-strings` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]` - error: literal with an empty format string --> $DIR/write_literal_2.rs:10:23 | @@ -36,7 +25,7 @@ LL + writeln!(v, r"{{hello}}"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:17:23 + --> $DIR/write_literal_2.rs:15:23 | LL | writeln!(v, "{}", '\''); | ^^^^ @@ -48,7 +37,7 @@ LL + writeln!(v, "'"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:19:23 + --> $DIR/write_literal_2.rs:17:23 | LL | writeln!(v, "{}", '"'); | ^^^ @@ -60,13 +49,13 @@ LL + writeln!(v, "\""); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:21:24 + --> $DIR/write_literal_2.rs:19:24 | LL | writeln!(v, r"{}", '"'); | ^^^ error: literal with an empty format string - --> $DIR/write_literal_2.rs:23:24 + --> $DIR/write_literal_2.rs:21:24 | LL | writeln!(v, r"{}", '\''); | ^^^^ @@ -78,22 +67,20 @@ LL + writeln!(v, r"'"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:28:9 + --> $DIR/write_literal_2.rs:26:9 | LL | / "hello \ -LL | | -LL | | world!" +LL | | world!", | |_______________^ | help: try | LL ~ "some hello \ -LL + -LL ~ world!" +LL ~ world!", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:36:9 + --> $DIR/write_literal_2.rs:34:9 | LL | "1", | ^^^ @@ -105,7 +92,7 @@ LL ~ {} \\ {}", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:37:9 + --> $DIR/write_literal_2.rs:35:9 | LL | "2", | ^^^ @@ -117,7 +104,7 @@ LL ~ "1", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:38:9 + --> $DIR/write_literal_2.rs:36:9 | LL | "3", | ^^^ @@ -130,7 +117,7 @@ LL ~ "2", | error: literal with an empty format string - --> $DIR/write_literal_2.rs:41:23 + --> $DIR/write_literal_2.rs:39:23 | LL | writeln!(v, "{}", "\\"); | ^^^^ @@ -142,7 +129,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:43:24 + --> $DIR/write_literal_2.rs:41:24 | LL | writeln!(v, r"{}", "\\"); | ^^^^ @@ -154,7 +141,7 @@ LL + writeln!(v, r"\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:45:26 + --> $DIR/write_literal_2.rs:43:26 | LL | writeln!(v, r#"{}"#, "\\"); | ^^^^ @@ -166,7 +153,7 @@ LL + writeln!(v, r#"\"#); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:47:23 + --> $DIR/write_literal_2.rs:45:23 | LL | writeln!(v, "{}", r"\"); | ^^^^ @@ -178,7 +165,7 @@ LL + writeln!(v, "\\"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:49:23 + --> $DIR/write_literal_2.rs:47:23 | LL | writeln!(v, "{}", "\r"); | ^^^^ @@ -190,16 +177,16 @@ LL + writeln!(v, "\r"); | error: literal with an empty format string - --> $DIR/write_literal_2.rs:52:28 + --> $DIR/write_literal_2.rs:50:28 | LL | writeln!(v, r#"{}{}"#, '#', '"'); | ^^^ error: literal with an empty format string - --> $DIR/write_literal_2.rs:52:33 + --> $DIR/write_literal_2.rs:50:33 | LL | writeln!(v, r#"{}{}"#, '#', '"'); | ^^^ -error: aborting due to 18 previous errors +error: aborting due to 17 previous errors