summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_parse/src/lexer
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /compiler/rustc_parse/src/lexer
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_parse/src/lexer')
-rw-r--r--compiler/rustc_parse/src/lexer/diagnostics.rs7
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs14
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs80
3 files changed, 65 insertions, 36 deletions
diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs
index b50bb47f2..b1bd4ac75 100644
--- a/compiler/rustc_parse/src/lexer/diagnostics.rs
+++ b/compiler/rustc_parse/src/lexer/diagnostics.rs
@@ -111,9 +111,10 @@ pub fn report_suspicious_mismatch_block(
// If there is no suspicious span, give the last properly closed block may help
if let Some(parent) = diag_info.matching_block_spans.last()
&& diag_info.open_braces.last().is_none()
- && diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1)) {
- err.span_label(parent.0, "this opening brace...");
- err.span_label(parent.1, "...matches this closing brace");
+ && diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1))
+ {
+ err.span_label(parent.0, "this opening brace...");
+ err.span_label(parent.1, "...matches this closing brace");
}
}
}
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index a375a1d69..f2eed5c9b 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -64,10 +64,10 @@ pub(crate) fn parse_token_trees<'a>(
override_span,
nbsp_is_whitespace: false,
};
- let (token_trees, unmatched_delims) =
+ let (stream, res, unmatched_delims) =
tokentrees::TokenTreesReader::parse_all_token_trees(string_reader);
- match token_trees {
- Ok(stream) if unmatched_delims.is_empty() => Ok(stream),
+ match res {
+ Ok(()) if unmatched_delims.is_empty() => Ok(stream),
_ => {
// Return error if there are unmatched delimiters or unclosed delimiters.
// We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
@@ -79,9 +79,11 @@ pub(crate) fn parse_token_trees<'a>(
err.buffer(&mut buffer);
}
}
- if let Err(err) = token_trees {
- // Add unclosing delimiter error
- err.buffer(&mut buffer);
+ if let Err(errs) = res {
+ // Add unclosing delimiter or diff marker errors
+ for err in errs {
+ err.buffer(&mut buffer);
+ }
}
Err(buffer)
}
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index 07910113d..31d91fe80 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -5,7 +5,7 @@ use super::{StringReader, UnmatchedDelim};
use rustc_ast::token::{self, Delimiter, Token};
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast_pretty::pprust::token_to_string;
-use rustc_errors::{PErr, PResult};
+use rustc_errors::PErr;
pub(super) struct TokenTreesReader<'a> {
string_reader: StringReader<'a>,
@@ -18,36 +18,42 @@ pub(super) struct TokenTreesReader<'a> {
impl<'a> TokenTreesReader<'a> {
pub(super) fn parse_all_token_trees(
string_reader: StringReader<'a>,
- ) -> (PResult<'a, TokenStream>, Vec<UnmatchedDelim>) {
+ ) -> (TokenStream, Result<(), Vec<PErr<'a>>>, Vec<UnmatchedDelim>) {
let mut tt_reader = TokenTreesReader {
string_reader,
token: Token::dummy(),
diag_info: TokenTreeDiagInfo::default(),
};
- let res = tt_reader.parse_token_trees(/* is_delimited */ false);
- (res, tt_reader.diag_info.unmatched_delims)
+ let (stream, res) = tt_reader.parse_token_trees(/* is_delimited */ false);
+ (stream, res, tt_reader.diag_info.unmatched_delims)
}
// Parse a stream of tokens into a list of `TokenTree`s.
- fn parse_token_trees(&mut self, is_delimited: bool) -> PResult<'a, TokenStream> {
+ fn parse_token_trees(
+ &mut self,
+ is_delimited: bool,
+ ) -> (TokenStream, Result<(), Vec<PErr<'a>>>) {
self.token = self.string_reader.next_token().0;
let mut buf = Vec::new();
loop {
match self.token.kind {
- token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)?),
+ token::OpenDelim(delim) => {
+ buf.push(match self.parse_token_tree_open_delim(delim) {
+ Ok(val) => val,
+ Err(errs) => return (TokenStream::new(buf), Err(errs)),
+ })
+ }
token::CloseDelim(delim) => {
- return if is_delimited {
- Ok(TokenStream::new(buf))
- } else {
- Err(self.close_delim_err(delim))
- };
+ return (
+ TokenStream::new(buf),
+ if is_delimited { Ok(()) } else { Err(vec![self.close_delim_err(delim)]) },
+ );
}
token::Eof => {
- return if is_delimited {
- Err(self.eof_err())
- } else {
- Ok(TokenStream::new(buf))
- };
+ return (
+ TokenStream::new(buf),
+ if is_delimited { Err(vec![self.eof_err()]) } else { Ok(()) },
+ );
}
_ => {
// Get the next normal token. This might require getting multiple adjacent
@@ -55,16 +61,14 @@ impl<'a> TokenTreesReader<'a> {
let (this_spacing, next_tok) = loop {
let (next_tok, is_next_tok_preceded_by_whitespace) =
self.string_reader.next_token();
- if !is_next_tok_preceded_by_whitespace {
- if let Some(glued) = self.token.glue(&next_tok) {
- self.token = glued;
- } else {
- let this_spacing =
- if next_tok.is_op() { Spacing::Joint } else { Spacing::Alone };
- break (this_spacing, next_tok);
- }
- } else {
+ if is_next_tok_preceded_by_whitespace {
break (Spacing::Alone, next_tok);
+ } else if let Some(glued) = self.token.glue(&next_tok) {
+ self.token = glued;
+ } else {
+ let this_spacing =
+ if next_tok.is_punct() { Spacing::Joint } else { Spacing::Alone };
+ break (this_spacing, next_tok);
}
};
let this_tok = std::mem::replace(&mut self.token, next_tok);
@@ -99,7 +103,10 @@ impl<'a> TokenTreesReader<'a> {
err
}
- fn parse_token_tree_open_delim(&mut self, open_delim: Delimiter) -> PResult<'a, TokenTree> {
+ fn parse_token_tree_open_delim(
+ &mut self,
+ open_delim: Delimiter,
+ ) -> Result<TokenTree, Vec<PErr<'a>>> {
// The span for beginning of the delimited section
let pre_span = self.token.span;
@@ -108,7 +115,26 @@ impl<'a> TokenTreesReader<'a> {
// Parse the token trees within the delimiters.
// We stop at any delimiter so we can try to recover if the user
// uses an incorrect delimiter.
- let tts = self.parse_token_trees(/* is_delimited */ true)?;
+ let (tts, res) = self.parse_token_trees(/* is_delimited */ true);
+ if let Err(mut errs) = res {
+ // If there are unclosed delims, see if there are diff markers and if so, point them
+ // out instead of complaining about the unclosed delims.
+ let mut parser = crate::stream_to_parser(self.string_reader.sess, tts, None);
+ let mut diff_errs = vec![];
+ while parser.token != token::Eof {
+ if let Err(diff_err) = parser.err_diff_marker() {
+ diff_errs.push(diff_err);
+ }
+ parser.bump();
+ }
+ if !diff_errs.is_empty() {
+ errs.iter_mut().for_each(|err| {
+ err.delay_as_bug();
+ });
+ return Err(diff_errs);
+ }
+ return Err(errs);
+ }
// Expand to cover the entire delimited token tree
let delim_span = DelimSpan::from_pair(pre_span, self.token.span);