Skip to content

Commit c976a4e

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 c82e0df commit c976a4e

File tree

11 files changed

+5
-118
lines changed

11 files changed

+5
-118
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_parse::parser::Parser;
2121
use rustc_session::config::CollapseMacroDebuginfo;
2222
use rustc_session::parse::ParseSess;
2323
use rustc_session::{Limit, Session};
24-
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
24+
use rustc_span::def_id::{DefId, LocalDefId};
2525
use rustc_span::edition::Edition;
2626
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
2727
use rustc_span::source_map::SourceMap;
@@ -1047,10 +1047,6 @@ pub trait ResolverExpand {
10471047
path: &ast::Path,
10481048
) -> Result<bool, Indeterminate>;
10491049

1050-
/// Decodes the proc-macro quoted span in the specified crate, with the specified id.
1051-
/// No caching is performed.
1052-
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;
1053-
10541050
/// The order of items in the HIR is unrelated to the order of
10551051
/// items in the AST. However, we generate proc macro harnesses
10561052
/// based on the AST order, and later refer to these harnesses

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@ use rustc_ast::token;
1010
use rustc_ast::tokenstream::{self, DelimSpacing, Spacing, TokenStream};
1111
use rustc_ast::util::literal::escape_byte_str_symbol;
1212
use rustc_ast_pretty::pprust;
13-
use rustc_data_structures::fx::FxHashMap;
1413
use rustc_data_structures::sync::Lrc;
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::{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::symbol::{self, Symbol, sym};
2220
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
2321
use smallvec::{SmallVec, smallvec};
@@ -422,8 +420,6 @@ pub(crate) struct Rustc<'a, 'b> {
422420
def_site: Span,
423421
call_site: Span,
424422
mixed_site: Span,
425-
krate: CrateNum,
426-
rebased_spans: FxHashMap<usize, Span>,
427423
}
428424

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

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

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,15 +1444,6 @@ impl<'a> CrateMetadataRef<'a> {
14441444
self.root.native_libraries.decode((self, sess))
14451445
}
14461446

1447-
fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
1448-
self.root
1449-
.tables
1450-
.proc_macro_quoted_spans
1451-
.get(self, index)
1452-
.unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}"))
1453-
.decode((self, sess))
1454-
}
1455-
14561447
fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + 'a {
14571448
self.root.foreign_modules.decode((self, sess))
14581449
}

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -620,15 +620,6 @@ impl CStore {
620620
self.get_crate_data(cnum).num_def_ids()
621621
}
622622

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

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,10 +1859,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18591859
let stability = tcx.lookup_stability(CRATE_DEF_ID);
18601860
let macros =
18611861
self.lazy_array(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
1862-
for (i, span) in self.tcx.sess.psess.proc_macro_quoted_spans() {
1863-
let span = self.lazy(span);
1864-
self.tables.proc_macro_quoted_spans.set_some(i, span);
1865-
}
18661862

18671863
self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
18681864
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

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

compiler/rustc_resolve/src/macros.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_expand::expand::{
2020
AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
2121
};
2222
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
23-
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
23+
use rustc_hir::def_id::{DefId, LocalDefId};
2424
use rustc_middle::middle::stability;
2525
use rustc_middle::ty::{RegisteredTools, TyCtxt, Visibility};
2626
use rustc_session::lint::BuiltinLintDiag;
@@ -480,10 +480,6 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
480480
self.path_accessible(expn_id, path, &[MacroNS])
481481
}
482482

483-
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
484-
self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.tcx.sess)
485-
}
486-
487483
fn declare_proc_macro(&mut self, id: NodeId) {
488484
self.proc_macros.push(id)
489485
}

compiler/rustc_session/src/parse.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,6 @@ pub struct ParseSess {
228228
pub file_depinfo: Lock<FxIndexSet<Symbol>>,
229229
/// Whether cfg(version) should treat the current release as incomplete
230230
pub assume_incomplete_release: bool,
231-
/// Spans passed to `proc_macro::quote_span`. Each span has a numerical
232-
/// identifier represented by its position in the vector.
233-
proc_macro_quoted_spans: AppendOnlyVec<Span>,
234231
/// Used to generate new `AttrId`s. Every `AttrId` is unique.
235232
pub attr_id_generator: AttrIdGenerator,
236233
}
@@ -265,7 +262,6 @@ impl ParseSess {
265262
env_depinfo: Default::default(),
266263
file_depinfo: Default::default(),
267264
assume_incomplete_release: false,
268-
proc_macro_quoted_spans: Default::default(),
269265
attr_id_generator: AttrIdGenerator::new(),
270266
}
271267
}
@@ -328,16 +324,6 @@ impl ParseSess {
328324
});
329325
}
330326

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

library/proc_macro/src/bridge/mod.rs

Lines changed: 0 additions & 2 deletions
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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ impl Default for TokenStream {
232232
}
233233

234234
#[unstable(feature = "proc_macro_quote", issue = "54722")]
235-
pub use quote::{quote, quote_span};
235+
pub use quote::quote;
236236

237237
fn tree_to_bridge_tree(
238238
tree: TokenTree,
@@ -582,20 +582,6 @@ impl Span {
582582
self.0.source_text()
583583
}
584584

585-
// Used by the implementation of `Span::quote`
586-
#[doc(hidden)]
587-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
588-
pub fn save_span(&self) -> usize {
589-
self.0.save_span()
590-
}
591-
592-
// Used by the implementation of `Span::quote`
593-
#[doc(hidden)]
594-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
595-
pub fn recover_proc_macro_span(id: usize) -> Span {
596-
Span(bridge::client::Span::recover_proc_macro_span(id))
597-
}
598-
599585
diagnostic_method!(error, Level::Error);
600586
diagnostic_method!(warning, Level::Warning);
601587
diagnostic_method!(note, Level::Note);

library/proc_macro/src/quote.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ pub fn quote(stream: TokenStream) -> TokenStream {
6464
if stream.is_empty() {
6565
return quote!(crate::TokenStream::new());
6666
}
67-
let proc_macro_crate = quote!(crate);
6867
let mut after_dollar = false;
6968
let tokens = stream
7069
.into_iter()
@@ -105,7 +104,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
105104
))),
106105
TokenTree::Ident(tt) => quote!(crate::TokenTree::Ident(crate::Ident::new(
107106
(@ TokenTree::from(Literal::string(&tt.to_string()))),
108-
(@ quote_span(proc_macro_crate.clone(), tt.span())),
107+
crate::Span::def_site(),
109108
))),
110109
TokenTree::Literal(tt) => quote!(crate::TokenTree::Literal({
111110
let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
@@ -115,7 +114,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
115114
if let (Some(crate::TokenTree::Literal(mut lit)), None) =
116115
(iter.next(), iter.next())
117116
{
118-
lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
117+
lit.set_span(crate::Span::def_site());
119118
lit
120119
} else {
121120
unreachable!()
@@ -131,11 +130,3 @@ pub fn quote(stream: TokenStream) -> TokenStream {
131130

132131
quote!([(@ tokens)].iter().cloned().collect::<crate::TokenStream>())
133132
}
134-
135-
/// Quote a `Span` into a `TokenStream`.
136-
/// This is needed to implement a custom quoter.
137-
#[unstable(feature = "proc_macro_quote", issue = "54722")]
138-
pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
139-
let id = span.save_span();
140-
quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
141-
}

0 commit comments

Comments
 (0)