Skip to content

Experimental: Add Derive Proc-Macro Caching #129102

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

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
eccec74
deps(rustc_expand): Add `rustc_middle` as a dep
futile Aug 11, 2024
e0fe67e
refactor(rustc_expand): Take &SyntaxExtension instead of only &*Kind
futile Aug 11, 2024
7081090
wip: So yeah, tests pass, but still `eval_always` (not far from disk …
futile Aug 12, 2024
377075a
fix: Prevent double-enter with same `&mut ExtCtxt` (which would be UB)
futile Aug 12, 2024
fdc7d63
chore: Remove old `allow`
futile Aug 12, 2024
efb8f71
chore: Remove unneeded code, adapt TODOs for pr-time
futile Aug 12, 2024
9175ccc
wip(test): Run with `-- --nocapture --verbose` and `invoked` should n…
futile Aug 12, 2024
b92601a
wip: Activate, test (and fix) on_disk caching for proc-macro expansions!
futile Aug 12, 2024
f9ec979
chore: Adjust timing outputs
futile Aug 12, 2024
f0e0006
feat: Add `-Zcache-all-derive-macros` to use/bypass cache
futile Aug 12, 2024
74b9365
wip: try also hashing query output
futile Aug 12, 2024
df518db
prepare for PR (tidy should pass, caching=yes by default for rustc-perf)
futile Aug 14, 2024
12c6d3e
wip: Undo unnecessary refactoring
futile Aug 19, 2024
5439803
rebase + fix unreachable pub-items, inline some CONTEXT-things
futile Sep 9, 2024
8610ec6
fix: comment + unused warning
futile Nov 16, 2024
1bad277
style: move import to correct place
futile Nov 16, 2024
bc58b22
chore: remove old comment
futile Nov 16, 2024
3e5e84b
don't flatten proc macro output, let's see how it goes
futile Nov 16, 2024
4652473
only retrieve expn_data once
futile Nov 16, 2024
1cd9a4f
fix: Ensure incremental compilation is also enabled
futile Dec 8, 2024
db56376
refactor!: Rename `cache-all-derive-macros` option to `cache-proc-mac…
futile Dec 28, 2024
70460d4
nit: remove comment
futile Dec 28, 2024
9352678
refactor: Require `ecx` less
futile Dec 28, 2024
6a62f9b
refactor: Only call invoc_id.expn_data() once, inline some `res`
futile Dec 28, 2024
4a3ed82
refactor: Don't enter context if not caching (don't need it then)
futile Dec 28, 2024
26cf691
refactor: Move derive_macro_expansion.rs to end of proc_macro.rs
futile Dec 28, 2024
39002fb
fix: Make non-context expansion actually work
futile Dec 28, 2024
0e125a5
fix: Build was broken, probably should squash all commits now or sth.
futile Mar 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3654,6 +3654,7 @@ dependencies = [
"rustc_lexer",
"rustc_lint_defs",
"rustc_macros",
"rustc_middle",
"rustc_parse",
"rustc_serialize",
"rustc_session",
Expand Down
94 changes: 93 additions & 1 deletion compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
//! ownership of the original.

use std::borrow::Cow;
use std::hash::Hash;
use std::sync::Arc;
use std::{cmp, fmt, iter};

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_serialize::{Decodable, Encodable};
use rustc_serialize::{Decodable, Encodable, Encoder};
use rustc_span::def_id::{CrateNum, DefIndex};
use rustc_span::{DUMMY_SP, Span, SpanDecoder, SpanEncoder, Symbol, sym};

use crate::ast::AttrStyle;
Expand Down Expand Up @@ -296,6 +298,96 @@ pub struct AttrsTarget {
#[derive(Clone, Debug, Default, Encodable, Decodable)]
pub struct TokenStream(pub(crate) Arc<Vec<TokenTree>>);

struct HashEncoder<H: std::hash::Hasher> {
hasher: H,
}

impl<H: std::hash::Hasher> Encoder for HashEncoder<H> {
fn emit_usize(&mut self, v: usize) {
self.hasher.write_usize(v)
}

fn emit_u128(&mut self, v: u128) {
self.hasher.write_u128(v)
}

fn emit_u64(&mut self, v: u64) {
self.hasher.write_u64(v)
}

fn emit_u32(&mut self, v: u32) {
self.hasher.write_u32(v)
}

fn emit_u16(&mut self, v: u16) {
self.hasher.write_u16(v)
}

fn emit_u8(&mut self, v: u8) {
self.hasher.write_u8(v)
}

fn emit_isize(&mut self, v: isize) {
self.hasher.write_isize(v)
}

fn emit_i128(&mut self, v: i128) {
self.hasher.write_i128(v)
}

fn emit_i64(&mut self, v: i64) {
self.hasher.write_i64(v)
}

fn emit_i32(&mut self, v: i32) {
self.hasher.write_i32(v)
}

fn emit_i16(&mut self, v: i16) {
self.hasher.write_i16(v)
}

fn emit_raw_bytes(&mut self, s: &[u8]) {
self.hasher.write(s)
}
}

impl<H: std::hash::Hasher> SpanEncoder for HashEncoder<H> {
fn encode_span(&mut self, span: Span) {
span.hash(&mut self.hasher)
}

fn encode_symbol(&mut self, symbol: Symbol) {
symbol.hash(&mut self.hasher)
}

fn encode_expn_id(&mut self, expn_id: rustc_span::ExpnId) {
expn_id.hash(&mut self.hasher)
}

fn encode_syntax_context(&mut self, syntax_context: rustc_span::SyntaxContext) {
syntax_context.hash(&mut self.hasher)
}

fn encode_crate_num(&mut self, crate_num: CrateNum) {
crate_num.hash(&mut self.hasher)
}

fn encode_def_index(&mut self, def_index: DefIndex) {
def_index.hash(&mut self.hasher)
}

fn encode_def_id(&mut self, def_id: rustc_span::def_id::DefId) {
def_id.hash(&mut self.hasher)
}
}

impl Hash for TokenStream {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
Encodable::encode(self, &mut HashEncoder { hasher: state });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Also the use of (Span)Encoder here is strange, I don't think it's supposed to be used like this.)

This comment is still relevant, why did you use the Encoder traits for implementing hashing?
Is this Hash implementation actually used? What happens if you put a panic into it?
Can it be implemented in terms of the already existing HashStable implementation for TokenStream?

}
}

/// Indicates whether a token can join with the following token to form a
/// compound token. Used for conversions to `proc_macro::Spacing`. Also used to
/// guide pretty-printing, which is where the `JointHidden` value (which isn't
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_expand/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rustc_hir = { path = "../rustc_hir" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_parse = { path = "../rustc_parse" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
Expand Down
21 changes: 11 additions & 10 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,17 +835,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
InvocationKind::GlobDelegation { item, of_trait } => {
let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
let suffixes = match ext {
SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
{
ExpandResult::Ready(suffixes) => suffixes,
ExpandResult::Retry(()) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(Invocation {
kind: InvocationKind::GlobDelegation { item, of_trait },
..invoc
});
SyntaxExtensionKind::GlobDelegation(expander) => {
match expander.expand(self.cx) {
ExpandResult::Ready(suffixes) => suffixes,
ExpandResult::Retry(()) => {
// Reassemble the original invocation for retrying.
return ExpandResult::Retry(Invocation {
kind: InvocationKind::GlobDelegation { item, of_trait },
..invoc
});
}
}
},
}
SyntaxExtensionKind::LegacyBang(..) => {
let msg = "expanded a dummy glob delegation";
let guar = self.cx.dcx().span_delayed_bug(span, msg);
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ pub mod module;
#[allow(rustc::untranslatable_diagnostic)]
pub mod proc_macro;

pub fn provide(providers: &mut rustc_middle::util::Providers) {
providers.derive_macro_expansion = proc_macro::provide_derive_macro_expansion;
}

rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
Loading
Loading