-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
[rustdoc] Have a more nuanced take on what is hidden by default #82114
Comments
The traits were the original reason why we added the possibility to change the settings. As far as I can tell, it's the same methods' header, but maybe I missed something? If not, I'm not sure to see how it would improve anything. As for the rest, why not! |
Another way to solve the problem: #81977 |
Hi, I'm the person linked on Twitter-- my perspective is that I am learning Rust and the first time I looked at |
Honestly yes I think @camelid 's suggestion would help. Since the name up top looks like a "header" for the entire document, it is natural that we should expect "T" to be reused again and again in the same way throughout the same page if it is in that "header" name. But it is not so obvious to me that if in a hideable (hidden by default...) section at the top you define a T within a { bracket } section you then close again, that every T throughout the page should be expected to be that T from the { brackets } at the top (if that way of putting it makes sense). |
I would rather show the trait definition by default than show the generic parameters. Showing the parameters won't help much for associated items, and could get overwhelming if there are a lot of parameters. |
Sorry, I'm not sure to fully understand what you mean. In #81977, it's suggested that we add the generics in the "title" but also in the fields/variants. I thought that your issue was that currently, those generics were only visible in the hidden section. If so, wouldn't #81977 fix this problem? If I'm completely off the plate, more explanations of your problem are welcome. :) |
That is a good point too. If possible, I'd prefer to not have the trait definition displayed by default. Just look at Iterator, it's (in my opinion) far too big to be really useful. As a reminder: we hid the traits' definition by default in the first place because people complained about it. |
Do you have a link to that discussion? It was before I joined the team. |
Time for speleology! |
This is kinda what I'm getting at with "nuanced take". What did people actually complain about, trait definitions or I actually think our current situation with a bunch of prefs for kinds of items is suboptimal, I think we should have the prefs, but perhaps have better takes on what the defaults should be, takes that are not just based on the types of items. |
That seems reasonable indeed. But on big items, wouldn't the missing generics information still be an issue? |
What about still showing the definition, but skipping associated items if there are more than e.g. 3 of them? Remove the option for toggling the whole definition and allow toggling the associated items instead. |
@GuillaumeGomez i think generics can be solved with @camelid's proposal @jyn514 something like that ,yeah. we should figure out exactly where the configurability should lie, but i'll point out: not everything needs to be completely configurable |
It might also be nice to use thresholds on required vs optional parts, so for instance pub trait Iterator {
type Item;
pub fn next(&mut self) -> Option<Self::Item>;
... optional methods ...
} and have the "expand to full" show all the optional/provided methods? |
I think the discussion was mostly offline based on the comments from #49412... Do you remember it maybe @Manishearth?
@jyn514 pointed out that it might be an issue in case there are a lot of generics, and I think it's a good point that we need to examine.
Agreed. @porglezomp This is a bit ahead of the conversation but yes, something like that could be nice. |
@porglezomp oh that's clever, yeah. Though.... optional/provided only really matters for implementors, right? Might be confusing if the optional method is what people are primarily expected to use. It's worth drilling down to see what different people need to see. Like, as a user of iterator, I absolutely don't care about But there are smaller traits like I think switching to collapsing based on size rather than type is probably the core thing we need to do here. |
Possibility to consider: "This definition is large and has been collapsed. Click here to expand" with some heuristic for the size. Might not be perfect, but could be 1. improvement over the status quo 2. a more flexible solution than trying to decide based on type |
Actually, I think I haven't been thinking enough out of the box here. Why do we need to collapse the entire declaration in the first place? This seems more useful as a default for everything, structs, etc. Always show the declaration, hide public fields if there are too many, hide methods if there are too many, hide methods and assoc items if you really really have to. It's way more obvious that there's an expandable thing here, as opposed to the current state where if you don't notice the + you won't be able to see the impl. |
Instead of showing everything except provided methods, we could hide all associated functions and only show associated types and constants since there are usually only a few. EDIT: Manish and I had the same idea at the same time 😆 |
Isn't there already a section for associated types and constants?
Yeah, that is one limitation. Another alternative is to have a section at the top of the page with all the generics. But if we're going that route, just showing a trimmed-down definition would probably still be better. |
Only the traits have methods. The other types only have fields/variants, and in those cases, we have them with their documentation just under, so if we go this road, we might need to think about maybe updating that part too. Ideas are welcome! :) |
Right, uh, that's what I'm saying, we should be applying this logic to everything. To be more explicit:
|
I would treat unions the same as enums.
Right now we show the pretty-printed initializer expression, I haven't heard complaints about it. |
What about enums with few variants, but many fields in each variant?
Unions are much closer to structs than enums, they have typed members instead of variants (each of which can be a struct-like-variant). |
A couple of thoughts— I recognize that you've spun off into some kind of other discussion that isn't specifically about my experience getting confused by the docs. But if my beginner's perspective is helpful—
|
Thanks for the feedback!
Yeah I'd explicitly started this discussion as a "we need to solve this problem in general" with your specific example as a motivator but not the focus
This is the problem I'm hoping to solve by making the type declaration always be shown and have an explicit "expand this" thing:
So we're discussing that in #81977, but I'll point out that by making the type decl be always shown this problem is solved too.
Yeah this is why I don't want to ever completely hide the type declaration on the top |
PR up at #83337 |
Note that there's a lot of redundancy in showing the type declaration:
In the second line, "trait" and "iterator" are duplicates of information that's already in the first line, and "pub" is implicit in the fact that this is documentation. Also the trailing I think it makes sense for the declaration to include the body of the item, but not the
|
@jsha I'm not really in favor of that, it does look like redundancy, but it's not just type parameters -- it's also associated types, and attributes and such. Special casing all of those seems like it would be brittle. Furthermore, there's a lot of value in just showing the body as is, that's typically the most useful for me when I am quickly visiting an item. This is why I want to introduce a threshold, so that items large enough to push textual docs below the fold get collapsed, but otherwise they don't, and the only part which gets collapsed is the contents. It feels the most intuitive to show the declaration as Rust-like code as opposed to scattering it everywhere. I don't always think redundancy is bad. Title vs docblock seems pretty okay to me, and I don't think it's worth it to bend over backwards in order to get rid of the redundancy. |
Actually it's not implicit; some docs, such as the rustc API docs, use |
Associated types are inside the declaration, so would be shown without resorting to a special case. But yes, it's true about attributes. Worth noting, though, that the current experience for attributes is not good: Even if there's only one attribute, it gets hidden behind a toggle. Opening the toggle to see just one attribute makes me wonder "why was this hidden?"
Note that we already have a place where the full, exact Rust code is shown: the |
I think this would be a good followup to my PR. Currently rustdoc hides based on a binary of types of things, whereas IMO we should be doing based on what we think is worth hiding. Single attributes? No. Multiple? Maybe, picking some threshold. It's the same thing with my PR, I'm trying to move away from "hide structs" "hide enums" etc to "hide all kinds of things when they get too big".
No, because it's more clicks: If I'm perusing the docs I'm going to want to check out types with a single click, not having to look for src (and src isn't that discoverable) |
Great! By the way, how common is it for there to be enough attributes that we would need to hide them? I'm working on the CSS for your PR right now, and I think it might simplify things if we could say "attributes are never hidden." In my limited experience, I've only ever seen a single attribute. I know there can be more, but it seems quite rare that there would be so many they need hiding.
Definitely. And further on that theme: I think as a general rule, the toggles should not be nested (in the default set of open/closed settings). So if someone opens up a section to see detail, they should not have to open up additional sections within that section. This has the added benefit of reducing the DOM complexity somewhat. And it might wind up simplifying the CSS and JS a tiny amount.
I was proposing that the docs would look like:
In other words, a link rather than a toggle, so no additional clicks. But looking at the source I see a problem: the methods are all preceded by a long comment block, so it's hard to get a bird's-eye view of them. So consider this suggestion dropped. |
Probably pretty rare! I'm okay with taking this approach for now.
I think this makes sense in the case of attributes, but not as a general rule: for example we let you collapse impl blocks and also their individual contents and I think that's fine. |
For traits it's probably relatively rare to have a lot of attributes on the associated items, but I think the standard library tends to have several attributes on structs, enums, enum variants, and fields. For example, #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[rustc_diagnostic_item = "option_type"]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Option<T> {
/// No value
#[lang = "None"]
#[stable(feature = "rust1", since = "1.0.0")]
None,
/// Some value `T`
#[lang = "Some"]
#[stable(feature = "rust1", since = "1.0.0")]
Some(#[stable(feature = "rust1", since = "1.0.0")] T),
} However, we don't currently show attributes for stuff in types, so the declaration looks like this: If we ever start showing attributes for these, we might need more complex attribute-hiding behavior. |
Interesting. Is there special logic for omitting the attributes on enums? If you look at e.g. https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html, and hit "Show declaration," it has the attributes. |
I feel like I saw Manish say somewhere that he was going to fix that? |
It looks like we only render attributes for methods: rust/src/librustdoc/html/render/mod.rs Line 1043 in f811f14
Probably we just need to call |
Actually, it looks like there is a list of allowed attributes, and the attributes you point out on rust/src/librustdoc/html/render/mod.rs Lines 1095 to 1103 in f811f14
|
@camelid This has nothing to do with enums vs traits; we only show a small set of attributes. I think the only relevant attribute is |
https://twitter.com/mcclure111/status/1361025145125634061
By default, we:
I feel like traits probably should be shown by default, since everything on the trait is important, especially for implementors.
Furthermore, it might be worth splitting "structs" into "structs with all-public fields" and "structs with private fields" for the same reason (with unit structs being treated as having all public). For the former kind the actual struct declaration is super useful, for the latter kind it's not at all.
cc @rust-lang/rustdoc
The text was updated successfully, but these errors were encountered: