Skip to content

Commit

Permalink
rustdoc: link to stable/beta docs consistently in documentation
Browse files Browse the repository at this point in the history
 ## User-facing changes

- Intra-doc links to primitives that currently go to rust-lang.org/nightly/std/primitive.x.html will start going to channel that rustdoc was built with. Nightly will continue going to /nightly; Beta will link to /beta; stable compilers will link to /1.52.1 (or whatever version they were built as).
- Cross-crate links from std to core currently go to /nightly unconditionally. They will start going to /1.52.0 on stable channels (but remain the same on nightly channels).
- Intra-crate links from std to std (or core to core) currently go to the same URL they are hosted at; they will continue to do so. Notably, this is different from everything else because it can preserve the distinction between /stable and /1.52.0 by using relative links.

Note that "links" includes both intra-doc links and rustdoc's own
automatically generated hyperlinks.

 ## Implementation changes

- Update the testsuite to allow linking to /beta and /1.52.1 in docs
- Use an html_root_url for the standard library that's dependent on the channel

  This avoids linking to nightly docs on stable.

- Update rustdoc to use channel-dependent links for primitives from an
  unknown crate

- Set DOC_RUST_LANG_ORG_CHANNEL from bootstrap to ensure it's in sync
- Include doc.rust-lang.org in the channel
  • Loading branch information
jyn514 committed Jun 4, 2021
1 parent c4c2ab5 commit 7411a9e
Show file tree
Hide file tree
Showing 41 changed files with 139 additions and 120 deletions.
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Expand Up @@ -59,7 +59,6 @@
#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Expand Up @@ -51,7 +51,6 @@
#![cfg(not(test))]
#![stable(feature = "core", since = "1.6.0")]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
Expand Down
5 changes: 1 addition & 4 deletions library/panic_abort/src/lib.rs
Expand Up @@ -5,10 +5,7 @@

#![no_std]
#![unstable(feature = "panic_abort", issue = "32837")]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/"
)]
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
#![panic_runtime]
#![allow(unused_features)]
#![feature(core_intrinsics)]
Expand Down
5 changes: 1 addition & 4 deletions library/panic_unwind/src/lib.rs
Expand Up @@ -13,10 +13,7 @@

#![no_std]
#![unstable(feature = "panic_unwind", issue = "32837")]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/"
)]
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
#![feature(core_intrinsics)]
#![feature(lang_items)]
#![feature(nll)]
Expand Down
1 change: 0 additions & 1 deletion library/proc_macro/src/lib.rs
Expand Up @@ -12,7 +12,6 @@
#![stable(feature = "proc_macro_lib", since = "1.15.0")]
#![deny(missing_docs)]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
Expand Down
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Expand Up @@ -190,7 +190,6 @@
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(feature = "restricted-std", unstable(feature = "restricted_std", issue = "none"))]
#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(deny(warnings))),
Expand Down
6 changes: 1 addition & 5 deletions library/term/src/lib.rs
Expand Up @@ -30,11 +30,7 @@
//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
//! [ti]: https://en.wikipedia.org/wiki/Terminfo

#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
test(attr(deny(warnings)))
)]
#![doc(html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
#![deny(missing_docs)]
#![cfg_attr(windows, feature(libc))]

Expand Down
2 changes: 1 addition & 1 deletion library/test/src/lib.rs
Expand Up @@ -19,7 +19,7 @@

#![crate_name = "test"]
#![unstable(feature = "test", issue = "50297")]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
#![doc(test(attr(deny(warnings))))]
#![cfg_attr(unix, feature(libc))]
#![feature(rustc_private)]
#![feature(nll)]
Expand Down
12 changes: 12 additions & 0 deletions src/bootstrap/builder.rs
Expand Up @@ -574,6 +574,18 @@ impl<'a> Builder<'a> {
self.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), paths);
}

/// NOTE: keep this in sync with `rustdoc::clean::utils::doc_rust_lang_org_channel`, or tests will fail on beta/stable.
pub fn doc_rust_lang_org_channel(&self) -> String {
let channel = match &*self.config.channel {
"stable" => &self.version,
"beta" => "beta",
"nightly" | "dev" => "nightly",
// custom build of rustdoc maybe? link to the latest stable docs just in case
_ => "stable",
};
"https://doc.rust-lang.org/".to_owned() + channel
}

fn run_step_descriptions(&self, v: &[StepDescription], paths: &[PathBuf]) {
StepDescription::run(v, self, paths);
}
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/compile.rs
Expand Up @@ -326,6 +326,11 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
if target.contains("riscv") {
cargo.rustflag("-Cforce-unwind-tables=yes");
}

let html_root =
format!("-Zcrate-attr=doc(html_root_url=\"{}/\")", builder.doc_rust_lang_org_channel(),);
cargo.rustflag(&html_root);
cargo.rustdocflag(&html_root);
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/test.rs
Expand Up @@ -1486,6 +1486,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
}
}
cmd.env("RUSTC_BOOTSTRAP", "1");
cmd.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel());
builder.add_rust_test_threads(&mut cmd);

if builder.config.sanitizers_enabled(target) {
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/tool.rs
Expand Up @@ -263,6 +263,7 @@ pub fn prepare_tool_cargo(
cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel);
cargo.env("CFG_VERSION", builder.rust_version());
cargo.env("CFG_RELEASE_NUM", &builder.version);
cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel());

let info = GitInfo::new(builder.config.ignore_git, &dir);
if let Some(sha) = info.sha() {
Expand Down
4 changes: 4 additions & 0 deletions src/etc/htmldocck.py
Expand Up @@ -135,6 +135,8 @@
unichr = chr


channel = os.environ["DOC_RUST_LANG_ORG_CHANNEL"]

class CustomHTMLParser(HTMLParser):
"""simplified HTML parser.
Expand Down Expand Up @@ -270,6 +272,7 @@ def flatten(node):


def normalize_xpath(path):
path = path.replace("{{channel}}", channel)
if path.startswith('//'):
return '.' + path # avoid warnings
elif path.startswith('.//'):
Expand Down Expand Up @@ -334,6 +337,7 @@ def get_dir(self, path):


def check_string(data, pat, regexp):
pat = pat.replace("{{channel}}", channel)
if not pat:
return True # special case a presence testing
elif regexp:
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/types.rs
Expand Up @@ -499,7 +499,7 @@ impl Item {
format!("{}/std/", s.trim_end_matches('/'))
}
Some(ExternalLocation::Unknown) | None => {
"https://doc.rust-lang.org/nightly/std/".to_string()
format!("{}/std/", crate::DOC_RUST_LANG_ORG_CHANNEL)
}
};
// This is a primitive so the url is done "by hand".
Expand Down
5 changes: 5 additions & 0 deletions src/librustdoc/clean/utils.rs
Expand Up @@ -543,3 +543,8 @@ crate fn has_doc_flag(attrs: ty::Attributes<'_>, flag: Symbol) -> bool {
&& attr.meta_item_list().map_or(false, |l| rustc_attr::list_contains_name(&l, flag))
})
}

/// A link to `doc.rust-lang.org` that includes the channel name.
///
/// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
crate const DOC_RUST_LANG_ORG_CHANNEL: &'static str = env!("DOC_RUST_LANG_ORG_CHANNEL");
2 changes: 2 additions & 0 deletions src/librustdoc/lib.rs
Expand Up @@ -81,6 +81,8 @@ use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGro
use rustc_session::getopts;
use rustc_session::{early_error, early_warn};

use crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL;

/// A macro to create a FxHashMap.
///
/// Example:
Expand Down
1 change: 1 addition & 0 deletions src/test/rustdoc-ui/check.rs
@@ -1,5 +1,6 @@
// check-pass
// compile-flags: -Z unstable-options --check
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"

#![warn(missing_docs)]
//~^ WARN
Expand Down
16 changes: 8 additions & 8 deletions src/test/rustdoc-ui/check.stderr
@@ -1,5 +1,5 @@
warning: missing documentation for the crate
--> $DIR/check.rs:4:1
--> $DIR/check.rs:5:1
|
LL | / #![warn(missing_docs)]
LL | |
Expand All @@ -10,30 +10,30 @@ LL | | pub fn foo() {}
| |_______________^
|
note: the lint level is defined here
--> $DIR/check.rs:4:9
--> $DIR/check.rs:5:9
|
LL | #![warn(missing_docs)]
| ^^^^^^^^^^^^

warning: missing documentation for a function
--> $DIR/check.rs:9:1
--> $DIR/check.rs:10:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^

warning: no documentation found for this crate's top-level module
|
note: the lint level is defined here
--> $DIR/check.rs:7:9
--> $DIR/check.rs:8:9
|
LL | #![warn(rustdoc::all)]
| ^^^^^^^^^^^^
= note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]`
= help: The following guide may be of use:
https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html
https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html

warning: missing code example in this documentation
--> $DIR/check.rs:4:1
--> $DIR/check.rs:5:1
|
LL | / #![warn(missing_docs)]
LL | |
Expand All @@ -44,14 +44,14 @@ LL | | pub fn foo() {}
| |_______________^
|
note: the lint level is defined here
--> $DIR/check.rs:7:9
--> $DIR/check.rs:8:9
|
LL | #![warn(rustdoc::all)]
| ^^^^^^^^^^^^
= note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]`

warning: missing code example in this documentation
--> $DIR/check.rs:9:1
--> $DIR/check.rs:10:1
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions src/test/rustdoc-ui/intra-doc/email-address-localhost.rs
@@ -1,3 +1,4 @@
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
#![deny(warnings)]

//! Email me at <hello@localhost>.
Expand Down
6 changes: 3 additions & 3 deletions src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr
@@ -1,16 +1,16 @@
error: unknown disambiguator `hello`
--> $DIR/email-address-localhost.rs:3:18
--> $DIR/email-address-localhost.rs:4:18
|
LL | //! Email me at <hello@localhost>.
| ^^^^^
|
note: the lint level is defined here
--> $DIR/email-address-localhost.rs:1:9
--> $DIR/email-address-localhost.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: aborting due to previous error

1 change: 1 addition & 0 deletions src/test/rustdoc-ui/intra-doc/unknown-disambiguator.rs
@@ -1,3 +1,4 @@
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
#![deny(warnings)]

//! Linking to [foo@banana] and [`bar@banana!()`].
Expand Down
26 changes: 13 additions & 13 deletions src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr
@@ -1,56 +1,56 @@
error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:3:17
--> $DIR/unknown-disambiguator.rs:4:17
|
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
| ^^^
|
note: the lint level is defined here
--> $DIR/unknown-disambiguator.rs:1:9
--> $DIR/unknown-disambiguator.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: unknown disambiguator `bar`
--> $DIR/unknown-disambiguator.rs:3:35
--> $DIR/unknown-disambiguator.rs:4:35
|
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
| ^^^
|
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:9:34
--> $DIR/unknown-disambiguator.rs:10:34
|
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: unknown disambiguator `foo`
--> $DIR/unknown-disambiguator.rs:9:48
--> $DIR/unknown-disambiguator.rs:10:48
|
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
| ^^^
|
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:6:31
--> $DIR/unknown-disambiguator.rs:7:31
|
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: unknown disambiguator ``
--> $DIR/unknown-disambiguator.rs:6:57
--> $DIR/unknown-disambiguator.rs:7:57
|
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
| ^
|
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators

error: aborting due to 6 previous errors

1 change: 1 addition & 0 deletions src/test/rustdoc-ui/no-crate-level-doc-lint.rs
@@ -1,4 +1,5 @@
// error-pattern: no documentation found
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
#![deny(rustdoc::missing_crate_level_docs)]
//^~ NOTE defined here

Expand Down
4 changes: 2 additions & 2 deletions src/test/rustdoc-ui/no-crate-level-doc-lint.stderr
@@ -1,12 +1,12 @@
error: no documentation found for this crate's top-level module
|
note: the lint level is defined here
--> $DIR/no-crate-level-doc-lint.rs:2:9
--> $DIR/no-crate-level-doc-lint.rs:3:9
|
LL | #![deny(rustdoc::missing_crate_level_docs)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: The following guide may be of use:
https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation.html
https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html

error: aborting due to previous error

6 changes: 3 additions & 3 deletions src/test/rustdoc/intra-doc/associated-items.rs
Expand Up @@ -3,9 +3,9 @@
/// [`std::collections::BTreeMap::into_iter`]
/// [`String::from`] is ambiguous as to which `From` impl
/// [Vec::into_iter()] uses a disambiguator
// @has 'associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/collections/btree/map/struct.BTreeMap.html#method.into_iter"]' 'std::collections::BTreeMap::into_iter'
// @has 'associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/string/struct.String.html#method.from"]' 'String::from'
// @has 'associated_items/fn.foo.html' '//a[@href="https://doc.rust-lang.org/nightly/alloc/vec/struct.Vec.html#method.into_iter"]' 'Vec::into_iter'
// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/collections/btree/map/struct.BTreeMap.html#method.into_iter"]' 'std::collections::BTreeMap::into_iter'
// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/string/struct.String.html#method.from"]' 'String::from'
// @has 'associated_items/fn.foo.html' '//a[@href="{{channel}}/alloc/vec/struct.Vec.html#method.into_iter"]' 'Vec::into_iter'
pub fn foo() {}

/// Link to [MyStruct], [link from struct][MyStruct::method], [MyStruct::clone], [MyStruct::Input]
Expand Down
2 changes: 1 addition & 1 deletion src/test/rustdoc/intra-doc/builtin-macros.rs
@@ -1,3 +1,3 @@
// @has builtin_macros/index.html
// @has - '//a/@href' 'https://doc.rust-lang.org/nightly/core/macro.cfg.html'
// @has - '//a/@href' '{{channel}}/core/macro.cfg.html'
//! [cfg]

0 comments on commit 7411a9e

Please sign in to comment.