-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Serialize additional data for procedural macros #63269
Conversation
r? @zackmdavis (rust_highfive has picked a reviewer for you, use r? to override) |
r? @eddyb |
Oh no. |
|
||
/// Whether or not this crate should be consider a private dependency | ||
/// for purposes of the 'exported_private_dependencies' lint | ||
pub private_dep: bool | ||
} | ||
|
||
pub struct FullProcMacro { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe call this ProcMacroDef
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's already a struct called ProcMacroDef
in src/libsyntax_ext/proc_macro_harness.rs
. I didn't want to have two different structs with the same name.
src/librustc_metadata/schema.rs
Outdated
/// This needs to come before 'def_path_table', | ||
/// as we need use data from it when decoding `def_path_table. | ||
/// This also needs to come at the very end of the 'Lazy/LazySeq' data, | ||
/// as we need all of the other data in order to deserialize it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last two lines here don't make sense: a Lazy
/LazySeq
is just an offset into the file (hence "lazy"), so the order doesn't matter at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant to refer to the encoding order, which does matter. However, now that I lazily deserialize the proc macros, it doesn't matter.
src/librustc_metadata/schema.rs
Outdated
/// This also needs to come at the very end of the 'Lazy/LazySeq' data, | ||
/// as we need all of the other data in order to deserialize it | ||
pub proc_macro_data: Option<LazySeq<ProcMacroData>>, | ||
pub def_path_table: Lazy<hir::map::definitions::DefPathTable>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to move this.
src/librustc_metadata/creader.rs
Outdated
// that's *almost* complete - it's just missing 'proc_macros' and 'def_path_table'. | ||
// We then deserialize 'proc_macros' and 'def_path_table', using (cmeta, self.sess) | ||
// as our deserializer. Then, we replace the dummy 'proc_macros' and 'def_path_table' | ||
// with the data we just deserialized. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct solution is to make loading the proc macros lazy.
src/librustc_metadata/creader.rs
Outdated
@@ -581,8 +597,10 @@ impl<'a> CrateLoader<'a> { | |||
/// implemented as dynamic libraries, but we have a possible future where | |||
/// custom derive (and other macro-1.1 style features) are implemented via | |||
/// executables and custom IPC. | |||
fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, span: Span) | |||
-> Vec<(ast::Name, Lrc<SyntaxExtension>)> { | |||
fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, span: Span, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, this should be load_proc_macros
nowadays.
src/librustc_metadata/cstore_impl.rs
Outdated
@@ -203,11 +203,6 @@ provide! { <'tcx> tcx, def_id, other, cdata, | |||
DefId { krate: def_id.krate, index } | |||
}) | |||
} | |||
proc_macro_decls_static => { | |||
cdata.root.proc_macro_decls_static.map(|index| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand, this was supposed to be used to compute the symbol name, what happened to that?
src/libsyntax/ast.rs
Outdated
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] | ||
pub struct ProcMacroInfo { | ||
pub span: Span, | ||
pub attrs: Vec<Attribute> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petrochenkov This is the part I was r?-ing you for but it's simpler than I initially thought.
proc_macro_infos.borrow_mut().push(ProcMacroInfo { | ||
span: cd.span, | ||
attrs: cd.raw_attrs.clone() | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petrochenkov I guess this is what I want to make sure you have nothing against.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something I have a lot against, actually.
Aren't fn
items encoded into the metadata already (including spans and attributes)?
As I understand it, a compiled proc macro crate has two views - the "regular" one with the original fn
items and everything, and the "proc-macro facade" one masking all the original items and making it look like the crate only exposes macros.
So we just need to link from the proc-macro view (CrateMetadata::proc_macros
) to the real items somehow instead of cloning some data from those items, keeping them in AST and encoding them for the second time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, we'd just need to map the DefId's.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to unconditionally decode and store the 'real' def_path_table
, but continue to use a 'fake' table for most operations on proc macro crates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose, yeah. At this point I'm not sure why we don't use the original DefId
s directly, and just change what def_kind
returns?
src/librustc_metadata/cstore_impl.rs
Outdated
@@ -427,7 +422,7 @@ impl cstore::CStore { | |||
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { | |||
let data = self.get_crate_data(id.krate); | |||
if let Some(ref proc_macros) = data.proc_macros { | |||
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); | |||
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].ext.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petrochenkov Does this need to be cached, or could the ext
be loaded here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolver already has a cache for this (macro_map
in fn get_macro_by_def_id
), so load_macro_untracked
can just load the extension from metadata.
src/librustc_metadata/decoder.rs
Outdated
return Lrc::new([]); | ||
return Lrc::from( | ||
self.proc_macros.as_ref().unwrap()[node_id.to_proc_macro_index()].attrs | ||
.clone() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could have attributes be lazy, like a regular Entry
.
src/librustc_metadata/creader.rs
Outdated
macros.len(), decls.len()); | ||
} | ||
|
||
let extensions = macros.zip(decls.iter()).map(|(proc_macro, &decl) | { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think CrateMetadata
should hold onto decls
(as a &'static [ProcMacro]
) rather than the FullProcMacro
s.
☔ The latest upstream changes (presumably #63469) made this pull request unmergeable. Please resolve the merge conflicts. |
ab06344
to
1aed667
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
@eddyb: I've made the changes you requested. |
463147c
to
73d7719
Compare
@petrochenkov: Squashed |
@bors r=eddyb,petrochenkov |
📌 Commit 73d7719 has been approved by |
…r=eddyb,petrochenkov Serialize additional data for procedural macros Split off from rust-lang#62855 This PR serializes the declaration `Span` and attributes for all procedural macros. This allows Rustdoc to properly render doc comments and source links when performing inlinig procedural macros across crates
Failed in #63653 (comment), @bors r- (Known by process of elimination as #63655 excluded that PR and it is working.) |
Split off from rust-lang#62855 This PR deerializes the declaration `Span` and attributes for all procedural macros from their underlying function definitions. This allows Rustdoc to properly render doc comments and source links when inlining procedural macros across crates
73d7719
to
64f867a
Compare
@petrochenkov: I had accidentally removed this check. The build should now pass. |
@bors r=eddyb,petrochenkov |
📌 Commit 64f867a has been approved by |
…rochenkov Serialize additional data for procedural macros Split off from #62855 This PR serializes the declaration `Span` and attributes for all procedural macros. This allows Rustdoc to properly render doc comments and source links when performing inlinig procedural macros across crates
@petrochenkov in #63269 (comment):
I've ranted about this before but I'm not sure if in this thread or on Discord. If you look at what that rust/src/libproc_macro/bridge/client.rs Lines 325 to 448 in ef1ecbe
|
☀️ Test successful - checks-azure |
Propagate spans and attributes from proc macro definitions Thanks to rust-lang#63269 we now have spans and attributes from proc macro definitions available in metadata. However, that PR didn't actually put them into use! This PR finishes that work. Attributes `rustc_macro_transparency`, `allow_internal_unstable`, `allow_internal_unsafe`, `local_inner_macros`, `rustc_builtin_macro`, `stable`, `unstable`, `rustc_deprecated`, `deprecated` now have effect when applied to proc macro definition functions. From those attributes only `deprecated` is both stable and supposed to be used in new code. (`#![staged_api]` still cannot be used in proc macro crates for unrelated reasons though.) `Span::def_site` from the proc macro API now returns the correct location of the proc macro definition. Also, I made a mistake in rust-lang#63269 (comment), loaded proc macros didn't actually use the resolver cache. This PR fixes the caching issue, now proc macros go through the `Resolver::macro_map` cache as well. (Also, the first commit turns `proc_macro::quote` into a regular built-in macro to reduce the number of places where `SyntaxExtension`s need to be manually created.)
Propagate spans and attributes from proc macro definitions Thanks to rust-lang#63269 we now have spans and attributes from proc macro definitions available in metadata. However, that PR didn't actually put them into use! This PR finishes that work. Attributes `rustc_macro_transparency`, `allow_internal_unstable`, `allow_internal_unsafe`, `local_inner_macros`, `rustc_builtin_macro`, `stable`, `unstable`, `rustc_deprecated`, `deprecated` now have effect when applied to proc macro definition functions. From those attributes only `deprecated` is both stable and supposed to be used in new code. (`#![staged_api]` still cannot be used in proc macro crates for unrelated reasons though.) `Span::def_site` from the proc macro API now returns the correct location of the proc macro definition. Also, I made a mistake in rust-lang#63269 (comment), loaded proc macros didn't actually use the resolver cache. This PR fixes the caching issue, now proc macros go through the `Resolver::macro_map` cache as well. (Also, the first commit turns `proc_macro::quote` into a regular built-in macro to reduce the number of places where `SyntaxExtension`s need to be manually created.)
Split off from #62855
This PR serializes the declaration
Span
and attributes for allprocedural macros. This allows Rustdoc to properly render doc comments
and source links when performing inlinig procedural macros across crates