They use references.
Traits aren't the important part. The work is in creating a data strcture, we'll figure out how it can go into emtadata later.
Do you have some other examples of serializable structures you can point me to?
My idea for making parent
non-referential was to have one structure that stored all modules and store an index into that structure
something like this:
/// A `ModuleData` that is non self-referential
struct OwnedModuleData {
parent: Option<ModuleIndex>,
...
}
/// An opaque reference to an `OwnedModuleData`. To be used in conjunction with a `ModuleStore`.
struct ModuleIndex(usize);
/// A list of all modules needed to serialize a specific module
struct ModuleStore(Vec<OwnedModuleData>);
and all the structs with lifetime parameters aren't a big deal, it's only the references that matter
so that leaves
glob_importers: RefCell<Vec<&'a Import<'a>>>,
globs: RefCell<Vec<&'a Import<'a>>>,
// Used to memoize the traits in this module for faster searches through all traits in scope.
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>
From the comment it seems like traits
might not need to be stored? Since it's only a cache and can be recalculated?
Do you know why glob_importers
and globs
are RefCells?
update: this is why globs
is a RefCell: https://hastebin.com/gorakaqiha.coffeescript
and all the structs with lifetime parameters aren't a big deal, it's only the references that matter
This appears to be incorrect, I don't see any easy way to make any of these owned.
What if I narrowed the scope and instead only tried to serialize Resolutions
? I think that's all rustdoc really needs
unless i'm misunderstanding glob imports
oh well that has a &'a Import<'a>
anyway so I'd have to solve this problem sooner or later
I'm finding it really hard to understand the lifetimes because of all the RefCell
The type Module = &ModuleData
alias is convenient but means that all the mutability is forced to use refcell
I'm seeing something called ResolverOutputs
which has no borrows and looks like basically what we'd need, can I reuse that?
@Joshua Nelson Given your comments here and in the github thread I think you're overfocusing on the "serialize" part of it. The high level thing is that rustdoc needs to be able to resolve reexport documentation against their original module map, which is not available in cross-crate scenarios. Serializing is necessary to stick it into the rlib so we can get it back.
I don't think we actually should be trying to serialize the _entire_ Resolver. Rather, we should be reading it and producing a new type that _can_ be serialized. The traits
field is unnecessary. globs
kind of is, sadly.
You really need to talk to compiler team members about this, though.
I'm really confused how serialization is related at all, to be honest
The reason I keep focusing on it is I'm trying to find out how it's related
none of the changes I made in https://github.com/rust-lang/rust/pull/73101/ were related to serialization
also I might be confused - I thought you were a compiler team member? @Manish Goregaokar
ah ok you're part of the clippy team, that's why I was confused (plus core of course)
@Joshua Nelson I mentioned serialization because this is information downstream crates do not have, and the way for them to get it is through metadata, and to put something in metadata we need to be able to serialize it cross crate (so, no self references)
@Joshua Nelson it's not clear to me how that PR fixes this bug. The test case is:
// crate a:
pub struct Foo;
/// Link to [Foo]
pub struct Bar;
// crate b:
pub use a::Bar;
the docs for b::Bar
should link correctly to a::Foo
.
Yeah I've never been compiler team. I'm capable of reviewing for most of the compiler, and I understand the resolver, but not well enough for something like this.
this is what my PR outputs for that test case: image.png
the link is to /a/struct.Foo.html
.
I'm not sure how to add test cases with multiple crates, I can look into that
the reason my PR works is because it resolves types relative to the other crate (a
), not to the current crate (b
)
which is correct because the docs were written in a
, not in b
. So if we try to resolve relative to b
none of the same items will be in scope.
@Joshua Nelson huh, that surprises me. Does that even work when A and B are within some deeper modules (all public)?
I think I have a guess here as to what's happening: the ExportMap already has what we needed to some extent
@Joshua Nelson another test case would be to stick Bar in a private module, and re-export it from the top level, and have Foo in a public module with Bar using Foo
in docs with a use foomod::Foo
in scope.
Sounds good, I'll try that tomorrow
Also --no-deps
breaks things for reasons I don't understand
Only if the item wasn't inlined though? That's weird, that means it can be fixed in rustdoc though
Only if the item wasn't inlined though? That's weird, that means it can be fixed in rustdoc though
@Joshua Nelson oh btw i am not watching htis channel, i won't see things you don't ping me on