Pre-RFC: Superseding public/private dependencies

I think that reexport would be a better name for the key than pub.

FYI discussion has moved to the above linked RFC.

I will say that reexport is inaccurate. Its not always about re-export but an item being referenced, like a impl From<foreign::Error> for Error.

No problem! Sorry it took me so long to get back to you on this one.

When Rustdoc renders a type, it shows all of the applicable trait implementations for it. These are broken out into direct implementations, blanket implementations, and auto trait implementations. Direct implementations can only come from the current crate and its dependents, of course, but auto traits and blanket implementations can come from anywhere in the graph.

For example, GioFuture in gio - Rust demonstrates this very well: GioFuture implements Future from the standard library. As a result, it also shows an implementation of FutureExt, from the futures-util crate (which is a dependency of gio). If futures-util were a private dependency of gio, it would not show up there.

I logically know it's difficult (and breaks separate/ordered processing), but when generating local documentation (as opposed to docs-rs, where each crate is documented independently), I've wished before for blanket implementations to show up more. Specifically, when documenting locally, for all applicable trait implementations to show up on every type they're available on, no matter whether the trait is up/down/sidestream of the type. For a magically perfect picture, culling the set of documented crates to those reachable from a local/workspace crate and not documenting any unreachable/transitive dependency. (And somehow choosing a canonical location to inline the documentation of any items reëxported from unreachable crates.)

i.e. if I have in tree and am using futures-util, it seems opaquely random which crates' types in my locally generated docs show the extension trait in the docs. It has to be this way for independent crate documentation, but it's a strange inconsistency for local full tree docs. Only showing blanket impls for transitively-public dependencies does seem like it would make this a bit more predictable, at least, since private helper crates will show up in docs much more rarely.


--document-private-items should also result in documenting private deps' impls.

It's also interesting to consider what should happen when there's a local implementation for a claimed private dependency's trait. As an example, consider RefCast. (Assuming compilation doesn't outright forbid them,) I think rustdoc needs to show such an impl. At a minimum, it should be available (but maybe tagged doc(hidden)) in the docs metadata, so tools like semver-checks can see it.


Obviously core is a public dependency, as is std when not #![no_std]. But when should alloc be considered as a public dependency? Would it even ever make an observable difference to consider all three to be public dependencies on all targets they're available, independent of #![no_std]?

2 Likes

The best approach I see to this is adding the metadata to cargo so that you can set it explicitly just the same as other crates

[dependencies]
core = { search-path = true, public = true }
alloc = { search-path = true, public = true, optional = true }
std = { search-path = true, public = false, optional = true }
1 Like

It shouldn't matter?

As long as almost everything in alloc gets re-exported by std anyway, and as long as Rustdoc is smart enough to give std priority and not show duplicates, it shouldn't.

Yeah, there's a major weakness here.