use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::token;
-use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
+use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_data_structures::sync::Lrc;
use rustc_errors::ErrorGuaranteed;
-use rustc_parse::nt_to_tokenstream;
use rustc_parse::parser::ForceCollect;
+use rustc_span::profiling::SpannedEventArgRecorder;
use rustc_span::{Span, DUMMY_SP};
const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread;
span: Span,
input: TokenStream,
) -> Result<TokenStream, ErrorGuaranteed> {
+ let _timer =
+ ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
+ recorder.record_arg_with_span(ecx.expansion_descr(), span);
+ });
+
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
annotation: TokenStream,
annotated: TokenStream,
) -> Result<TokenStream, ErrorGuaranteed> {
+ let _timer =
+ ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
+ recorder.record_arg_with_span(ecx.expansion_descr(), span);
+ });
+
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
let server = proc_macro_server::Rustc::new(ecx);
self.client
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
// We need special handling for statement items
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
- let mut is_stmt = false;
- let item = match item {
- Annotatable::Item(item) => token::NtItem(item),
- Annotatable::Stmt(stmt) => {
- is_stmt = true;
- assert!(stmt.is_item());
-
- // A proc macro can't observe the fact that we're passing
- // them an `NtStmt` - it can only see the underlying tokens
- // of the wrapped item
- token::NtStmt(stmt.into_inner())
- }
- _ => unreachable!(),
- };
- let input = if crate::base::pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess)
- {
- TokenTree::token(token::Interpolated(Lrc::new(item)), DUMMY_SP).into()
+ let is_stmt = matches!(item, Annotatable::Stmt(..));
+ let hack = crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.parse_sess);
+ let input = if hack {
+ let nt = match item {
+ Annotatable::Item(item) => token::NtItem(item),
+ Annotatable::Stmt(stmt) => token::NtStmt(stmt),
+ _ => unreachable!(),
+ };
+ TokenTree::token(token::Interpolated(Lrc::new(nt)), DUMMY_SP).into()
} else {
- nt_to_tokenstream(&item, &ecx.sess.parse_sess, CanSynthesizeMissingTokens::No)
+ item.to_tokens(&ecx.sess.parse_sess)
};
- let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
- let server = proc_macro_server::Rustc::new(ecx);
- let stream = match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
- Ok(stream) => stream,
- Err(e) => {
- let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
- if let Some(s) = e.as_str() {
- err.help(&format!("message: {}", s));
+ let stream = {
+ let _timer =
+ ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
+ recorder.record_arg_with_span(ecx.expansion_descr(), span);
+ });
+ let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
+ let server = proc_macro_server::Rustc::new(ecx);
+ match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {
+ Ok(stream) => stream,
+ Err(e) => {
+ let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
+ if let Some(s) = e.as_str() {
+ err.help(&format!("message: {}", s));
+ }
+ err.emit();
+ return ExpandResult::Ready(vec![]);
}
- err.emit();
- return ExpandResult::Ready(vec![]);
}
};