From e8747d04140cba8fa4af01368437e870fceb867a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Apr 2022 21:39:50 +0200 Subject: [PATCH 1/2] Add support for doc(extern_html_root_url()) attribute --- compiler/rustc_passes/src/check_attr.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + src/librustdoc/config.rs | 3 +- src/librustdoc/core.rs | 39 +++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3d5da114ecfde..f7a6e4aec9fc2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1020,6 +1020,7 @@ impl CheckAttrVisitor<'_> { | sym::html_root_url | sym::html_no_source | sym::test + | sym::extern_html_root_url if !self.check_attr_crate_level(attr, meta, hir_id) => { is_valid = false; @@ -1052,6 +1053,7 @@ impl CheckAttrVisitor<'_> { sym::alias | sym::cfg | sym::cfg_hide + | sym::extern_html_root_url | sym::hidden | sym::html_favicon_url | sym::html_logo_url diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5c9c16350e469..fe07471542c10 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -653,6 +653,7 @@ symbols! { extern_absolute_paths, extern_crate_item_prelude, extern_crate_self, + extern_html_root_url, extern_in_paths, extern_prelude, extern_types, diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index b934a1a59d717..d19db86f211df 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -230,7 +230,8 @@ pub(crate) struct RenderOptions { pub(crate) extension_css: Option, /// A map of crate names to the URL to use instead of querying the crate's `html_root_url`. pub(crate) extern_html_root_urls: BTreeMap, - /// Whether to give precedence to `html_root_url` or `--exten-html-root-url`. + /// Whether to give precedence to `html_root_url` or `--extern-html-root-url`. + /// By default it is `html_root_url`. pub(crate) extern_html_root_takes_precedence: bool, /// A map of the default settings (values are as for DOM storage API). Keys should lack the /// `rustdoc-` prefix. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 53281bfde2e4f..39d1ab54addc5 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -21,6 +21,7 @@ use rustc_span::symbol::sym; use rustc_span::{source_map, Span, Symbol}; use std::cell::RefCell; +use std::collections::btree_map::Entry; use std::lazy::SyncLazy; use std::mem; use std::rc::Rc; @@ -456,6 +457,44 @@ pub(crate) fn run_global_ctxt( if attr.is_word() && name == sym::document_private_items { ctxt.render_options.document_private = true; } + + if name == sym::extern_html_root_url { + if let Some(attr) = attr.meta_item_list() { + for sub_attr in attr { + let name = sub_attr.name_or_empty().as_str().to_owned(); + match sub_attr.value_str() { + Some(value) => { + let value = value.as_str().to_owned(); + if value.is_empty() { + tcx.sess.span_err(sub_attr.span(), "URL cannot be empty"); + continue; + } + match ctxt.render_options.extern_html_root_urls.entry(name) { + Entry::Occupied(_) => { + // do nothing since command line `--extern_html_root_url` + // takes precedence. + } + Entry::Vacant(v) => { + v.insert(value); + } + } + } + None => { + tcx.sess.span_err( + sub_attr.span(), + "extern_html_root_url() only accepts `crate_name = \"url\"`", + ); + } + } + } + } else { + diag.span_err( + attr.span(), + "extern_html_root_url only accepts this form: \ + `extern_html_root_url(crate = \"url\")`", + ); + } + } } info!("Executing passes"); From cd2a21a9c0477c5f7e4a92dd72de4df96fd2545c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Apr 2022 22:23:12 +0200 Subject: [PATCH 2/2] Add test for new attribute `extern_html_root_url` --- src/test/rustdoc-ui/extern_html_root_url.rs | 18 +++++++++ .../rustdoc-ui/extern_html_root_url.stderr | 38 +++++++++++++++++++ src/test/rustdoc/extern_html_root_url.rs | 6 +++ 3 files changed, 62 insertions(+) create mode 100644 src/test/rustdoc-ui/extern_html_root_url.rs create mode 100644 src/test/rustdoc-ui/extern_html_root_url.stderr create mode 100644 src/test/rustdoc/extern_html_root_url.rs diff --git a/src/test/rustdoc-ui/extern_html_root_url.rs b/src/test/rustdoc-ui/extern_html_root_url.rs new file mode 100644 index 0000000000000..91b57a8cd5ce4 --- /dev/null +++ b/src/test/rustdoc-ui/extern_html_root_url.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] + +#![doc(extern_html_root_url)] +//~^ ERROR +#![doc(extern_html_root_url = "a")] +//~^ ERROR +#![doc(extern_html_root_url(a))] +//~^ ERROR +#![doc(extern_html_root_url(a()))] +//~^ ERROR +#![doc(extern_html_root_url(a = 1))] +//~^ ERROR +#![doc(extern_html_root_url(a = ""))] +//~^ ERROR +#![doc(extern_html_root_url(a = "1"))] // This one is supposed to work. +#![doc(extern_html_root_url(b = "2", c = "3"))] // This one is supposed to work. + +pub fn foo() {} diff --git a/src/test/rustdoc-ui/extern_html_root_url.stderr b/src/test/rustdoc-ui/extern_html_root_url.stderr new file mode 100644 index 0000000000000..47cbd18214ed5 --- /dev/null +++ b/src/test/rustdoc-ui/extern_html_root_url.stderr @@ -0,0 +1,38 @@ +error: extern_html_root_url only accepts this form: `extern_html_root_url(crate = "url")` + --> $DIR/extern_html_root_url.rs:3:8 + | +LL | #![doc(extern_html_root_url)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: extern_html_root_url only accepts this form: `extern_html_root_url(crate = "url")` + --> $DIR/extern_html_root_url.rs:5:8 + | +LL | #![doc(extern_html_root_url = "a")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: extern_html_root_url() only accepts `crate_name = "url"` + --> $DIR/extern_html_root_url.rs:7:29 + | +LL | #![doc(extern_html_root_url(a))] + | ^ + +error: extern_html_root_url() only accepts `crate_name = "url"` + --> $DIR/extern_html_root_url.rs:9:29 + | +LL | #![doc(extern_html_root_url(a()))] + | ^^^ + +error: extern_html_root_url() only accepts `crate_name = "url"` + --> $DIR/extern_html_root_url.rs:11:29 + | +LL | #![doc(extern_html_root_url(a = 1))] + | ^^^^^ + +error: URL cannot be empty + --> $DIR/extern_html_root_url.rs:13:29 + | +LL | #![doc(extern_html_root_url(a = ""))] + | ^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/rustdoc/extern_html_root_url.rs b/src/test/rustdoc/extern_html_root_url.rs new file mode 100644 index 0000000000000..3baceb41e1939 --- /dev/null +++ b/src/test/rustdoc/extern_html_root_url.rs @@ -0,0 +1,6 @@ +#![crate_name = "foo"] +#![doc(extern_html_root_url(std = "https://doc.rust-lang.org/nightly"))] + +// @has 'foo/index.html' +// @has - '//a[@class="mod"]/@href' 'https://doc.rust-lang.org/nightly/std/index.html' +pub use std as other;