@@ -13,7 +13,8 @@ declare_clippy_lint! {
13
13
/// Checks for raw string literals where a string literal can be used instead.
14
14
///
15
15
/// ### Why is this bad?
16
- /// It's just unnecessary.
16
+ /// It's just unnecessary, but there are many cases where using a raw string literal is more
17
+ /// idiomatic than a string literal, so it's opt-in.
17
18
///
18
19
/// ### Example
19
20
/// ```rust
@@ -25,7 +26,7 @@ declare_clippy_lint! {
25
26
/// ```
26
27
#[ clippy:: version = "1.72.0" ]
27
28
pub NEEDLESS_RAW_STRING ,
28
- complexity ,
29
+ restriction ,
29
30
"suggests using a string literal when a raw string literal is unnecessary"
30
31
}
31
32
declare_clippy_lint ! {
@@ -46,7 +47,7 @@ declare_clippy_lint! {
46
47
/// ```
47
48
#[ clippy:: version = "1.72.0" ]
48
49
pub NEEDLESS_RAW_STRING_HASHES ,
49
- complexity ,
50
+ style ,
50
51
"suggests reducing the number of hashes around a raw string literal"
51
52
}
52
53
impl_lint_pass ! ( RawStrings => [ NEEDLESS_RAW_STRING , NEEDLESS_RAW_STRING_HASHES ] ) ;
@@ -59,7 +60,7 @@ impl EarlyLintPass for RawStrings {
59
60
fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , expr : & Expr ) {
60
61
if !in_external_macro ( cx. sess ( ) , expr. span )
61
62
&& let ExprKind :: Lit ( lit) = expr. kind
62
- && let LitKind :: StrRaw ( num ) | LitKind :: ByteStrRaw ( num ) | LitKind :: CStrRaw ( num ) = lit. kind
63
+ && let LitKind :: StrRaw ( max ) | LitKind :: ByteStrRaw ( max ) | LitKind :: CStrRaw ( max ) = lit. kind
63
64
{
64
65
let prefix = match lit. kind {
65
66
LitKind :: StrRaw ( ..) => "r" ,
@@ -86,14 +87,26 @@ impl EarlyLintPass for RawStrings {
86
87
}
87
88
88
89
#[ expect( clippy:: cast_possible_truncation) ]
89
- let req = lit. symbol . as_str ( ) . as_bytes ( )
90
+ let req = lit
91
+ . symbol
92
+ . as_str ( )
93
+ . as_bytes ( )
90
94
. split ( |& b| b == b'"' )
91
95
. skip ( 1 )
92
- . map ( |bs| 1 + bs. iter ( ) . take_while ( |& & b| b == b'#' ) . count ( ) as u8 )
96
+ . map_while ( |bs| {
97
+ let num = bs. iter ( ) . take_while ( |& & b| b == b'#' ) . count ( ) as u8 ;
98
+ if num. saturating_sub ( 1 ) == max {
99
+ // Since `num - 1` is the max number of hashes it can have, we can
100
+ // short-circuit with full confidence this is correct
101
+ return None ;
102
+ }
103
+
104
+ Some ( num + 1 )
105
+ } )
93
106
. max ( )
94
107
. unwrap_or ( 0 ) ;
95
108
96
- if req < num {
109
+ if req < max {
97
110
let hashes = "#" . repeat ( req as usize ) ;
98
111
99
112
span_lint_and_sugg (
0 commit comments