Skip to content
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

Use name.namespace.html as the canonical URL, not kind.name.html #55160

Open
scottmcm opened this issue Oct 17, 2018 · 50 comments
Open

Use name.namespace.html as the canonical URL, not kind.name.html #55160

scottmcm opened this issue Oct 17, 2018 · 50 comments
Labels
A-stability Area: `#[stable]`, `#[unstable]` etc. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@scottmcm
Copy link
Member

I just wanted to look at the ManuallyDrop docs again, and my browser helpfully remembered that it's at https://doc.rust-lang.org/std/mem/union.ManuallyDrop.html. But, despite the type being stable, that page no longer exists; it's now https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html.

Is the specific item kind actually important to have in the path? The namespace (type vs value vs ...) certainly is, but especially for things without public fields, making the struct-vs-union distinction so front-and-centre seems overall unhelpful.

@Havvy Havvy added the T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. label Oct 17, 2018
@GuillaumeGomez
Copy link
Member

For me it's a positive thing. I'd argue that you'd better not use direct URLs and just search or rustdoc links. The current URLs are clear and represent what they should.

@mikeyhew
Copy link
Contributor

@GuillaumeGomez I disagree with that, I think that direct links to documentation are useful, their use should be encouraged, and we should avoid breaking them if possible.

Having the extra information of struct, enum or type in the URL is kind of nice too, but the other thing is that switching from the current URLs to new ones would result in a lot of links breaking, so maybe there is some way to use redirects instead? Like if you went to https://doc.rust-lang.org/std/mem/union.ManuallyDrop.html or https://doc.rust-lang.org/std/mem/type.ManuallyDrop.html it would redirect you to https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html.

@GuillaumeGomez
Copy link
Member

I'm not sure we understood each other. To be clear: the current state of rustdoc URLs seems good and should be kept unless something way better is proposed.

@RalfJung
Copy link
Member

I agree with the OP that encoding the "kind" of type in the URL seems suboptimal. Rust has three namespaces (macro-level, fn/variable-level, type-level), so that needs to be encoded, but I see no good reason to encode more. type.ManuallyDrophtml has all the information needed to uniquely identify this type.

As another argument for why the current URLs are bad: this is one of the few cases where doing a semver-compatible change (changing a struct to an enum, for example) breaks docs links.

@nox
Copy link
Contributor

nox commented Sep 14, 2019

Changing a struct to an enum isn't backwards-compatible (one can match against Struct { .. }), but I support removing the type kind from URLs, for the same rationale as in #64454.

@bluss
Copy link
Member

bluss commented Sep 14, 2019

We have a bunch of redirects that only focus on the namespace an item belongs to.

For example the URL https://doc.rust-lang.org/stable/std/mem/ManuallyDrop.t.html with "t" for type, will redirect to the correct place and I assume this URL was there before the struct/union switch happened. Only problem is that it's not the canonical URL. (And, it would be more ideal if we didn't have lots of extra redirect files, there are enough small files already in a rustdoc site).

@RalfJung
Copy link
Member

@bluss wow, I had no idea these files even existed!

For use in rustc/libstd, if they should be useful we need a tidy pass that tells people to link to the "t" file instead of the "struct"/"enum"/"union" file.

@GuillaumeGomez
Copy link
Member

It was for RLS iirc. Not sure if removing it is fine but I'd like to remove it.

@jyn514
Copy link
Member

jyn514 commented Aug 25, 2020

I disagree with that, I think that direct links to documentation are useful, their use should be encouraged, and we should avoid breaking them if possible.

I have the same comment as in #71912 (comment): direct links should use intra-doc links, the links rustdoc generates are not stable.

@RalfJung
Copy link
Member

@jyn514 so say I am writing a blog post and mentioning some Rust types whose docs I want to reference. Obviously my site generator does not support intra-doc links. What do you propose I do?

This is something people already do -- anything that has a URL has people link to it. It's what makes the web so amazing. Please don't break that.

@GuillaumeGomez
Copy link
Member

URLs are stable, the DOM content isn't. However, since you always use a specific version of a crate, you can just link to the element of this specific version of the crate on docs.rs.

@RalfJung
Copy link
Member

URLs are not stable when a struct becomes an enum (which otherwise is semver-compatible if the struct had a private field).

@GuillaumeGomez
Copy link
Member

Then that's on the crate owner, not on rustdoc. We the URLs are defined as [type].[type name].html. If you change an item's type, then you change the URL. It's predictable. But again: always reference to a specific version of a crate and that shouldn't be an issue.

@RalfJung
Copy link
Member

The entire point of this issue is that there is no good reason to include struct vs union in the URL. The "item type" of all structs, unions and enums should be just type.

It's predictable, sure, but that does not make it sensible.

@GuillaumeGomez
Copy link
Member

So you would want to include a breaking change for something stable even before 1.0? You'd need very strong reasons for it to be done and I'm really not convinced...

@RalfJung
Copy link
Member

No we don't need a breaking change -- as @bluss wrote above, reasonably stable URLs already exist: https://doc.rust-lang.org/stable/std/mem/ManuallyDrop.t.html
But nobody knows about them because they are not used by default. So all it would take is swap the role of ManuallyDrop.t.html and struct.ManuallyDrop.html, making the latter a redirect and the former the target of all the automatically generated links.

@GuillaumeGomez
Copy link
Member

Well, we kinda want to remove this URL format since a while. It's still there because it's being used by RLS iirc. Also, this would be a regression in my point of view considering you lose information. And since it's not the default URL format, it's definitely a breaking change.

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

So you would want to include a breaking change for something stable

The point of discussion IMO is whether or not it is stable. Currently, it's stable with respect to rustdoc versions, but not with respect to the code being documented. Either

a) The file names should be predictable across versions being documented, in which case we should recommend ManuallyDrop.t.html, or
b) The file names are unstable and no one should depend on them, in which case we should change them every release so people don't depend on them by accident.

The current middle ground is sort of the worst of both worlds because it looks like it's stable, but can break for changes that do not break semver.

@RalfJung
Copy link
Member

RalfJung commented Aug 26, 2020

The information you lose is not semver-stable and irrelevant for API consumers. It's like having the line number in the URL -- sure that would be more inforamtion, but it's not good information to have in the URL. That's what this issue is all about -- please consult the arguments given above.

Also, how is this a breaking change if it doesn't break anything? All existing URLs keep working.

@RalfJung
Copy link
Member

RalfJung commented Aug 26, 2020

IMO the question is quite simple at a fundamental level -- what does it take to uniquely identify an item in Rust (assuming you already know the crate it is in)? You need its name, its full module path, and its "kind" -- which can be value, type, or macro. And that's it. So this information should be sufficient to construct a URL, and no other information should be contained in the URL. After all, a "Uniform Resource Locator" is all about being able to locate resources, such as the documentation about items in Rust, in a uniform and consistent way.

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

@RalfJung what do you propose we do about all the existing URLs that point to enum.ManuallyUninit.html? Should we generate redirects for all pages in the type namespace? That seems like it would bloat the size of the docs quite a bit. But if we don't do that, then the URLs are still broken even if we make union.ManuallyUninit.html a redirect.

@jyn514 jyn514 added the A-stability Area: `#[stable]`, `#[unstable]` etc. label Aug 26, 2020
@RalfJung
Copy link
Member

If my understanding is correct, currently we generate two pages for every type:

  • [enum|struct|union].$name.html is the main page with all the fields and methods and stuff
  • $name.t.html redirects to the above.

What I am proposing is to swap the role of these two files, so every existing link keeps working:

  • $name.t.html is the main page with all the fields and methods and stuff
  • [enum|struct|union].$name.html redirects to the above.

This cannot break any link that currently works. It means changing e.g. union to enum still breaks people that use the "wrong" (deprecated) union.$name.html, but that's certainly better than not having the union.$name.html redirect! Currently we break all links on a union -> enum change; with the new scheme we only break old links -- but new links that people set will go to the .t.html page. So, I'd say this is a strict improvement over the status quo.

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

I'm happy with that. It doesn't fix the existing links to union.ManuallyDrop.html, but it encourages good practice for future links without being too much of a burden on rustdoc.

@RalfJung
Copy link
Member

(I am not sure what ManuallyInit is. ManuallyDrop changed from union to struct, so if you mean the existing links to union.ManuallyDrop.html then I agree.)

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

I was actually thinking of MaybeUninit 😆 so not even close

@RalfJung
Copy link
Member

MaybeUninit is a union and always was, so I don't think it is relevant here.^^

@jyn514 jyn514 changed the title RustDoc: Including "struct" and "union" in URLs makes them fragile Use name.namespace.html as the canonical URL, not kind.name.html Aug 26, 2020
@ollie27
Copy link
Member

ollie27 commented Aug 26, 2020

The namespace based redirects were removed in #70563.

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

It looks like that was mostly to fix wonky hash handling? The only comment about namespaces I see is #70563 (comment):

We should also fully revert #35236 not just part of it.

Is there any reason not to add the namespace redirects back?

@GuillaumeGomez
Copy link
Member

Why would we want it? It's a duplication of the current system. We removed it to stop having to maintain it and therefore reduce the amount of code.

@jyn514
Copy link
Member

jyn514 commented Aug 26, 2020

The entire issue is giving reasons why we would want it. #55160 (comment) has a good summary.

@RalfJung
Copy link
Member

Why would we want it?

Please read this issue.

@Kixunil
Copy link
Contributor

Kixunil commented Jan 20, 2022

@nox turns out you're right, I'm glad I double-checked it. I think this is a mistake in the language design and should be deprecated. It's very impractical and I was unknowingly relying on it not being the case.

The comment I originally intended to write, still relevant if the incompatibility gets fixed:

Somewhat less related but IMO if the type has no public fields people shouldn't even know what "kind" the type is. Whether it's a tuple struct or ordinary struct or an enum with private variants, if Rust ever gets those, should be completely irrelevant to the consumer because it has no observable effects. This information shouldn't be present in URL or docs or anywhere outside the source code. It's exactly like the analogy with having line numbers in the docs.

Edit: opened a discussion about this

@RalfJung
Copy link
Member

RalfJung commented Mar 10, 2025

@rust-lang/rustdoc this has caused trouble again recently when NonZeroU64 etc types where turned into type aliases -- now all the old links to struct.NonZeroU64.html are broken. I think every case where a semver-compatible update breaks links to docs is a rustdoc bug.

@GuillaumeGomez 4 years ago you asked for reasons about why we'd want to use different URLs. Examples have been given in this issue both before and after you asked that question. So now that we have answered your question, would be great to hear your thoughts on this issue. :)

people shouldn't even know what "kind" the type is. Whether it's a tuple struct or ordinary struct or an enum with private variants

There are no enums with private variants. However if we ever get such a feature, then I agree.

@Kixunil
Copy link
Contributor

Kixunil commented Mar 10, 2025

That's what I meant by "if Rust ever gets those". :)

@lolbinarycat
Copy link
Contributor

There are no enums with private variants. However if we ever get such a feature, then I agree.

Rust actually used to have enums with private variants, before 1.0, however they were removed because they were the only thing keeping the priv keyword in the language.

@GuillaumeGomez
Copy link
Member

Coming back to this: using the suggested namespace would worsen the situation on case insensitive file systems (Windows). Intra-doc links normally should prevent having doc link generation. The only remaining issue is for users relying on URLs, but for them, I don't really see a good solution.

@hanna-kruppe
Copy link
Contributor

What’s the problem with case insensitive file systems?

@GuillaumeGomez
Copy link
Member

It increases the likelihood of having duplicates (because of less namespaces). It's already an issue for some C bindings with a lot of constants sharing the same name but with different upper/lower casing.

@RalfJung
Copy link
Member

The only remaining issue is for users relying on URLs, but for them, I don't really see a good solution.

We have a great solution: just use a URL that only contains information that semver mandates to be stable.

It increases the likelihood of having duplicates (because of less namespaces).

So you mean e.g. if there is an enum and a struct whose name differs only by the case? Do you have any reason to believe that this is more likely than having two structs whose name differs only by case? "Put the kind of ADT into the URL" is not a solution to this problem. It just helps sometimes, while also making rustdoc URLs unsuited for bookmarking or any sort of other reference from the rest of the web.

Between "having stable URLs one can actually rely on" and "sometimes successfully paper over case insensitivity without actually solving the problem", why would you prefer the latter?

@GuillaumeGomez
Copy link
Member

Between "having stable URLs one can actually rely on" and "sometimes successfully paper over case insensitivity without actually solving the problem", why would you prefer the latter?

Because:

  1. It means not breaking all existing URLs (on docs.rs for example)
  2. It works all the time as long as you use the crate version in the URL (in docs.rs)
  3. It's easy to go around this limitation by using ?search=WhateverYouNeed

I agree with you that the current URL scheme isn't the best, but the proposed solution has short-comings too.

@RalfJung
Copy link
Member

RalfJung commented Mar 13, 2025

It means not breaking all existing URLs (on docs.rs for example)

This has been discussed above -- no breakage is needed, the existing URLs can keep working as redirects.

It works all the time as long as you use the crate version in the URL (in docs.rs)

It's easy to go around this limitation by using ?search=WhateverYouNeed

The default way to grab a URL is to just copy it from your browser. Both for the std docs and for docsrs, that will not give a stable URL. Only a tiny fraction of people will know to even do anything by hand here, and even fewer will bother doing so if it requires manual work. The search variant will also often not give a unique answer, making it not very suited.

In my estimation, ~everyone linking to std docs uses the stable or nightly URLs. There's really no reason not to, unless you happen to know about this rustdoc issue. "In theory people could avoid the problem" is really not helpful advice when in practice, nobody knows they have to avoid it. We should build systems that work well by default. Telling users they are wrong when they do the obvious thing and it doesn't work should never be the first reply.

@GuillaumeGomez
Copy link
Member

As long as you don't link to nightly std items, URL will always work.

@hanna-kruppe
Copy link
Contributor

hanna-kruppe commented Mar 13, 2025

As Ralf described earlier, the URLs for the stable NonZero{U,I}{8,16,32,64,size} types recently changed because those types were distinct structs before but are now type aliases (type NonZeroT = NonZero<T>;).

@GuillaumeGomez
Copy link
Member

😮

I wonder if changing the type of an item is considered a semver breaking change...

@hanna-kruppe
Copy link
Contributor

It’s not, at least not in this case, as evidenced by the fact that Rust did it.

@its-the-shrimp
Copy link
Contributor

Changing from an enum should be a breaking change, since one can always match on its variant, there are no more private variants. However changing from any type kind to a type alias is always backwards-compatible, as is going from a struct with all fields private to an enum

@lolbinarycat
Copy link
Contributor

as is going from a struct with all fields private to an enum

As mentioned before, this is untrue, since you can match against Struct { .. }.

@scottmcm
Copy link
Member Author

As long as you don't link to nightly std items, URL will always work.

To further emphasize, the reason I created this issue in the first place (way back in 2018) was a case where that wasn't true.

Back when 1.22.0 was the stable, https://doc.rust-lang.org/stable/std/mem/union.ManuallyDrop.html worked. It no longer does, because that type is now https://doc.rust-lang.org/stable/std/mem/struct.ManuallyDrop.html despite the type being stable since 1.20.

3. It's easy to go around this limitation by using ?search=WhateverYouNeed

I don't think it's a reasonable expectation that people would do that give the current § links on the page.

If I want to link to impl !Clone for &mut, I go to the page and copy the link from the § to get https://doc.rust-lang.org/std/clone/trait.Clone.html#impl-Clone-for-%26mut+T. I don't craft a search URL for it.

Similarly, the reason this broke for the nonzero change is that I'd give people links to something like
https://doc.rust-lang.org/std/num/struct.NonZeroU32.html#method.ilog2
because I'm talking about that specific method, and that's the obvious URL.

There's no button to copy a link like
https://doc.rust-lang.org/std/?search=NonZeroU32%3A%3Ailog2
and even if there was, I don't want to send someone a search page.

I want to send them a link that when they click it, actually opens the method.

(I especially wouldn't have sent the search page before, because https://doc.rust-lang.org/1.70.0/std/?search=NonZeroU32%3A%3Ailog2 was pretty bad. Thankfully in later versions it got better, and the search page is specific now, having just the one result for the specific thing.)

If there were "copy URL" icons for everything that gave me an "I'm feeling lucky" search link, and thus worked as well as the direct anchor links, I'd plausibly use those, especially if the actual anchors were ugly. But as it is today, I never would, even though I know about this problem.

@GuillaumeGomez
Copy link
Member

Ok, then time for an RFC I guess.

@jyn514
Copy link
Member

jyn514 commented Mar 14, 2025

cc rust-lang/rfcs#2988

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-stability Area: `#[stable]`, `#[unstable]` etc. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests