Skip to content

Stop using intermediate macros in definition of symbols #80036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 18, 2020

Conversation

sivadeilra
Copy link

Currently, the rustc_macros::symbols macro generates two
macro_rules! macros as its output. These two macros are
used in rustc_span/src/symbol.rs.

This means that each Symbol that we define is represented
in the AST of rustc_symbols twice: once in the definition
of the define_symbols! macro (similarly for the
`keywords! macro), and once in the rustc_span::symbols
definition.

That would be OK if there were only a handful of symbols,
but currently we define over 1100 symbols. The definition
of the define_symbols! macro contains the expanded definition
of each symbol, so that's a lot of AST storage wasted on a
macro that is used exactly once.

This commit removes the define_symbols macro, and simply
allows the proc macro to directly generate the
rustc_symbols::symbol::sym module.

The benefit is mainly in reducing memory wasted during
compilation of rustc itself. It should also reduce memory used
by Rust Analyzer.

This commit also reduces the size of the AST for symbol
definitions, by moving two #[allow(...)] attributes from
the symbol constants to the sym module. This eliminates 2200+
attribute nodes.

This commit also eliminates the need for the digits_array
constant. There's no need to store an array of Symbol values
for digits. We can simply define a constant of the base value,
and add to that base value.

I left the sym::integer function in rustc_span/src/symbol.rs
instead of moving it into rustc_macros/src/symbols.rs for two
reasons. First, because it's human-written code; it doesn't need
to be generated by the proc-macro. Second, because I didn't want
the #[allow(...)] attributes that I moved to the sym module
scope to apply to this function. The sym module re-exports the
integer function from its parent module.

@rust-highfive
Copy link
Contributor

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @oli-obk (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 14, 2020
@petrochenkov
Copy link
Contributor

r? @petrochenkov

@jyn514 jyn514 added A-contributor-roadblock Area: Makes things more difficult for new or seasoned contributors to Rust A-parser Area: The lexing & parsing of Rust source code to an AST T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 14, 2020
@petrochenkov
Copy link
Contributor

petrochenkov commented Dec 14, 2020

The current structure was motivated by IDE experience first of all.
If code is not generated by a proc macro, then "Go to Definition" works on it, otherwise it does not.
(E.g. you can go to mod sym or mod kw and see where they are defined and which macros generate symbol lists.)
So as much code as possible was moved to outside of the macro.

I've just checked this branch with vscode + rust-analyzer, and the difference is pretty much the same as it was when the macro was introduced.

@sivadeilra
Copy link
Author

The current structure was motivated by IDE experience first of all.

I can see how that would be useful. Go-to-definition could still be supported, by having the proc-macro generate sym_internal and then having rustc_span/src/symbol.rs contain pub use sym_internal as sym;, immediately before the symbols! { ... } table.

@rylev
Copy link
Member

rylev commented Dec 15, 2020

@sivadeilra Do we have any numbers on how much this helps memory usage? It would help to assess any possible tradeoffs in the experience of rust-analyzer.

@petrochenkov
Copy link
Contributor

I think something like this would be optimal.
I.e. we keep the old structure, but use glob reexports instead of macros.
This way mod kw can be found by both go-to-definition and by textual search, and it's generally more clear what happens.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 15, 2020
@sivadeilra
Copy link
Author

That's pretty much what my second update in this PR does. It uses 2 re-exports, rather than macros.

@petrochenkov
Copy link
Contributor

@sivadeilra
I mean reexporting only the macro-generated entities rather than the whole modules.

@sivadeilra
Copy link
Author

I mean reexporting only the macro-generated entities rather than the whole modules.

That sounds good. I'll update with that.

@petrochenkov
Copy link
Contributor

Thanks!
r=me with commits squashed.

Currently, the rustc_macros::symbols macro generates two
`macro_rules!` macros as its output. These two macros are
used in rustc_span/src/symbol.rs.

This means that each Symbol that we define is represented
in the AST of rustc_symbols twice: once in the definition
of the `define_symbols!` macro (similarly for the
`keywords! macro), and once in the rustc_span::symbols
definition.

That would be OK if there were only a handful of symbols,
but currently we define over 1100 symbols. The definition
of the `define_symbols!` macro contains the expanded definition
of each symbol, so that's a lot of AST storage wasted on a
macro that is used exactly once.

This commit removes the `define_symbols` macro, and simply
allows the proc macro to directly generate the
`rustc_symbols::symbol::sym` module.

The benefit is mainly in reducing memory wasted during
compilation of rustc itself. It should also reduce memory used
by Rust Analyzer.

This commit also reduces the size of the AST for symbol
definitions, by moving two `#[allow(...)]` attributes from
the symbol constants to the `sym` module. This eliminates 2200+
attribute nodes.

This commit also eliminates the need for the `digits_array`
constant. There's no need to store an array of Symbol values
for digits. We can simply define a constant of the base value,
and add to that base value.
@sivadeilra
Copy link
Author

Rebased & squashed. Thanks!

@petrochenkov
Copy link
Contributor

@bors r+

@bors
Copy link
Collaborator

bors commented Dec 17, 2020

📌 Commit 2b2462e has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 17, 2020
@bors
Copy link
Collaborator

bors commented Dec 18, 2020

⌛ Testing commit 2b2462e with merge 8d006c0...

@bors
Copy link
Collaborator

bors commented Dec 18, 2020

☀️ Test successful - checks-actions
Approved by: petrochenkov
Pushing 8d006c0 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 18, 2020
@bors bors merged commit 8d006c0 into rust-lang:master Dec 18, 2020
@rustbot rustbot added this to the 1.50.0 milestone Dec 18, 2020
@sivadeilra sivadeilra deleted the syms_no_macro branch December 18, 2020 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-contributor-roadblock Area: Makes things more difficult for new or seasoned contributors to Rust A-parser Area: The lexing & parsing of Rust source code to an AST merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants