diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-12-04 15:55:06 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-12-19 16:05:41 +1100 |
| commit | b9bf0b4b10148aa914243a527d9010aba9b7b827 (patch) | |
| tree | 2478d44acd2d710543d168353b729e0716aefb70 /compiler/rustc_expand/src/proc_macro_server.rs | |
| parent | d5370d981f58ebadf575f075a6f0d8c35bc704e8 (diff) | |
| download | rust-b9bf0b4b10148aa914243a527d9010aba9b7b827.tar.gz rust-b9bf0b4b10148aa914243a527d9010aba9b7b827.zip | |
Speed up `Parser::expected_token_types`.
The parser pushes a `TokenType` to `Parser::expected_token_types` on every call to the various `check`/`eat` methods, and clears it on every call to `bump`. Some of those `TokenType` values are full tokens that require cloning and dropping. This is a *lot* of work for something that is only used in error messages and it accounts for a significant fraction of parsing execution time. This commit overhauls `TokenType` so that `Parser::expected_token_types` can be implemented as a bitset. This requires changing `TokenType` to a C-style parameterless enum, and adding `TokenTypeSet` which uses a `u128` for the bits. (The new `TokenType` has 105 variants.) The new types `ExpTokenPair` and `ExpKeywordPair` are now arguments to the `check`/`eat` methods. This is for maximum speed. The elements in the pairs are always statically known; e.g. a `token::BinOp(token::Star)` is always paired with a `TokenType::Star`. So we now compute `TokenType`s in advance and pass them in to `check`/`eat` rather than the current approach of constructing them on insertion into `expected_token_types`. Values of these pair types can be produced by the new `exp!` macro, which is used at every `check`/`eat` call site. The macro is for convenience, allowing any pair to be generated from a single identifier. The ident/keyword filtering in `expected_one_of_not_found` is no longer necessary. It was there to account for some sloppiness in `TokenKind`/`TokenType` comparisons. The existing `TokenType` is moved to a new file `token_type.rs`, and all its new infrastructure is added to that file. There is more boilerplate code than I would like, but I can't see how to make it shorter.
Diffstat (limited to 'compiler/rustc_expand/src/proc_macro_server.rs')
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro_server.rs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 8577aa110af..7eb09a64e96 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -15,7 +15,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult}; use rustc_parse::lexer::nfc_normalize; use rustc_parse::parser::Parser; -use rustc_parse::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; +use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal}; use rustc_session::parse::ParseSess; use rustc_span::def_id::CrateNum; use rustc_span::{BytePos, FileName, Pos, SourceFile, Span, Symbol, sym}; @@ -473,7 +473,7 @@ impl server::FreeFunctions for Rustc<'_, '_> { unwrap_or_emit_fatal(new_parser_from_source_str(self.psess(), name, s.to_owned())); let first_span = parser.token.span.data(); - let minus_present = parser.eat(&token::BinOp(token::Minus)); + let minus_present = parser.eat(exp!(Minus)); let lit_span = parser.token.span.data(); let token::Literal(mut lit) = parser.token.kind else { |
