# Pre-RFC: Stable rustdoc URLs

**URL:** https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099
**Category:** language design
**Created:** [September 18, 2020, 10:32pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099 "2020-09-18T22:32:24Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![dhm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/dhm/32/4879_2.png) [@dhm](https://internals.rust-lang.org/u/dhm)
#### Post date: [September 19, 2020, 1:33pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/21 "2020-09-19T13:33:58Z")

</div>

> [@elidupree](#):
>
> The trouble with `type` is that a trait is not a type.

I didn't think of traits; that makes `t` a neat way to avoid the issue altogether 😄

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [September 19, 2020, 1:42pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/22 "2020-09-19T13:42:25Z")

</div>

Yeah, if we combine this with your "omit the prefix for the value namespace" idea, it becomes:

- `t.Name.html` for traits and types (haha convenient), and theoretically modules, which are in the same namespace, except not actually because modules are subdirectories instead (haha convenient x2)
- `m.Name.html` for macros (seems fine)
- `name.html` for fns and `NAME.html` for consts and statics (seems fine)

which seems pretty reasonable.

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 19, 2020, 1:48pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/23 "2020-09-19T13:48:01Z")

</div>

Ok, I updated the post to use `t.Name`, `m.name`, and `name` respectively (with a mention of `type.` and `macro.` in the alternatives section). I also opened [https://github.com/rust-lang/rust/issues/76922](https://github.com/rust-lang/rust/issues/76922) and moved most of the naming conflict section there.

---

<div class="post-metadata">

### Author: ![camelid](https://avatars.discourse-cdn.com/v4/letter/c/c67d28/32.png) [@camelid](https://internals.rust-lang.org/u/camelid)
#### Post date: [September 19, 2020, 6:14pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/24 "2020-09-19T18:14:58Z")

</div>

> [@jyn514](#):
>
> Note that these names are easy to 'bikeshed' and don't substantially change the RFC.
> 
> - Rustdoc could add a `v.` prefix for items in the value namespace. This would be more consistent with the other namespaces, at the cost of making the URLs for functions slightly confusing (favoring criteria 2 over criteria 3).

Another reason to _not_ have a `v.` prefix is that the URL would be longer and noisier. Functions and values are very likely more common than types/traits and macros.

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [September 19, 2020, 6:22pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/25 "2020-09-19T18:22:21Z")

</div>

My personal experience is that I spend vastly more time looking at `struct` pages than at all other item pages put together. I'm technically looking at functions when I do that, but most of the important functions in Rust are struct methods.

---

<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: [September 19, 2020, 7:10pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/26 "2020-09-19T19:10:24Z")

</div>

> [@elidupree](#):
>
> It seems plausible that we might ultimately want to mangle _Unicode_ names in documentation URLs in order to be compatible with old filesystems; if we're going to do that, it might make sense for the "case insensitive name collision" mangling to use the same mangling scheme.

Either way, I think it makes sense for Unicode mangling into URLs to use [punycode](https://en.wikipedia.org/wiki/Punycode), as it's already used for domain names. (I'm not sure how browsers treat punycode not in the domain, however; they're probably required to not demangle outside of the domain name. But also they're moving away from showing anything other than the domain anyway, so...) Unfortunately, punycode (by design) is no help in encoding ASCII case information.

(edit after later post: @jyn514 sorry, my bad.)

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 19, 2020, 8:51pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/27 "2020-09-19T20:51:38Z")

</div>

Could you please move discussion on avoiding name collisions to the issue? These are great ideas but they're not super relevant to the RFC. [https://github.com/rust-lang/rust/issues/76922](https://github.com/rust-lang/rust/issues/76922)

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 20, 2020, 12:46pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/28 "2020-09-20T12:46:14Z")

</div>

I posted an RFC: [https://github.com/rust-lang/rfcs/pull/2988](https://github.com/rust-lang/rfcs/pull/2988). Thanks to everyone for the feedback, especially @elidupree and @dhm for getting some of the name bikeshedding done early 😉

---

<div class="post-metadata">

### Author: ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)
#### Post date: [September 20, 2020, 2:08pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/29 "2020-09-20T14:08:44Z")

</div>

> [@jyn514](#):
>
> However, Rustdoc does _not_ currently guarantee that making a semver-compatible change to your code will preserve the same URL. This means that, for instance, making a type an `enum` instead of a `struct` will change the URL, even if your change is in every other way semver-compatible.

Is that really semver-compatible though? Doesn't it break pattern matching? Even structs `Foo`, `Foo(..)`, and `Foo { .. }` are different in that regard.

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 20, 2020, 2:19pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/30 "2020-09-20T14:19:47Z")

</div>

Hmm, the specific use case in [https://github.com/rust-lang/rust/issues/55160](https://github.com/rust-lang/rust/issues/55160) was switching from a union to a struct. Can you pattern match on unions?

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [September 20, 2020, 2:28pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/31 "2020-09-20T14:28:03Z")

</div>

Ooooh, that is _nasty_. Even with all private fields, this code compiles:

```rust
mod foo {
    pub struct Foo {
        field: i32,
    }
}
use foo::Foo;

fn fooer(foo: foo::Foo) {
    let Foo { .. } = foo;
}

```

and thus Foo can't be changed into an enum without breaking compilation. (It _can_ be changed into a tuple-like struct, though, oddly enough?) I haven't thought of an example that prevents union-\>struct or union-\>enum though. And even enum-\>struct might be possible if the enum's variants were all `#[doc(hidden)]`.

Regardless, at the very least, it's clearly compatible to switch an item from any concrete type into a `pub use` or a type alias to that type. So we definitely need this RFC for _something_, and it doesn't seem especially valuable to try to _preserve_ the URL naming distinction between `struct`, `enum`, and `union`.

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 20, 2020, 2:37pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/32 "2020-09-20T14:37:04Z")

</div>

> it's clearly compatible to switch an item from any concrete type into a pub use or a type alias to that type

Oof, I knew I forgot something. I don't think rustdoc generates pages for type aliases currently, to support this it would have to.

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [September 20, 2020, 2:38pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/33 "2020-09-20T14:38:39Z")

</div>

It does - for example, [https://www.nalgebra.org/rustdoc/nalgebra/base/type.Vector2.html](https://www.nalgebra.org/rustdoc/nalgebra/base/type.Vector2.html)

---

<div class="post-metadata">

### Author: ![cuviper](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cuviper/32/1897_2.png) [@cuviper](https://internals.rust-lang.org/u/cuviper)
#### Post date: [September 20, 2020, 2:39pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/34 "2020-09-20T14:39:48Z")

</div>

> [@jyn514](#):
>
> Can you pattern match on unions?

It's `unsafe`, but otherwise yes:

> **[Unions - The Rust Reference](https://doc.rust-lang.org/reference/items/unions.html#pattern-matching-on-unions)**

> [@elidupree](#):
>
> (It _can_ be changed into a tuple-like struct, though, oddly enough?)

Huh, I didn't know that worked!

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [September 20, 2020, 2:55pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/35 "2020-09-20T14:55:36Z")

</div>

> [@cuviper](#):
>
> It's `unsafe` , but otherwise yes:

…but since pattern matching on unions is only possible if you specify exactly one field, it is _not_ possible for dependent crates to pattern match on a union with no public fields, which preserves the possibility of semver-compatible conversions from union to struct or enum.

---

<div class="post-metadata">

### Author: ![tanriol](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tanriol/32/2112_2.png) [@tanriol](https://internals.rust-lang.org/u/tanriol)
#### Post date: [September 23, 2020, 6:25pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/36 "2020-09-23T18:25:35Z")

</div>

There seems to be one more class of semver-compatible, but possibly link-breaking changes - replacement with reexports. There are at least a few kinds with different amount of problems caused

```rust
pub fn my_fn() { ... } // Before
pub use self::submod::my_fn; // After

pub fn my_fn() { ... } // Before
pub use self::submod::*; // After

pub mod my_mod {
    pub fn my_fn() { ... } // Before
}
pub use self::container_mod::my_mod; // After, container_mod definition elided for brevity

pub mod my_mod {
    pub fn my_fn() { ... } // Before
}
pub use my_helper_crate as my_mod; // After :-)

```

Note that some of them would require replicating whole subtrees if all links are supposed to be stable, possibly even cross-crate.

---

<div class="post-metadata">

### Author: ![jyn514](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jyn514/32/13245_2.png) [@jyn514](https://internals.rust-lang.org/u/jyn514)
#### Post date: [September 23, 2020, 6:45pm UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/37 "2020-09-23T18:45:05Z")

</div>

This is covered in the section 'Re-exports will generate a page pointing to the canonical version'.

It will be a larger number of pages, but each individual page will be very small.

---

<div class="post-metadata">

### Author: ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)
#### Post date: [September 30, 2020, 7:00am UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/38 "2020-09-30T07:00:28Z")

</div>

IMO it would be a good idea to match the namespaces the way they work in rustc also as a slight hint for how names work in rustc -- answering questions like "why can I have a function and a type of the same name but not a trait and a type of the same name".

So 👍 for this proposal:

> [@elidupree](#):
>
> Yeah, if we combine this with your "omit the prefix for the value namespace" idea, it becomes:
> 
> - `t.Name.html` for traits and types (haha convenient), and theoretically modules, which are in the same namespace, except not actually because modules are subdirectories instead (haha convenient x2)
> - `m.Name.html` for macros (seems fine)
> - `name.html` for fns and `NAME.html` for consts and statics (seems fine)
> 
> which seems pretty reasonable.

---

<div class="post-metadata">

### Author: ![bjorn3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjorn3/32/2736_2.png) [@bjorn3](https://internals.rust-lang.org/u/bjorn3)
#### Post date: [September 30, 2020, 9:29am UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/39 "2020-09-30T09:29:25Z")

</div>

What should be done for things like tuple structs that are both in the type and value namespace?

---

<div class="post-metadata">

### Author: ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)
#### Post date: [September 30, 2020, 10:09am UTC](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099/40 "2020-09-30T10:09:02Z")

</div>

That is a good question... from a purely technical perspective, I'd say both files should exist, likely with one redirecting to the other.

(They exist in both namespaces but really these are different components -- the thing in the value namespace is the constructor. This is similar to enum variants which also have a constructor in the value namespace.)

[Previous page](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099.md?page=1)

[Next page](https://internals.rust-lang.org/t/pre-rfc-stable-rustdoc-urls/13099.md?page=3)
