Skip to content

Commit fffb901

Browse files
committed
Stop emitting spans from proc macro compile time in quote expansion
Before this commit if the proc_macro::quote!{} macro was used, the span of each token as written in the source of the proc macro itself would be saved in the crate metadata of the proc macro and then recovered at proc macro runtime to forward this to the macro expansion of the proc macro. This commit stops doing this and instead generates def-site spans for each token. This removes the only case where spans from the proc macro source have a semantic effect on the compilation of crates that use the proc macro. This makes it easier to stop requiring all dependencies of proc macros to be present when using the proc macro. And will make it easier to stop requiring a proc macro to be present when using a crate that used this proc macro internally but doesn't expose it as part of it's public api. The latter is necessary to be able to cross-compile tools that link against rustc internals without requiring to be built as part of rustc with the -Zdual-proc-macro hack. It may also enable using proc macros inside the standard library or it's dependencies without breaking cross-compilation.
1 parent 57a4736 commit fffb901

File tree

11 files changed

+5
-118
lines changed

11 files changed

+5
-118
lines changed

compiler/rustc_expand/src/base.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_parse::parser::Parser;
2323
use rustc_session::config::CollapseMacroDebuginfo;
2424
use rustc_session::parse::ParseSess;
2525
use rustc_session::{Limit, Session};
26-
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
26+
use rustc_span::def_id::{DefId, LocalDefId};
2727
use rustc_span::edition::Edition;
2828
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
2929
use rustc_span::source_map::SourceMap;
@@ -1072,10 +1072,6 @@ pub trait ResolverExpand {
10721072
path: &ast::Path,
10731073
) -> Result<bool, Indeterminate>;
10741074

1075-
/// Decodes the proc-macro quoted span in the specified crate, with the specified id.
1076-
/// No caching is performed.
1077-
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1078-
10791075
/// The order of items in the HIR is unrelated to the order of
10801076
/// items in the AST. However, we generate proc macro harnesses
10811077
/// based on the AST order, and later refer to these harnesses

compiler/rustc_expand/src/proc_macro_server.rs

-43
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@ use rustc_ast::token;
1111
use rustc_ast::tokenstream::{self, DelimSpacing, Spacing, TokenStream};
1212
use rustc_ast::util::literal::escape_byte_str_symbol;
1313
use rustc_ast_pretty::pprust;
14-
use rustc_data_structures::fx::FxHashMap;
1514
use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
1615
use rustc_parse::lexer::nfc_normalize;
1716
use rustc_parse::parser::Parser;
1817
use rustc_parse::{exp, new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
1918
use rustc_session::parse::ParseSess;
20-
use rustc_span::def_id::CrateNum;
2119
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span, Symbol, sym};
2220
use smallvec::{SmallVec, smallvec};
2321

@@ -419,8 +417,6 @@ pub(crate) struct Rustc<'a, 'b> {
419417
def_site: Span,
420418
call_site: Span,
421419
mixed_site: Span,
422-
krate: CrateNum,
423-
rebased_spans: FxHashMap<usize, Span>,
424420
}
425421

426422
impl<'a, 'b> Rustc<'a, 'b> {
@@ -430,8 +426,6 @@ impl<'a, 'b> Rustc<'a, 'b> {
430426
def_site: ecx.with_def_site_ctxt(expn_data.def_site),
431427
call_site: ecx.with_call_site_ctxt(expn_data.call_site),
432428
mixed_site: ecx.with_mixed_site_ctxt(expn_data.call_site),
433-
krate: expn_data.macro_def_id.unwrap().krate,
434-
rebased_spans: FxHashMap::default(),
435429
ecx,
436430
}
437431
}
@@ -773,43 +767,6 @@ impl server::Span for Rustc<'_, '_> {
773767
fn source_text(&mut self, span: Self::Span) -> Option<String> {
774768
self.psess().source_map().span_to_snippet(span).ok()
775769
}
776-
777-
/// Saves the provided span into the metadata of
778-
/// *the crate we are currently compiling*, which must
779-
/// be a proc-macro crate. This id can be passed to
780-
/// `recover_proc_macro_span` when our current crate
781-
/// is *run* as a proc-macro.
782-
///
783-
/// Let's suppose that we have two crates - `my_client`
784-
/// and `my_proc_macro`. The `my_proc_macro` crate
785-
/// contains a procedural macro `my_macro`, which
786-
/// is implemented as: `quote! { "hello" }`
787-
///
788-
/// When we *compile* `my_proc_macro`, we will execute
789-
/// the `quote` proc-macro. This will save the span of
790-
/// "hello" into the metadata of `my_proc_macro`. As a result,
791-
/// the body of `my_proc_macro` (after expansion) will end
792-
/// up containing a call that looks like this:
793-
/// `proc_macro::Ident::new("hello", proc_macro::Span::recover_proc_macro_span(0))`
794-
///
795-
/// where `0` is the id returned by this function.
796-
/// When `my_proc_macro` *executes* (during the compilation of `my_client`),
797-
/// the call to `recover_proc_macro_span` will load the corresponding
798-
/// span from the metadata of `my_proc_macro` (which we have access to,
799-
/// since we've loaded `my_proc_macro` from disk in order to execute it).
800-
/// In this way, we have obtained a span pointing into `my_proc_macro`
801-
fn save_span(&mut self, span: Self::Span) -> usize {
802-
self.psess().save_proc_macro_span(span)
803-
}
804-
805-
fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
806-
let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site);
807-
*self.rebased_spans.entry(id).or_insert_with(|| {
808-
// FIXME: `SyntaxContext` for spans from proc macro crates is lost during encoding,
809-
// replace it with a def-site context until we are encoding it properly.
810-
resolver.get_proc_macro_quoted_span(krate, id).with_ctxt(def_site.ctxt())
811-
})
812-
}
813770
}
814771

815772
impl server::Symbol for Rustc<'_, '_> {

compiler/rustc_metadata/src/rmeta/decoder.rs

-9
Original file line numberDiff line numberDiff line change
@@ -1461,15 +1461,6 @@ impl<'a> CrateMetadataRef<'a> {
14611461
self.root.native_libraries.decode((self, sess))
14621462
}
14631463

1464-
fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
1465-
self.root
1466-
.tables
1467-
.proc_macro_quoted_spans
1468-
.get(self, index)
1469-
.unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}"))
1470-
.decode((self, sess))
1471-
}
1472-
14731464
fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> {
14741465
self.root.foreign_modules.decode((self, sess))
14751466
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

-9
Original file line numberDiff line numberDiff line change
@@ -618,15 +618,6 @@ impl CStore {
618618
self.get_crate_data(cnum).num_def_ids()
619619
}
620620

621-
pub fn get_proc_macro_quoted_span_untracked(
622-
&self,
623-
cnum: CrateNum,
624-
id: usize,
625-
sess: &Session,
626-
) -> Span {
627-
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
628-
}
629-
630621
pub fn set_used_recursively(&mut self, cnum: CrateNum) {
631622
let cmeta = self.get_crate_data_mut(cnum);
632623
if !cmeta.used {

compiler/rustc_metadata/src/rmeta/encoder.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1891,10 +1891,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18911891
let stability = tcx.lookup_stability(CRATE_DEF_ID);
18921892
let macros =
18931893
self.lazy_array(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
1894-
for (i, span) in self.tcx.sess.psess.proc_macro_quoted_spans() {
1895-
let span = self.lazy(span);
1896-
self.tables.proc_macro_quoted_spans.set_some(i, span);
1897-
}
18981894

18991895
self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
19001896
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));

compiler/rustc_metadata/src/rmeta/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,6 @@ define_tables! {
458458
// `DefPathTable` up front, since we may only ever use a few
459459
// definitions from any given crate.
460460
def_keys: Table<DefIndex, LazyValue<DefKey>>,
461-
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
462461
variant_data: Table<DefIndex, LazyValue<VariantData>>,
463462
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
464463
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,

compiler/rustc_resolve/src/macros.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_expand::expand::{
1919
AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
2020
};
2121
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
22-
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
22+
use rustc_hir::def_id::{DefId, LocalDefId};
2323
use rustc_middle::middle::stability;
2424
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
2525
use rustc_session::lint::BuiltinLintDiag;
@@ -457,10 +457,6 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
457457
self.path_accessible(expn_id, path, &[MacroNS])
458458
}
459459

460-
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
461-
self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.tcx.sess)
462-
}
463-
464460
fn declare_proc_macro(&mut self, id: NodeId) {
465461
self.proc_macros.push(id)
466462
}

compiler/rustc_session/src/parse.rs

-14
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,6 @@ pub struct ParseSess {
229229
pub file_depinfo: Lock<FxIndexSet<Symbol>>,
230230
/// Whether cfg(version) should treat the current release as incomplete
231231
pub assume_incomplete_release: bool,
232-
/// Spans passed to `proc_macro::quote_span`. Each span has a numerical
233-
/// identifier represented by its position in the vector.
234-
proc_macro_quoted_spans: AppendOnlyVec<Span>,
235232
/// Used to generate new `AttrId`s. Every `AttrId` is unique.
236233
pub attr_id_generator: AttrIdGenerator,
237234
}
@@ -266,7 +263,6 @@ impl ParseSess {
266263
env_depinfo: Default::default(),
267264
file_depinfo: Default::default(),
268265
assume_incomplete_release: false,
269-
proc_macro_quoted_spans: Default::default(),
270266
attr_id_generator: AttrIdGenerator::new(),
271267
}
272268
}
@@ -325,16 +321,6 @@ impl ParseSess {
325321
});
326322
}
327323

328-
pub fn save_proc_macro_span(&self, span: Span) -> usize {
329-
self.proc_macro_quoted_spans.push(span)
330-
}
331-
332-
pub fn proc_macro_quoted_spans(&self) -> impl Iterator<Item = (usize, Span)> {
333-
// This is equivalent to `.iter().copied().enumerate()`, but that isn't possible for
334-
// AppendOnlyVec, so we resort to this scheme.
335-
self.proc_macro_quoted_spans.iter_enumerated()
336-
}
337-
338324
pub fn dcx(&self) -> DiagCtxtHandle<'_> {
339325
self.dcx.handle()
340326
}

library/proc_macro/src/bridge/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,6 @@ macro_rules! with_api {
9999
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
100100
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
101101
fn source_text($self: $S::Span) -> Option<String>;
102-
fn save_span($self: $S::Span) -> usize;
103-
fn recover_proc_macro_span(id: usize) -> $S::Span;
104102
},
105103
Symbol {
106104
fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;

library/proc_macro/src/lib.rs

+1-15
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl Default for TokenStream {
222222
}
223223

224224
#[unstable(feature = "proc_macro_quote", issue = "54722")]
225-
pub use quote::{quote, quote_span};
225+
pub use quote::quote;
226226

227227
fn tree_to_bridge_tree(
228228
tree: TokenTree,
@@ -572,20 +572,6 @@ impl Span {
572572
self.0.source_text()
573573
}
574574

575-
// Used by the implementation of `Span::quote`
576-
#[doc(hidden)]
577-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
578-
pub fn save_span(&self) -> usize {
579-
self.0.save_span()
580-
}
581-
582-
// Used by the implementation of `Span::quote`
583-
#[doc(hidden)]
584-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
585-
pub fn recover_proc_macro_span(id: usize) -> Span {
586-
Span(bridge::client::Span::recover_proc_macro_span(id))
587-
}
588-
589575
diagnostic_method!(error, Level::Error);
590576
diagnostic_method!(warning, Level::Warning);
591577
diagnostic_method!(note, Level::Note);

library/proc_macro/src/quote.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ pub fn quote(stream: TokenStream) -> TokenStream {
6767
if stream.is_empty() {
6868
return minimal_quote!(crate::TokenStream::new());
6969
}
70-
let proc_macro_crate = minimal_quote!(crate);
7170
let mut after_dollar = false;
7271

7372
let mut tokens = crate::TokenStream::new();
@@ -120,7 +119,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
120119
};
121120
minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Ident((@ ctor)(
122121
(@ TokenTree::from(Literal::string(literal))),
123-
(@ quote_span(proc_macro_crate.clone(), tt.span())),
122+
crate::Span::def_site(),
124123
)), &mut ts);)
125124
}
126125
TokenTree::Literal(tt) => {
@@ -132,7 +131,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
132131
if let (Some(crate::TokenTree::Literal(mut lit)), None) =
133132
(iter.next(), iter.next())
134133
{
135-
lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
134+
lit.set_span(crate::Span::def_site());
136135
lit
137136
} else {
138137
unreachable!()
@@ -154,11 +153,3 @@ pub fn quote(stream: TokenStream) -> TokenStream {
154153
}
155154
}
156155
}
157-
158-
/// Quote a `Span` into a `TokenStream`.
159-
/// This is needed to implement a custom quoter.
160-
#[unstable(feature = "proc_macro_quote", issue = "54722")]
161-
pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
162-
let id = span.save_span();
163-
minimal_quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
164-
}

0 commit comments

Comments
 (0)