diff options
| author | mejrs <59372212+mejrs@users.noreply.github.com> | 2025-05-23 19:48:18 +0200 |
|---|---|---|
| committer | mejrs <59372212+mejrs@users.noreply.github.com> | 2025-06-09 16:28:57 +0200 |
| commit | 716190632f58f073f3cac903324b62899599876b (patch) | |
| tree | 14c4fb92ac080b5dcbf115f0a8fc285ab79682f1 /compiler/rustc_parse_format/src | |
| parent | 70f78fb2ba2b5ada70dfda2ea219483e545816c7 (diff) | |
| download | rust-716190632f58f073f3cac903324b62899599876b.tar.gz rust-716190632f58f073f3cac903324b62899599876b.zip | |
rustc_parse_format: introduce `peek` and `peek_ahead`
Diffstat (limited to 'compiler/rustc_parse_format/src')
| -rw-r--r-- | compiler/rustc_parse_format/src/lib.rs | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 9dd064aca66..358723a17ef 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -241,11 +241,11 @@ impl<'a> Iterator for Parser<'a> { type Item = Piece<'a>; fn next(&mut self) -> Option<Piece<'a>> { - if let Some(&(Range { start, end }, idx, ch)) = self.input_vec.get(self.input_vec_index) { + if let Some((Range { start, end }, idx, ch)) = self.peek() { match ch { '{' => { self.input_vec_index += 1; - if let Some(&(_, i, '{')) = self.input_vec.get(self.input_vec_index) { + if let Some((_, i, '{')) = self.peek() { self.input_vec_index += 1; // double open brace escape: "{{" // next state after this is either end-of-input or seen-a-brace @@ -258,7 +258,7 @@ impl<'a> Iterator for Parser<'a> { if self.is_source_literal { self.arg_places.push(start..close_brace_range.end); } - } else if let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) { + } else if let Some((_, _, c)) = self.peek() { match c { '?' => self.suggest_format_debug(), '<' | '^' | '>' => self.suggest_format_align(c), @@ -272,7 +272,7 @@ impl<'a> Iterator for Parser<'a> { } '}' => { self.input_vec_index += 1; - if let Some(&(_, i, '}')) = self.input_vec.get(self.input_vec_index) { + if let Some((_, i, '}')) = self.peek() { self.input_vec_index += 1; // double close brace escape: "}}" // next state after this is either end-of-input or start @@ -406,6 +406,16 @@ impl<'a> Parser<'a> { } } + /// Peeks at the current position, without incrementing the pointer. + pub fn peek(&self) -> Option<(Range<usize>, usize, char)> { + self.input_vec.get(self.input_vec_index).cloned() + } + + /// Peeks at the current position + 1, without incrementing the pointer. + pub fn peek_ahead(&self) -> Option<(Range<usize>, usize, char)> { + self.input_vec.get(self.input_vec_index + 1).cloned() + } + /// Optionally consumes the specified character. If the character is not at /// the current position, then the current iterator isn't moved and `false` is /// returned, otherwise the character is consumed and `true` is returned. @@ -418,10 +428,10 @@ impl<'a> Parser<'a> { /// returned, otherwise the character is consumed and the current position is /// returned. fn consume_pos(&mut self, ch: char) -> Option<(Range<usize>, usize)> { - if let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) { - if ch == *c { + if let Some((r, i, c)) = self.peek() { + if ch == c { self.input_vec_index += 1; - return Some((r.clone(), *i)); + return Some((r, i)); } } None @@ -432,11 +442,10 @@ impl<'a> Parser<'a> { fn consume_closing_brace(&mut self, arg: &Argument<'_>) -> Option<Range<usize>> { self.ws(); - let (range, description) = if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) - { - if *c == '}' { + let (range, description) = if let Some((r, _, c)) = self.peek() { + if c == '}' { self.input_vec_index += 1; - return Some(r.clone()); + return Some(r); } // or r.clone()? (r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug())) @@ -484,10 +493,10 @@ impl<'a> Parser<'a> { /// Parses all of a string which is to be considered a "raw literal" in a /// format string. This is everything outside of the braces. fn string(&mut self, start: usize) -> &'a str { - while let Some((r, i, c)) = self.input_vec.get(self.input_vec_index) { + while let Some((r, i, c)) = self.peek() { match c { '{' | '}' => { - return &self.input[start..*i]; + return &self.input[start..i]; } '\n' if self.is_source_literal => { self.input_vec_index += 1; @@ -540,19 +549,18 @@ impl<'a> Parser<'a> { if let Some(i) = self.integer() { Some(ArgumentIs(i.into())) } else { - match self.input_vec.get(self.input_vec_index) { - Some((range, _, c)) if rustc_lexer::is_id_start(*c) => { + match self.peek() { + Some((range, _, c)) if rustc_lexer::is_id_start(c) => { let start = range.start; let word = self.word(); // Recover from `r#ident` in format strings. // FIXME: use a let chain if word == "r" { - if let Some((r, _, '#')) = self.input_vec.get(self.input_vec_index) { + if let Some((r, _, '#')) = self.peek() { if self - .input_vec - .get(self.input_vec_index + 1) - .is_some_and(|(_, _, c)| rustc_lexer::is_id_start(*c)) + .peek_ahead() + .is_some_and(|(_, _, c)| rustc_lexer::is_id_start(c)) { self.input_vec_index += 1; let prefix_end = r.end; @@ -584,7 +592,7 @@ impl<'a> Parser<'a> { } fn input_vec_index2pos(&self, index: usize) -> usize { - if let Some(&(_, pos, _)) = self.input_vec.get(index) { pos } else { self.input.len() } + if let Some((_, pos, _)) = self.input_vec.get(index) { *pos } else { self.input.len() } } fn input_vec_index2range(&self, index: usize) -> Range<usize> { @@ -618,11 +626,11 @@ impl<'a> Parser<'a> { } // fill character - if let Some(&(ref r, _, c)) = self.input_vec.get(self.input_vec_index) { - if let Some((_, _, '>' | '<' | '^')) = self.input_vec.get(self.input_vec_index + 1) { + if let Some((r, _, c)) = self.peek() { + if let Some((_, _, '>' | '<' | '^')) = self.peek_ahead() { self.input_vec_index += 1; spec.fill = Some(c); - spec.fill_span = Some(r.clone()); + spec.fill_span = Some(r); } } // Alignment @@ -701,7 +709,7 @@ impl<'a> Parser<'a> { } } else if let Some((range, _)) = self.consume_pos('?') { spec.ty = "?"; - if let Some((r, _, c)) = self.input_vec.get(self.input_vec_index) { + if let Some((r, _, c)) = self.peek() { match c { '#' | 'x' | 'X' => self.errors.insert( 0, @@ -788,8 +796,8 @@ impl<'a> Parser<'a> { /// Rust identifier, except that it can't start with `_` character. fn word(&mut self) -> &'a str { let index = self.input_vec_index; - match self.input_vec.get(self.input_vec_index) { - Some(&(ref r, i, c)) if rustc_lexer::is_id_start(c) => { + match self.peek() { + Some((ref r, i, c)) if rustc_lexer::is_id_start(c) => { self.input_vec_index += 1; (r.start, i) } @@ -798,7 +806,7 @@ impl<'a> Parser<'a> { } }; let (err_end, end): (usize, usize) = loop { - if let Some(&(ref r, i, c)) = self.input_vec.get(self.input_vec_index) { + if let Some((ref r, i, c)) = self.peek() { if rustc_lexer::is_id_continue(c) { self.input_vec_index += 1; } else { @@ -828,7 +836,7 @@ impl<'a> Parser<'a> { let mut found = false; let mut overflow = false; let start_index = self.input_vec_index; - while let Some(&(_, _, c)) = self.input_vec.get(self.input_vec_index) { + while let Some((_, _, c)) = self.peek() { if let Some(i) = c.to_digit(10) { self.input_vec_index += 1; let (tmp, mul_overflow) = cur.overflowing_mul(10); |
