@@ -13,12 +13,12 @@ use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION};
13
13
use source_map:: { SourceMap , FilePathMapping } ;
14
14
use errors:: { Applicability , FatalError , Diagnostic , DiagnosticBuilder } ;
15
15
use parse:: { token, ParseSess } ;
16
- use str:: char_at;
17
16
use symbol:: { Symbol , keywords} ;
18
17
use core:: unicode:: property:: Pattern_White_Space ;
19
18
20
19
use std:: borrow:: Cow ;
21
20
use std:: char;
21
+ use std:: iter;
22
22
use std:: mem:: replace;
23
23
use rustc_data_structures:: sync:: Lrc ;
24
24
@@ -459,45 +459,42 @@ impl<'a> StringReader<'a> {
459
459
460
460
/// Converts CRLF to LF in the given string, raising an error on bare CR.
461
461
fn translate_crlf < ' b > ( & self , start : BytePos , s : & ' b str , errmsg : & ' b str ) -> Cow < ' b , str > {
462
- let mut i = 0 ;
463
- while i < s. len ( ) {
464
- let ch = char_at ( s, i) ;
465
- let next = i + ch. len_utf8 ( ) ;
462
+ let mut chars = s. char_indices ( ) . peekable ( ) ;
463
+ while let Some ( ( i, ch) ) = chars. next ( ) {
466
464
if ch == '\r' {
467
- if next < s . len ( ) && char_at ( s , next ) == '\n' {
468
- return translate_crlf_ ( self , start, s, errmsg , i ) . into ( ) ;
465
+ if let Some ( ( lf_idx , '\n' ) ) = chars . peek ( ) {
466
+ return translate_crlf_ ( self , start, s, * lf_idx , chars , errmsg ) . into ( ) ;
469
467
}
470
468
let pos = start + BytePos ( i as u32 ) ;
471
- let end_pos = start + BytePos ( next as u32 ) ;
469
+ let end_pos = start + BytePos ( ( i + ch . len_utf8 ( ) ) as u32 ) ;
472
470
self . err_span_ ( pos, end_pos, errmsg) ;
473
471
}
474
- i = next;
475
472
}
476
473
return s. into ( ) ;
477
474
478
475
fn translate_crlf_ ( rdr : & StringReader ,
479
476
start : BytePos ,
480
477
s : & str ,
481
- errmsg : & str ,
482
- mut i : usize )
478
+ mut j : usize ,
479
+ mut chars : iter:: Peekable < impl Iterator < Item = ( usize , char ) > > ,
480
+ errmsg : & str )
483
481
-> String {
484
482
let mut buf = String :: with_capacity ( s. len ( ) ) ;
485
- let mut j = 0 ;
486
- while i < s. len ( ) {
487
- let ch = char_at ( s, i) ;
488
- let next = i + ch. len_utf8 ( ) ;
483
+ // Skip first CR
484
+ buf. push_str ( & s[ .. j - 1 ] ) ;
485
+ while let Some ( ( i, ch) ) = chars. next ( ) {
489
486
if ch == '\r' {
490
487
if j < i {
491
488
buf. push_str ( & s[ j..i] ) ;
492
489
}
490
+ let next = i + ch. len_utf8 ( ) ;
493
491
j = next;
494
- if next >= s . len ( ) || char_at ( s , next ) != '\n' {
492
+ if chars . peek ( ) . map ( | ( _ , ch ) | * ch ) != Some ( '\n' ) {
495
493
let pos = start + BytePos ( i as u32 ) ;
496
494
let end_pos = start + BytePos ( next as u32 ) ;
497
495
rdr. err_span_ ( pos, end_pos, errmsg) ;
498
496
}
499
497
}
500
- i = next;
501
498
}
502
499
if j < s. len ( ) {
503
500
buf. push_str ( & s[ j..] ) ;
@@ -1858,6 +1855,11 @@ fn ident_continue(c: Option<char>) -> bool {
1858
1855
( c > '\x7f' && c. is_xid_continue ( ) )
1859
1856
}
1860
1857
1858
+ #[ inline]
1859
+ fn char_at ( s : & str , byte : usize ) -> char {
1860
+ s[ byte..] . chars ( ) . next ( ) . unwrap ( )
1861
+ }
1862
+
1861
1863
#[ cfg( test) ]
1862
1864
mod tests {
1863
1865
use super :: * ;
0 commit comments