Skip to content

Commit e948f31

Browse files
Rollup merge of rust-lang#87073 - jyn514:primitive-docs, r=GuillaumeGomez
Fix rustdoc handling of primitive items This is a complicated PR and does a lot of things. I'm willing to split it up a little more if it would help reviewing, but it would be tricky and I'd rather not unless it's necessary. ## What does this do? - Fixes rust-lang#73423. - Fixes rust-lang#79630. I'm not sure how to test this for the standard library explicitly, but you can see from some of the diffs from the `no_std` tests. I also tested it locally and it works correctly: ![image](https://user-images.githubusercontent.com/23638587/125214383-e1fdd000-e284-11eb-8048-76b5df958aad.png) - Fixes rust-lang#83083. ## Why are these changes interconnected? - Allowing anchors (rust-lang#83083) without fixing the online/offline problem (rust-lang#79630) will actually just silently discard the anchors, that's not a fix. The online/offline problem is directly related to the fragment hack; links need to go through `fn href()` to be fixed. - Technically I could fix the online/offline problem without removing the error on anchors; I am willing to separate that out if it would be helpful for reviewing. However I can't fix the anchor problem without adding docs to core, since rustdoc needs all those primitives to have docs to avoid a fallback, and currently `#![no_std]` crates don't have docs for primitives. I also can't fix the online/offline problem without removing the fragment hack, since otherwise diffs like this will be wrong for some primitives but not others: ```diff `@@` -385,7 +381,7 `@@` fn resolve_primitive_associated_item( ty::AssocKind::Const => "associatedconstant", ty::AssocKind::Type => "associatedtype", }; - let fragment = format!("{}#{}.{}", prim_ty.as_sym(), out, item_name); + let fragment = format!("{}.{}", out, item_name); (Res::Primitive(prim_ty), fragment, Some((kind.as_def_kind(), item.def_id))) }) }) ``` - Adding primitive docs to core without making any other change will cause links to go to `core` instead of `std`, even for crates with `extern crate std`. See "Breaking changes to doc(primitive)" below for why this is the case. That said, I could add some special casing to rustdoc at the same time that would let me separate this change from the others (it would fix rust-lang#73423 but still special-case intra-doc links). I'm willing to separate that out if helpful for reviewing. ### Add primitive documentation to libcore This works by reusing the same `include!("primitive_docs.rs")` file in both core and std, and then special-casing links in core to use relative links instead of intra-doc links. This doesn't use purely intra-doc links because some of the primitive docs links to items only in std; this doesn't use purely relative links because that introduces new broken links when the docs are re-exported (e.g. String's `&str` deref impl, or Vec's slice deref impl). ### Fix inconsistent online/offline primitive docs This does four things: - Records modules with `doc(primitive)` in `cache.external_paths`. This is necessary for `href()` to find them later. - Makes `cache.primitive_locations` available to the intra-doc link pass, by refactoring out a `PrimitiveType::primitive_locations` function that only uses `TyCtxt`. - Special cases modules with `doc(primitive)` to be treated as always public for the purpose of links. - Removes the fragment hack. cc `@notriddle,` I know you added some comments about this in the code (thank you for that!) ### Breaking changes to `doc(primitive)` "Breaking" is a little misleading here - these are changes in behavior, none of them will cause code to fail to compile. Let me preface this by saying I think stabilizing `doc(primitive)` was a uniquely terrible idea. As far as I can tell, it was stabilized by oversight; it's been stable since 1.0. No one should have need to use it except the standard library, and a crater run shows that in fact no one is using it: rust-lang#87050 (comment). I hope to actually make `doc(primitive)` a no-op unless you opt-in with a nightly feature, which will keep crates compiling without forcing rustdoc into trying to keep somewhat arbitrary behavior guarantees; but for now, this just subtly changes some of the behavior if you use `doc(primitive)` in a dependency. That said, here are the changes: - Refactoring out `primitive_locations()` is technically a change in behavior, since it no longer looks for primitives in crates that were passed through `--extern`, but not used by the crate; however, that seems like such an unlikely edge case it's not worth dealing with. - The precedence given to primitive locations is no longer just arbitrary, it can also be inconsistent from run to run. Let me explain that more: previously, primitive locations were sorted by the `CrateNum`; the comment on that sort said "Favor linking to as local extern as possible, so iterate all crates in reverse topological order." Unfortunately, that's not actually what CrateNum tracks: it measures the order crates are loaded, not the number of intermediate crates between that dependency and the root crate. It happened to work as intended before because the compiler injects `extern crate std;` at the top of every crate, which ensured it would have the first CrateNum other than the current, but every other CrateNum was completely arbitrary (for example, `core` often had a later CrateNum than `std`). This now removes the sort on CrateNum completely and special-cases core instead. In particular, if you depend on both `std` and a crate which defines a `doc(primitive)` module, it's arbitrary whether rustdoc will use the docs from std or the ones from the other crate. cc `@alexcrichton,` you wrote this originally. cc `@rust-lang/rustdoc` cc `@rust-lang/libs` for the addition to `core` (the commit you're interested in is rust-lang@36729b0)
2 parents 3b3ce37 + 7e435ce commit e948f31

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1587
-188
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/boxed/struct.Box.html#method.into_raw
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/fs/struct.File.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/io/trait.BufRead.html
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/io/trait.Read.html
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/io/trait.Seek.html
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/io/trait.Write.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/net/trait.ToSocketAddrs.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/process/fn.exit.html
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../std/string/struct.String.html

library/core/src/char/methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl char {
2424
/// decoding error.
2525
///
2626
/// It can occur, for example, when giving ill-formed UTF-8 bytes to
27-
/// [`String::from_utf8_lossy`](string/struct.String.html#method.from_utf8_lossy).
27+
/// [`String::from_utf8_lossy`](../std/string/struct.String.html#method.from_utf8_lossy).
2828
#[stable(feature = "assoc_char_consts", since = "1.52.0")]
2929
pub const REPLACEMENT_CHARACTER: char = '\u{FFFD}';
3030

library/core/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
#![feature(decl_macro)]
133133
#![feature(doc_cfg)]
134134
#![feature(doc_notable_trait)]
135+
#![cfg_attr(not(bootstrap), feature(doc_primitive))]
135136
#![feature(exhaustive_patterns)]
136137
#![feature(extern_types)]
137138
#![feature(fundamental)]
@@ -357,3 +358,5 @@ pub mod arch {
357358
/* compiler built-in */
358359
}
359360
}
361+
362+
include!("primitive_docs.rs");

0 commit comments

Comments
 (0)