diff options
| author | bors <bors@rust-lang.org> | 2024-12-18 16:21:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-12-18 16:21:57 +0000 |
| commit | a52085d9f6a6e596b0cbad4502cddf86bc878028 (patch) | |
| tree | 1297ae0a4686318bc8377eded4e43b0371916743 /compiler/rustc_parse/src/parser | |
| parent | 057bdb37eccff6a2bd402509bbbadb9d73ad7bf5 (diff) | |
| parent | 29d201a3cb0ce0d0052bb4edd5fdca9c2d08894d (diff) | |
| download | rust-a52085d9f6a6e596b0cbad4502cddf86bc878028.tar.gz rust-a52085d9f6a6e596b0cbad4502cddf86bc878028.zip | |
Auto merge of #134470 - jieyouxu:rollup-kld7kmk, r=jieyouxu
Rollup of 11 pull requests Successful merges: - #130786 ( mir-opt: a sub-BB of a cleanup BB must also be a cleanup BB in `EarlyOtherwiseBranch`) - #133926 (Fix const conditions for RPITITs) - #134161 (Overhaul token cursors) - #134253 (Overhaul keyword handling) - #134394 (Clarify the match ergonomics 2024 migration lint's output) - #134399 (Do not do if ! else, use unnegated cond and swap the branches instead) - #134420 (refactor: replace &PathBuf with &Path to enhance generality) - #134436 (tests/assembly/asm: Remove uses of rustc_attrs and lang_items features by using minicore) - #134444 (Fix `x build --stage 1 std` when using cg_cranelift as the default backend) - #134452 (fix(LazyCell): documentation of get[_mut] was wrong) - #134460 (Merge some patterns together) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 92 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/tests.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/tokenstream/tests.rs | 8 |
5 files changed, 76 insertions, 46 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d1a725e729a..8417701ac0c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -22,7 +22,7 @@ use rustc_errors::{ use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::source_map::Spanned; -use rustc_span::symbol::AllKeywords; +use rustc_span::symbol::used_keywords; use rustc_span::{BytePos, DUMMY_SP, Ident, Span, SpanSnippetError, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::{debug, trace}; @@ -811,12 +811,12 @@ impl<'a> Parser<'a> { // so that it gets generated only when the diagnostic needs it. // Also, it is unlikely that this list is generated multiple times because the // parser halts after execution hits this path. - let all_keywords = AllKeywords::new().collect_used(|| prev_ident.span.edition()); + let all_keywords = used_keywords(|| prev_ident.span.edition()); // Otherwise, check the previous token with all the keywords as possible candidates. // This handles code like `Struct Human;` and `While a < b {}`. - // We check the previous token only when the current token is an identifier to avoid false - // positives like suggesting keyword `for` for `extern crate foo {}`. + // We check the previous token only when the current token is an identifier to avoid + // false positives like suggesting keyword `for` for `extern crate foo {}`. if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) { err.subdiagnostic(misspelled_kw); // We don't want other suggestions to be added as they are most likely meaningless diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 5a377464223..2f34dcb9308 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -8,6 +8,7 @@ use ast::token::IdentIsRaw; use ast::{CoroutineKind, ForLoopKind, GenBlockKind, MatchKind, Pat, Path, PathSegment, Recovered}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::tokenstream::TokenTree; use rustc_ast::util::case::Case; use rustc_ast::util::classify; use rustc_ast::util::parser::{AssocOp, ExprPrecedence, Fixity, prec_let_scrutinee_needs_par}; @@ -2392,7 +2393,8 @@ impl<'a> Parser<'a> { } if self.token == TokenKind::Semi - && matches!(self.token_cursor.stack.last(), Some((.., Delimiter::Parenthesis))) + && let Some(last) = self.token_cursor.stack.last() + && let Some(TokenTree::Delimited(_, _, Delimiter::Parenthesis, _)) = last.curr() && self.may_recover() { // It is likely that the closure body is a block but where the diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 0d220e74c0e..4bc8f5913b2 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -24,9 +24,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{ self, Delimiter, IdentIsRaw, InvisibleOrigin, MetaVarKind, Nonterminal, Token, TokenKind, }; -use rustc_ast::tokenstream::{ - AttrsTarget, DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree, TokenTreeCursor, -}; +use rustc_ast::tokenstream::{AttrsTarget, Spacing, TokenStream, TokenTree}; use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, AnonConst, AttrArgs, AttrId, ByRef, Const, CoroutineKind, DUMMY_NODE_ID, @@ -272,21 +270,48 @@ struct CaptureState { seen_attrs: IntervalSet<AttrId>, } -/// Iterator over a `TokenStream` that produces `Token`s. It's a bit odd that +#[derive(Clone, Debug)] +struct TokenTreeCursor { + stream: TokenStream, + /// Points to the current token tree in the stream. In `TokenCursor::curr`, + /// this can be any token tree. In `TokenCursor::stack`, this is always a + /// `TokenTree::Delimited`. + index: usize, +} + +impl TokenTreeCursor { + #[inline] + fn new(stream: TokenStream) -> Self { + TokenTreeCursor { stream, index: 0 } + } + + #[inline] + fn curr(&self) -> Option<&TokenTree> { + self.stream.get(self.index) + } + + #[inline] + fn bump(&mut self) { + self.index += 1; + } +} + +/// A `TokenStream` cursor that produces `Token`s. It's a bit odd that /// we (a) lex tokens into a nice tree structure (`TokenStream`), and then (b) /// use this type to emit them as a linear sequence. But a linear sequence is /// what the parser expects, for the most part. #[derive(Clone, Debug)] struct TokenCursor { - // Cursor for the current (innermost) token stream. The delimiters for this - // token stream are found in `self.stack.last()`; when that is `None` then - // we are in the outermost token stream which never has delimiters. - tree_cursor: TokenTreeCursor, - - // Token streams surrounding the current one. The delimiters for stack[n]'s - // tokens are in `stack[n-1]`. `stack[0]` (when present) has no delimiters - // because it's the outermost token stream which never has delimiters. - stack: Vec<(TokenTreeCursor, DelimSpan, DelimSpacing, Delimiter)>, + // Cursor for the current (innermost) token stream. The index within the + // cursor can point to any token tree in the stream (or one past the end). + // The delimiters for this token stream are found in `self.stack.last()`; + // if that is `None` we are in the outermost token stream which never has + // delimiters. + curr: TokenTreeCursor, + + // Token streams surrounding the current one. The index within each cursor + // always points to a `TokenTree::Delimited`. + stack: Vec<TokenTreeCursor>, } impl TokenCursor { @@ -301,32 +326,33 @@ impl TokenCursor { // FIXME: we currently don't return `Delimiter::Invisible` open/close delims. To fix // #67062 we will need to, whereupon the `delim != Delimiter::Invisible` conditions // below can be removed. - if let Some(tree) = self.tree_cursor.next_ref() { + if let Some(tree) = self.curr.curr() { match tree { &TokenTree::Token(ref token, spacing) => { debug_assert!(!matches!( token.kind, token::OpenDelim(_) | token::CloseDelim(_) )); - return (token.clone(), spacing); + let res = (token.clone(), spacing); + self.curr.bump(); + return res; } &TokenTree::Delimited(sp, spacing, delim, ref tts) => { - let trees = tts.clone().into_trees(); - self.stack.push(( - mem::replace(&mut self.tree_cursor, trees), - sp, - spacing, - delim, - )); + let trees = TokenTreeCursor::new(tts.clone()); + self.stack.push(mem::replace(&mut self.curr, trees)); if !delim.skip() { return (Token::new(token::OpenDelim(delim), sp.open), spacing.open); } // No open delimiter to return; continue on to the next iteration. } }; - } else if let Some((tree_cursor, span, spacing, delim)) = self.stack.pop() { + } else if let Some(parent) = self.stack.pop() { // We have exhausted this token stream. Move back to its parent token stream. - self.tree_cursor = tree_cursor; + let Some(&TokenTree::Delimited(span, spacing, delim, _)) = parent.curr() else { + panic!("parent should be Delimited") + }; + self.curr = parent; + self.curr.bump(); // move past the `Delimited` if !delim.skip() { return (Token::new(token::CloseDelim(delim), span.close), spacing.close); } @@ -465,7 +491,7 @@ impl<'a> Parser<'a> { capture_cfg: false, restrictions: Restrictions::empty(), expected_tokens: Vec::new(), - token_cursor: TokenCursor { tree_cursor: stream.into_trees(), stack: Vec::new() }, + token_cursor: TokenCursor { curr: TokenTreeCursor::new(stream), stack: Vec::new() }, num_bump_calls: 0, break_last_token: 0, unmatched_angle_bracket_count: 0, @@ -1191,7 +1217,7 @@ impl<'a> Parser<'a> { if dist == 1 { // The index is zero because the tree cursor's index always points // to the next token to be gotten. - match self.token_cursor.tree_cursor.look_ahead(0) { + match self.token_cursor.curr.curr() { Some(tree) => { // Indexing stayed within the current token tree. match tree { @@ -1201,12 +1227,13 @@ impl<'a> Parser<'a> { return looker(&Token::new(token::OpenDelim(delim), dspan.open)); } } - }; + } } None => { // The tree cursor lookahead went (one) past the end of the // current token tree. Try to return a close delimiter. - if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last() + if let Some(last) = self.token_cursor.stack.last() + && let Some(&TokenTree::Delimited(span, _, delim, _)) = last.curr() && !delim.skip() { // We are not in the outermost token stream, so we have @@ -1398,9 +1425,10 @@ impl<'a> Parser<'a> { pub fn parse_token_tree(&mut self) -> TokenTree { match self.token.kind { token::OpenDelim(..) => { - // Grab the tokens within the delimiters. - let stream = self.token_cursor.tree_cursor.stream.clone(); - let (_, span, spacing, delim) = *self.token_cursor.stack.last().unwrap(); + // Clone the `TokenTree::Delimited` that we are currently + // within. That's what we are going to return. + let tree = self.token_cursor.stack.last().unwrap().curr().unwrap().clone(); + debug_assert_matches!(tree, TokenTree::Delimited(..)); // Advance the token cursor through the entire delimited // sequence. After getting the `OpenDelim` we are *within* the @@ -1420,7 +1448,7 @@ impl<'a> Parser<'a> { // Consume close delimiter self.bump(); - TokenTree::Delimited(span, spacing, delim, stream) + tree } token::CloseDelim(_) | token::Eof => unreachable!(), _ => { diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index ca9e78be201..3f8d66c2c95 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -2286,7 +2286,7 @@ fn bad_path_expr_1() { fn string_to_tts_macro() { create_default_session_globals_then(|| { let stream = string_to_stream("macro_rules! zip (($a)=>($a))".to_string()); - let tts = &stream.trees().collect::<Vec<_>>()[..]; + let tts = &stream.iter().collect::<Vec<_>>()[..]; match tts { [ @@ -2298,14 +2298,14 @@ fn string_to_tts_macro() { TokenTree::Token(Token { kind: token::Ident(name_zip, IdentIsRaw::No), .. }, _), TokenTree::Delimited(.., macro_delim, macro_tts), ] if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" => { - let tts = ¯o_tts.trees().collect::<Vec<_>>(); + let tts = ¯o_tts.iter().collect::<Vec<_>>(); match &tts[..] { [ TokenTree::Delimited(.., first_delim, first_tts), TokenTree::Token(Token { kind: token::FatArrow, .. }, _), TokenTree::Delimited(.., second_delim, second_tts), ] if macro_delim == &Delimiter::Parenthesis => { - let tts = &first_tts.trees().collect::<Vec<_>>(); + let tts = &first_tts.iter().collect::<Vec<_>>(); match &tts[..] { [ TokenTree::Token(Token { kind: token::Dollar, .. }, _), @@ -2317,7 +2317,7 @@ fn string_to_tts_macro() { } _ => panic!("value 3: {:?} {:?}", first_delim, first_tts), } - let tts = &second_tts.trees().collect::<Vec<_>>(); + let tts = &second_tts.iter().collect::<Vec<_>>(); match &tts[..] { [ TokenTree::Token(Token { kind: token::Dollar, .. }, _), @@ -2545,7 +2545,7 @@ fn ttdelim_span() { .unwrap(); let ast::ExprKind::MacCall(mac) = &expr.kind else { panic!("not a macro") }; - let span = mac.args.tokens.trees().last().unwrap().span(); + let span = mac.args.tokens.iter().last().unwrap().span(); match psess.source_map().span_to_snippet(span) { Ok(s) => assert_eq!(&s[..], "{ body }"), diff --git a/compiler/rustc_parse/src/parser/tokenstream/tests.rs b/compiler/rustc_parse/src/parser/tokenstream/tests.rs index b13b68c266a..037b5b1a9de 100644 --- a/compiler/rustc_parse/src/parser/tokenstream/tests.rs +++ b/compiler/rustc_parse/src/parser/tokenstream/tests.rs @@ -23,8 +23,8 @@ fn test_concat() { let mut eq_res = TokenStream::default(); eq_res.push_stream(test_fst); eq_res.push_stream(test_snd); - assert_eq!(test_res.trees().count(), 5); - assert_eq!(eq_res.trees().count(), 5); + assert_eq!(test_res.iter().count(), 5); + assert_eq!(eq_res.iter().count(), 5); assert_eq!(test_res.eq_unspanned(&eq_res), true); }) } @@ -33,7 +33,7 @@ fn test_concat() { fn test_to_from_bijection() { create_default_session_globals_then(|| { let test_start = string_to_ts("foo::bar(baz)"); - let test_end = test_start.trees().cloned().collect(); + let test_end = test_start.iter().cloned().collect(); assert_eq!(test_start, test_end) }) } @@ -105,6 +105,6 @@ fn test_dotdotdot() { stream.push_tree(TokenTree::token_joint(token::Dot, sp(1, 2))); stream.push_tree(TokenTree::token_alone(token::Dot, sp(2, 3))); assert!(stream.eq_unspanned(&string_to_ts("..."))); - assert_eq!(stream.trees().count(), 1); + assert_eq!(stream.iter().count(), 1); }) } |
