Skip to content

Commit b92601a

Browse files
committed
wip: Activate, test (and fix) on_disk caching for proc-macro expansions!
Also add manual test.
1 parent 9175ccc commit b92601a

File tree

10 files changed

+71
-65
lines changed

10 files changed

+71
-65
lines changed

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,13 @@ impl fmt::Debug for LazyAttrTokenStream {
141141
}
142142

143143
impl<S: SpanEncoder> Encodable<S> for LazyAttrTokenStream {
144-
fn encode(&self, s: &mut S) {
145-
// TODO(pr-time): welp, do we really want this impl? maybe newtype wrapper?
146-
// TODO(pr-time): (also) `.flattened()` here?
147-
self.to_attr_token_stream().encode(s)
144+
fn encode(&self, _s: &mut S) {
145+
// TODO(pr-time): Just a reminder that this exists/was tried out,
146+
// but probably not necessary anymore (see below).
147+
// self.to_attr_token_stream().encode(s)
148+
// We should not need to anymore, now that we `flatten`?
149+
// Yep, that seems to be true! :)
150+
panic!("Attempted to encode LazyAttrTokenStream");
148151
}
149152
}
150153

compiler/rustc_expand/src/derive_macro_expansion.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::cell::Cell;
22
use std::ptr;
33

44
use rustc_ast::tokenstream::TokenStream;
5+
use rustc_data_structures::svh::Svh;
56
use rustc_middle::ty::TyCtxt;
67
use rustc_span::LocalExpnId;
78
use rustc_span::profiling::SpannedEventArgRecorder;
@@ -11,9 +12,9 @@ use crate::errors;
1112

1213
pub(super) fn provide_derive_macro_expansion<'tcx>(
1314
tcx: TyCtxt<'tcx>,
14-
key: (LocalExpnId, &'tcx TokenStream),
15+
key: (LocalExpnId, Svh, &'tcx TokenStream),
1516
) -> Result<&'tcx TokenStream, ()> {
16-
let (invoc_id, input) = key;
17+
let (invoc_id, _macro_crate_hash, input) = key;
1718

1819
let res = with_context(|(ecx, client)| {
1920
let span = invoc_id.expn_data().call_site;

compiler/rustc_expand/src/proc_macro.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,18 @@ impl MultiItemModifier for DeriveProcMacro {
130130
let input = tcx.arena.alloc(input.flattened()) as &TokenStream;
131131
let invoc_id = ecx.current_expansion.id;
132132

133+
// TODO(pr-time): Just using the crate hash to notice when the proc-macro code has
134+
// changed. How to *correctly* depend on exactly the macro definition?
135+
// I.e., depending on the crate hash is just a HACK (and leaves garbage in the
136+
// incremental compilation dir).
137+
let macro_def_id = invoc_id.expn_data().macro_def_id.unwrap();
138+
let proc_macro_crate_hash = tcx.crate_hash(macro_def_id.krate);
139+
133140
assert_eq!(invoc_id.expn_data().call_site, span);
134141

135142
let res = crate::derive_macro_expansion::enter_context((ecx, self.client), move || {
136-
let res = tcx.derive_macro_expansion((invoc_id, input)).cloned();
143+
let res =
144+
tcx.derive_macro_expansion((invoc_id, proc_macro_crate_hash, input)).cloned();
137145
res
138146
});
139147

compiler/rustc_middle/src/arena.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ macro_rules! arena_types {
116116
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
117117
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
118118
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
119-
[] token_stream: rustc_ast::tokenstream::TokenStream,
119+
[decode] token_stream: rustc_ast::tokenstream::TokenStream,
120120
]);
121121
)
122122
}

compiler/rustc_middle/src/query/keys.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::ffi::OsStr;
44

55
use rustc_ast::tokenstream::TokenStream;
6+
use rustc_data_structures::svh::Svh;
67
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
78
use rustc_hir::hir_id::{HirId, OwnerId};
89
use rustc_query_system::dep_graph::DepNodeIndex;
@@ -609,7 +610,7 @@ impl Key for (LocalDefId, HirId) {
609610
}
610611
}
611612

612-
impl<'tcx> Key for (LocalExpnId, &'tcx TokenStream) {
613+
impl<'tcx> Key for (LocalExpnId, Svh, &'tcx TokenStream) {
613614
type Cache<V> = DefaultCache<Self, V>;
614615

615616
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {

compiler/rustc_middle/src/query/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,11 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk};
108108
// Queries marked with `fatal_cycle` do not need the latter implementation,
109109
// as they will raise an fatal error on query cycles instead.
110110
rustc_queries! {
111-
query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
112-
eval_always
111+
query derive_macro_expansion(key: (LocalExpnId, Svh, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
112+
// eval_always
113113
no_hash
114114
desc { "expanding a derive (proc) macro" }
115+
cache_on_disk_if { true }
115116
}
116117

117118
/// This exists purely for testing the interactions between delayed bugs and incremental.

compiler/rustc_middle/src/query/on_disk_cache.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,13 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
773773
}
774774
}
775775

776+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx rustc_ast::tokenstream::TokenStream {
777+
#[inline]
778+
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
779+
RefDecodable::decode(d)
780+
}
781+
}
782+
776783
macro_rules! impl_ref_decoder {
777784
(<$tcx:tt> $($ty:ty,)*) => {
778785
$(impl<'a, $tcx> Decodable<CacheDecoder<'a, $tcx>> for &$tcx [$ty] {

tests/incremental/derive_macro_expansion/auxiliary/derive_nothing.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,11 @@ use proc_macro::TokenStream;
1010
pub fn derive(input: TokenStream) -> TokenStream {
1111
eprintln!("invoked");
1212

13-
r#"
13+
return r#"
1414
pub mod nothing_mod {
15-
// #[cfg(cfail1)]
1615
pub fn nothing() {
1716
eprintln!("nothing");
1817
}
19-
20-
// #[cfg(cfail2)]
21-
// fn nothingx() {}
2218
}
23-
"#.parse().unwrap()
19+
"#.parse().unwrap();
2420
}

tests/incremental/derive_macro_expansion/item_changed.rs

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This test tests that derive-macro execution is cached.
2+
// HOWEVER, this test can currently only be checked manually,
3+
// by running it (through compiletest) with `-- --nocapture --verbose`.
4+
// The proc-macro (for `Nothing`) prints a message to stderr when invoked,
5+
// and this message should only be present during the second invocation
6+
// (which has `cfail2` set via cfg).
7+
// TODO(pr-time): Properly have the test check this, but how? UI-test that tests for `.stderr`?
8+
9+
//@ aux-build:derive_nothing.rs
10+
//@ revisions:cfail1 cfail2
11+
//@ compile-flags: -Z query-dep-graph
12+
//@ build-pass
13+
14+
#![feature(rustc_attrs)]
15+
#![feature(stmt_expr_attributes)]
16+
#![allow(dead_code)]
17+
#![crate_type = "rlib"]
18+
19+
#![rustc_partition_codegened(module="proc_macro_unchanged-foo", cfg="cfail1")]
20+
#![rustc_partition_codegened(module="proc_macro_unchanged-foo", cfg="cfail2")]
21+
22+
// `foo::nothing_mod` is created by the derive macro and doesn't change
23+
#![rustc_partition_reused(module="proc_macro_unchanged-foo", cfg="cfail2")]
24+
25+
#[macro_use]
26+
extern crate derive_nothing;
27+
28+
pub mod foo {
29+
#[derive(Nothing)]
30+
pub struct Foo;
31+
32+
pub fn use_foo(_f: Foo) {
33+
nothing_mod::nothing();
34+
35+
eprintln!("foo used");
36+
}
37+
}

0 commit comments

Comments
 (0)