Documentation of types, discoverability problem

I'm reading about:

and as a first example I see:

[...]
reader.read_line(&mut line)?;
[...]

Then I am trying to find that function read_line at the left of the documentation, but it is not listed there!!!
I finally found it, but tbh, discoveribility of functions one can use with type is at the moment poor. It could be better if there (at the left side of documentation page for a type/trait, whatever) was a section called let's say "inherited" which would list all the functions that we are able to use with the type and those functions are coming from other traits that type implements.

First, that link goes to the rustdocs for Rust 1.39.0, which is several versions out of date at this point (the current stable release is 1.48.0) -- you can get the latest docs by replacing 1.39.0 with stable or beta or nightly in the URL. Sometimes search engines will point you to outdated docs, so it's useful to be in the habit of checking the version like this.

Anyway, I agree that it can be hard to discover callable methods for a particular type that come from trait impls. If you have a specific method name in mind, like in this case, you can type it in the search box:

And the second result there sends you to the right place.

Also, if you go to the "Trait Implementations" section of the BufReader page, you can click [+] just to the left of each impl, and then again next to "Show hidden undocumented items", to see the list of associated items available from that trait. (Although this isn't much fun if there are a lot of impls to go through -- the search box is much more helpful in that case.)

1 Like

Hi and thank you for the answer.

Doesn't "undocumented" means that I shouldn't be using it really? Because that's normally the case in other documentations. Undocumented means generally that one shouldn't be using it, because it may be removed/changed whatever...

In this case, it means that the implementation block is undocumented. The trait methods themselves, however, are documented in the trait’s definition (and that’s the documentation that appears when you expand the message).

Crate authors are supposed to use a breaking-change version number bump when removing a public trait implementation, but AFAIK there’s no mechanical enforcement of that.

2 Likes

Yes, this is a slightly unfortunate feature of rustdoc -- impl Trait for Type blocks are usually not themselves documented, to avoid having M * N * P mostly trivial documentation strings for M types that each implement N traits, each of which has P items.

(@piter76 you can absolutely rely on the standard library maintainers not to remove any public trait implementations without at minimum a new language edition. They take this stuff very seriously.)

1 Like

You should not feel worried about using the trait methods. They will absolutely not be changed or removed in the future as the standard library has very strict backwards compatibility guarantees. I agree that this part of the documentation is unfortunate.

Rustdoc should absolutely not hide trait impls like that, it's more than just unfortunate and presents a really big discoverability problem. Rustdoc should autoderive impl docs from the corresponding trait item doc or at least provide a link to the parent doc, or implementors should be able to use a special doc tag or attribute to either link to or inherit parent doc, the way Javadoc has @see and @inheritDoc tags (note that Javadoc auto-inherits docs; @inheritDoc is mostly for when you want the parent doc verbatim but also write additional implementor-specific docs). This is especially important in the case of basic vocabulary types/traits/impls like File/Read/Write.

It does provide a link to the parent doc. Clicking on the trait name anywhere it appears will send you to the main documentation page for the trait. All the “show hidden” button does is list the trait’s methods inline (or maybe just the overridden ones; I’m not sure).

The big problem I anticipate with changing rustdoc to include trait methods on the page for a type is that the vast majority of traits implemented for any given type are irrelevant to the average reader, and some may be named the same as other trait methods, or as inherent methods of the type, which would just make it more confusing.

For example, including Read methods for BufReader probably makes sense because Read is relevant to the majority of people using BufReader. But including Borrow methods for RefCell would just be confusing because the Borrow trait has a method named borrow that does something different than the borrow method on RefCell (and RefCell<T> implements Borrow<RefCell<T>>). There's (at present) no real way to distinguish between "probably relevant" and "probably irrelevant and maybe confusing" implementations.

5 Likes

Yes, but in general people familiarizing themselves with an API don't care about traits implemented, at all. They care about functions, methods, and other items provided. It's only when you're more familiar with the API that traits become a useful mental shortcut ("Ah, this implements Read! I know what I can do with it.")

Perhaps traits marked with the #[doc(spotlight)] attribute should be expanded by default, and this attribute could be added to the BufRead and BufWrite traits. Or there could be a similar #[doc] attribute for specific impls that should be expanded/spotlighted.

7 Likes

Also, in case we ever get inherent trait implementations the methods from those should feature prominently in the documentation.

2 Likes

The edition change can NOT break the stdlib compatibility. The edition mechanism is to make possibly breaking change to the syntax not library APIs. There's only single version of stdlib linked to the binary across the editions, otherwise you can't pass stdlib types between crates with different editions.

3 Likes

Issue on rust rustdoc "expand all docs" button does not expand "hidden undocumented items" · Issue #56073 · rust-lang/rust · GitHub