Skip to content

Commit 93ac09c

Browse files
committed
Auto merge of #55466 - sinkuu:cleanup, r=petrochenkov
syntax: Use iterator and pattern APIs instead of `char_at` Iterating over chars with the `char_at(str, i)` `i += ch.len_utf8()` loop seems unidiomatic.
2 parents 21cb46a + f423ff7 commit 93ac09c

File tree

7 files changed

+34
-64
lines changed

7 files changed

+34
-64
lines changed

src/libsyntax/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ pub mod parse;
173173
pub mod ptr;
174174
pub mod show_span;
175175
pub mod std_inject;
176-
pub mod str;
177176
pub use syntax_pos::edition;
178177
pub use syntax_pos::symbol;
179178
pub mod test;

src/libsyntax/parse/lexer/comments.rs

+7-21
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use syntax_pos::{BytePos, CharPos, Pos, FileName};
1616
use parse::lexer::{is_block_doc_comment, is_pattern_whitespace};
1717
use parse::lexer::{self, ParseSess, StringReader, TokenAndSpan};
1818
use print::pprust;
19-
use str::char_at;
2019

2120
use std::io::Read;
2221
use std::usize;
@@ -207,28 +206,22 @@ fn read_line_comments(rdr: &mut StringReader,
207206
/// Otherwise returns Some(k) where k is first char offset after that leading
208207
/// whitespace. Note k may be outside bounds of s.
209208
fn all_whitespace(s: &str, col: CharPos) -> Option<usize> {
210-
let len = s.len();
211-
let mut col = col.to_usize();
212-
let mut cursor: usize = 0;
213-
214-
while col > 0 && cursor < len {
215-
let ch = char_at(s, cursor);
209+
let mut idx = 0;
210+
for (i, ch) in s.char_indices().take(col.to_usize()) {
216211
if !ch.is_whitespace() {
217212
return None;
218213
}
219-
cursor += ch.len_utf8();
220-
col -= 1;
214+
idx = i + ch.len_utf8();
221215
}
222-
223-
Some(cursor)
216+
Some(idx)
224217
}
225218

226219
fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<String>, s: String, col: CharPos) {
227220
let len = s.len();
228221
let s1 = match all_whitespace(&s[..], col) {
229222
Some(col) => {
230223
if col < len {
231-
(&s[col..len]).to_string()
224+
s[col..len].to_string()
232225
} else {
233226
String::new()
234227
}
@@ -247,20 +240,13 @@ fn read_block_comment(rdr: &mut StringReader,
247240
let mut lines: Vec<String> = Vec::new();
248241

249242
// Count the number of chars since the start of the line by rescanning.
250-
let mut src_index = rdr.src_index(rdr.source_file.line_begin_pos(rdr.pos));
243+
let src_index = rdr.src_index(rdr.source_file.line_begin_pos(rdr.pos));
251244
let end_src_index = rdr.src_index(rdr.pos);
252245
assert!(src_index <= end_src_index,
253246
"src_index={}, end_src_index={}, line_begin_pos={}",
254247
src_index, end_src_index, rdr.source_file.line_begin_pos(rdr.pos).to_u32());
255-
let mut n = 0;
256-
257-
while src_index < end_src_index {
258-
let c = char_at(&rdr.src, src_index);
259-
src_index += c.len_utf8();
260-
n += 1;
261-
}
262248

263-
let col = CharPos(n);
249+
let col = CharPos(rdr.src[src_index..end_src_index].chars().count());
264250

265251
rdr.bump();
266252
rdr.bump();

src/libsyntax/parse/lexer/mod.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION};
1313
use source_map::{SourceMap, FilePathMapping};
1414
use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
1515
use parse::{token, ParseSess};
16-
use str::char_at;
1716
use symbol::{Symbol, keywords};
1817
use core::unicode::property::Pattern_White_Space;
1918

2019
use std::borrow::Cow;
2120
use std::char;
21+
use std::iter;
2222
use std::mem::replace;
2323
use rustc_data_structures::sync::Lrc;
2424

@@ -459,45 +459,42 @@ impl<'a> StringReader<'a> {
459459

460460
/// Converts CRLF to LF in the given string, raising an error on bare CR.
461461
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() {
466464
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();
469467
}
470468
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);
472470
self.err_span_(pos, end_pos, errmsg);
473471
}
474-
i = next;
475472
}
476473
return s.into();
477474

478475
fn translate_crlf_(rdr: &StringReader,
479476
start: BytePos,
480477
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)
483481
-> String {
484482
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() {
489486
if ch == '\r' {
490487
if j < i {
491488
buf.push_str(&s[j..i]);
492489
}
490+
let next = i + ch.len_utf8();
493491
j = next;
494-
if next >= s.len() || char_at(s, next) != '\n' {
492+
if chars.peek().map(|(_, ch)| *ch) != Some('\n') {
495493
let pos = start + BytePos(i as u32);
496494
let end_pos = start + BytePos(next as u32);
497495
rdr.err_span_(pos, end_pos, errmsg);
498496
}
499497
}
500-
i = next;
501498
}
502499
if j < s.len() {
503500
buf.push_str(&s[j..]);
@@ -1858,6 +1855,11 @@ fn ident_continue(c: Option<char>) -> bool {
18581855
(c > '\x7f' && c.is_xid_continue())
18591856
}
18601857

1858+
#[inline]
1859+
fn char_at(s: &str, byte: usize) -> char {
1860+
s[byte..].chars().next().unwrap()
1861+
}
1862+
18611863
#[cfg(test)]
18621864
mod tests {
18631865
use super::*;

src/libsyntax/parse/mod.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
1919
use feature_gate::UnstableFeatures;
2020
use parse::parser::Parser;
2121
use ptr::P;
22-
use str::char_at;
2322
use symbol::Symbol;
2423
use tokenstream::{TokenStream, TokenTree};
2524
use diagnostics::plugin::ErrorMap;
@@ -436,9 +435,7 @@ fn raw_str_lit(lit: &str) -> String {
436435

437436
// check if `s` looks like i32 or u1234 etc.
438437
fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
439-
s.len() > 1 &&
440-
first_chars.contains(&char_at(s, 0)) &&
441-
s[1..].chars().all(|c| '0' <= c && c <= '9')
438+
s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
442439
}
443440

444441
macro_rules! err {
@@ -645,11 +642,11 @@ fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
645642
let orig = s;
646643
let mut ty = ast::LitIntType::Unsuffixed;
647644

648-
if char_at(s, 0) == '0' && s.len() > 1 {
649-
match char_at(s, 1) {
650-
'x' => base = 16,
651-
'o' => base = 8,
652-
'b' => base = 2,
645+
if s.starts_with('0') && s.len() > 1 {
646+
match s.as_bytes()[1] {
647+
b'x' => base = 16,
648+
b'o' => base = 8,
649+
b'b' => base = 2,
653650
_ => { }
654651
}
655652
}

src/libsyntax/str.rs

-14
This file was deleted.

src/libsyntax/util/lev_distance.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ pub fn lev_distance(a: &str, b: &str) -> usize {
3838
current = next;
3939
t_last = j;
4040
}
41-
} dcol[t_last + 1]
41+
}
42+
dcol[t_last + 1]
4243
}
4344

4445
/// Find the best match for a given word in the given iterator

src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use syntax::parse::new_parser_from_source_str;
2525
use syntax::parse::parser::Parser;
2626
use syntax::parse::token;
2727
use syntax::ptr::P;
28-
use syntax::str::char_at;
2928
use syntax::parse::attr::*;
3029
use syntax::print::pprust;
3130
use std::fmt;

0 commit comments

Comments
 (0)