From 07bb2f701e5bae0da724068bbce1920458df9cda Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Thu, 27 Oct 2022 11:16:30 -0700 Subject: [PATCH 01/12] rustdoc: change `.src-line-numbers > span` to `.src-line-numbers > a` This allows people to treat them like real links, such as right-click to copy URL, and makes the line numbers in a scraped example work at all, when before this commit was added, they had the clickable pointer cursor but did not actually do anything when clicked. --- src/librustdoc/html/render/mod.rs | 11 +++--- src/librustdoc/html/sources.rs | 21 +++++----- src/librustdoc/html/static/css/rustdoc.css | 5 +-- .../html/static/js/source-script.js | 11 ++++-- src/test/rustdoc-gui/source-code-page.goml | 39 ++++++++++++++----- .../rustdoc/check-source-code-urls-to-def.rs | 32 +++++++-------- 6 files changed, 72 insertions(+), 47 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 27dea8ec0b312..e09106077f7ed 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2888,9 +2888,6 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite })() .unwrap_or(rustc_span::DUMMY_SP); - // The root path is the inverse of Context::current - let root_path = vec!["../"; cx.current.len() - 1].join(""); - let mut decoration_info = FxHashMap::default(); decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]); decoration_info.insert("highlight", byte_ranges); @@ -2900,9 +2897,13 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite contents_subset, file_span, cx, - &root_path, + &cx.root_path(), highlight::DecorationInfo(decoration_info), - sources::SourceContext::Embedded { offset: line_min, needs_expansion }, + sources::SourceContext::Embedded { + url: &call_data.url, + offset: line_min, + needs_expansion, + }, ); write!(w, "</div></div>"); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 8a01c01049d6e..99b4678c4577f 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -256,9 +256,9 @@ where } } -pub(crate) enum SourceContext { +pub(crate) enum SourceContext<'a> { Standalone, - Embedded { offset: usize, needs_expansion: bool }, + Embedded { url: &'a str, offset: usize, needs_expansion: bool }, } /// Wrapper struct to render the source code of a file. This will do things like @@ -270,31 +270,32 @@ pub(crate) fn print_src( context: &Context<'_>, root_path: &str, decoration_info: highlight::DecorationInfo, - source_context: SourceContext, + source_context: SourceContext<'_>, ) { let lines = s.lines().count(); let mut line_numbers = Buffer::empty_from(buf); let extra; line_numbers.write_str("<pre class=\"src-line-numbers\">"); + let current_href = &context + .href_from_span(clean::Span::new(file_span), false) + .expect("only local crates should have sources emitted"); match source_context { SourceContext::Standalone => { extra = None; for line in 1..=lines { - writeln!(line_numbers, "<span id=\"{0}\">{0}</span>", line) + writeln!(line_numbers, "<a href=\"#{line}\" id=\"{line}\">{line}</a>") } } - SourceContext::Embedded { offset, needs_expansion } => { + SourceContext::Embedded { url, offset, needs_expansion } => { extra = if needs_expansion { Some(r#"<span class="expand">↕</span>"#) } else { None }; - for line in 1..=lines { - writeln!(line_numbers, "<span>{0}</span>", line + offset) + for line_number in 1..=lines { + let line = line_number + offset; + writeln!(line_numbers, "<a href=\"{root_path}{url}#{line}\">{line}</a>") } } } line_numbers.write_str("</pre>"); - let current_href = &context - .href_from_span(clean::Span::new(file_span), false) - .expect("only local crates should have sources emitted"); highlight::render_source_with_highlighting( s, buf, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 894499e5c4fc9..df7b6e9b99a4e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -575,8 +575,7 @@ ul.block, .block li { border-color: var(--example-line-numbers-border-color); } -.src-line-numbers span { - cursor: pointer; +.src-line-numbers a { color: var(--src-line-numbers-span-color); } .src-line-numbers .line-highlighted { @@ -2060,7 +2059,7 @@ in storage.js padding: 14px 0; } -.scraped-example .code-wrapper .src-line-numbers span { +.scraped-example .code-wrapper .src-line-numbers a { padding: 0 14px; } diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 0b9368dd89948..5db768c1c5753 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -157,7 +157,7 @@ function highlightSourceLines(match) { x.scrollIntoView(); } onEachLazy(document.getElementsByClassName("src-line-numbers"), e => { - onEachLazy(e.getElementsByTagName("span"), i_e => { + onEachLazy(e.getElementsByTagName("a"), i_e => { removeClass(i_e, "line-highlighted"); }); }); @@ -188,8 +188,13 @@ const handleSourceHighlight = (function() { return ev => { let cur_line_id = parseInt(ev.target.id, 10); - // It can happen when clicking not on a line number span. - if (isNaN(cur_line_id)) { + // This event handler is attached to the entire line number column, but it should only + // be run if one of the anchors is clicked. It also shouldn't do anything if the anchor + // is clicked with a modifier key (to open a new browser tab). + if (isNaN(cur_line_id) || + ev.ctrlKey || + ev.altKey || + ev.metaKey) { return; } ev.preventDefault(); diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index a2dac2aa681d5..31d55cd7885d3 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -2,17 +2,17 @@ goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" show-text: true // Check that we can click on the line number. -click: ".src-line-numbers > span:nth-child(4)" // This is the span for line 4. +click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4. // Ensure that the page URL was updated. assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH) assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) -// We now check that the good spans are highlighted +// We now check that the good anchors are highlighted goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6" -assert-attribute-false: (".src-line-numbers > span:nth-child(3)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(4)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(5)", {"class": "line-highlighted"}) -assert-attribute: (".src-line-numbers > span:nth-child(6)", {"class": "line-highlighted"}) -assert-attribute-false: (".src-line-numbers > span:nth-child(7)", {"class": "line-highlighted"}) +assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(4)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(5)", {"class": "line-highlighted"}) +assert-attribute: (".src-line-numbers > a:nth-child(6)", {"class": "line-highlighted"}) +assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-highlighted"}) define-function: ( "check-colors", @@ -21,12 +21,12 @@ define-function: ( ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}), ("reload"), ("assert-css", ( - ".src-line-numbers > span:not(.line-highlighted)", + ".src-line-numbers > a:not(.line-highlighted)", {"color": |color|, "background-color": |background_color|}, ALL, )), ("assert-css", ( - ".src-line-numbers > span.line-highlighted", + ".src-line-numbers > a.line-highlighted", {"color": |highlight_color|, "background-color": |highlight_background_color|}, ALL, )), @@ -57,6 +57,25 @@ call-function: ("check-colors", { // This is to ensure that the content is correctly align with the line numbers. compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) +// Check the `href` property so that users can treat anchors as links. +assert-property: (".src-line-numbers > a:nth-child(1)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#1" +}) +assert-property: (".src-line-numbers > a:nth-child(2)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#2" +}) +assert-property: (".src-line-numbers > a:nth-child(3)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#3" +}) +assert-property: (".src-line-numbers > a:nth-child(4)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4" +}) +assert-property: (".src-line-numbers > a:nth-child(5)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#5" +}) +assert-property: (".src-line-numbers > a:nth-child(6)", { + "href": "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#6" +}) // Assert that the line numbers text is aligned to the right. assert-css: (".src-line-numbers", {"text-align": "right"}) @@ -66,7 +85,7 @@ assert-css: (".src-line-numbers", {"text-align": "right"}) goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" // We use this assert-position to know where we will click. assert-position: ("//*[@id='1']", {"x": 104, "y": 112}) -// We click on the left of the "1" span but still in the "src-line-number" `<pre>`. +// We click on the left of the "1" anchor but still in the "src-line-number" `<pre>`. click: (103, 103) assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH) diff --git a/src/test/rustdoc/check-source-code-urls-to-def.rs b/src/test/rustdoc/check-source-code-urls-to-def.rs index d00a3e3551991..5959f9c7c5992 100644 --- a/src/test/rustdoc/check-source-code-urls-to-def.rs +++ b/src/test/rustdoc/check-source-code-urls-to-def.rs @@ -10,14 +10,14 @@ extern crate source_code; // @has 'src/foo/check-source-code-urls-to-def.rs.html' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#1-17"]' 'bar' #[path = "auxiliary/source-code-bar.rs"] pub mod bar; -// @count - '//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4 +// @count - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#5"]' 4 use bar::Bar; -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#13"]' 'self' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' use bar::sub::{self, Trait}; pub struct Foo; @@ -28,29 +28,29 @@ impl Foo { fn babar() {} -// @has - '//a/@href' '/struct.String.html' -// @has - '//a/@href' '/primitive.u32.html' -// @has - '//a/@href' '/primitive.str.html' -// @count - '//a[@href="#23"]' 5 -// @has - '//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode' +// @has - '//pre[@class="rust"]//a/@href' '/struct.String.html' +// @has - '//pre[@class="rust"]//a/@href' '/primitive.u32.html' +// @has - '//pre[@class="rust"]//a/@href' '/primitive.str.html' +// @count - '//pre[@class="rust"]//a[@href="#23"]' 5 +// @has - '//pre[@class="rust"]//a[@href="../../source_code/struct.SourceCode.html"]' 'source_code::SourceCode' pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) { let x = 12; let y: Foo = Foo; let z: Bar = bar::Bar { field: Foo }; babar(); - // @has - '//a[@href="#26"]' 'hello' + // @has - '//pre[@class="rust"]//a[@href="#26"]' 'hello' y.hello(); } -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait' -// @has - '//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'bar::sub::Trait' +// @has - '//pre[@class="rust"]//a[@href="auxiliary/source-code-bar.rs.html#14"]' 'Trait' pub fn foo2<T: bar::sub::Trait, V: Trait>(t: &T, v: &V, b: bool) {} pub trait AnotherTrait {} pub trait WhyNot {} -// @has - '//a[@href="#49"]' 'AnotherTrait' -// @has - '//a[@href="#50"]' 'WhyNot' +// @has - '//pre[@class="rust"]//a[@href="#49"]' 'AnotherTrait' +// @has - '//pre[@class="rust"]//a[@href="#50"]' 'WhyNot' pub fn foo3<T, V>(t: &T, v: &V) where T: AnotherTrait, @@ -59,11 +59,11 @@ where pub trait AnotherTrait2 {} -// @has - '//a[@href="#60"]' 'AnotherTrait2' +// @has - '//pre[@class="rust"]//a[@href="#60"]' 'AnotherTrait2' pub fn foo4() { let x: Vec<AnotherTrait2> = Vec::new(); } -// @has - '//a[@href="../../foo/primitive.bool.html"]' 'bool' +// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool' #[doc(primitive = "bool")] mod whatever {} From ba4ae13528428cf770701ea5d9203cbf64b5a1cd Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 28 Oct 2022 09:51:57 -0700 Subject: [PATCH 02/12] rustdoc: remove left border from `.src-line-numbers > a` --- src/librustdoc/html/static/css/rustdoc.css | 8 +++++--- src/test/rustdoc-gui/source-code-page.goml | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index df7b6e9b99a4e..b64fe74e960e3 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -578,11 +578,13 @@ ul.block, .block li { .src-line-numbers a { color: var(--src-line-numbers-span-color); } -.src-line-numbers .line-highlighted { - background-color: var(--src-line-number-highlighted-background-color); -} .src-line-numbers :target { background-color: transparent; + border-right: none; + padding-right: 0; +} +.src-line-numbers .line-highlighted { + background-color: var(--src-line-number-highlighted-background-color); } .search-loading { diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index 31d55cd7885d3..c71a3d64d0c8a 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -6,6 +6,11 @@ click: ".src-line-numbers > a:nth-child(4)" // This is the anchor for line 4. // Ensure that the page URL was updated. assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH) assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) +// Ensure that the default style, with the right border, isn't used. +assert-css: ("//*[@id='4']", {"border-right-width": "0px"}) +reload: +assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) +assert-css: ("//*[@id='4']", {"border-right-width": "0px"}) // We now check that the good anchors are highlighted goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html#4-6" assert-attribute-false: (".src-line-numbers > a:nth-child(3)", {"class": "line-highlighted"}) From 9bcc083c873be61e62446d0240a72f99d71350e0 Mon Sep 17 00:00:00 2001 From: David Wood <david.wood@huawei.com> Date: Mon, 7 Nov 2022 14:43:28 +0000 Subject: [PATCH 03/12] run-make-fulldeps: fix split debuginfo test Add lots of comments to this test and enable parts of the test that were added but never ran. Signed-off-by: David Wood <david.wood@huawei.com> --- .../split-debuginfo/Makefile | 160 ++++++++++++++++-- 1 file changed, 145 insertions(+), 15 deletions(-) diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile index 1032f3408f062..a511aff4f3af2 100644 --- a/src/test/run-make-fulldeps/split-debuginfo/Makefile +++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile @@ -3,7 +3,7 @@ include ../tools.mk all: off packed unpacked ifeq ($(UNAME),Darwin) -# If disabled, don't run dsymutil +# If disabled, don't run `dsymutil`. off: rm -rf $(TMPDIR)/*.dSYM $(RUSTC) foo.rs -g -C split-debuginfo=off @@ -29,98 +29,228 @@ unpacked: [ ! -d $(TMPDIR)/foo.dSYM ] else ifdef IS_WINDOWS -# Windows only supports =packed +# Windows only supports packed debuginfo - nothing to test. off: packed: unpacked: else +# Some non-Windows, non-Darwin platforms are not stable, and some are. ifeq ($(UNAME),Linux) UNSTABLEOPTS := else UNSTABLEOPTS := -Zunstable-options endif +# - Debuginfo in `.o` files +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` never created off: $(RUSTC) foo.rs -g -C $(UNSTABLEOPTS) split-debuginfo=off [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] - $(RUSTC) foo.rs -g [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] -packed: packed-split packed-single +packed: packed-split packed-single packed-remapped packed-crosscrate +# - Debuginfo in `.dwo` files +# - `.o` deleted +# - `.dwo` deleted +# - `.dwp` present packed-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=split - ls $(TMPDIR)/*.dwp - rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` present packed-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=packed -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.dwp + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 - rm -rf $(TMPDIR)/*.dwp + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) packed-remapped: packed-remapped-split packed-remapped-single +# - Debuginfo in `.dwo` files +# - `.o` and binary refer to remapped `.dwo` paths which do not exist +# - `.o` deleted +# - `.dwo` deleted +# - `.dwp` present packed-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` and binary refer to remapped `.o` paths which do not exist +# - `.o` deleted +# - `.dwo` never created +# - `.dwp` present packed-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=packed -C debuginfo=2 \ -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + rm $(TMPDIR)/foo.dwp + rm $(TMPDIR)/$(call BIN,foo) packed-crosscrate: packed-crosscrate-split packed-crosscrate-single +# - Debuginfo in `.dwo` files +# - (bar) `.rlib` file created, contains `.dwo` +# - (bar) `.o` deleted +# - (bar) `.dwo` deleted +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` deleted +# - (main) `.dwp` present packed-crosscrate-split: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \ + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ -C split-debuginfo=packed -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs - rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) +# - Debuginfo in `.o` files +# - (bar) `.rlib` file created, contains `.o` +# - (bar) `.o` deleted +# - (bar) `.dwo` never created +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` never created +# - (main) `.dwp` present packed-crosscrate-single: $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=packed \ -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib -Z unstable-options $(UNSTABLEOPTS) \ + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ -C split-debuginfo=packed -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o && exit 1 || exit 0 ls $(TMPDIR)/*.dwo && exit 1 || exit 0 rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) -unpacked: unpacked-split unpacked-single unpacked-remapped-split unpacked-remapped-single +unpacked: unpacked-split unpacked-single unpacked-remapped unpacked-crosscrate +# - Debuginfo in `.dwo` files +# - `.o` deleted +# - `.dwo` present +# - `.dwp` never created unpacked-split: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo ls $(TMPDIR)/*.dwp && exit 1 || exit 0 - ls $(TMPDIR)/*.dwo - rm -rf $(TMPDIR)/*.dwp $(TMPDIR)/*.dwo + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` present +# - `.dwo` never created +# - `.dwp` never created unpacked-single: $(RUSTC) foo.rs -g $(UNSTABLEOPTS) -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single - ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + ls $(TMPDIR)/*.o ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) + +unpacked-remapped: unpacked-remapped-split unpacked-remapped-single +# - Debuginfo in `.dwo` files +# - `.o` and binary refer to remapped `.dwo` paths which do not exist +# - `.o` deleted +# - `.dwo` present +# - `.dwp` never created unpacked-remapped-split: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ -Z split-dwarf-kind=split --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) +# - Debuginfo in `.o` files +# - `.o` and binary refer to remapped `.o` paths which do not exist +# - `.o` present +# - `.dwo` never created +# - `.dwp` never created unpacked-remapped-single: $(RUSTC) $(UNSTABLEOPTS) -C split-debuginfo=unpacked -C debuginfo=2 \ -Z split-dwarf-kind=single --remap-path-prefix $(TMPDIR)=/a foo.rs -g objdump -Wi $(TMPDIR)/foo | grep DW_AT_GNU_dwo_name | (! grep $(TMPDIR)) || exit 1 + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,foo) + +unpacked-crosscrate: packed-crosscrate-split packed-crosscrate-single + +# - Debuginfo in `.dwo` files +# - (bar) `.rlib` file created, contains `.dwo` +# - (bar) `.o` deleted +# - (bar) `.dwo` present +# - (bar) `.dwp` never created +# - (main) `.o` deleted +# - (main) `.dwo` present +# - (main) `.dwp` never created +unpacked-crosscrate-split: + $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ + -Zsplit-dwarf-kind=split -C debuginfo=2 -g bar.rs + ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ + -C split-debuginfo=unpacked -Zsplit-dwarf-kind=split -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o && exit 1 || exit 0 + rm $(TMPDIR)/*.dwo + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,main) + +# - Debuginfo in `.o` files +# - (bar) `.rlib` file created, contains `.o` +# - (bar) `.o` present +# - (bar) `.dwo` never created +# - (bar) `.dwp` never created +# - (main) `.o` present +# - (main) `.dwo` never created +# - (main) `.dwp` never created +unpacked-crosscrate-single: + $(RUSTC) --crate-type lib $(UNSTABLEOPTS) -C split-debuginfo=unpacked \ + -Zsplit-dwarf-kind=single -C debuginfo=2 -g bar.rs + ls $(TMPDIR)/*.rlib + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + $(RUSTC) --extern bar=$(TMPDIR)/libbar.rlib $(UNSTABLEOPTS) \ + -C split-debuginfo=unpacked -Zsplit-dwarf-kind=single -C debuginfo=2 -g main.rs + ls $(TMPDIR)/*.o + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/$(call BIN,main) endif endif From 29dc08307dde3051ab6bf17c53f2db99e32681ee Mon Sep 17 00:00:00 2001 From: David Wood <david.wood@huawei.com> Date: Mon, 7 Nov 2022 15:15:24 +0000 Subject: [PATCH 04/12] llvm: dwo only emitted when object code emitted `CompiledModule` should not think a DWARF object was emitted when a bitcode-only compilation has happened, this can confuse archive file creation (which expects to create an archive containing non-existent dwo files). Signed-off-by: David Wood <david.wood@huawei.com> --- compiler/rustc_codegen_llvm/src/back/write.rs | 16 +++++- .../split-debuginfo/Makefile | 56 ++++++++++++++++++- .../run-make-fulldeps/split-debuginfo/baz.rs | 1 + 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 src/test/run-make-fulldeps/split-debuginfo/baz.rs diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 11053a8f6c452..97d0de47b3a6e 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -765,11 +765,21 @@ pub(crate) unsafe fn codegen( drop(handlers); } + // `.dwo` files are only emitted if: + // + // - Object files are being emitted (i.e. bitcode only or metadata only compilations will not + // produce dwarf objects, even if otherwise enabled) + // - Target supports Split DWARF + // - Split debuginfo is enabled + // - Split DWARF kind is `split` (i.e. debuginfo is split into `.dwo` files, not different + // sections in the `.o` files). + let dwarf_object_emitted = matches!(config.emit_obj, EmitObj::ObjectCode(_)) + && cgcx.target_can_use_split_dwarf + && cgcx.split_debuginfo != SplitDebuginfo::Off + && cgcx.split_dwarf_kind == SplitDwarfKind::Split; Ok(module.into_compiled_module( config.emit_obj != EmitObj::None, - cgcx.target_can_use_split_dwarf - && cgcx.split_debuginfo != SplitDebuginfo::Off - && cgcx.split_dwarf_kind == SplitDwarfKind::Split, + dwarf_object_emitted, config.emit_bc, &cgcx.output_filenames, )) diff --git a/src/test/run-make-fulldeps/split-debuginfo/Makefile b/src/test/run-make-fulldeps/split-debuginfo/Makefile index a511aff4f3af2..1831ab38fab49 100644 --- a/src/test/run-make-fulldeps/split-debuginfo/Makefile +++ b/src/test/run-make-fulldeps/split-debuginfo/Makefile @@ -53,7 +53,7 @@ off: [ ! -f $(TMPDIR)/*.dwp ] [ ! -f $(TMPDIR)/*.dwo ] -packed: packed-split packed-single packed-remapped packed-crosscrate +packed: packed-split packed-single packed-lto packed-remapped packed-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted @@ -77,6 +77,32 @@ packed-single: rm $(TMPDIR)/foo.dwp rm $(TMPDIR)/$(call BIN,foo) +packed-lto: packed-lto-split packed-lto-single + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +packed-lto-split: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +packed-lto-single: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=packed -Zsplit-dwarf-kind=single \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + packed-remapped: packed-remapped-split packed-remapped-single # - Debuginfo in `.dwo` files @@ -153,7 +179,7 @@ packed-crosscrate-single: rm $(TMPDIR)/main.dwp rm $(TMPDIR)/$(call BIN,main) -unpacked: unpacked-split unpacked-single unpacked-remapped unpacked-crosscrate +unpacked: unpacked-split unpacked-single unpacked-lto unpacked-remapped unpacked-crosscrate # - Debuginfo in `.dwo` files # - `.o` deleted @@ -177,6 +203,32 @@ unpacked-single: ls $(TMPDIR)/*.dwp && exit 1 || exit 0 rm $(TMPDIR)/$(call BIN,foo) +unpacked-lto: packed-lto-split packed-lto-single + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +unpacked-lto-split: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=split \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + +# - rmeta file added to rlib, no object files are generated and thus no debuginfo is generated +# - `.o` never created +# - `.dwo` never created +# - `.dwp` never created +unpacked-lto-single: + $(RUSTC) baz.rs -g $(UNSTABLEOPTS) -Csplit-debuginfo=unpacked -Zsplit-dwarf-kind=single \ + --crate-type=rlib -Clinker-plugin-lto + ls $(TMPDIR)/*.o && exit 1 || exit 0 + ls $(TMPDIR)/*.dwo && exit 1 || exit 0 + ls $(TMPDIR)/*.dwp && exit 1 || exit 0 + rm $(TMPDIR)/libbaz.rlib + unpacked-remapped: unpacked-remapped-split unpacked-remapped-single # - Debuginfo in `.dwo` files diff --git a/src/test/run-make-fulldeps/split-debuginfo/baz.rs b/src/test/run-make-fulldeps/split-debuginfo/baz.rs new file mode 100644 index 0000000000000..8b1a393741c96 --- /dev/null +++ b/src/test/run-make-fulldeps/split-debuginfo/baz.rs @@ -0,0 +1 @@ +// empty From 89ba71649f59e402a0019828223a878c06f625b1 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Tue, 8 Nov 2022 18:00:22 -0700 Subject: [PATCH 05/12] rustdoc: use consistent "popover" styling for notable traits --- src/librustdoc/html/render/mod.rs | 6 +- src/librustdoc/html/static/css/rustdoc.css | 73 +++++-------------- src/librustdoc/html/static/css/themes/ayu.css | 4 - .../html/static/css/themes/dark.css | 4 - .../html/static/css/themes/light.css | 4 - src/librustdoc/html/static/js/main.js | 52 ++++++++++--- src/test/rustdoc-gui/notable-trait.goml | 61 +++++++--------- 7 files changed, 89 insertions(+), 115 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 266ec2ac7ad73..75fdd6ade235f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1312,9 +1312,7 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O if has_notable_trait { cx.types_with_notable_traits.insert(ty.clone()); Some(format!( - "<span class=\"notable-traits\" data-ty=\"{ty}\">\ - <span class=\"notable-traits-tooltip\">ⓘ</span>\ - </span>", + " <a href=\"#\" class=\"notable-traits\" data-ty=\"{ty}\">ⓘ</a>", ty = Escape(&format!("{:#}", ty.print(cx))), )) } else { @@ -1343,7 +1341,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) { if out.is_empty() { write!( &mut out, - "<h3 class=\"notable\">Notable traits for <code>{}</code></h3>\ + "<h3>Notable traits for <code>{}</code></h3>\ <pre class=\"content\"><code>", impl_.for_.print(cx) ); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6a068a3d243d9..1209187dc4817 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -183,8 +183,6 @@ h4.code-header { font-weight: 600; margin: 0; padding: 0; - /* position notable traits in mobile mode within the header */ - position: relative; } #crate-search, @@ -930,13 +928,14 @@ so that we can apply CSS-filters to change the arrow color in themes */ border-radius: 3px; border: 1px solid var(--border-color); font-size: 1rem; + --popover-arrow-offset: 11px; } /* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ .popover::before { content: ''; position: absolute; - right: 11px; + right: var(--popover-arrow-offset); border: solid var(--border-color); border-width: 1px 1px 0 0; display: inline-block; @@ -953,10 +952,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ /* use larger max-width for help popover, but not for help.html */ #help.popover { max-width: 600px; -} - -#help.popover::before { - right: 48px; + --popover-arrow-offset: 48px; } #help dt { @@ -1275,54 +1271,34 @@ h3.variant { border-right: 3px solid var(--target-border-color); } -.notable-traits-tooltip { - display: inline-block; - cursor: pointer; -} - -.notable-traits .notable-traits-tooltiptext { - display: inline-block; - visibility: hidden; +.notable-traits { + color: inherit; + margin-right: 15px; + position: relative; } -.notable-traits-tooltiptext { - padding: 5px 3px 3px 3px; - border-radius: 6px; - margin-left: 5px; - z-index: 10; - font-size: 1rem; - cursor: default; +/* placeholder thunk so that the mouse can easily travel from "(i)" to popover + the resulting "hover tunnel" is a stepped triangle, approximating + https://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown */ +.notable-traits:hover::after { position: absolute; - border: 1px solid; -} - -.notable-traits-tooltip::after { - /* The margin on the tooltip does not capture hover events, - this extends the area of hover enough so that mouse hover is not - lost when moving the mouse to the tooltip */ - content: "\00a0\00a0\00a0"; -} - -.notable-traits-tooltiptext .docblock { - margin: 0; + top: calc(100% - 10px); + left: -15px; + right: -15px; + height: 20px; + content: "\00a0"; } -.notable-traits-tooltiptext .notable { - font-size: 1.1875rem; - font-weight: 600; - display: block; +.notable .docblock { + margin: 0.25em 0.5em; } -.notable-traits-tooltiptext pre, .notable-traits-tooltiptext code { +.notable .docblock pre, .notable .docblock code { background: transparent; -} - -.notable-traits-tooltiptext .docblock pre.content { margin: 0; padding: 0; font-size: 1.25rem; white-space: pre-wrap; - overflow: hidden; } .search-failed { @@ -1365,12 +1341,6 @@ h3.variant { font-size: 1rem; } -.notable-traits { - cursor: pointer; - z-index: 2; - margin-left: 5px; -} - #sidebar-toggle { position: sticky; top: 0; @@ -1855,11 +1825,6 @@ in storage.js border-bottom: 1px solid; } - .notable-traits .notable-traits-tooltiptext { - left: 0; - top: 100%; - } - /* We don't display the help button on mobile devices. */ #help-button { display: none; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 2fa1fa39d63ab..eec3ce55e22f9 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -183,10 +183,6 @@ details.rustdoc-toggle > summary::before { border-color: transparent #314559 transparent transparent; } -.notable-traits-tooltiptext { - background-color: #314559; -} - #titles > button.selected { background-color: #141920 !important; border-bottom: 1px solid #ffb44c !important; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 43f8dd42ab347..a93d9d6790a17 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -106,10 +106,6 @@ details.rustdoc-toggle > summary::before { border-color: transparent black transparent transparent; } -.notable-traits-tooltiptext { - background-color: #111; -} - #titles > button:not(.selected) { background-color: #252525; border-top-color: #252525; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index c8c5289ab540c..e69ae5abbc393 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -98,10 +98,6 @@ body.source .example-wrap pre.rust a { border-color: transparent black transparent transparent; } -.notable-traits-tooltiptext { - background-color: #eee; -} - #titles > button:not(.selected) { background-color: #e6e6e6; border-top-color: #e6e6e6; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 0426774e80d46..b670ea3f0201d 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -850,18 +850,33 @@ function loadCss(cssUrl) { } hideNotable(); const ty = e.getAttribute("data-ty"); - const tooltip = e.getElementsByClassName("notable-traits-tooltip")[0]; const wrapper = document.createElement("div"); wrapper.innerHTML = "<div class=\"docblock\">" + window.NOTABLE_TRAITS[ty] + "</div>"; - wrapper.className = "notable-traits-tooltiptext"; - tooltip.appendChild(wrapper); - const pos = wrapper.getBoundingClientRect(); - tooltip.removeChild(wrapper); - wrapper.style.top = (pos.top + window.scrollY) + "px"; - wrapper.style.left = (pos.left + window.scrollX) + "px"; - wrapper.style.width = pos.width + "px"; + wrapper.className = "notable popover"; + const focusCatcher = document.createElement("div"); + focusCatcher.setAttribute("tabindex", "0"); + focusCatcher.onfocus = hideNotable; + wrapper.appendChild(focusCatcher); + const pos = e.getBoundingClientRect(); + // 5px overlap so that the mouse can easily travel from place to place + wrapper.style.top = (pos.top + window.scrollY + pos.height) + "px"; + wrapper.style.left = 0; + wrapper.style.right = "auto"; + wrapper.style.visibility = "hidden"; const body = document.getElementsByTagName("body")[0]; body.appendChild(wrapper); + const wrapperPos = wrapper.getBoundingClientRect(); + // offset so that the arrow points at the center of the "(i)" + const finalPos = pos.left + window.scrollX - wrapperPos.width + 24; + if (finalPos > 0) { + wrapper.style.left = finalPos + "px"; + } else { + wrapper.style.setProperty( + "--popover-arrow-offset", + (wrapperPos.right - pos.right + 4) + "px" + ); + } + wrapper.style.visibility = ""; window.CURRENT_NOTABLE_ELEMENT = wrapper; window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE = e; wrapper.onpointerleave = function(ev) { @@ -875,9 +890,23 @@ function loadCss(cssUrl) { }; } + function notableBlurHandler(event) { + if (window.CURRENT_NOTABLE_ELEMENT && + !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT) && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT) && + !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) && + !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) + ) { + hideNotable(); + } + } + function hideNotable() { if (window.CURRENT_NOTABLE_ELEMENT) { - window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; + if (window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE) { + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.focus(); + window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE.NOTABLE_FORCE_VISIBLE = false; + } const body = document.getElementsByTagName("body")[0]; body.removeChild(window.CURRENT_NOTABLE_ELEMENT); window.CURRENT_NOTABLE_ELEMENT = null; @@ -891,7 +920,11 @@ function loadCss(cssUrl) { hideNotable(); } else { showNotable(this); + window.CURRENT_NOTABLE_ELEMENT.setAttribute("tabindex", "0"); + window.CURRENT_NOTABLE_ELEMENT.focus(); + window.CURRENT_NOTABLE_ELEMENT.onblur = notableBlurHandler; } + return false; }; e.onpointerenter = function(ev) { // If this is a synthetic touch event, ignore it. A click event will be along shortly. @@ -1018,6 +1051,7 @@ function loadCss(cssUrl) { onEachLazy(document.querySelectorAll(".search-form .popover"), elem => { elem.style.display = "none"; }); + hideNotable(); }; /** diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index d8261d8dc902c..3bc1c5365e9e1 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -22,31 +22,26 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 951}, + {"x": 955}, ) -// The tooltip should be beside the `i` +// The tooltip should be below the `i` // Also, clicking the tooltip should bring its text into the DOM -assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) +assert-count: ("//*[@class='notable popover']", 0) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable-traits-tooltiptext']", 1) +assert-count: ("//*[@class='notable popover']", 1) compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable-traits-tooltiptext']", - {"y": 2} + "//*[@class='notable popover']", + {"y": 30} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable-traits-tooltiptext']", + "//*[@class='notable popover']", ("x") ) -// The docblock should be flush with the border. -assert-css: ( - "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']", - {"margin-left": "0px"} -) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" move-cursor-to: "//h1" -assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) +assert-count: ("//*[@class='notable popover']", 0) // Now only the `i` should be on the next line. size: (1055, 600) @@ -77,7 +72,7 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 519}, + {"x": 523}, ) // Checking on mobile now. @@ -101,34 +96,28 @@ assert-position: ( ) assert-position: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - {"x": 289}, + {"x": 293}, ) -// The tooltip should be below `i` +// The tooltip should STILL be below `i` click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" -assert-count: ("//*[@class='notable-traits-tooltiptext']", 1) -compare-elements-position-near-false: ( +assert-count: ("//*[@class='notable popover']", 1) +compare-elements-position-near: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable-traits-tooltiptext']", - {"y": 2} + "//*[@class='notable popover']", + {"y": 30} ) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - "//*[@class='notable-traits-tooltiptext']", + "//*[@class='notable popover']", ("x") ) -compare-elements-position-near: ( - "//*[@id='method.create_an_iterator_from_read']", - "//*[@class='notable-traits-tooltiptext']", - {"x": 10} -) -// The docblock should be flush with the border. -assert-css: ( - "//*[@class='notable-traits-tooltiptext']/*[@class='docblock']", - {"margin-left": "0px"} +assert-position: ( + "//*[@class='notable popover']", + {"x": 0} ) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" move-cursor-to: "//h1" -assert-count: ("//*[@class='notable-traits-tooltiptext']", 0) +assert-count: ("//*[@class='notable popover']", 0) // Checking on very small mobile. The `i` should be on its own line. size: (365, 600) @@ -153,25 +142,25 @@ define-function: ( ("reload"), ("move-cursor-to", "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']"), - ("assert-count", (".notable-traits-tooltiptext", 1)), + ("assert-count", (".notable.popover", 1)), ("assert-css", ( - ".notable-traits-tooltiptext h3.notable", + ".notable.popover h3", {"color": |header_color|}, ALL, )), ("assert-css", ( - ".notable-traits-tooltiptext pre.content", + ".notable.popover pre", {"color": |content_color|}, ALL, )), ("assert-css", ( - ".notable-traits-tooltiptext pre.content a.struct", + ".notable.popover pre a.struct", {"color": |type_color|}, ALL, )), ("assert-css", ( - ".notable-traits-tooltiptext pre.content a.trait", + ".notable.popover pre a.trait", {"color": |trait_color|}, ALL, )), From 155750dc330d0a2148cff7efadd75d821854e947 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Tue, 8 Nov 2022 17:59:03 -0700 Subject: [PATCH 06/12] rustdoc: make notable traits popover behavior consistent with Help and Settings --- src/librustdoc/html/static/js/main.js | 10 ++++++++- src/test/rustdoc-gui/notable-trait.goml | 28 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b670ea3f0201d..0538762e44d03 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -897,7 +897,15 @@ function loadCss(cssUrl) { !elemIsInParent(document.activeElement, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) && !elemIsInParent(event.relatedTarget, window.CURRENT_NOTABLE_ELEMENT.NOTABLE_BASE) ) { - hideNotable(); + // Work around a difference in the focus behaviour between Firefox, Chrome, and Safari. + // When I click the button on an already-opened notable trait popover, Safari + // hides the popover and then immediately shows it again, while everyone else hides it + // and it stays hidden. + // + // To work around this, make sure the click finishes being dispatched before + // hiding the popover. Since `hideNotable()` is idempotent, this makes Safari behave + // consistently with the other two. + setTimeout(hideNotable, 0); } } diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index 3bc1c5365e9e1..0b97cbae4991d 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -199,3 +199,31 @@ call-function: ( "trait_color": "rgb(110, 79, 201)", }, ) + +reload: + +// Check that pressing escape works +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//*[@class='notable popover']" +assert-count: ("//*[@class='notable popover']", 1) +press-key: "Escape" +assert-count: ("//*[@class='notable popover']", 0) + +// Check that clicking outside works. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +assert-count: ("//*[@class='notable popover']", 1) +click: ".search-input" +assert-count: ("//*[@class='notable popover']", 0) + +// Check that pressing tab over and over works. +click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']" +move-cursor-to: "//*[@class='notable popover']" +assert-count: ("//*[@class='notable popover']", 1) +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +press-key: "Tab" +assert-count: ("//*[@class='notable popover']", 0) From 79b6112ab53a9f5cd2b267dfbdb8bcae7049b2f7 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Tue, 8 Nov 2022 17:49:29 -0700 Subject: [PATCH 07/12] rustdoc: update test cases --- src/test/rustdoc-gui/notable-trait.goml | 8 -------- .../rustdoc/doc-notable_trait-slice.bare_fn_matches.html | 2 +- src/test/rustdoc/doc-notable_trait.bare-fn.html | 2 +- src/test/rustdoc/doc-notable_trait.rs | 6 +++--- src/test/rustdoc/doc-notable_trait.some-struct-new.html | 2 +- src/test/rustdoc/doc-notable_trait.wrap-me.html | 2 +- src/test/rustdoc/spotlight-from-dependency.odd.html | 2 +- src/test/rustdoc/spotlight-from-dependency.rs | 2 +- 8 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/test/rustdoc-gui/notable-trait.goml b/src/test/rustdoc-gui/notable-trait.goml index 0b97cbae4991d..4c3943d885830 100644 --- a/src/test/rustdoc-gui/notable-trait.goml +++ b/src/test/rustdoc-gui/notable-trait.goml @@ -119,14 +119,6 @@ click: "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits move-cursor-to: "//h1" assert-count: ("//*[@class='notable popover']", 0) -// Checking on very small mobile. The `i` should be on its own line. -size: (365, 600) -compare-elements-position-false: ( - "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", - "//*[@id='method.create_an_iterator_from_read']//*[@class='notable-traits']", - ("y", "x"), -) - // Now check the colors. define-function: ( "check-colors", diff --git a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html index 6b58be7e6853e..f2ec8320a0525 100644 --- a/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html +++ b/src/test/rustdoc/doc-notable_trait-slice.bare_fn_matches.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3 class=\"notable\">Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"&'static [SomeStruct]":"<h3>Notable traits for <code>&amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait_slice::SomeTrait\">SomeTrait</a> for &amp;[<a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait_slice::SomeStruct\">SomeStruct</a>]</span>"}</script> \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.bare-fn.html b/src/test/rustdoc/doc-notable_trait.bare-fn.html index 4e4a3f18f2498..b426a4d7a8b7b 100644 --- a/src/test/rustdoc/doc-notable_trait.bare-fn.html +++ b/src/test/rustdoc/doc-notable_trait.bare-fn.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>"}</script> \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.rs b/src/test/rustdoc/doc-notable_trait.rs index 1f2cd7181c3d4..279faf5540140 100644 --- a/src/test/rustdoc/doc-notable_trait.rs +++ b/src/test/rustdoc/doc-notable_trait.rs @@ -9,7 +9,7 @@ impl<T: SomeTrait> SomeTrait for Wrapper<T> {} #[doc(notable_trait)] pub trait SomeTrait { // @has doc_notable_trait/trait.SomeTrait.html - // @has - '//span[@class="notable-traits"]/@data-ty' 'Wrapper<Self>' + // @has - '//a[@class="notable-traits"]/@data-ty' 'Wrapper<Self>' // @snapshot wrap-me - '//script[@id="notable-traits-data"]' fn wrap_me(self) -> Wrapper<Self> where Self: Sized { Wrapper { @@ -23,7 +23,7 @@ impl SomeTrait for SomeStruct {} impl SomeStruct { // @has doc_notable_trait/struct.SomeStruct.html - // @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct' + // @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' // @snapshot some-struct-new - '//script[@id="notable-traits-data"]' pub fn new() -> SomeStruct { SomeStruct @@ -31,7 +31,7 @@ impl SomeStruct { } // @has doc_notable_trait/fn.bare_fn.html -// @has - '//span[@class="notable-traits"]/@data-ty' 'SomeStruct' +// @has - '//a[@class="notable-traits"]/@data-ty' 'SomeStruct' // @snapshot bare-fn - '//script[@id="notable-traits-data"]' pub fn bare_fn() -> SomeStruct { SomeStruct diff --git a/src/test/rustdoc/doc-notable_trait.some-struct-new.html b/src/test/rustdoc/doc-notable_trait.some-struct-new.html index c0fd9748fd371..4f8063807e67d 100644 --- a/src/test/rustdoc/doc-notable_trait.some-struct-new.html +++ b/src/test/rustdoc/doc-notable_trait.some-struct-new.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>","Wrapper<Self>":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"SomeStruct":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.SomeStruct.html\" title=\"struct doc_notable_trait::SomeStruct\">SomeStruct</a></span>","Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file diff --git a/src/test/rustdoc/doc-notable_trait.wrap-me.html b/src/test/rustdoc/doc-notable_trait.wrap-me.html index 9a59d5edd12a8..bed2a38b24a2b 100644 --- a/src/test/rustdoc/doc-notable_trait.wrap-me.html +++ b/src/test/rustdoc/doc-notable_trait.wrap-me.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"Wrapper<Self>":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl&lt;T:&nbsp;<a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a>&gt; <a class=\"trait\" href=\"trait.SomeTrait.html\" title=\"trait doc_notable_trait::SomeTrait\">SomeTrait</a> for <a class=\"struct\" href=\"struct.Wrapper.html\" title=\"struct doc_notable_trait::Wrapper\">Wrapper</a>&lt;T&gt;</span>"}</script> \ No newline at end of file diff --git a/src/test/rustdoc/spotlight-from-dependency.odd.html b/src/test/rustdoc/spotlight-from-dependency.odd.html index 987a949af44b1..1d02c13ebfb3c 100644 --- a/src/test/rustdoc/spotlight-from-dependency.odd.html +++ b/src/test/rustdoc/spotlight-from-dependency.odd.html @@ -1 +1 @@ -<script type="text/json" id="notable-traits-data">{"Odd":"<h3 class=\"notable\">Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></span><span class=\"where fmt-newline\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</span>"}</script> \ No newline at end of file +<script type="text/json" id="notable-traits-data">{"Odd":"<h3>Notable traits for <code><a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></code></h3><pre class=\"content\"><code><span class=\"where fmt-newline\">impl <a class=\"trait\" href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html\" title=\"trait core::iter::traits::iterator::Iterator\">Iterator</a> for <a class=\"struct\" href=\"struct.Odd.html\" title=\"struct foo::Odd\">Odd</a></span><span class=\"where fmt-newline\"> type <a href=\"{{channel}}/core/iter/traits/iterator/trait.Iterator.html#associatedtype.Item\" class=\"associatedtype\">Item</a> = <a class=\"primitive\" href=\"{{channel}}/std/primitive.usize.html\">usize</a>;</span>"}</script> \ No newline at end of file diff --git a/src/test/rustdoc/spotlight-from-dependency.rs b/src/test/rustdoc/spotlight-from-dependency.rs index 156aedca62b4e..090ad187d9cc0 100644 --- a/src/test/rustdoc/spotlight-from-dependency.rs +++ b/src/test/rustdoc/spotlight-from-dependency.rs @@ -3,7 +3,7 @@ use std::iter::Iterator; // @has foo/struct.Odd.html -// @has - '//*[@id="method.new"]//span[@class="notable-traits"]/@data-ty' 'Odd' +// @has - '//*[@id="method.new"]//a[@class="notable-traits"]/@data-ty' 'Odd' // @snapshot odd - '//script[@id="notable-traits-data"]' pub struct Odd { current: usize, From fa2c08112fd9e7ce9d4109ed52a36f7378710526 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Sat, 12 Nov 2022 09:21:29 -0700 Subject: [PATCH 08/12] rustdoc: remove no-op CSS `.scrape-help { background: transparent }` It's a link. This is the default CSS for it. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 6a068a3d243d9..74d7518de6b66 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1984,7 +1984,6 @@ in storage.js font-size: 12px; position: relative; bottom: 1px; - background: transparent; border-width: 1px; border-style: solid; border-radius: 50px; From cb3a04b6ef4db1b16d5e8dac5fcc00d66183eed6 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Sat, 12 Nov 2022 08:53:12 -0700 Subject: [PATCH 09/12] rustdoc: avoid excessive HTML generated in example sources --- src/librustdoc/html/render/mod.rs | 6 +----- src/librustdoc/html/sources.rs | 10 +++++----- src/librustdoc/html/static/css/rustdoc.css | 5 +++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e09106077f7ed..1fe52353449ba 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2899,11 +2899,7 @@ fn render_call_locations(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Ite cx, &cx.root_path(), highlight::DecorationInfo(decoration_info), - sources::SourceContext::Embedded { - url: &call_data.url, - offset: line_min, - needs_expansion, - }, + sources::SourceContext::Embedded { offset: line_min, needs_expansion }, ); write!(w, "</div></div>"); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 99b4678c4577f..50135d6019006 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -256,9 +256,9 @@ where } } -pub(crate) enum SourceContext<'a> { +pub(crate) enum SourceContext { Standalone, - Embedded { url: &'a str, offset: usize, needs_expansion: bool }, + Embedded { offset: usize, needs_expansion: bool }, } /// Wrapper struct to render the source code of a file. This will do things like @@ -270,7 +270,7 @@ pub(crate) fn print_src( context: &Context<'_>, root_path: &str, decoration_info: highlight::DecorationInfo, - source_context: SourceContext<'_>, + source_context: SourceContext, ) { let lines = s.lines().count(); let mut line_numbers = Buffer::empty_from(buf); @@ -286,12 +286,12 @@ pub(crate) fn print_src( writeln!(line_numbers, "<a href=\"#{line}\" id=\"{line}\">{line}</a>") } } - SourceContext::Embedded { url, offset, needs_expansion } => { + SourceContext::Embedded { offset, needs_expansion } => { extra = if needs_expansion { Some(r#"<span class="expand">↕</span>"#) } else { None }; for line_number in 1..=lines { let line = line_number + offset; - writeln!(line_numbers, "<a href=\"{root_path}{url}#{line}\">{line}</a>") + writeln!(line_numbers, "<span>{line}</span>") } } } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index b64fe74e960e3..bbcce72666852 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -575,7 +575,7 @@ ul.block, .block li { border-color: var(--example-line-numbers-border-color); } -.src-line-numbers a { +.src-line-numbers a, .src-line-numbers span { color: var(--src-line-numbers-span-color); } .src-line-numbers :target { @@ -2061,7 +2061,8 @@ in storage.js padding: 14px 0; } -.scraped-example .code-wrapper .src-line-numbers a { +.scraped-example .code-wrapper .src-line-numbers a, +.scraped-example .code-wrapper .src-line-numbers span { padding: 0 14px; } From 34972c512b3384d2194eaa0a85afdf896c6a4d75 Mon Sep 17 00:00:00 2001 From: Joshua Nelson <jnelson@cloudflare.com> Date: Sun, 6 Nov 2022 16:59:43 -0600 Subject: [PATCH 10/12] Distinguish `--dry-run` from the automatic dry run check --- src/bootstrap/builder.rs | 12 ++++----- src/bootstrap/builder/tests.rs | 4 +-- src/bootstrap/compile.rs | 12 ++++----- src/bootstrap/config.rs | 30 +++++++++++++++++----- src/bootstrap/dist.rs | 12 ++++----- src/bootstrap/doc.rs | 10 ++++---- src/bootstrap/format.rs | 2 +- src/bootstrap/lib.rs | 46 +++++++++++++++++----------------- src/bootstrap/native.rs | 20 +++++++-------- src/bootstrap/sanity.rs | 4 +-- src/bootstrap/tarball.rs | 2 +- src/bootstrap/test.rs | 10 ++++---- src/bootstrap/tool.rs | 2 +- src/bootstrap/toolstate.rs | 4 +-- src/bootstrap/util.rs | 4 +-- 15 files changed, 96 insertions(+), 78 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 6fd363935079d..31158870f394e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1074,11 +1074,11 @@ impl<'a> Builder<'a> { let mut hasher = sha2::Sha256::new(); // FIXME: this is ok for rustfmt (4.1 MB large at time of writing), but it seems memory-intensive for rustc and larger components. // Consider using streaming IO instead? - let contents = if self.config.dry_run { vec![] } else { t!(fs::read(path)) }; + let contents = if self.config.dry_run() { vec![] } else { t!(fs::read(path)) }; hasher.update(&contents); let found = hex::encode(hasher.finalize().as_slice()); let verified = found == expected; - if !verified && !self.config.dry_run { + if !verified && !self.config.dry_run() { println!( "invalid checksum: \n\ found: {found}\n\ @@ -1292,7 +1292,7 @@ impl<'a> Builder<'a> { /// Note that this returns `None` if LLVM is disabled, or if we're in a /// check build or dry-run, where there's no need to build all of LLVM. fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> { - if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run { + if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() { let llvm_config = self.ensure(native::Llvm { target }); if llvm_config.is_file() { return Some(llvm_config); @@ -1644,7 +1644,7 @@ impl<'a> Builder<'a> { // // Only clear out the directory if we're compiling std; otherwise, we // should let Cargo take care of things for us (via depdep info) - if !self.config.dry_run && mode == Mode::Std && cmd == "build" { + if !self.config.dry_run() && mode == Mode::Std && cmd == "build" { self.clear_if_dirty(&out_dir, &self.rustc(compiler)); } @@ -2142,7 +2142,7 @@ impl<'a> Builder<'a> { (out, dur - deps) }; - if self.config.print_step_timings && !self.config.dry_run { + if self.config.print_step_timings && !self.config.dry_run() { let step_string = format!("{:?}", step); let brace_index = step_string.find("{").unwrap_or(0); let type_string = type_name::<S>(); @@ -2216,7 +2216,7 @@ impl<'a> Builder<'a> { } pub(crate) fn open_in_browser(&self, path: impl AsRef<Path>) { - if self.config.dry_run || !self.config.cmd.open() { + if self.config.dry_run() || !self.config.cmd.open() { return; } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 88bbcc93d072c..5f21d2b0067dc 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::config::{Config, TargetSelection}; +use crate::config::{Config, DryRun, TargetSelection}; use std::thread; fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config { @@ -10,7 +10,7 @@ fn configure_with_args(cmd: &[String], host: &[&str], target: &[&str]) -> Config let mut config = Config::parse(cmd); // don't save toolstates config.save_toolstates = None; - config.dry_run = true; + config.dry_run = DryRun::SelfCheck; // Ignore most submodules, since we don't need them for a dry run. // But make sure to check out the `doc` and `rust-analyzer` submodules, since some steps need them diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 18e780a108d5a..79e07be614c0b 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -447,7 +447,7 @@ fn copy_sanitizers( ) -> Vec<PathBuf> { let runtimes: Vec<native::SanitizerRuntime> = builder.ensure(native::Sanitizers { target }); - if builder.config.dry_run { + if builder.config.dry_run() { return Vec::new(); } @@ -986,7 +986,7 @@ impl Step for CodegenBackend { compiler.stage, backend, &compiler.host, target )); let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false); - if builder.config.dry_run { + if builder.config.dry_run() { return; } let mut files = files.into_iter().filter(|f| { @@ -1034,7 +1034,7 @@ fn copy_codegen_backends_to_sysroot( let dst = builder.sysroot_codegen_backends(target_compiler); t!(fs::create_dir_all(&dst), dst); - if builder.config.dry_run { + if builder.config.dry_run() { return; } @@ -1332,7 +1332,7 @@ impl Step for Assemble { if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host }); - if !builder.config.dry_run { + if !builder.config.dry_run() { let llvm_bin_dir = output(Command::new(llvm_config_bin).arg("--bindir")); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); @@ -1402,7 +1402,7 @@ pub fn run_cargo( additional_target_deps: Vec<(PathBuf, DependencyType)>, is_check: bool, ) -> Vec<PathBuf> { - if builder.config.dry_run { + if builder.config.dry_run() { return Vec::new(); } @@ -1542,7 +1542,7 @@ pub fn stream_cargo( cb: &mut dyn FnMut(CargoMessage<'_>), ) -> bool { let mut cargo = Command::from(cargo); - if builder.config.dry_run { + if builder.config.dry_run() { return true; } // Instruct Cargo to give us json messages on stdout, critically leaving diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 2afce4fac42f8..e843bd411c172 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -33,6 +33,17 @@ macro_rules! check_ci_llvm { }; } +#[derive(Clone, Default)] +pub enum DryRun { + /// This isn't a dry run. + #[default] + Disabled, + /// This is a dry run enabled by bootstrap itself, so it can verify that no work is done. + SelfCheck, + /// This is a dry run enabled by the `--dry-run` flag. + UserSelected, +} + /// Global configuration for the entire build and/or bootstrap. /// /// This structure is derived from a combination of both `config.toml` and @@ -84,7 +95,7 @@ pub struct Config { pub jobs: Option<u32>, pub cmd: Subcommand, pub incremental: bool, - pub dry_run: bool, + pub dry_run: DryRun, /// `None` if we shouldn't download CI compiler artifacts, or the commit to download if we should. #[cfg(not(test))] download_rustc_commit: Option<String>, @@ -820,7 +831,7 @@ impl Config { config.jobs = flags.jobs.map(threads_from_config); config.cmd = flags.cmd; config.incremental = flags.incremental; - config.dry_run = flags.dry_run; + config.dry_run = if flags.dry_run { DryRun::UserSelected } else { DryRun::Disabled }; config.keep_stage = flags.keep_stage; config.keep_stage_std = flags.keep_stage_std; config.color = flags.color; @@ -965,7 +976,7 @@ impl Config { .unwrap_or_else(|| config.out.join(config.build.triple).join("stage0/bin/cargo")); // NOTE: it's important this comes *after* we set `initial_rustc` just above. - if config.dry_run { + if config.dry_run() { let dir = config.out.join("tmp-dry-run"); t!(fs::create_dir_all(&dir)); config.out = dir; @@ -1372,6 +1383,13 @@ impl Config { config } + pub(crate) fn dry_run(&self) -> bool { + match self.dry_run { + DryRun::Disabled => false, + DryRun::SelfCheck | DryRun::UserSelected => true, + } + } + /// A git invocation which runs inside the source directory. /// /// Use this rather than `Command::new("git")` in order to support out-of-tree builds. @@ -1461,7 +1479,7 @@ impl Config { /// This is computed on demand since LLVM might have to first be downloaded from CI. pub(crate) fn llvm_link_shared(builder: &Builder<'_>) -> bool { let mut opt = builder.config.llvm_link_shared.get(); - if opt.is_none() && builder.config.dry_run { + if opt.is_none() && builder.config.dry_run() { // just assume static for now - dynamic linking isn't supported on all platforms return false; } @@ -1488,7 +1506,7 @@ impl Config { /// Return whether we will use a downloaded, pre-compiled version of rustc, or just build from source. pub(crate) fn download_rustc(builder: &Builder<'_>) -> bool { static DOWNLOAD_RUSTC: OnceCell<bool> = OnceCell::new(); - if builder.config.dry_run && DOWNLOAD_RUSTC.get().is_none() { + if builder.config.dry_run() && DOWNLOAD_RUSTC.get().is_none() { // avoid trying to actually download the commit return false; } @@ -1507,7 +1525,7 @@ impl Config { RustfmtState::SystemToolchain(p) | RustfmtState::Downloaded(p) => Some(p.clone()), RustfmtState::Unavailable => None, r @ RustfmtState::LazyEvaluated => { - if builder.config.dry_run { + if builder.config.dry_run() { return Some(PathBuf::new()); } let path = maybe_download_rustfmt(builder); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 110a3ee4918da..9fbe476534eb7 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -945,7 +945,7 @@ impl Step for PlainSourceTarball { .arg(builder.src.join("./src/bootstrap/Cargo.toml")) .current_dir(&plain_dst_src); - let config = if !builder.config.dry_run { + let config = if !builder.config.dry_run() { t!(String::from_utf8(t!(cmd.output()).stdout)) } else { String::new() @@ -1386,7 +1386,7 @@ impl Step for Extended { let etc = builder.src.join("src/etc/installer"); // Avoid producing tarballs during a dry run. - if builder.config.dry_run { + if builder.config.dry_run() { return; } @@ -1818,7 +1818,7 @@ impl Step for Extended { let _time = timeit(builder); builder.run(&mut cmd); - if !builder.config.dry_run { + if !builder.config.dry_run() { t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename))); } } @@ -1882,12 +1882,12 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir if llvm_dylib_path.exists() { builder.install(&llvm_dylib_path, dst_libdir, 0o644); } - !builder.config.dry_run + !builder.config.dry_run() } else if let Ok(llvm_config) = crate::native::prebuilt_llvm_config(builder, target) { let mut cmd = Command::new(llvm_config); cmd.arg("--libfiles"); builder.verbose(&format!("running {:?}", cmd)); - let files = if builder.config.dry_run { "".into() } else { output(&mut cmd) }; + let files = if builder.config.dry_run() { "".into() } else { output(&mut cmd) }; let build_llvm_out = &builder.llvm_out(builder.config.build); let target_llvm_out = &builder.llvm_out(target); for file in files.trim_end().split(' ') { @@ -1899,7 +1899,7 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir }; builder.install(&file, dst_libdir, 0o644); } - !builder.config.dry_run + !builder.config.dry_run() } else { false } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 280e232ca2dd0..c7d21bf3cdb3f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -151,7 +151,7 @@ impl Step for RustbookSrc { let index = out.join("index.html"); let rustbook = builder.tool_exe(Tool::Rustbook); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - if builder.config.dry_run || up_to_date(&src, &index) && up_to_date(&rustbook, &index) { + if builder.config.dry_run() || up_to_date(&src, &index) && up_to_date(&rustbook, &index) { return; } builder.info(&format!("Rustbook ({}) - {}", target, name)); @@ -331,8 +331,8 @@ impl Step for Standalone { && up_to_date(&footer, &html) && up_to_date(&favicon, &html) && up_to_date(&full_toc, &html) - && (builder.config.dry_run || up_to_date(&version_info, &html)) - && (builder.config.dry_run || up_to_date(&rustdoc, &html)) + && (builder.config.dry_run() || up_to_date(&version_info, &html)) + && (builder.config.dry_run() || up_to_date(&rustdoc, &html)) { continue; } @@ -402,7 +402,7 @@ impl Step for SharedAssets { let version_input = builder.src.join("src").join("doc").join("version_info.html.template"); let version_info = out.join("version_info.html"); - if !builder.config.dry_run && !up_to_date(&version_input, &version_info) { + if !builder.config.dry_run() && !up_to_date(&version_input, &version_info) { let info = t!(fs::read_to_string(&version_input)) .replace("VERSION", &builder.rust_release()) .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or("")) @@ -900,7 +900,7 @@ impl Step for UnstableBookGen { } fn symlink_dir_force(config: &Config, src: &Path, dst: &Path) -> io::Result<()> { - if config.dry_run { + if config.dry_run() { return Ok(()); } if let Ok(m) = fs::symlink_metadata(dst) { diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 37322670e6564..5e7264fe765a9 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -43,7 +43,7 @@ struct RustfmtConfig { } pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { - if build.config.dry_run { + if build.config.dry_run() { return; } let mut builder = ignore::types::TypesBuilder::new(); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f5def8ba8341f..7dfd75a53519f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -112,7 +112,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use config::Target; +use config::{DryRun, Target}; use filetime::FileTime; use once_cell::sync::OnceCell; @@ -430,7 +430,7 @@ impl Build { // we always try to use git for LLVM builds let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project")); - let initial_target_libdir_str = if config.dry_run { + let initial_target_libdir_str = if config.dry_run() { "/dummy/lib/path/to/lib/".to_string() } else { output( @@ -444,7 +444,7 @@ impl Build { let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap(); let initial_lld = initial_target_dir.join("bin").join("rust-lld"); - let initial_sysroot = if config.dry_run { + let initial_sysroot = if config.dry_run() { "/dummy".to_string() } else { output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot")) @@ -689,13 +689,13 @@ impl Build { } } - if !self.config.dry_run { + if !self.config.dry_run() { { - self.config.dry_run = true; + self.config.dry_run = DryRun::SelfCheck; let builder = builder::Builder::new(&self); builder.execute_cli(); } - self.config.dry_run = false; + self.config.dry_run = DryRun::Disabled; let builder = builder::Builder::new(&self); builder.execute_cli(); } else { @@ -947,7 +947,7 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. fn run(&self, cmd: &mut Command) { - if self.config.dry_run { + if self.config.dry_run() { return; } self.verbose(&format!("running: {:?}", cmd)); @@ -956,7 +956,7 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. fn run_quiet(&self, cmd: &mut Command) { - if self.config.dry_run { + if self.config.dry_run() { return; } self.verbose(&format!("running: {:?}", cmd)); @@ -967,7 +967,7 @@ impl Build { /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. fn try_run(&self, cmd: &mut Command) -> bool { - if self.config.dry_run { + if self.config.dry_run() { return true; } self.verbose(&format!("running: {:?}", cmd)); @@ -978,7 +978,7 @@ impl Build { /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. fn try_run_quiet(&self, cmd: &mut Command) -> bool { - if self.config.dry_run { + if self.config.dry_run() { return true; } self.verbose(&format!("running: {:?}", cmd)); @@ -989,7 +989,7 @@ impl Build { /// Returns false if do not execute at all, otherwise returns its /// `status.success()`. fn check_run(&self, cmd: &mut Command) -> bool { - if self.config.dry_run { + if self.config.dry_run() { return true; } self.verbose(&format!("running: {:?}", cmd)); @@ -1019,7 +1019,7 @@ impl Build { } fn info(&self, msg: &str) { - if self.config.dry_run { + if self.config.dry_run() { return; } println!("{}", msg); @@ -1400,7 +1400,7 @@ impl Build { } fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> { - if self.config.dry_run { + if self.config.dry_run() { return Vec::new(); } @@ -1440,7 +1440,7 @@ impl Build { } fn copy_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) { - if self.config.dry_run { + if self.config.dry_run() { return; } self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst)); @@ -1477,7 +1477,7 @@ impl Build { /// Copies the `src` directory recursively to `dst`. Both are assumed to exist /// when this function is called. pub fn cp_r(&self, src: &Path, dst: &Path) { - if self.config.dry_run { + if self.config.dry_run() { return; } for f in self.read_dir(src) { @@ -1530,7 +1530,7 @@ impl Build { } fn install(&self, src: &Path, dstdir: &Path, perms: u32) { - if self.config.dry_run { + if self.config.dry_run() { return; } let dst = dstdir.join(src.file_name().unwrap()); @@ -1544,28 +1544,28 @@ impl Build { } fn create(&self, path: &Path, s: &str) { - if self.config.dry_run { + if self.config.dry_run() { return; } t!(fs::write(path, s)); } fn read(&self, path: &Path) -> String { - if self.config.dry_run { + if self.config.dry_run() { return String::new(); } t!(fs::read_to_string(path)) } fn create_dir(&self, dir: &Path) { - if self.config.dry_run { + if self.config.dry_run() { return; } t!(fs::create_dir_all(dir)) } fn remove_dir(&self, dir: &Path) { - if self.config.dry_run { + if self.config.dry_run() { return; } t!(fs::remove_dir_all(dir)) @@ -1574,7 +1574,7 @@ impl Build { fn read_dir(&self, dir: &Path) -> impl Iterator<Item = fs::DirEntry> { let iter = match fs::read_dir(dir) { Ok(v) => v, - Err(_) if self.config.dry_run => return vec![].into_iter(), + Err(_) if self.config.dry_run() => return vec![].into_iter(), Err(err) => panic!("could not read dir {:?}: {:?}", dir, err), }; iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter() @@ -1585,11 +1585,11 @@ impl Build { use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; - if !self.config.dry_run { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } + if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } } fn remove(&self, f: &Path) { - if self.config.dry_run { + if self.config.dry_run() { return; } fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f)); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 94a61b727a32b..2407291ceea30 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -226,7 +226,7 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { let llvm_stamp = llvm_root.join(".llvm-stamp"); let llvm_sha = detect_llvm_sha(&config, builder.rust_info.is_managed_git_subrepository()); let key = format!("{}{}", llvm_sha, config.llvm_assertions); - if program_out_of_date(&llvm_stamp, &key) && !config.dry_run { + if program_out_of_date(&llvm_stamp, &key) && !config.dry_run() { download_ci_llvm(builder, &llvm_sha); for entry in t!(fs::read_dir(llvm_root.join("bin"))) { builder.fix_bin_or_dylib(&t!(entry).path()); @@ -505,7 +505,7 @@ impl Step for Llvm { // https://llvm.org/docs/HowToCrossCompileLLVM.html if target != builder.config.build { let llvm_config = builder.ensure(Llvm { target: builder.config.build }); - if !builder.config.dry_run { + if !builder.config.dry_run() { let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir")); let host_bin = Path::new(llvm_bindir.trim()); cfg.define( @@ -519,7 +519,7 @@ impl Step for Llvm { if builder.config.llvm_clang { let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin"); let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION); - if !builder.config.dry_run && !clang_tblgen.exists() { + if !builder.config.dry_run() && !clang_tblgen.exists() { panic!("unable to find {}", clang_tblgen.display()); } cfg.define("CLANG_TABLEGEN", clang_tblgen); @@ -553,7 +553,7 @@ impl Step for Llvm { // tools. Figure out how to filter them down and only build the right // tools and libs on all platforms. - if builder.config.dry_run { + if builder.config.dry_run() { return build_llvm_config; } @@ -611,7 +611,7 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { return; } - if builder.config.dry_run { + if builder.config.dry_run() { return; } @@ -872,7 +872,7 @@ impl Step for Lld { /// Compile LLD for `target`. fn run(self, builder: &Builder<'_>) -> PathBuf { - if builder.config.dry_run { + if builder.config.dry_run() { return PathBuf::from("lld-out-dir-test-gen"); } let target = self.target; @@ -990,7 +990,7 @@ impl Step for TestHelpers { /// Compiles the `rust_test_helpers.c` library which we used in various /// `run-pass` tests for ABI testing. fn run(self, builder: &Builder<'_>) { - if builder.config.dry_run { + if builder.config.dry_run() { return; } // The x86_64-fortanix-unknown-sgx target doesn't have a working C @@ -1066,7 +1066,7 @@ impl Step for Sanitizers { } let llvm_config = builder.ensure(Llvm { target: builder.config.build }); - if builder.config.dry_run { + if builder.config.dry_run() { return runtimes; } @@ -1240,7 +1240,7 @@ impl Step for CrtBeginEnd { fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); - if builder.config.dry_run { + if builder.config.dry_run() { return out_dir; } @@ -1304,7 +1304,7 @@ impl Step for Libunwind { /// Build linunwind.a fn run(self, builder: &Builder<'_>) -> Self::Output { - if builder.config.dry_run { + if builder.config.dry_run() { return PathBuf::new(); } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index bdfd5fe5c421c..35c66cfd95f2f 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -163,7 +163,7 @@ than building it. continue; } - if !build.config.dry_run { + if !build.config.dry_run() { cmd_finder.must_have(build.cc(*target)); if let Some(ar) = build.ar(*target) { cmd_finder.must_have(ar); @@ -172,7 +172,7 @@ than building it. } for host in &build.hosts { - if !build.config.dry_run { + if !build.config.dry_run() { cmd_finder.must_have(build.cxx(*host).unwrap()); } } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index d999b6c150333..82b063583c9f9 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -323,7 +323,7 @@ impl<'a> Tarball<'a> { // Ensure there are no symbolic links in the tarball. In particular, // rustup-toolchain-install-master and most versions of Windows can't handle symbolic links. let decompressed_output = self.temp_dir.join(&package_name); - if !self.builder.config.dry_run && !self.permit_symlinks { + if !self.builder.config.dry_run() && !self.permit_symlinks { for entry in walkdir::WalkDir::new(&decompressed_output) { let entry = t!(entry); if entry.path_is_symlink() { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 2b2257b72ae79..fd362b8367cc0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -508,7 +508,7 @@ impl Miri { cargo.arg("--print-sysroot"); // FIXME: Is there a way in which we can re-use the usual `run` helpers? - if builder.config.dry_run { + if builder.config.dry_run() { String::new() } else { builder.verbose(&format!("running: {:?}", cargo)); @@ -1537,7 +1537,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the let mut copts_passed = false; if builder.config.llvm_enabled() { let llvm_config = builder.ensure(native::Llvm { target: builder.config.build }); - if !builder.config.dry_run { + if !builder.config.dry_run() { let llvm_version = output(Command::new(&llvm_config).arg("--version")); let llvm_components = output(Command::new(&llvm_config).arg("--components")); // Remove trailing newline from llvm-config output. @@ -1555,14 +1555,14 @@ note: if you're sure you want to do this, please open an issue as to why. In the // requirement, but the `-L` library path is not propagated across // separate compilations. We can add LLVM's library path to the // platform-specific environment variable as a workaround. - if !builder.config.dry_run && suite.ends_with("fulldeps") { + if !builder.config.dry_run() && suite.ends_with("fulldeps") { let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); } // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. let llvm_bin_path = llvm_config @@ -1590,7 +1590,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d395220694705..ba329ea6c7592 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -522,7 +522,7 @@ impl Step for Rustdoc { builder.ensure(compile::Rustc::new(build_compiler, target_compiler.host)); // NOTE: this implies that `download-rustc` is pretty useless when compiling with the stage0 // compiler, since you do just as much work. - if !builder.config.dry_run && builder.download_rustc() && build_compiler.stage == 0 { + if !builder.config.dry_run() && builder.download_rustc() && build_compiler.stage == 0 { println!( "warning: `download-rustc` does nothing when building stage1 tools; consider using `--stage 2` instead" ); diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 1a17744322753..1969e0b6f8722 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -158,7 +158,7 @@ impl Step for ToolStateCheck { /// stable tool. That is, the status is not allowed to get worse /// (test-pass to test-fail or build-fail). fn run(self, builder: &Builder<'_>) { - if builder.config.dry_run { + if builder.config.dry_run() { return; } @@ -265,7 +265,7 @@ impl Builder<'_> { // If we're in a dry run setting we don't want to save toolstates as // that means if we e.g. panic down the line it'll look like we tested // everything (but we actually haven't). - if self.config.dry_run { + if self.config.dry_run() { return; } // Toolstate isn't tracked for clippy or rustfmt, but since most tools do, we avoid checking diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 20c3801f0a502..8a2f46abbd23c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -105,7 +105,7 @@ pub struct TimeIt(bool, Instant); /// Returns an RAII structure that prints out how long it took to drop. pub fn timeit(builder: &Builder<'_>) -> TimeIt { - TimeIt(builder.config.dry_run, Instant::now()) + TimeIt(builder.config.dry_run(), Instant::now()) } impl Drop for TimeIt { @@ -128,7 +128,7 @@ pub(crate) fn program_out_of_date(stamp: &Path, key: &str) -> bool { /// Symlinks two directories, using junctions on Windows and normal symlinks on /// Unix. pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { - if config.dry_run { + if config.dry_run() { return Ok(()); } let _ = fs::remove_dir(dest); From 24378885c8ca7e3cae25723da577445d200fe8e8 Mon Sep 17 00:00:00 2001 From: Joshua Nelson <jnelson@cloudflare.com> Date: Sun, 6 Nov 2022 17:00:58 -0600 Subject: [PATCH 11/12] Print "Checking/Building ..." message even when --dry-run is passed This makes it a lot easier to understand what commands will be run without having to parse the `-vv` output, which isn't meant to be user facing. --- src/bootstrap/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 7dfd75a53519f..bbb5a18ba07ba 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1019,10 +1019,12 @@ impl Build { } fn info(&self, msg: &str) { - if self.config.dry_run() { - return; + match self.config.dry_run { + DryRun::SelfCheck => return, + DryRun::Disabled | DryRun::UserSelected => { + println!("{}", msg); + } } - println!("{}", msg); } /// Returns the number of parallel jobs that have been configured for this From 01b9c8847a6b09988b70603878f10c9859bf2029 Mon Sep 17 00:00:00 2001 From: Joshua Nelson <jnelson@cloudflare.com> Date: Thu, 27 Oct 2022 13:00:55 -0500 Subject: [PATCH 12/12] Don't set `is_preview` for clippy and rustfmt These have been shipped on stable for many years now and it would be very disruptive to ever remove them. Remove the `-preview` suffix from their dist components. --- src/bootstrap/dist.rs | 2 -- src/tools/build-manifest/src/versions.rs | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 110a3ee4918da..e95170b8818ca 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1153,7 +1153,6 @@ impl Step for Clippy { let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); - tarball.is_preview(true); tarball.add_file(clippy, "bin", 0o755); tarball.add_file(cargoclippy, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/clippy"); @@ -1251,7 +1250,6 @@ impl Step for Rustfmt { .expect("cargo fmt expected to build - essential tool"); let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); tarball.set_overlay(OverlayKind::Rustfmt); - tarball.is_preview(true); tarball.add_file(rustfmt, "bin", 0o755); tarball.add_file(cargofmt, "bin", 0o755); tarball.add_legal_and_readme_to("share/doc/rustfmt"); diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index dde9745afb785..66e6982d6b4d3 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -49,10 +49,10 @@ pkg_type! { Cargo = "cargo", HtmlDocs = "rust-docs", RustAnalysis = "rust-analysis", + Clippy = "clippy", + Rustfmt = "rustfmt", Rls = "rls"; preview = true, RustAnalyzer = "rust-analyzer"; preview = true, - Clippy = "clippy"; preview = true, - Rustfmt = "rustfmt"; preview = true, LlvmTools = "llvm-tools"; preview = true, Miri = "miri"; preview = true, JsonDocs = "rust-docs-json"; preview = true,