Skip to content

Commit 7161906

Browse files
committed
rustc_parse_format: introduce peek and peek_ahead
1 parent 70f78fb commit 7161906

File tree

1 file changed

+36
-28
lines changed
  • compiler/rustc_parse_format/src

1 file changed

+36
-28
lines changed

compiler/rustc_parse_format/src/lib.rs

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,11 @@ impl<'a> Iterator for Parser<'a> {
241241
type Item = Piece<'a>;
242242

243243
fn next(&mut self) -> Option<Piece<'a>> {
244-
if let Some(&(Range { start, end }, idx, ch)) = self.input_vec.get(self.input_vec_index) {
244+
if let Some((Range { start, end }, idx, ch)) = self.peek() {
245245
match ch {
246246
'{' => {
247247
self.input_vec_index += 1;
248-
if let Some(&(_, i, '{')) = self.input_vec.get(self.input_vec_index) {
248+
if let Some((_, i, '{')) = self.peek() {
249249
self.input_vec_index += 1;
250250
// double open brace escape: "{{"
251251
// next state after this is either end-of-input or seen-a-brace
@@ -258,7 +258,7 @@ impl<'a> Iterator for Parser<'a> {
258258
if self.is_source_literal {
259259
self.arg_places.push(start..close_brace_range.end);
260260
}
261-
} else if let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
261+
} else if let Some((_, _, c)) = self.peek() {
262262
match c {
263263
'?' => self.suggest_format_debug(),
264264
'<' | '^' | '>' => self.suggest_format_align(c),
@@ -272,7 +272,7 @@ impl<'a> Iterator for Parser<'a> {
272272
}
273273
'}' => {
274274
self.input_vec_index += 1;
275-
if let Some(&(_, i, '}')) = self.input_vec.get(self.input_vec_index) {
275+
if let Some((_, i, '}')) = self.peek() {
276276
self.input_vec_index += 1;
277277
// double close brace escape: "}}"
278278
// next state after this is either end-of-input or start
@@ -406,6 +406,16 @@ impl<'a> Parser<'a> {
406406
}
407407
}
408408

409+
/// Peeks at the current position, without incrementing the pointer.
410+
pub fn peek(&self) -> Option<(Range<usize>, usize, char)> {
411+
self.input_vec.get(self.input_vec_index).cloned()
412+
}
413+
414+
/// Peeks at the current position + 1, without incrementing the pointer.
415+
pub fn peek_ahead(&self) -> Option<(Range<usize>, usize, char)> {
416+
self.input_vec.get(self.input_vec_index + 1).cloned()
417+
}
418+
409419
/// Optionally consumes the specified character. If the character is not at
410420
/// the current position, then the current iterator isn't moved and `false` is
411421
/// returned, otherwise the character is consumed and `true` is returned.
@@ -418,10 +428,10 @@ impl<'a> Parser<'a> {
418428
/// returned, otherwise the character is consumed and the current position is
419429
/// returned.
420430
fn consume_pos(&mut self, ch: char) -> Option<(Range<usize>, usize)> {
421-
if let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
422-
if ch == *c {
431+
if let Some((r, i, c)) = self.peek() {
432+
if ch == c {
423433
self.input_vec_index += 1;
424-
return Some((r.clone(), *i));
434+
return Some((r, i));
425435
}
426436
}
427437
None
@@ -432,11 +442,10 @@ impl<'a> Parser<'a> {
432442
fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<Range<usize>> {
433443
self.ws();
434444

435-
let (range, description) = if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index)
436-
{
437-
if *c == '}' {
445+
let (range, description) = if let Some((r, _, c)) = self.peek() {
446+
if c == '}' {
438447
self.input_vec_index += 1;
439-
return Some(r.clone());
448+
return Some(r);
440449
}
441450
// or r.clone()?
442451
(r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug()))
@@ -484,10 +493,10 @@ impl<'a> Parser<'a> {
484493
/// Parses all of a string which is to be considered a "raw literal" in a
485494
/// format string. This is everything outside of the braces.
486495
fn string(&mut self, start: usize) -> &'a str {
487-
while let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) {
496+
while let Some((r, i, c)) = self.peek() {
488497
match c {
489498
'{' | '}' => {
490-
return &self.input[start..*i];
499+
return &self.input[start..i];
491500
}
492501
'\n' if self.is_source_literal => {
493502
self.input_vec_index += 1;
@@ -540,19 +549,18 @@ impl<'a> Parser<'a> {
540549
if let Some(i) = self.integer() {
541550
Some(ArgumentIs(i.into()))
542551
} else {
543-
match self.input_vec.get(self.input_vec_index) {
544-
Some((range, _, c)) if rustc_lexer::is_id_start(*c) => {
552+
match self.peek() {
553+
Some((range, _, c)) if rustc_lexer::is_id_start(c) => {
545554
let start = range.start;
546555
let word = self.word();
547556

548557
// Recover from `r#ident` in format strings.
549558
// FIXME: use a let chain
550559
if word == "r" {
551-
if let Some((r, _, '#')) = self.input_vec.get(self.input_vec_index) {
560+
if let Some((r, _, '#')) = self.peek() {
552561
if self
553-
.input_vec
554-
.get(self.input_vec_index + 1)
555-
.is_some_and(|(_, _, c)| rustc_lexer::is_id_start(*c))
562+
.peek_ahead()
563+
.is_some_and(|(_, _, c)| rustc_lexer::is_id_start(c))
556564
{
557565
self.input_vec_index += 1;
558566
let prefix_end = r.end;
@@ -584,7 +592,7 @@ impl<'a> Parser<'a> {
584592
}
585593

586594
fn input_vec_index2pos(&self, index: usize) -> usize {
587-
if let Some(&(_, pos, _)) = self.input_vec.get(index) { pos } else { self.input.len() }
595+
if let Some((_, pos, _)) = self.input_vec.get(index) { *pos } else { self.input.len() }
588596
}
589597

590598
fn input_vec_index2range(&self, index: usize) -> Range<usize> {
@@ -618,11 +626,11 @@ impl<'a> Parser<'a> {
618626
}
619627

620628
// fill character
621-
if let Some(&(ref r, _, c)) = self.input_vec.get(self.input_vec_index) {
622-
if let Some((_, _, '>' | '<' | '^')) = self.input_vec.get(self.input_vec_index + 1) {
629+
if let Some((r, _, c)) = self.peek() {
630+
if let Some((_, _, '>' | '<' | '^')) = self.peek_ahead() {
623631
self.input_vec_index += 1;
624632
spec.fill = Some(c);
625-
spec.fill_span = Some(r.clone());
633+
spec.fill_span = Some(r);
626634
}
627635
}
628636
// Alignment
@@ -701,7 +709,7 @@ impl<'a> Parser<'a> {
701709
}
702710
} else if let Some((range, _)) = self.consume_pos('?') {
703711
spec.ty = "?";
704-
if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) {
712+
if let Some((r, _, c)) = self.peek() {
705713
match c {
706714
'#' | 'x' | 'X' => self.errors.insert(
707715
0,
@@ -788,8 +796,8 @@ impl<'a> Parser<'a> {
788796
/// Rust identifier, except that it can't start with `_` character.
789797
fn word(&mut self) -> &'a str {
790798
let index = self.input_vec_index;
791-
match self.input_vec.get(self.input_vec_index) {
792-
Some(&(ref r, i, c)) if rustc_lexer::is_id_start(c) => {
799+
match self.peek() {
800+
Some((ref r, i, c)) if rustc_lexer::is_id_start(c) => {
793801
self.input_vec_index += 1;
794802
(r.start, i)
795803
}
@@ -798,7 +806,7 @@ impl<'a> Parser<'a> {
798806
}
799807
};
800808
let (err_end, end): (usize, usize) = loop {
801-
if let Some(&(ref r, i, c)) = self.input_vec.get(self.input_vec_index) {
809+
if let Some((ref r, i, c)) = self.peek() {
802810
if rustc_lexer::is_id_continue(c) {
803811
self.input_vec_index += 1;
804812
} else {
@@ -828,7 +836,7 @@ impl<'a> Parser<'a> {
828836
let mut found = false;
829837
let mut overflow = false;
830838
let start_index = self.input_vec_index;
831-
while let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) {
839+
while let Some((_, _, c)) = self.peek() {
832840
if let Some(i) = c.to_digit(10) {
833841
self.input_vec_index += 1;
834842
let (tmp, mul_overflow) = cur.overflowing_mul(10);

0 commit comments

Comments
 (0)