@@ -109,7 +109,7 @@ impl Escapee for char {
109109/// Checks whether the character is skipped after a string continue start
110110/// (unescaped backlash followed by `\n`).
111111fn is_string_continue_skipable_whitespace ( b : u8 ) -> bool {
112- b == b' ' || b == b'\t' || b == b'\n' || b == b'\r'
112+ b == b' ' || b == b'\t' || b == b'\n'
113113}
114114
115115/// Unescapes a whole string or byte string.
@@ -143,16 +143,7 @@ pub(crate) fn unescape_string<E: Escapee>(
143143 i += len;
144144 end_last_escape = i;
145145 }
146- b'\r' => {
147- if input. as_bytes ( ) . get ( i + 1 ) == Some ( & b'\n' ) {
148- value. push_str ( & input[ end_last_escape..i] ) ;
149- value. push ( '\n' ) ;
150- i += 2 ;
151- end_last_escape = i;
152- } else {
153- return Err ( perr ( i, IsolatedCr ) )
154- }
155- }
146+ b'\r' => return Err ( perr ( i, CarriageReturn ) ) ,
156147 b'"' => {
157148 closing_quote_pos = Some ( i) ;
158149 break ;
@@ -184,14 +175,13 @@ pub(crate) fn unescape_string<E: Escapee>(
184175 Ok ( ( value, start_suffix) )
185176}
186177
187- /// Reads and checks a raw (byte) string literal, converting `\r\n` sequences to
188- /// just `\n` sequences. Returns an optional new string (if the input contained
189- /// any `\r\n`) and the number of hashes used by the literal.
178+ /// Reads and checks a raw (byte) string literal. Returns the number of hashes
179+ /// and the index when the suffix starts.
190180#[ inline( never) ]
191181pub ( crate ) fn scan_raw_string < E : Escapee > (
192182 input : & str ,
193183 offset : usize ,
194- ) -> Result < ( Option < String > , u32 , usize ) , ParseError > {
184+ ) -> Result < ( u32 , usize ) , ParseError > {
195185 // Raw string literal
196186 let num_hashes = input[ offset..] . bytes ( ) . position ( |b| b != b'#' )
197187 . ok_or ( perr ( None , InvalidLiteral ) ) ?;
@@ -204,31 +194,18 @@ pub(crate) fn scan_raw_string<E: Escapee>(
204194
205195 let mut closing_quote_pos = None ;
206196 let mut i = start_inner;
207- let mut end_last_escape = start_inner;
208- let mut value = String :: new ( ) ;
209197 while i < input. len ( ) {
210198 let b = input. as_bytes ( ) [ i] ;
211199 if b == b'"' && input[ i + 1 ..] . starts_with ( hashes) {
212200 closing_quote_pos = Some ( i) ;
213201 break ;
214202 }
215203
204+ // CR are just always disallowed in all (raw) strings. Rust performs
205+ // a normalization of CR LF to just LF in a pass prior to lexing. But
206+ // in lexing, it's disallowed.
216207 if b == b'\r' {
217- // Convert `\r\n` into `\n`. This is currently not well documented
218- // in the Rust reference, but is done even for raw strings. That's
219- // because rustc simply converts all line endings when reading
220- // source files.
221- if input. as_bytes ( ) . get ( i + 1 ) == Some ( & b'\n' ) {
222- value. push_str ( & input[ end_last_escape..i] ) ;
223- value. push ( '\n' ) ;
224- i += 2 ;
225- end_last_escape = i;
226- continue ;
227- } else if E :: SUPPORTS_UNICODE {
228- // If no \n follows the \r and we are scanning a raw string
229- // (not raw byte string), we error.
230- return Err ( perr ( i, IsolatedCr ) )
231- }
208+ return Err ( perr ( i, CarriageReturn ) ) ;
232209 }
233210
234211 if !E :: SUPPORTS_UNICODE {
@@ -246,17 +223,5 @@ pub(crate) fn scan_raw_string<E: Escapee>(
246223 let suffix = & input[ start_suffix..] ;
247224 check_suffix ( suffix) . map_err ( |kind| perr ( start_suffix, kind) ) ?;
248225
249- // `value` is only empty if there was no \r\n in the input string (with the
250- // special case of the input being empty). This means the string value
251- // equals the input, so we store `None`.
252- let value = if value. is_empty ( ) {
253- None
254- } else {
255- // There was an \r\n in the string, so we need to push the remaining
256- // unescaped part of the string still.
257- value. push_str ( & input[ end_last_escape..closing_quote_pos] ) ;
258- Some ( value)
259- } ;
260-
261- Ok ( ( value, num_hashes as u32 , start_suffix) )
226+ Ok ( ( num_hashes as u32 , start_suffix) )
262227}
0 commit comments