Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop emitting spans from proc macro compile time in quote expansion #125721

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiag, RegisteredTools};
use rustc_parse::{parser, MACRO_ARGUMENTS};
use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::{parse::ParseSess, Limit, Session};
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::edition::Edition;
use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::source_map::SourceMap;
Expand Down Expand Up @@ -1015,10 +1015,6 @@ pub trait ResolverExpand {
path: &ast::Path,
) -> Result<bool, Indeterminate>;

/// Decodes the proc-macro quoted span in the specified crate, with the specified id.
/// No caching is performed.
fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span;

/// The order of items in the HIR is unrelated to the order of
/// items in the AST. However, we generate proc macro harnesses
/// based on the AST order, and later refer to these harnesses
Expand Down
43 changes: 0 additions & 43 deletions compiler/rustc_expand/src/proc_macro_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ use rustc_ast::token;
use rustc_ast::tokenstream::{self, DelimSpacing, Spacing, TokenStream};
use rustc_ast::util::literal::escape_byte_str_symbol;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Diag, ErrorGuaranteed, MultiSpan, PResult};
use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess;
use rustc_span::def_id::CrateNum;
use rustc_span::symbol::{self, sym, Symbol};
use rustc_span::{BytePos, FileName, Pos, SourceFile, Span};
use smallvec::{smallvec, SmallVec};
Expand Down Expand Up @@ -419,8 +417,6 @@ pub(crate) struct Rustc<'a, 'b> {
def_site: Span,
call_site: Span,
mixed_site: Span,
krate: CrateNum,
rebased_spans: FxHashMap<usize, Span>,
}

impl<'a, 'b> Rustc<'a, 'b> {
Expand All @@ -430,8 +426,6 @@ impl<'a, 'b> Rustc<'a, 'b> {
def_site: ecx.with_def_site_ctxt(expn_data.def_site),
call_site: ecx.with_call_site_ctxt(expn_data.call_site),
mixed_site: ecx.with_mixed_site_ctxt(expn_data.call_site),
krate: expn_data.macro_def_id.unwrap().krate,
rebased_spans: FxHashMap::default(),
ecx,
}
}
Expand Down Expand Up @@ -781,43 +775,6 @@ impl server::Span for Rustc<'_, '_> {
fn source_text(&mut self, span: Self::Span) -> Option<String> {
self.psess().source_map().span_to_snippet(span).ok()
}

/// Saves the provided span into the metadata of
/// *the crate we are currently compiling*, which must
/// be a proc-macro crate. This id can be passed to
/// `recover_proc_macro_span` when our current crate
/// is *run* as a proc-macro.
///
/// Let's suppose that we have two crates - `my_client`
/// and `my_proc_macro`. The `my_proc_macro` crate
/// contains a procedural macro `my_macro`, which
/// is implemented as: `quote! { "hello" }`
///
/// When we *compile* `my_proc_macro`, we will execute
/// the `quote` proc-macro. This will save the span of
/// "hello" into the metadata of `my_proc_macro`. As a result,
/// the body of `my_proc_macro` (after expansion) will end
/// up containing a call that looks like this:
/// `proc_macro::Ident::new("hello", proc_macro::Span::recover_proc_macro_span(0))`
///
/// where `0` is the id returned by this function.
/// When `my_proc_macro` *executes* (during the compilation of `my_client`),
/// the call to `recover_proc_macro_span` will load the corresponding
/// span from the metadata of `my_proc_macro` (which we have access to,
/// since we've loaded `my_proc_macro` from disk in order to execute it).
/// In this way, we have obtained a span pointing into `my_proc_macro`
fn save_span(&mut self, span: Self::Span) -> usize {
self.psess().save_proc_macro_span(span)
}

fn recover_proc_macro_span(&mut self, id: usize) -> Self::Span {
let (resolver, krate, def_site) = (&*self.ecx.resolver, self.krate, self.def_site);
*self.rebased_spans.entry(id).or_insert_with(|| {
// FIXME: `SyntaxContext` for spans from proc macro crates is lost during encoding,
// replace it with a def-site context until we are encoding it properly.
resolver.get_proc_macro_quoted_span(krate, id).with_ctxt(def_site.ctxt())
})
}
}

impl server::Symbol for Rustc<'_, '_> {
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,15 +1475,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.native_libraries.decode((self, sess))
}

fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
self.root
.tables
.proc_macro_quoted_spans
.get(self, index)
.unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}"))
.decode((self, sess))
}

fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
self.root.foreign_modules.decode((self, sess))
}
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,15 +579,6 @@ impl CStore {
self.get_crate_data(cnum).num_def_ids()
}

pub fn get_proc_macro_quoted_span_untracked(
&self,
cnum: CrateNum,
id: usize,
sess: &Session,
) -> Span {
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
}

pub fn set_used_recursively(&mut self, cnum: CrateNum) {
let cmeta = self.get_crate_data_mut(cnum);
if !cmeta.used {
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1809,10 +1809,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let stability = tcx.lookup_stability(CRATE_DEF_ID);
let macros =
self.lazy_array(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
for (i, span) in self.tcx.sess.psess.proc_macro_quoted_spans() {
let span = self.lazy(span);
self.tables.proc_macro_quoted_spans.set_some(i, span);
}

self.tables.def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,6 @@ define_tables! {
// `DefPathTable` up front, since we may only ever use a few
// definitions from any given crate.
def_keys: Table<DefIndex, LazyValue<DefKey>>,
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
variant_data: Table<DefIndex, LazyValue<VariantData>>,
assoc_container: Table<DefIndex, ty::AssocItemContainer>,
macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::middle::stability;
use rustc_middle::ty::RegisteredTools;
use rustc_middle::ty::{TyCtxt, Visibility};
Expand Down Expand Up @@ -437,10 +437,6 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
self.path_accessible(expn_id, path, &[MacroNS])
}

fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span {
self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.tcx.sess)
}

fn declare_proc_macro(&mut self, id: NodeId) {
self.proc_macros.push(id)
}
Expand Down
14 changes: 0 additions & 14 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,6 @@ pub struct ParseSess {
pub file_depinfo: Lock<FxIndexSet<Symbol>>,
/// Whether cfg(version) should treat the current release as incomplete
pub assume_incomplete_release: bool,
/// Spans passed to `proc_macro::quote_span`. Each span has a numerical
/// identifier represented by its position in the vector.
proc_macro_quoted_spans: AppendOnlyVec<Span>,
/// Used to generate new `AttrId`s. Every `AttrId` is unique.
pub attr_id_generator: AttrIdGenerator,
}
Expand Down Expand Up @@ -264,7 +261,6 @@ impl ParseSess {
env_depinfo: Default::default(),
file_depinfo: Default::default(),
assume_incomplete_release: false,
proc_macro_quoted_spans: Default::default(),
attr_id_generator: AttrIdGenerator::new(),
}
}
Expand Down Expand Up @@ -316,14 +312,4 @@ impl ParseSess {
});
});
}

pub fn save_proc_macro_span(&self, span: Span) -> usize {
self.proc_macro_quoted_spans.push(span)
}

pub fn proc_macro_quoted_spans(&self) -> impl Iterator<Item = (usize, Span)> + '_ {
// This is equivalent to `.iter().copied().enumerate()`, but that isn't possible for
// AppendOnlyVec, so we resort to this scheme.
self.proc_macro_quoted_spans.iter_enumerated()
}
}
2 changes: 0 additions & 2 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ macro_rules! with_api {
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
fn source_text($self: $S::Span) -> Option<String>;
fn save_span($self: $S::Span) -> usize;
fn recover_proc_macro_span(id: usize) -> $S::Span;
},
Symbol {
fn normalize_and_validate_ident(string: &str) -> Result<$S::Symbol, ()>;
Expand Down
16 changes: 1 addition & 15 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ impl Default for TokenStream {
}

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

fn tree_to_bridge_tree(
tree: TokenTree,
Expand Down Expand Up @@ -576,20 +576,6 @@ impl Span {
self.0.source_text()
}

// Used by the implementation of `Span::quote`
#[doc(hidden)]
#[unstable(feature = "proc_macro_internals", issue = "27812")]
pub fn save_span(&self) -> usize {
self.0.save_span()
}

// Used by the implementation of `Span::quote`
#[doc(hidden)]
#[unstable(feature = "proc_macro_internals", issue = "27812")]
pub fn recover_proc_macro_span(id: usize) -> Span {
Span(bridge::client::Span::recover_proc_macro_span(id))
}

diagnostic_method!(error, Level::Error);
diagnostic_method!(warning, Level::Warning);
diagnostic_method!(note, Level::Note);
Expand Down
13 changes: 2 additions & 11 deletions library/proc_macro/src/quote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pub fn quote(stream: TokenStream) -> TokenStream {
if stream.is_empty() {
return quote!(crate::TokenStream::new());
}
let proc_macro_crate = quote!(crate);
let mut after_dollar = false;
let tokens = stream
.into_iter()
Expand Down Expand Up @@ -105,7 +104,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
))),
TokenTree::Ident(tt) => quote!(crate::TokenTree::Ident(crate::Ident::new(
(@ TokenTree::from(Literal::string(&tt.to_string()))),
(@ quote_span(proc_macro_crate.clone(), tt.span())),
crate::Span::def_site(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Span::def_site() is unstable, so is quote!{}. In addition Span::def_site() is the closest to the behavior before this PR.

))),
TokenTree::Literal(tt) => quote!(crate::TokenTree::Literal({
let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
Expand All @@ -115,7 +114,7 @@ pub fn quote(stream: TokenStream) -> TokenStream {
if let (Some(crate::TokenTree::Literal(mut lit)), None) =
(iter.next(), iter.next())
{
lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
lit.set_span(crate::Span::def_site());
lit
} else {
unreachable!()
Expand All @@ -131,11 +130,3 @@ pub fn quote(stream: TokenStream) -> TokenStream {

quote!([(@ tokens)].iter().cloned().collect::<crate::TokenStream>())
}

/// Quote a `Span` into a `TokenStream`.
/// This is needed to implement a custom quoter.
#[unstable(feature = "proc_macro_quote", issue = "54722")]
pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
let id = span.save_span();
quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
}
Original file line number Diff line number Diff line change
Expand Up @@ -312,18 +312,6 @@ impl server::Span for RaSpanServer {
// FIXME stub, requires db
SourceFile {}
}
fn save_span(&mut self, _span: Self::Span) -> usize {
// FIXME, quote is incompatible with third-party tools
// This is called by the quote proc-macro which is expanded when the proc-macro is compiled
// As such, r-a will never observe this
0
}
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
// FIXME, quote is incompatible with third-party tools
// This is called by the expansion of quote!, r-a will observe this, but we don't have
// access to the spans that were encoded
self.call_site
}
/// Recent feature, not yet in the proc_macro
///
/// See PR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,6 @@ impl server::Span for TokenIdServer {
fn source_file(&mut self, _span: Self::Span) -> Self::SourceFile {
SourceFile {}
}
fn save_span(&mut self, _span: Self::Span) -> usize {
0
}
fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
self.call_site
}
/// Recent feature, not yet in the proc_macro
///
/// See PR:
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/macros/same-sequence-span.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ LL | $(= $z:tt)*
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
--> $DIR/same-sequence-span.rs:19:1
|
LL | | }
| |_________________________________^ not allowed after `expr` fragments
LL |
LL | | (1 $x:expr $($y:tt,)*
| |______________________________________________^ not allowed after `expr` fragments
...
LL | proc_macro_sequence::make_foo!();
| ^-------------------------------
| |
Expand Down
32 changes: 0 additions & 32 deletions tests/ui/proc-macro/auxiliary/custom-quote.rs

This file was deleted.

10 changes: 1 addition & 9 deletions tests/ui/proc-macro/auxiliary/span-from-proc-macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#![crate_type = "proc-macro"]

extern crate proc_macro;
extern crate custom_quote;

use proc_macro::{quote, TokenStream};

Expand All @@ -15,21 +14,14 @@ macro_rules! expand_to_quote {
quote! {
let bang_error: bool = 25;
}
}
};
}

#[proc_macro]
pub fn error_from_bang(_input: TokenStream) -> TokenStream {
expand_to_quote!()
}

#[proc_macro]
pub fn other_error_from_bang(_input: TokenStream) -> TokenStream {
custom_quote::custom_quote! {
my_ident
}
}

#[proc_macro_attribute]
pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream {
quote! {
Expand Down
Loading
Loading