@@ -81,94 +81,105 @@ impl EarlyLintPass for RawStrings {
81
81
&& !in_external_macro ( cx. sess ( ) , expr. span )
82
82
&& expr. span . check_source_text ( cx, |src| src. starts_with ( prefix) )
83
83
{
84
- let str = lit. symbol . as_str ( ) ;
85
- let descr = lit. kind . descr ( ) ;
86
-
87
- if !str. contains ( [ '\\' , '"' ] ) {
88
- span_lint_and_then (
89
- cx,
90
- NEEDLESS_RAW_STRINGS ,
91
- expr. span ,
92
- "unnecessary raw string literal" ,
93
- |diag| {
94
- let ( start, end) = hash_spans ( expr. span , prefix. len ( ) , 0 , max) ;
95
-
96
- // BytePos: skip over the `b` in `br`, we checked the prefix appears in the source text
97
- let r_pos = expr. span . lo ( ) + BytePos :: from_usize ( prefix. len ( ) - 1 ) ;
98
- let start = start. with_lo ( r_pos) ;
99
-
100
- let mut remove = vec ! [ ( start, String :: new( ) ) ] ;
101
- // avoid debug ICE from empty suggestions
102
- if !end. is_empty ( ) {
103
- remove. push ( ( end, String :: new ( ) ) ) ;
104
- }
84
+ self . check_raw_string ( cx, lit. symbol . as_str ( ) , expr. span , prefix, max, lit. kind . descr ( ) ) ;
85
+ }
86
+ }
87
+ }
105
88
106
- diag. multipart_suggestion_verbose (
107
- format ! ( "use a plain {descr} literal instead" ) ,
108
- remove,
109
- Applicability :: MachineApplicable ,
110
- ) ;
111
- } ,
112
- ) ;
113
- if !matches ! ( cx. get_lint_level( NEEDLESS_RAW_STRINGS ) , rustc_lint:: Allow ) {
114
- return ;
115
- }
89
+ impl RawStrings {
90
+ fn check_raw_string (
91
+ & mut self ,
92
+ cx : & EarlyContext < ' _ > ,
93
+ str : & str ,
94
+ lit_span : Span ,
95
+ prefix : & str ,
96
+ max : u8 ,
97
+ descr : & str ,
98
+ ) {
99
+ if !str. contains ( [ '\\' , '"' ] ) {
100
+ span_lint_and_then (
101
+ cx,
102
+ NEEDLESS_RAW_STRINGS ,
103
+ lit_span,
104
+ "unnecessary raw string literal" ,
105
+ |diag| {
106
+ let ( start, end) = hash_spans ( lit_span, prefix. len ( ) , 0 , max) ;
107
+
108
+ // BytePos: skip over the `b` in `br`, we checked the prefix appears in the source text
109
+ let r_pos = lit_span. lo ( ) + BytePos :: from_usize ( prefix. len ( ) - 1 ) ;
110
+ let start = start. with_lo ( r_pos) ;
111
+
112
+ let mut remove = vec ! [ ( start, String :: new( ) ) ] ;
113
+ // avoid debug ICE from empty suggestions
114
+ if !end. is_empty ( ) {
115
+ remove. push ( ( end, String :: new ( ) ) ) ;
116
+ }
117
+
118
+ diag. multipart_suggestion_verbose (
119
+ format ! ( "use a plain {descr} literal instead" ) ,
120
+ remove,
121
+ Applicability :: MachineApplicable ,
122
+ ) ;
123
+ } ,
124
+ ) ;
125
+ if !matches ! ( cx. get_lint_level( NEEDLESS_RAW_STRINGS ) , rustc_lint:: Allow ) {
126
+ return ;
116
127
}
128
+ }
117
129
118
- let mut req = {
119
- let mut following_quote = false ;
120
- let mut req = 0 ;
121
- // `once` so a raw string ending in hashes is still checked
122
- let num = str. as_bytes ( ) . iter ( ) . chain ( once ( & 0 ) ) . try_fold ( 0u8 , |acc, & b| {
123
- match b {
124
- b'"' if !following_quote => ( following_quote, req) = ( true , 1 ) ,
125
- b'#' => req += u8:: from ( following_quote) ,
126
- _ => {
127
- if following_quote {
128
- following_quote = false ;
129
-
130
- if req == max {
131
- return ControlFlow :: Break ( req) ;
132
- }
133
-
134
- return ControlFlow :: Continue ( acc. max ( req) ) ;
130
+ let mut req = {
131
+ let mut following_quote = false ;
132
+ let mut req = 0 ;
133
+ // `once` so a raw string ending in hashes is still checked
134
+ let num = str. as_bytes ( ) . iter ( ) . chain ( once ( & 0 ) ) . try_fold ( 0u8 , |acc, & b| {
135
+ match b {
136
+ b'"' if !following_quote => ( following_quote, req) = ( true , 1 ) ,
137
+ b'#' => req += u8:: from ( following_quote) ,
138
+ _ => {
139
+ if following_quote {
140
+ following_quote = false ;
141
+
142
+ if req == max {
143
+ return ControlFlow :: Break ( req) ;
135
144
}
136
- } ,
137
- }
138
-
139
- ControlFlow :: Continue ( acc)
140
- } ) ;
141
145
142
- match num {
143
- ControlFlow :: Continue ( num) | ControlFlow :: Break ( num) => num,
144
- }
145
- } ;
146
- if self . allow_one_hash_in_raw_strings {
147
- req = req. max ( 1 ) ;
148
- }
149
- if req < max {
150
- span_lint_and_then (
151
- cx,
152
- NEEDLESS_RAW_STRING_HASHES ,
153
- expr. span ,
154
- "unnecessary hashes around raw string literal" ,
155
- |diag| {
156
- let ( start, end) = hash_spans ( expr. span , prefix. len ( ) , req, max) ;
157
-
158
- let message = match max - req {
159
- _ if req == 0 => format ! ( "remove all the hashes around the {descr} literal" ) ,
160
- 1 => format ! ( "remove one hash from both sides of the {descr} literal" ) ,
161
- n => format ! ( "remove {n} hashes from both sides of the {descr} literal" ) ,
162
- } ;
163
-
164
- diag. multipart_suggestion (
165
- message,
166
- vec ! [ ( start, String :: new( ) ) , ( end, String :: new( ) ) ] ,
167
- Applicability :: MachineApplicable ,
168
- ) ;
146
+ return ControlFlow :: Continue ( acc. max ( req) ) ;
147
+ }
169
148
} ,
170
- ) ;
149
+ }
150
+
151
+ ControlFlow :: Continue ( acc)
152
+ } ) ;
153
+
154
+ match num {
155
+ ControlFlow :: Continue ( num) | ControlFlow :: Break ( num) => num,
171
156
}
157
+ } ;
158
+ if self . allow_one_hash_in_raw_strings {
159
+ req = req. max ( 1 ) ;
160
+ }
161
+ if req < max {
162
+ span_lint_and_then (
163
+ cx,
164
+ NEEDLESS_RAW_STRING_HASHES ,
165
+ lit_span,
166
+ "unnecessary hashes around raw string literal" ,
167
+ |diag| {
168
+ let ( start, end) = hash_spans ( lit_span, prefix. len ( ) , req, max) ;
169
+
170
+ let message = match max - req {
171
+ _ if req == 0 => format ! ( "remove all the hashes around the {descr} literal" ) ,
172
+ 1 => format ! ( "remove one hash from both sides of the {descr} literal" ) ,
173
+ n => format ! ( "remove {n} hashes from both sides of the {descr} literal" ) ,
174
+ } ;
175
+
176
+ diag. multipart_suggestion (
177
+ message,
178
+ vec ! [ ( start, String :: new( ) ) , ( end, String :: new( ) ) ] ,
179
+ Applicability :: MachineApplicable ,
180
+ ) ;
181
+ } ,
182
+ ) ;
172
183
}
173
184
}
174
185
}
0 commit comments