Skip to content

Commit 39002fb

Browse files
committed
fix: Make non-context expansion actually work
1 parent 26cf691 commit 39002fb

File tree

1 file changed

+50
-41
lines changed

1 file changed

+50
-41
lines changed

compiler/rustc_expand/src/proc_macro.rs

+50-41
Original file line numberDiff line numberDiff line change
@@ -143,26 +143,27 @@ impl MultiItemModifier for DeriveProcMacro {
143143
let invoc_id = ecx.current_expansion.id;
144144
let invoc_expn_data = invoc_id.expn_data();
145145

146-
// FIXME(pr-time): Just using the crate hash to notice when the proc-macro code has
147-
// changed. How to *correctly* depend on exactly the macro definition?
148-
// I.e., depending on the crate hash is just a HACK, and ideally the dependency would be
149-
// more narrow.
150-
let macro_def_id = invoc_expn_data.macro_def_id.unwrap();
151-
let proc_macro_crate_hash = tcx.crate_hash(macro_def_id.krate);
152-
153146
assert_eq!(invoc_expn_data.call_site, span);
154147

155-
let key = (invoc_id, proc_macro_crate_hash, input);
156-
157148
// FIXME(pr-time): Is this the correct way to check for incremental compilation (as
158-
// well)?
149+
// well as for `cache_proc_macros`)?
159150
if tcx.sess.opts.incremental.is_some() && tcx.sess.opts.unstable_opts.cache_proc_macros
160151
{
152+
// FIXME(pr-time): Just using the crate hash to notice when the proc-macro code has
153+
// changed. How to *correctly* depend on exactly the macro definition?
154+
// I.e., depending on the crate hash is just a HACK, and ideally the dependency would be
155+
// more narrow.
156+
let macro_def_id = invoc_expn_data.macro_def_id.unwrap();
157+
let proc_macro_crate_hash = tcx.crate_hash(macro_def_id.krate);
158+
159+
let key = (invoc_id, proc_macro_crate_hash, input);
160+
161161
enter_context((ecx, self.client), move || tcx.derive_macro_expansion(key).cloned())
162162
} else {
163-
provide_derive_macro_expansion(tcx, key).cloned()
163+
expand_derive_macro(tcx, invoc_id, input, ecx, self.client).cloned()
164164
}
165165
});
166+
166167
let Ok(output) = res else {
167168
// error will already have been emitted
168169
return ExpandResult::Ready(vec![]);
@@ -204,40 +205,48 @@ pub(super) fn provide_derive_macro_expansion<'tcx>(
204205
) -> Result<&'tcx TokenStream, ()> {
205206
let (invoc_id, _macro_crate_hash, input) = key;
206207

207-
with_context(|(ecx, client)| {
208-
let invoc_expn_data = invoc_id.expn_data();
209-
let span = invoc_expn_data.call_site;
210-
let event_arg = invoc_expn_data.kind.descr();
211-
let _timer = tcx.sess.prof.generic_activity_with_arg_recorder(
212-
"expand_derive_proc_macro_inner",
213-
|recorder| {
214-
recorder.record_arg_with_span(tcx.sess.source_map(), event_arg.clone(), span);
215-
},
216-
);
217-
218-
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
219-
let strategy = crate::proc_macro::exec_strategy(tcx.sess);
220-
let server = crate::proc_macro_server::Rustc::new(ecx);
221-
222-
match client.run(&strategy, server, input.clone(), proc_macro_backtrace) {
223-
Ok(stream) => Ok(tcx.arena.alloc(stream) as &TokenStream),
224-
Err(e) => {
225-
tcx.dcx().emit_err({
226-
errors::ProcMacroDerivePanicked {
227-
span,
228-
message: e.as_str().map(|message| errors::ProcMacroDerivePanickedHelp {
229-
message: message.into(),
230-
}),
231-
}
232-
});
233-
Err(())
234-
}
235-
}
236-
})
208+
with_context(|(ecx, client)| expand_derive_macro(tcx, invoc_id, input, ecx, *client))
237209
}
238210

239211
type CLIENT = pm::bridge::client::Client<pm::TokenStream, pm::TokenStream>;
240212

213+
fn expand_derive_macro<'tcx>(
214+
tcx: TyCtxt<'tcx>,
215+
invoc_id: LocalExpnId,
216+
input: &'tcx TokenStream,
217+
ecx: &mut ExtCtxt<'_>,
218+
client: CLIENT,
219+
) -> Result<&'tcx TokenStream, ()> {
220+
let invoc_expn_data = invoc_id.expn_data();
221+
let span = invoc_expn_data.call_site;
222+
let event_arg = invoc_expn_data.kind.descr();
223+
let _timer = tcx.sess.prof.generic_activity_with_arg_recorder(
224+
"expand_derive_proc_macro_inner",
225+
|recorder| {
226+
recorder.record_arg_with_span(tcx.sess.source_map(), event_arg.clone(), span);
227+
},
228+
);
229+
230+
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
231+
let strategy = crate::proc_macro::exec_strategy(tcx.sess);
232+
let server = crate::proc_macro_server::Rustc::new(ecx);
233+
234+
match client.run(&strategy, server, input.clone(), proc_macro_backtrace) {
235+
Ok(stream) => Ok(tcx.arena.alloc(stream) as &TokenStream),
236+
Err(e) => {
237+
tcx.dcx().emit_err({
238+
errors::ProcMacroDerivePanicked {
239+
span,
240+
message: e.as_str().map(|message| errors::ProcMacroDerivePanickedHelp {
241+
message: message.into(),
242+
}),
243+
}
244+
});
245+
Err(())
246+
}
247+
}
248+
}
249+
241250
// based on rust/compiler/rustc_middle/src/ty/context/tls.rs
242251
thread_local! {
243252
/// A thread local variable that stores a pointer to the current `CONTEXT`.

0 commit comments

Comments
 (0)