Skip to content

Commit fc3bc29

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

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
@@ -140,10 +140,13 @@ impl fmt::Debug for LazyAttrTokenStream {
140140
}
141141

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

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::profiling::SpannedEventArgRecorder;
78
use rustc_span::LocalExpnId;
@@ -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
@@ -114,7 +114,7 @@ macro_rules! arena_types {
114114
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
115115
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
116116
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
117-
[] token_stream: rustc_ast::tokenstream::TokenStream,
117+
[decode] token_stream: rustc_ast::tokenstream::TokenStream,
118118
]);
119119
)
120120
}

compiler/rustc_middle/src/query/keys.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Defines the set of legal keys that can be used in queries.
22
33
use rustc_ast::tokenstream::TokenStream;
4+
use rustc_data_structures::svh::Svh;
45
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
56
use rustc_hir::hir_id::{HirId, OwnerId};
67
use rustc_query_system::dep_graph::DepNodeIndex;
@@ -585,7 +586,7 @@ impl Key for (LocalDefId, HirId) {
585586
}
586587
}
587588

588-
impl<'tcx> Key for (LocalExpnId, &'tcx TokenStream) {
589+
impl<'tcx> Key for (LocalExpnId, Svh, &'tcx TokenStream) {
589590
type Cache<V> = DefaultCache<Self, V>;
590591

591592
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
@@ -106,10 +106,11 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
106106
// Queries marked with `fatal_cycle` do not need the latter implementation,
107107
// as they will raise an fatal error on query cycles instead.
108108
rustc_queries! {
109-
query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
110-
eval_always
109+
query derive_macro_expansion(key: (LocalExpnId, Svh, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
110+
// eval_always
111111
no_hash
112112
desc { "expanding a derive (proc) macro" }
113+
cache_on_disk_if { true }
113114
}
114115

115116
/// 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
@@ -785,6 +785,13 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
785785
}
786786
}
787787

788+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx rustc_ast::tokenstream::TokenStream {
789+
#[inline]
790+
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
791+
RefDecodable::decode(d)
792+
}
793+
}
794+
788795
macro_rules! impl_ref_decoder {
789796
(<$tcx:tt> $($ty:ty,)*) => {
790797
$(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)