# Rustdoc hiding important bounds

**URL:** https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753
**Category:** documentation
**Created:** [November 16, 2022, 8:50am UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753 "2022-11-16T08:50:42Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![2e71828](https://avatars.discourse-cdn.com/v4/letter/2/3e96dc/32.png) [@2e71828](https://internals.rust-lang.org/u/2e71828)
#### Post date: [November 16, 2022, 8:50am UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/1 "2022-11-16T08:50:42Z")

</div>

I was playing around with some `HashMap` trait object silliness, so I went to the docs to find out the necessary bounds for [`HashMap::insert()`](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.insert). To my surprise, it appears that there are no bounds on `K` at all.

In practice, of course, there are (`Hash + Eq`), but the only mention of them is [hidden in the middle of the page](https://doc.rust-lang.org/std/collections/struct.HashMap.html#impl-HashMap%3CK%2C%20V%2C%20S%3E-1). Is there some way we could make this sort of _de facto_ required bound more prominent, even if it's not strictly required for all methods?

---

<div class="post-metadata">

### Author: ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)
#### Post date: [November 16, 2022, 9:15am UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/2 "2022-11-16T09:15:21Z")

</div>

I too would appreciate a way to keep the `impl` block around a list of methods more visible. I’m not deeply familiar with what is or isn’t easily possible in HTML, but I would appreciate e.g. if the

```rust
impl<K, V, S> HashMap<K, V, S>
where
    K: Eq + Hash,
    S: BuildHasher,

```

would stay visible at the top of the page (similar to a top menu), and scrolling would happen inside of the `impl` block, as long as you are inside of that `impl`, only disappearing e.g. once the (start of the) last item leaves the page.

E.g. for

```nohighlight
... previous
... items
... contents
impl Foo {
    fn first_method()
    ... method
    ... documentation
    fn second_method()
    ... method
    ... documentation
    fn third_method()
    ... method
    ... documentation
}
... next
... items
... contents

```

a 6-line scroll area should animate roughly as follows:

```nohighlight
... previous
... items
... contents
impl Foo {
    fn first_method()
    ... method

```

```nohighlight
... items
... contents
impl Foo {
    fn first_method()
    ... method
    ... documentation

```

```nohighlight
... contents
impl Foo {
    fn first_method()
    ... method
    ... documentation
    fn second_method()

```

```nohighlight
impl Foo {
    fn first_method()
    ... method
    ... documentation
    fn second_method()
    ... method

```

```nohighlight
impl Foo {
    ... method
    ... documentation
    fn second_method()
    ... method
    ... documentation

```

```nohighlight
impl Foo {
    ... documentation
    fn second_method()
    ... method
    ... documentation
    fn third_method()

```

```nohighlight
impl Foo {
    fn second_method()
    ... method
    ... documentation
    fn third_method()
    ... method

```

```nohighlight
impl Foo {
    ... method
    ... documentation
    fn third_method()
    ... method
    ... documentation

```

```nohighlight
impl Foo {
    ... documentation
    fn third_method()
    ... method
    ... documentation
}

```

```nohighlight
impl Foo {
    fn third_method()
    ... method
    ... documentation
}
... next

```

```nohighlight
    fn third_method()
    ... method
    ... documentation
}
... next
... items

```

```nohighlight
    ... method
    ... documentation
}
... next
... items
... contents

```

(above, the `impl Foo` line starts disappearing as soon as the _beginning_ of the last item, i.e. `fn third_method()`, has reached the top of the screen)

---

<div class="post-metadata">

### Author: ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)
#### Post date: [November 16, 2022, 9:58am UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/3 "2022-11-16T09:58:06Z")

</div>

That should be possible with [position: sticky](https://developer.mozilla.org/en-US/docs/Web/CSS/position).

---

<div class="post-metadata">

### Author: ![notriddle](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/notriddle/32/14082_2.png) [@notriddle](https://internals.rust-lang.org/u/notriddle)
#### Post date: [November 16, 2022, 4:19pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/4 "2022-11-16T16:19:49Z")

</div>

I'd rather just make the generic types link to the impl block where they're defined, like this:

> pub fn [insert](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.insert)(&mut self, k: [K](https://doc.rust-lang.org/std/collections/struct.HashMap.html#impl-HashMap%3CK%2C%20V%2C%20RandomState%3E), v: [V](https://doc.rust-lang.org/std/collections/struct.HashMap.html#impl-HashMap%3CK%2C%20V%2C%20RandomState%3E)) -\> [Option](https://doc.rust-lang.org/std/option/enum.Option.html)\<V\>

The problem with using a sticky header is that we don't know how tall it needs to be. If it's too tall, [there won't be enough space](https://www.nngroup.com/articles/sticky-headers/) for the scrolled content, but if it's truncated, it's the `where` clauses, the most important information, that will be removed.

Also, [scroll-margin-top](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-margin-top) requires a specified height to make sure anchor links work correctly.

---

<div class="post-metadata">

### Author: ![tczajka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tczajka/32/8923_2.png) [@tczajka](https://internals.rust-lang.org/u/tczajka)
#### Post date: [November 16, 2022, 5:48pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/5 "2022-11-16T17:48:31Z")

</div>

I think it would be good if Rustdoc normalized everything so that equivalent things show up the same way, regardless of how they are written in the source code.

In this case, the bounds would show up with each method affected rather than on the impl. I think there shouldn't be separate impl blocks in the docs for inherent methods.

In my own libraries, I often have inherent method implementations spread out in separate modules (typically with the same bounds or no bounds), which should be invisible to users. But this causes rustdoc to split the documentation into those impl blocks.

Getting rid of separate impl blocks would also allow listing inherent methods in the same alphabetical order as the appear in the navigation menu on the left.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [November 16, 2022, 6:04pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/6 "2022-11-16T18:04:39Z")

</div>

> [@tczajka](#):
>
> In this case, the bounds would show up with each method affected rather than on the impl. I think there shouldn't be separate impl blocks in the docs for inherent methods.

👍 for this. Whether it's an impl block with bounds or a boundless impl block with bounds on the `fn` doesn't really matter to the consumer. TBH I'm not sure why it seems common (at least in the standard library) to add one-item impl blocks with different bounds instead of just putting the bounds on the method.

> [@tczajka](#):
>
> Getting rid of separate impl blocks would also allow listing inherent methods in the same alphabetical order as the appear in the navigation menu on the left.

`impl` blocks can be commented, which is part of why they're replicated into the the rustdoc.

Also, it can be considered a positive that things aren't in the same order. The left menu is an index, where alphabetical makes sense as a way to find things. But in the body of the page, allowing the code author to put things in a meaningful order is also a good thing -- especially when there are method variants with prefixes.

---

<div class="post-metadata">

### Author: ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)
#### Post date: [November 16, 2022, 6:07pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/7 "2022-11-16T18:07:11Z")

</div>

> The problem with using a sticky header is that we don't know how tall it needs to be.

This is a general problem with rustdoc that it doesn't use available horizontal space and instead reformats stuff vertically by default. Which leads to this problem and [others](https://internals.rust-lang.org/t/javadoc-skin/17678/3). I don't get the current design decisions behind rustdoc. Did I miss some trend where people started coding on their smartphones?

---

<div class="post-metadata">

### Author: ![tczajka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tczajka/32/8923_2.png) [@tczajka](https://internals.rust-lang.org/u/tczajka)
#### Post date: [November 16, 2022, 6:10pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/8 "2022-11-16T18:10:15Z")

</div>

> [@scottmcm](#):
>
> `impl` blocks can be commented, which is part of why they're replicated into the the rustdoc.

True, but probably unusual. At least in the common case without multiple different comments it could merge these.

> [@scottmcm](#):
>
> Also, it can be considered a positive that things aren't in the same order. The left menu is an index, where alphabetical makes sense as a way to find things. But in the body of the page, allowing the code author to put things in a meaningful order is also a good thing -- especially when there are method variants with prefixes.

I can see this rationale in theory, but in practice I have found it more annoying than useful that the orders are different. If you try to scroll through the page to find something rather than clicking (which should make sense given it's all on one page) you never know which way to scroll.

---

<div class="post-metadata">

### Author: ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)
#### Post date: [November 16, 2022, 8:10pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/9 "2022-11-16T20:10:44Z")

</div>

It definitely seems like adjacent uncommented `impl` blocks with the same bounds could be trivially merged without causing any issues.

The big thing that having the method order follow source order allows is putting all constructors at the top. I find it very useful when I'm trying to figure out how to make some type that normally I can just collapse-all then inspect the signatures of the top few associated functions.

---

<div class="post-metadata">

### Author: ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)
#### Post date: [November 16, 2022, 8:17pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/10 "2022-11-16T20:17:10Z")

</div>

> [@the8472](#):
>
> [rustdoc] doesn't use available horizontal space and instead reformats stuff vertically by default.

Take this with a grain of salt, etc., but FWIW,

It's generally considered good design to limit content width. For the same reason we wrap code at N characters, actually—we're surprisingly bad at consuming text with long lines. Most typographers recommend a body text width of ~80\[1\] characters\[2\] for legibility.

It's not just the ability to side-by-side multiple windows. But actually, I often _do_ use rustdoc (and other reference sites) with a narrow side-by-side window, rather than a 16:9\[3\] window. In fact, web resources is actually why I keep my second monitor portrait; it's a much more comfortable experience to to browse any "document-like" resources with the narrower layout.

In order to take efficient advantage of the width of modern displays, you need a multiple-column layout. To a first order of approximation, though, using multiple browser windows is a very good way to utilize the space, and it's very difficult for an individual website to beat that, especially when it needs to support the narrow layout anyway.

> [@tczajka](#):
>
> I can see this rationale in theory, but in practice I have found it more annoying than useful that the orders are different.

It really differs based on how much thought the crate author put into the organization. Personally I think it's very useful that e.g. `new` and other construction functions are typically presented first.

If the implementation puts little thought into the documentation presentation (or is broken across multiple files, where controlling ordering between impl blocks is opaque at best\[4\]), though, I agree that representing the implementation happenstance isn't helpful to the documentation.

There's no silver bullet here. The current ordering is biased towards "exploratory" docs usage, where grouping related functionality and presenting it "in reading order" is beneficial. For reference usage, there's the sidebar, but it's not ideal since e.g. it lacks any signature information.

It's a hard problem to solve. Rustdoc is at the end of the day for API reference documentation, but at the same time it's also the most accurate way to get an overview of "what is this type used for," especially due to the culture of examples.

IMHO, rustdoc is kinda stuck in a local maximum. I don't know how much better it's possible to do with in-source annotation, though, and the further documentation is separated from the code the harder it is to keep it in sync.

* * *

1. Of course, guidelines vary. What seems to be the [most well cited literature review](https://eric.ed.gov/?id=EJ749012) suggests 50–75 characters (roughly 30–50em) as the ideal band. 

2. For English, anyway. I unfortunately lack the resources to find if anyone's done similar research into ideal text width for other languages. It's definitely an interesting topic, but not a flashy one. 

3. 🤓 Minus the browser and OS chrome, of course. 

4. IIRC it's based on the source order if all `mod` were inlined.

---

<div class="post-metadata">

### Author: ![the8472](https://avatars.discourse-cdn.com/v4/letter/t/0ea827/32.png) [@the8472](https://internals.rust-lang.org/u/the8472)
#### Post date: [November 16, 2022, 9:54pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/11 "2022-11-16T21:54:03Z")

</div>

> [@CAD97](#):
>
> Take this with a grain of salt, etc., but FWIW,
> 
> It's generally considered good design to limit content width. For the same reason we wrap code at N characters, actually—we're surprisingly bad at consuming text with long lines. Most typographers recommend a body text width of ~80[[1]](#footnote-116641-1)
> 
> characters[[2]](#footnote-116641-2)
> 
> for legibility.
> 
> It's not just the ability to side-by-side multiple windows. But actually, I often _do_ use rustdoc (and other reference sites) with a narrow side-by-side window, rather than a 16:9[[3]](#footnote-116641-3)
> 
> window. In fact, web resources is actually why I keep my second monitor portrait; it's a much more comfortable experience to to browse any "document-like" resources with the narrower layout.
> 
> In order to take efficient advantage of the width of modern displays, you need a multiple-column layout. To a first order of approximation, though, using multiple browser windows is a very good way to utilize the space, and it's very difficult for an individual website to beat that, especially when it needs to support the narrow layout anyway.

Well that might be true for some people when reading paragraphs of text. But even for text I personally prefer reading wikipedia on fullscreen, not the mobile layout. That's mostly because all the boxes take up even more horizontal space. If they used the margins for infoboxes or to bring footnotes closer to the section referencing them like gwern's site does that would be a different story.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/5/578d70b3a5b5c9cdf49e32b6487cfe1a1e64d8b3.png)

But the bulk of API documentation isn't continuous text it's quite structured and could benefit from a more grid-like, columnar layout that's used when there's enough screen estate. And I don't mean newspaper-style multi-column layout, I mean aligning different kinds of information horizontally.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/4/4b4d1048d7da725f0b2ac378865b3fa8d4718063.png)

See, there's not just the red space wasted. If we're specifically talking about where-clauses then it's also wasting the green space.

Compare to java

 ![image](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/f/f7b5e6e779499740bacb68ad1aba76ccd90ece4b.png)

The current layout may be fine for people with small windows on a single screen. But it doesn't work well when you bring up documentation fullscreen on a separate monitor.

> especially when it needs to support the narrow layout anyway.

Well, different layouts can be applied based on window width. The javadoc table linked above is not actually a table, it's a grid that folds in the last column on smaller widths

 ![image](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/b/b62361bbad4b2f97b33653ed50ee23410b75c2ef.png)

---

<div class="post-metadata">

### Author: ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)
#### Post date: [November 20, 2022, 8:46am UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/12 "2022-11-20T08:46:20Z")

</div>

> [@notriddle](#):
>
> The problem with using a sticky header is that we don't know how tall it needs to be. If it's too tall, [there won't be enough space](https://www.nngroup.com/articles/sticky-headers/) for the scrolled content, but if it's truncated, it's the `where` clauses, the most important information, that will be removed.

As mentioned before, I have no intuition about what is or isn’t possible with HTML/CSS easily, but I can imagine solutions to the “not enough space” problem without killing the sticky header entirely, namely

- the sticky-header-based design could be limited to display sizes of some appropriate minimal size
- for particularly long where clauses that don’t fit the screen size, the where clause could collapse and only be shown when expanded with a button and/or by hovering maybe; the expanded where clause could then be a temporary pop-up / overlay over the contents below

* * *

With the second idea in mind, a minimal and definitely possible _easy_ improvement could be to offer some button to click (or hover) in order to show an overlay with (a copy of) the entire `impl` block and its where clause for every item in an `impl` block. Perhaps comparable in design to the already existing “notable traits” information. Hovering over or clicking some on-screen button seems infinitely better than the status quo of needing to scroll up an unknown distance (and afterwards find your way back down to the item).

_For anyone unfamiliar with the “notable traits” information, here’s a screenshot:_

 ![Screenshot_20221120_174656](https://us1.discourse-cdn.com/flex002/uploads/rustlang/original/2X/e/e42b477b2772ad87c81a33e8e961338bae4316ff.png)

---

<div class="post-metadata">

### Author: ![notriddle](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/notriddle/32/14082_2.png) [@notriddle](https://internals.rust-lang.org/u/notriddle)
#### Post date: [November 20, 2022, 7:07pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/13 "2022-11-20T19:07:34Z")

</div>

Any problem can be solved by adding another button, except having too many buttons.

Could this be fixed by adding to the existing notable trait popover, and making it a general info box?

---

<div class="post-metadata">

### Author: ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)
#### Post date: [February 18, 2023, 7:07pm UTC](https://internals.rust-lang.org/t/rustdoc-hiding-important-bounds/17753/14 "2023-02-18T19:07:54Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
