summary refs log tree commit diff
path: root/compiler/rustc_parse/src/lib.rs
AgeCommit message (Collapse)AuthorLines
2021-04-11Implement token-based handling of attributes during expansionAaron Hill-38/+37
This PR modifies the macro expansion infrastructure to handle attributes in a fully token-based manner. As a result: * Derives macros no longer lose spans when their input is modified by eager cfg-expansion. This is accomplished by performing eager cfg-expansion on the token stream that we pass to the derive proc-macro * Inner attributes now preserve spans in all cases, including when we have multiple inner attributes in a row. This is accomplished through the following changes: * New structs `AttrAnnotatedTokenStream` and `AttrAnnotatedTokenTree` are introduced. These are very similar to a normal `TokenTree`, but they also track the position of attributes and attribute targets within the stream. They are built when we collect tokens during parsing. An `AttrAnnotatedTokenStream` is converted to a regular `TokenStream` when we invoke a macro. * Token capturing and `LazyTokenStream` are modified to work with `AttrAnnotatedTokenStream`. A new `ReplaceRange` type is introduced, which is created during the parsing of a nested AST node to make the 'outer' AST node aware of the attributes and attribute target stored deeper in the token stream. * When we need to perform eager cfg-expansion (either due to `#[derive]` or `#[cfg_eval]`), we tokenize and reparse our target, capturing additional information about the locations of `#[cfg]` and `#[cfg_attr]` attributes at any depth within the target. This is a performance optimization, allowing us to perform less work in the typical case where captured tokens never have eager cfg-expansion run.
2021-03-19stabilize or_patternsmark-1/+1
2021-03-14Bump recursion_limit in a few placesAaron Hill-0/+1
This is needed to get rustdoc to succeed on `dist-x86_64-linux-alt`
2021-02-27Combine HasAttrs and HasTokens into AstLikeAaron Hill-1/+1
When token-based attribute handling is implemeneted in #80689, we will need to access tokens from `HasAttrs` (to perform cfg-stripping), and we will to access attributes from `HasTokens` (to construct a `PreexpTokenStream`). This PR merges the `HasAttrs` and `HasTokens` traits into a new `AstLike` trait. The previous `HasAttrs` impls from `Vec<Attribute>` and `AttrVec` are removed - they aren't attribute targets, so the impls never really made sense.
2021-02-01Box the biggest ast::ItemKind variantsDániel Buga-0/+2
2021-01-22Refactor token collection to capture trailing token immediatelyAaron Hill-1/+1
2021-01-10Auto merge of #80789 - Aaron1011:fix/stmt-empty, r=petrochenkovbors-1/+10
Synthesize a `TokenStream` for `StmtKind::Empty` Fixes #80760
2021-01-09Synthesize a `TokenStream` for `StmtKind::Empty`Aaron Hill-1/+10
Fixes #80760
2021-01-08rustc_ast_pretty: Remove `PrintState::insert_extra_parens`Vadim Petrochenkov-2/+1
It's no longer necessary after #79472
2021-01-07rustc_parse: Better spans for synthesized token streamsVadim Petrochenkov-12/+8
2020-12-29Remove pretty-print/reparse hack, and add derive-specific hackAaron Hill-359/+31
2020-11-28Auto merge of #78296 - Aaron1011:fix/stmt-tokens, r=petrochenkovbors-14/+9
Properly handle attributes on statements We now collect tokens for the underlying node wrapped by `StmtKind` nstead of storing tokens directly in `Stmt`. `LazyTokenStream` now supports capturing a trailing semicolon after it is initially constructed. This allows us to avoid refactoring statement parsing to wrap the parsing of the semicolon in `parse_tokens`. Attributes on item statements (e.g. `fn foo() { #[bar] struct MyStruct; }`) are now treated as item attributes, not statement attributes, which is consistent with how we handle attributes on other kinds of statements. The feature-gating code is adjusted so that proc-macro attributes are still allowed on item statements on stable. Two built-in macros (`#[global_allocator]` and `#[test]`) needed to be adjusted to support being passed `Annotatable::Stmt`.
2020-11-26Properly handle attributes on statementsAaron Hill-14/+9
We now collect tokens for the underlying node wrapped by `StmtKind` instead of storing tokens directly in `Stmt`. `LazyTokenStream` now supports capturing a trailing semicolon after it is initially constructed. This allows us to avoid refactoring statement parsing to wrap the parsing of the semicolon in `parse_tokens`. Attributes on item statements (e.g. `fn foo() { #[bar] struct MyStruct; }`) are now treated as item attributes, not statement attributes, which is consistent with how we handle attributes on other kinds of statements. The feature-gating code is adjusted so that proc-macro attributes are still allowed on item statements on stable. Two built-in macros (`#[global_allocator]` and `#[test]`) needed to be adjusted to support being passed `Annotatable::Stmt`.
2020-11-26Auto merge of #79338 - Aaron1011:fix/token-reparse-cache, r=petrochenkovbors-3/+35
Cache pretty-print/retokenize result to avoid compile time blowup Fixes #79242 If a `macro_rules!` recursively builds up a nested nonterminal (passing it to a proc-macro at each step), we will end up repeatedly pretty-printing/retokenizing the same nonterminals. Unfortunately, the 'probable equality' check we do has a non-trivial cost, which leads to a blowup in compilation time. As a workaround, we cache the result of the 'probable equality' check, which eliminates the compilation time blowup for the linked issue. This commit only touches a single file (other than adding tests), so it should be easy to backport. The proper solution is to remove the pretty-print/retokenize hack entirely. However, this will almost certainly break a large number of crates that were relying on hygiene bugs created by using the reparsed `TokenStream`. As a result, we will definitely not want to backport such a change.
2020-11-23Cache pretty-print/retokenize result to avoid compile time blowupAaron Hill-3/+35
Fixes #79242 If a `macro_rules!` recursively builds up a nested nonterminal (passing it to a proc-macro at each step), we will end up repeatedly pretty-printing/retokenizing the same nonterminals. Unfortunately, the 'probable equality' check we do has a non-trivial cost, which leads to a blowup in compilation time. As a workaround, we cache the result of the 'probable equality' check, which eliminates the compilation time blowup for the linked issue. This commit only touches a single file (other than adding tests), so it should be easy to backport. The proper solution is to remove the pretty-print/retokenize hack entirely. However, this will almost certainly break a large number of crates that were relying on hygiene bugs created by using the reparsed `TokenStream`. As a result, we will definitely not want to backport such a change.
2020-11-22Stabilise `then`varkor-1/+0
2020-11-09Do not collect tokens for doc commentsVadim Petrochenkov-6/+1
2020-11-02Use reparsed `TokenStream` if we captured any inner attributesAaron Hill-5/+5
Fixes #78675 We now bail out of `prepend_attrs` if we ended up capturing any inner attributes (which can happen in several places, due to token capturing for `macro_rules!` arguments.
2020-10-31parser: Cleanup `LazyTokenStream` and avoid some clonesVadim Petrochenkov-11/+12
by using a named struct instead of a closure.
2020-10-30Fix even more clippy warningsJoshua Nelson-2/+2
2020-10-21Unconditionally capture tokens for attributes.Aaron Hill-47/+8
This allows us to avoid synthesizing tokens in `prepend_attr`, since we have the original tokens available. We still need to synthesize tokens when expanding `cfg_attr`, but this is an unavoidable consequence of the syntax of `cfg_attr` - the user does not supply the `#` and `[]` tokens that a `cfg_attr` expands to.
2020-10-19Rewrite `collect_tokens` implementations to use a flattened bufferAaron Hill-10/+13
Instead of trying to collect tokens at each depth, we 'flatten' the stream as we go allong, pushing open/close delimiters to our buffer just like regular tokens. One capturing is complete, we reconstruct a nested `TokenTree::Delimited` structure, producing a normal `TokenStream`. The reconstructed `TokenStream` is not created immediately - instead, it is produced on-demand by a closure (wrapped in a new `LazyTokenStream` type). This closure stores a clone of the original `TokenCursor`, plus a record of the number of calls to `next()/next_desugared()`. This is sufficient to reconstruct the tokenstream seen by the callback without storing any additional state. If the tokenstream is never used (e.g. when a captured `macro_rules!` argument is never passed to a proc macro), we never actually create a `TokenStream`. This implementation has a number of advantages over the previous one: * It is significantly simpler, with no edge cases around capturing the start/end of a delimited group. * It can be easily extended to allow replacing tokens an an arbitrary 'depth' by just using `Vec::splice` at the proper position. This is important for PR #76130, which requires us to track information about attributes along with tokens. * The lazy approach to `TokenStream` construction allows us to easily parse an AST struct, and then decide after the fact whether we need a `TokenStream`. This will be useful when we start collecting tokens for `Attribute` - we can discard the `LazyTokenStream` if the parsed attribute doesn't need tokens (e.g. is a builtin attribute). The performance impact seems to be neglibile (see https://github.com/rust-lang/rust/pull/77250#issuecomment-703960604). There is a small slowdown on a few benchmarks, but it only rises above 1% for incremental builds, where it represents a larger fraction of the much smaller instruction count. There a ~1% speedup on a few other incremental benchmarks - my guess is that the speedups and slowdowns will usually cancel out in practice.
2020-10-18Remove redundant 'static in the compilerest31-1/+1
2020-10-15Rollup merge of #77739 - est31:remove_unused_code, r=petrochenkov,varkorYuki Okushi-16/+0
Remove unused code Rustc has a builtin lint for detecting unused code inside a crate, but when an item is marked `pub`, the code, even if unused inside the entire workspace, is never marked as such. Therefore, I've built [warnalyzer](https://github.com/est31/warnalyzer) to detect unused items in a cross-crate setting. Closes https://github.com/est31/warnalyzer/issues/2
2020-10-14Remove unused code from remaining compiler cratesest31-16/+0
2020-10-11Remove unused importAaron Hill-1/+1
2020-10-11Add `relaxed_delim_match` parameterAaron Hill-16/+53
2020-10-11Allow skipping extra paren insertion during AST pretty-printingAaron Hill-7/+30
Fixes #74616 Makes progress towards #43081 Unblocks PR #76130 When pretty-printing an AST node, we may insert additional parenthesis to ensure that precedence is properly preserved in code we output. However, the proc macro implementation relies on comparing a pretty-printed AST node to the captured `TokenStream`. Inserting extra parenthesis changes the structure of the reparsed `TokenStream`, making the comparison fail. This PR refactors the AST pretty-printing code to allow skipping the insertion of additional parenthesis. Several freestanding methods are moved to trait methods on `PrintState`, which keep track of an internal `insert_extra_parens` flag. This flag is normally `true`, but we expose a public method which allows pretty-printing a nonterminal with `insert_extra_parens = false`. To avoid changing the public interface of `rustc_ast_pretty`, the freestanding `_to_string` methods are changed to delegate to a newly-crated `State`. The main pretty-printing code is moved to a new `state` module to ensure that it does not accidentally call any of these public helper functions (instead, the internal functions with the same name should be used).
2020-09-28Fix recursive nonterminal expansion during pretty-print/reparse checkAaron Hill-23/+34
Makes progress towards #43081 In PR #73084, we started recursively expanded nonterminals during the pretty-print/reparse check, allowing them to be properly compared against the reparsed tokenstream. Unfortunately, the recursive logic in that PR only handles the case where a nonterminal appears inside a `TokenTree::Delimited`. If a nonterminal appears directly in the expanded tokens of another nonterminal, the inner nonterminal will not be expanded. This PR fixes the recursive expansion of nonterminals, ensuring that they are expanded wherever they occur.
2020-09-26pretty-print-reparse hack: Remove an impossible caseVadim Petrochenkov-4/+1
Delimiters cannot appear as isolated tokens in a token stream
2020-09-26pretty-print-reparse hack: Rename some variables for clarityVadim Petrochenkov-16/+21
2020-09-21Don't use `zip` to compare iterators during pretty-print hackAaron Hill-8/+5
If the right-hand iterator has exactly one more element than the left-hand iterator, then both iterators will be fully consumed, but the extra element will never be compared.
2020-09-17Remove redundant #![feature(...)] 's from compiler/est31-1/+0
2020-09-13Auto merge of #76585 - Aaron1011:ignore-vert-plus, r=petrochenkovbors-0/+6
Ignore `|` and `+` tokens during proc-macro pretty-print check Fixes #76182 This is an alternative to PR #76188 These tokens are not preserved in the AST in certain cases (e.g. a leading `|` in a pattern or a trailing `+` in a trait bound). This PR ignores them entirely during the pretty-print/reparse check to avoid spuriously using the re-parsed tokenstream.
2020-09-10Attach tokens to `ast::Stmt`Aaron Hill-0/+7
We currently only attach tokens when parsing a `:stmt` matcher for a `macro_rules!` macro. Proc-macro attributes on statements are still unstable, and need additional work.
2020-09-10Attach `TokenStream` to `ast::Visibility`Aaron Hill-1/+1
A `Visibility` does not have outer attributes, so we only capture tokens when parsing a `macro_rules!` matcher
2020-09-10Attach `TokenStream` to `ast::Path`Aaron Hill-0/+1
2020-09-10Attach tokens to `NtMeta` (`ast::AttrItem`)Aaron Hill-0/+1
An `AttrItem` does not have outer attributes, so we only capture tokens when parsing a `macro_rules!` matcher
2020-09-10Collect tokens when handling `:literal` matcherAaron Hill-1/+1
An `NtLiteral` just wraps an `Expr`, so we don't need to add a new `tokens` field to an AST struct.
2020-09-10Attach `TokenStream` to `ast::Ty`Aaron Hill-0/+1
A `Ty` does not have outer attributes, so we only capture tokens when parsing a `macro_rules!` matcher
2020-09-10Attach `TokenStream` to `ast::Block`Aaron Hill-0/+1
A `Block` does not have outer attributes, so we only capture tokens when parsing a `macro_rules!` matcher
2020-09-10Ignore `|` and `+` tokens during proc-macro pretty-print checkAaron Hill-0/+6
Fixes #76182 This is an alternative to PR #76188 These tokens are not preserved in the AST in certain cases (e.g. a leading `|` in a pattern or a trailing `+` in a trait bound). This PR ignores them entirely during the pretty-print/reparse check to avoid spuriously using the re-parsed tokenstream.
2020-09-10Rollup merge of #76563 - yokodake:patch-1, r=jonas-schievinkTyler Mandry-1/+1
small typo fix in rustc_parse docs small typo in rustc_parse::new_parser_from_file's documentation I'm not sure a PR is the way to do this though.
2020-09-10small typo fix in rustc_parse docsNanami-1/+1
2020-09-03Rename IsJoint -> SpacingAleksey Kladov-2/+2
To match better naming from proc-macro
2020-09-03Condense StringReader's API to a single functionAleksey Kladov-2/+7
2020-09-01Remove trivia tokensAleksey Kladov-7/+0
2020-08-30mv compiler to compiler/mark-0/+595