Skip to content

Commit d88bc96

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

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::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
@@ -115,7 +115,7 @@ macro_rules! arena_types {
115115
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
116116
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
117117
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
118-
[] token_stream: rustc_ast::tokenstream::TokenStream,
118+
[decode] token_stream: rustc_ast::tokenstream::TokenStream,
119119
]);
120120
)
121121
}

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, LocalDefId, LocalModDefId, ModDefId, LOCAL_CRATE};
56
use rustc_hir::hir_id::{HirId, OwnerId};
67
use rustc_query_system::query::{DefIdCache, DefaultCache, SingleCache, VecCache};
@@ -576,7 +577,7 @@ impl Key for (LocalDefId, HirId) {
576577
}
577578
}
578579

579-
impl<'tcx> Key for (LocalExpnId, &'tcx TokenStream) {
580+
impl<'tcx> Key for (LocalExpnId, Svh, &'tcx TokenStream) {
580581
type Cache<V> = DefaultCache<Self, V>;
581582

582583
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
@@ -104,10 +104,11 @@ pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue
104104
// Queries marked with `fatal_cycle` do not need the latter implementation,
105105
// as they will raise an fatal error on query cycles instead.
106106
rustc_queries! {
107-
query derive_macro_expansion(key: (LocalExpnId, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
108-
eval_always
107+
query derive_macro_expansion(key: (LocalExpnId, Svh, &'tcx TokenStream)) -> Result<&'tcx TokenStream, ()> {
108+
// eval_always
109109
no_hash
110110
desc { "expanding a derive (proc) macro" }
111+
cache_on_disk_if { true }
111112
}
112113

113114
/// 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
@@ -790,6 +790,13 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
790790
}
791791
}
792792

793+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx rustc_ast::tokenstream::TokenStream {
794+
#[inline]
795+
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
796+
RefDecodable::decode(d)
797+
}
798+
}
799+
793800
macro_rules! impl_ref_decoder {
794801
(<$tcx:tt> $($ty:ty,)*) => {
795802
$(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)