From 3ae5fed04c94be2f8591c7f4ab76f78ec882cd32 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 6 Apr 2021 15:34:29 -0400 Subject: [PATCH 01/21] Fix a couple resolve bugs from binder refactor --- compiler/rustc_resolve/src/late/lifetimes.rs | 16 +++++++++++++++- ...3-invalid-associated-type-supertrait-hrtb.rs | 8 ++++++++ ...valid-associated-type-supertrait-hrtb.stderr | 9 +++++++++ .../issue-83907-invalid-fn-like-path.rs | 7 +++++++ .../issue-83907-invalid-fn-like-path.stderr | 17 +++++++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs create mode 100644 src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr create mode 100644 src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.rs create mode 100644 src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index b89ad867f46..70ddfcc9004 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2659,6 +2659,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Some(next) => next, None => break None, }; + // See issue #83753. If someone writes an associated type on a non-trait, just treat it as + // there being no supertrait HRTBs. + match tcx.def_kind(def_id) { + DefKind::Trait | DefKind::TraitAlias | DefKind::Impl => {} + _ => break None, + } + if trait_defines_associated_type_named(def_id) { break Some(bound_vars.into_iter().collect()); } @@ -2703,7 +2710,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { | Scope::Supertrait { ref s, .. } => { scope = *s; } - Scope::Root => bug!("In fn_like_elision without appropriate scope above"), + Scope::Root => { + // See issue #83907. Just bail out from looking inside. + self.tcx.sess.delay_span_bug( + rustc_span::DUMMY_SP, + "In fn_like_elision without appropriate scope above", + ); + return; + } } }; // While not strictly necessary, we gather anon lifetimes *before* actually diff --git a/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs b/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs new file mode 100644 index 00000000000..7f0ea730dd3 --- /dev/null +++ b/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs @@ -0,0 +1,8 @@ +// check-fail + +struct Foo {} +impl Foo { + fn bar(foo: Foo) {} + //~^ associated type bindings are not allowed here +} +fn main() {} diff --git a/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr b/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr new file mode 100644 index 00000000000..f7bdee6336e --- /dev/null +++ b/src/test/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21 + | +LL | fn bar(foo: Foo) {} + | ^^^^^^^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.rs b/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.rs new file mode 100644 index 00000000000..604687ce711 --- /dev/null +++ b/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.rs @@ -0,0 +1,7 @@ +// check-fail + +static STATIC_VAR_FIVE: &One(); +//~^ cannot find type +//~| free static item without body + +fn main() {} diff --git a/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr b/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr new file mode 100644 index 00000000000..e57933da558 --- /dev/null +++ b/src/test/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr @@ -0,0 +1,17 @@ +error: free static item without body + --> $DIR/issue-83907-invalid-fn-like-path.rs:3:1 + | +LL | static STATIC_VAR_FIVE: &One(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the static: `= ;` + +error[E0412]: cannot find type `One` in this scope + --> $DIR/issue-83907-invalid-fn-like-path.rs:3:26 + | +LL | static STATIC_VAR_FIVE: &One(); + | ^^^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0412`. From c96f86de3026f864e78397aff9097e885f2f8fdf Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 20 Mar 2021 17:36:19 -0700 Subject: [PATCH 02/21] rustdoc: Stop hiding entire item declarations --- src/librustdoc/html/render/mod.rs | 11 ----------- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/html/static/main.js | 25 ++++-------------------- 3 files changed, 5 insertions(+), 33 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fbe799e7184..ca754fa347b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -486,17 +486,6 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result(w: &mut Buffer, f: F) where F: FnOnce(&mut Buffer), { - w.write_str("
"); + w.write_str("
"); f(w); w.write_str("
") } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 80dc6b923f6..0abfe18a19f 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2683,18 +2683,7 @@ function hideThemeButtonState() { }); } } - var showItemDeclarations = getSettingValue("auto-hide-" + className); - if (showItemDeclarations === null) { - if (className === "enum" || className === "macro") { - showItemDeclarations = "false"; - } else if (className === "struct" || className === "union" || className === "trait") { - showItemDeclarations = "true"; - } else { - // In case we found an unknown type, we just use the "parent" value. - showItemDeclarations = getSettingValue("auto-hide-declarations"); - } - } - showItemDeclarations = showItemDeclarations === "false"; + function buildToggleWrapper(e) { if (hasClass(e, "autohide")) { var wrap = e.previousElementSibling; @@ -2721,11 +2710,8 @@ function hideThemeButtonState() { var extraClass; if (hasClass(e, "type-decl")) { - fontSize = "20px"; - otherMessage = " Show declaration"; - if (showItemDeclarations === false) { - extraClass = "collapsed"; - } + // We do something special for these + return; } else if (hasClass(e, "sub-variant")) { otherMessage = " Show fields"; } else if (hasClass(e, "non-exhaustive")) { @@ -2750,11 +2736,8 @@ function hideThemeButtonState() { otherMessage, fontSize, extraClass, - hasClass(e, "type-decl") === false || showItemDeclarations === true), + false), e); - if (hasClass(e, "type-decl") === true && showItemDeclarations === true) { - collapseDocs(e.previousSibling.childNodes[0], "toggle"); - } if (hasClass(e, "non-exhaustive") === true) { collapseDocs(e.previousSibling.childNodes[0], "toggle"); } From 71c52acf32efb48975edb86a1cef1df810f60c45 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 20 Mar 2021 19:02:25 -0700 Subject: [PATCH 03/21] rustdoc: hide variants of enums > 5 --- src/librustdoc/html/render/print_item.rs | 24 ++++++++++++++++++++++++ src/librustdoc/html/static/main.js | 4 ++++ src/librustdoc/html/static/rustdoc.css | 13 ++++++------- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6c0c8a01014..3b9750a8d63 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -131,6 +131,23 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) } } +/// For large structs, enums, unions, etc, determine whether to hide their fields +fn should_hide_fields(n_fields: usize) -> bool { + // todo: figure out what this should be + n_fields > 5 +} + +fn toggle_open(w: &mut Buffer, text: &str) +{ + write!(w, "
", text); +} + +fn toggle_close(w: &mut Buffer) +{ + w.write_str("
"); +} + + fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { document(w, cx, item, None); @@ -816,6 +833,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum w.write_str(" {}"); } else { w.write_str(" {\n"); + let toggle = should_hide_fields(e.variants.len()); + if toggle { + toggle_open(w, "variants"); + } for v in &e.variants { w.write_str(" "); let name = v.name.as_ref().unwrap(); @@ -844,6 +865,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum if e.variants_stripped { w.write_str(" // some variants omitted\n"); } + if toggle { + toggle_close(w); + } w.write_str("}"); } w.write_str("") diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 0abfe18a19f..f112a113adc 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2703,6 +2703,10 @@ function hideThemeButtonState() { } }); } + } else if (hasClass(e, "type-contents-toggle")) { + let text = e.getAttribute("data-toggle-text"); + let tog = createToggle(toggle, `Show ${text}`, null, "", true); + e.parentNode.insertBefore(tog, e); } if (e.parentNode.id === "main") { var otherMessage = ""; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 585b7459bd7..3a171a1d652 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -970,6 +970,10 @@ a.test-arrow:hover{ position: absolute; left: -23px; top: 0; + + /* The click event for this is defined on the document, + so bubbling does not work. See https://github.com/rust-lang/rust/issues/83332 */ + z-index: 10; } h3 > .collapse-toggle, h4 > .collapse-toggle { @@ -1054,10 +1058,9 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { margin-top: 3px; } +/* for enum and struct fields */ .enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock { - margin-left: 30px; - margin-bottom: 20px; - margin-top: 5px; + margin-left: 0px; } .docblock > .section-header:first-child { @@ -1069,10 +1072,6 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { left: -10px; } -.enum > .collapsed, .struct > .collapsed { - margin-bottom: 25px; -} - #main > .variant, #main > .structfield { display: block; } From f146b9701df0e26dad61422089d3a7e9a49989c5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 20 Mar 2021 19:11:49 -0700 Subject: [PATCH 04/21] rustdoc: hide fields of structs/unions > 5 --- src/librustdoc/html/render/print_item.rs | 37 +++++++++++++++++++----- src/librustdoc/html/static/rustdoc.css | 2 +- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3b9750a8d63..b6e9a8e244a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -137,17 +137,14 @@ fn should_hide_fields(n_fields: usize) -> bool { n_fields > 5 } -fn toggle_open(w: &mut Buffer, text: &str) -{ +fn toggle_open(w: &mut Buffer, text: &str) { write!(w, "
", text); } -fn toggle_close(w: &mut Buffer) -{ +fn toggle_close(w: &mut Buffer) { w.write_str("
"); } - fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { document(w, cx, item, None); @@ -1285,6 +1282,17 @@ fn render_union( } write!(w, " {{\n{}", tab); + let count_fields = fields + .iter() + .filter( + |f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }, + ) + .count(); + let toggle = should_hide_fields(count_fields); + if toggle { + toggle_open(w, "fields"); + } + for field in fields { if let clean::StructFieldItem(ref ty) = *field.kind { write!( @@ -1301,6 +1309,9 @@ fn render_union( if it.has_stripped_fields().unwrap() { write!(w, " // some fields omitted\n{}", tab); } + if toggle { + toggle_close(w); + } w.write_str("}"); } @@ -1329,8 +1340,18 @@ fn render_struct( if let Some(g) = g { write!(w, "{}", print_where_clause(g, cx.cache(), cx.tcx(), 0, true),) } - let mut has_visible_fields = false; w.write_str(" {"); + let count_fields = fields + .iter() + .filter( + |f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }, + ) + .count(); + let has_visible_fields = count_fields > 0; + let toggle = should_hide_fields(count_fields); + if toggle { + toggle_open(w, "fields"); + } for field in fields { if let clean::StructFieldItem(ref ty) = *field.kind { write!( @@ -1341,7 +1362,6 @@ fn render_struct( field.name.as_ref().unwrap(), ty.print(cx.cache(), cx.tcx()), ); - has_visible_fields = true; } } @@ -1355,6 +1375,9 @@ fn render_struct( // `{ /* fields omitted */ }` to save space. write!(w, " /* fields omitted */ "); } + if toggle { + toggle_close(w); + } w.write_str("}"); } CtorKind::Fn => { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 3a171a1d652..2cdacbe0b06 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1059,7 +1059,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { } /* for enum and struct fields */ -.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock { +.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock, .union > .toggle-wrapper + .docblock { margin-left: 0px; } From 173cbecc66ee1bbb54c039a00c3b75b4cdf7e277 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 20 Mar 2021 19:39:29 -0700 Subject: [PATCH 05/21] rustdoc: smartly hide associated items of traits if there are too many of them --- src/librustdoc/html/render/print_item.rs | 30 ++++++++++++++++----- src/librustdoc/html/static/rustdoc.css | 6 ++--- src/librustdoc/html/static/themes/ayu.css | 2 +- src/librustdoc/html/static/themes/dark.css | 2 +- src/librustdoc/html/static/themes/light.css | 2 +- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index b6e9a8e244a..8db78e7718d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -443,10 +443,25 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } else { // FIXME: we should be using a derived_id for the Anchors here w.write_str("{\n"); + let mut toggle = false; + + // If there are too many associated types, hide _everything_ + if should_hide_fields(types.len()) { + toggle = true; + toggle_open(w, "associated items"); + } for t in &types { render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); w.write_str(";\n"); } + // If there are too many associated constants, hide everything after them + // We also do this if the types + consts is large because otherwise we could + // render a bunch of types and _then_ a bunch of consts just because both were + // _just_ under the limit + if !toggle & should_hide_fields(types.len() + consts.len()) { + toggle = true; + toggle_open(w, "associated constants and methods"); + } if !types.is_empty() && !consts.is_empty() { w.write_str("\n"); } @@ -454,6 +469,10 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); w.write_str(";\n"); } + if !toggle & should_hide_fields(required.len() + provided.len()) { + toggle = true; + toggle_open(w, "methods"); + } if !consts.is_empty() && !required.is_empty() { w.write_str("\n"); } @@ -484,6 +503,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w.write_str("
"); } } + if toggle { + toggle_close(w); + } w.write_str("}"); } w.write_str("") @@ -1284,9 +1306,7 @@ fn render_union( write!(w, " {{\n{}", tab); let count_fields = fields .iter() - .filter( - |f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }, - ) + .filter(|f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }) .count(); let toggle = should_hide_fields(count_fields); if toggle { @@ -1343,9 +1363,7 @@ fn render_struct( w.write_str(" {"); let count_fields = fields .iter() - .filter( - |f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }, - ) + .filter(|f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }) .count(); let has_visible_fields = count_fields > 0; let toggle = should_hide_fields(count_fields); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 2cdacbe0b06..309e55670b1 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1058,8 +1058,8 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { margin-top: 3px; } -/* for enum and struct fields */ -.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock, .union > .toggle-wrapper + .docblock { +/* for hiding fields/variants/associated items */ +.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock, .union > .toggle-wrapper + .docblock, .trait > .toggle-wrapper + .docblock { margin-left: 0px; } @@ -1785,7 +1785,7 @@ div.name.expand::before { .type-decl > pre > .docblock.attributes.top-attr { margin-left: 1.8em !important; } -.type-decl > pre > .toggle-attributes { +.type-decl > pre .toggle-attributes { margin-left: 2.2em; } .type-decl > pre > .docblock.attributes { diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index b24f4035ca8..0404fa50b99 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -218,7 +218,7 @@ a { color: #c5c5c5; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #39AFD7; diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index e863ed03f51..15b485a966f 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -176,7 +176,7 @@ a { color: #ddd; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #D2991D; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 9335dd96d29..4c83879e234 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -174,7 +174,7 @@ a { color: #000; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #3873AD; From 256e594b0a75ddc792adb35e3810d29133ee0f79 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 20 Mar 2021 19:44:55 -0700 Subject: [PATCH 06/21] rustdoc: Add setting for hiding large items --- src/librustdoc/html/render/mod.rs | 1 + src/librustdoc/html/static/main.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index ca754fa347b..00a19006bb9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -486,6 +486,7 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result Date: Mon, 22 Mar 2021 09:08:52 -0700 Subject: [PATCH 07/21] Update src/librustdoc/html/render/print_item.rs Co-authored-by: Joshua Nelson --- src/librustdoc/html/render/print_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 8db78e7718d..6272790740e 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1363,7 +1363,7 @@ fn render_struct( w.write_str(" {"); let count_fields = fields .iter() - .filter(|f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }) + .filter(|f| matches!(clean::StructFieldItem(..) = *f.kind)) .count(); let has_visible_fields = count_fields > 0; let toggle = should_hide_fields(count_fields); From 846a4e9b5cc49ab42a62a15cd2813b0be34fb868 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 22 Mar 2021 09:08:58 -0700 Subject: [PATCH 08/21] Update src/librustdoc/html/render/print_item.rs Co-authored-by: Joshua Nelson --- src/librustdoc/html/render/print_item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 6272790740e..d5a5ecd3e88 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1306,7 +1306,7 @@ fn render_union( write!(w, " {{\n{}", tab); let count_fields = fields .iter() - .filter(|f| if let clean::StructFieldItem(..) = *f.kind { true } else { false }) + .filter(|f| matches!(clean::StructFieldItem(..), *f.kind)) .count(); let toggle = should_hide_fields(count_fields); if toggle { From def144c2e752cf2040d21fbd0cf04f5779cce898 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 27 Mar 2021 12:50:09 -0700 Subject: [PATCH 09/21] Improve CSS for "hide contents, not items" Introduce a first use of the `
` and `` tags as replacements for the JS-built toggles. I think this has the potential to replace all the JS toggles and generally clean up the JS, CSS, and HTML. Split rendering of attributes into two cases: in the case where they are rendered as descendents of a `
` tag, where they use indent spaces and
newlines for formatting, matching their surrounding markup. In the case
where they are rendered as descendants of a `` tag, they are
rendered as `
`. This let me clean up some fragile CSS that was adjusting the margin-left of attributes depending on context. Remove toggles for attributes. With the ALLOWED_ATTRIBUTES filter, it's rare for an item to have more than one attribute, so hiding attributes behind a toggle doesn't save any screen space in the common case. Fix a couple of invocations of `matches!` that didn't compile on my machine. Fix a boolean for the JS `createToggle` call that was causing "Expand description" to show up spuriously on already-expanded descriptions. Add JS for auto-hide settings and hide all / show all. Remove a z-index property and some font color tweaks made unnecessary by the
toggles. Add CSS for the
toggles. --- src/librustdoc/html/render/mod.rs | 52 +++++++------ src/librustdoc/html/render/print_item.rs | 46 ++++++------ src/librustdoc/html/static/main.js | 58 ++++---------- src/librustdoc/html/static/rustdoc.css | 83 ++++++++++++--------- src/librustdoc/html/static/storage.js | 1 - src/librustdoc/html/static/themes/ayu.css | 2 +- src/librustdoc/html/static/themes/dark.css | 2 +- src/librustdoc/html/static/themes/light.css | 2 +- 8 files changed, 116 insertions(+), 130 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 00a19006bb9..d0d9034f6e6 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -43,7 +43,6 @@ use std::path::PathBuf; use std::str; use std::string::ToString; -use itertools::Itertools; use rustc_ast_pretty::pprust; use rustc_attr::{Deprecation, StabilityLevel}; use rustc_data_structures::fx::FxHashSet; @@ -487,7 +486,6 @@ fn settings(root_path: &str, suffix: &str, themes: &[StylePath]) -> Result{".len() + "".len()); write!( w, "{}{}{}{}{}{}{}fn {name}\ {generics}{decl}{notable_traits}{where_clause}", - if parent == ItemType::Trait { " " } else { "" }, + indent_str, vis, constness, asyncness, @@ -1004,35 +1004,33 @@ const ALLOWED_ATTRIBUTES: &[Symbol] = &[ sym::non_exhaustive, ]; -// The `top` parameter is used when generating the item declaration to ensure it doesn't have a -// left padding. For example: -// -// #[foo] <----- "top" attribute -// struct Foo { -// #[bar] <---- not "top" attribute -// bar: usize, -// } -fn render_attributes(w: &mut Buffer, it: &clean::Item, top: bool) { - let attrs = it - .attrs +fn attributes(it: &clean::Item) -> Vec { + it.attrs .other_attrs .iter() .filter_map(|attr| { if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { - Some(pprust::attribute_to_string(&attr)) + Some(pprust::attribute_to_string(&attr).replace("\n", "").replace(" ", " ")) } else { None } }) - .join("\n"); + .collect() +} - if !attrs.is_empty() { - write!( - w, - "{}", - if top { " top-attr" } else { "" }, - &attrs - ); +// When an attribute is rendered inside a `
` tag, it is formatted using
+// a whitespace prefix and newline.
+fn render_attributes_in_pre(w: &mut Buffer, it: &clean::Item, prefix: &str) {
+    for a in attributes(it) {
+        write!(w, "{}{}\n", prefix, a);
+    }
+}
+
+// When an attribute is rendered inside a  tag, it is formatted using
+// a div to produce a newline after it.
+fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item) {
+    for a in attributes(it) {
+        write!(w, "
{}
", a); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index d5a5ecd3e88..03c4bb837f5 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -11,8 +11,8 @@ use rustc_span::symbol::{kw, sym, Symbol}; use super::{ collect_paths_for_type, document, ensure_trailing_slash, item_ty_to_strs, notable_traits_decl, - render_assoc_item, render_assoc_items, render_attributes, render_impl, - render_stability_since_raw, write_srclink, AssocItemLink, Context, + render_assoc_item, render_assoc_items, render_attributes_in_code, render_attributes_in_pre, + render_impl, render_stability_since_raw, write_srclink, AssocItemLink, Context, }; use crate::clean::{self, GetDefId}; use crate::formats::cache::Cache; @@ -138,11 +138,15 @@ fn should_hide_fields(n_fields: usize) -> bool { } fn toggle_open(w: &mut Buffer, text: &str) { - write!(w, "
", text); + write!( + w, + "
Show {}", + text + ); } fn toggle_close(w: &mut Buffer) { - w.write_str("
"); + w.write_str("
"); } fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) { @@ -391,7 +395,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: ) .len(); w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_pre(w, it, "");
     write!(
         w,
         "{vis}{constness}{asyncness}{unsafety}{abi}fn \
@@ -420,7 +424,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
     // Output the trait definition
     wrap_into_docblock(w, |w| {
         w.write_str("
");
-        render_attributes(w, it, true);
+        render_attributes_in_pre(w, it, "");
         write!(
             w,
             "{}{}{}trait {}{}{}",
@@ -729,7 +733,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
 
 fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
     w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_pre(w, it, "");
     write!(
         w,
         "trait {}{}{} = {};
", @@ -750,7 +754,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_pre(w, it, "");
     write!(
         w,
         "type {}{}{where_clause} = impl {bounds};
", @@ -771,7 +775,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean: fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_pre(w, it, "");
     write!(
         w,
         "type {}{}{where_clause} = {type_};
", @@ -793,7 +797,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { wrap_into_docblock(w, |w| { w.write_str("
");
-        render_attributes(w, it, true);
+        render_attributes_in_pre(w, it, "");
         render_union(w, it, Some(&s.generics), &s.fields, "", true, cx);
         w.write_str("
") }); @@ -839,7 +843,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { wrap_into_docblock(w, |w| { w.write_str("
");
-        render_attributes(w, it, true);
+        render_attributes_in_pre(w, it, "");
         write!(
             w,
             "{}enum {}{}{}",
@@ -1019,7 +1023,7 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
 
 fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
     w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_code(w, it);
 
     write!(
         w,
@@ -1058,7 +1062,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
 fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) {
     wrap_into_docblock(w, |w| {
         w.write_str("
");
-        render_attributes(w, it, true);
+        render_attributes_in_code(w, it);
         render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx);
         w.write_str("
") }); @@ -1107,7 +1111,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { w.write_str("
");
-    render_attributes(w, it, false);
+    render_attributes_in_code(w, it);
     write!(
         w,
         "{vis}static {mutability}{name}: {typ}
", @@ -1121,7 +1125,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { w.write_str("
extern {\n");
-    render_attributes(w, it, false);
+    render_attributes_in_code(w, it);
     write!(
         w,
         "    {}type {};\n}}
", @@ -1304,10 +1308,8 @@ fn render_union( } write!(w, " {{\n{}", tab); - let count_fields = fields - .iter() - .filter(|f| matches!(clean::StructFieldItem(..), *f.kind)) - .count(); + let count_fields = + fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count(); let toggle = should_hide_fields(count_fields); if toggle { toggle_open(w, "fields"); @@ -1361,10 +1363,8 @@ fn render_struct( write!(w, "{}", print_where_clause(g, cx.cache(), cx.tcx(), 0, true),) } w.write_str(" {"); - let count_fields = fields - .iter() - .filter(|f| matches!(clean::StructFieldItem(..) = *f.kind)) - .count(); + let count_fields = + fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count(); let has_visible_fields = count_fields > 0; let toggle = should_hide_fields(count_fields); if toggle { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index af66a7a135a..1b14f67fce1 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1,4 +1,3 @@ -// ignore-tidy-filelength // Local js definitions: /* global addClass, getSettingValue, hasClass */ /* global onEach, onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ @@ -2316,6 +2315,9 @@ function hideThemeButtonState() { if (hasClass(innerToggle, "will-expand")) { updateLocalStorage("rustdoc-collapse", "false"); removeClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByTagName("details"), function(e) { + e.open = true; + }); onEveryMatchingChild(innerToggle, "inner", function(e) { e.innerHTML = labelForToggleButton(false); }); @@ -2328,6 +2330,9 @@ function hideThemeButtonState() { } else { updateLocalStorage("rustdoc-collapse", "true"); addClass(innerToggle, "will-expand"); + onEachLazy(document.getElementsByTagName("details"), function(e) { + e.open = false; + }); onEveryMatchingChild(innerToggle, "inner", function(e) { var parent = e.parentNode; var superParent = null; @@ -2569,6 +2574,7 @@ function hideThemeButtonState() { var toggle = createSimpleToggle(false); var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false"; + let hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; var func = function(e) { var next = e.nextElementSibling; @@ -2615,6 +2621,14 @@ function hideThemeButtonState() { onEachLazy(document.getElementsByClassName("associatedconstant"), func); onEachLazy(document.getElementsByClassName("impl"), funcImpl); var impl_call = function() {}; + // Large items are hidden by default in the HTML. If the setting overrides that, show 'em. + if (!hideLargeItemContents) { + onEachLazy(document.getElementsByTagName("details"), function (e) { + if (hasClass(e, "type-contents-toggle")) { + e.open = true; + } + }); + } if (hideMethodDocs === true) { impl_call = function(e, newToggle) { if (e.id.match(/^impl(?:-\d+)?$/) === null) { @@ -2703,14 +2717,6 @@ function hideThemeButtonState() { } }); } - } else if (hasClass(e, "type-contents-toggle")) { - let text = e.getAttribute("data-toggle-text"); - let hideItemContents = getSettingValue("auto-hide-large-items") !== "false"; - let tog = createToggle(toggle, `Show ${text}`, null, "", !hideItemContents); - e.parentNode.insertBefore(tog, e); - if (hideItemContents) { - collapseDocs(e.previousSibling.childNodes[0], "toggle"); - } } if (e.parentNode.id === "main") { var otherMessage = ""; @@ -2744,7 +2750,7 @@ function hideThemeButtonState() { otherMessage, fontSize, extraClass, - false), + true), e); if (hasClass(e, "non-exhaustive") === true) { collapseDocs(e.previousSibling.childNodes[0], "toggle"); @@ -2763,38 +2769,6 @@ function hideThemeButtonState() { } }()); - function createToggleWrapper(tog) { - var span = document.createElement("span"); - span.className = "toggle-label"; - span.style.display = "none"; - span.innerHTML = " Expand attributes"; - tog.appendChild(span); - - var wrapper = document.createElement("div"); - wrapper.className = "toggle-wrapper toggle-attributes"; - wrapper.appendChild(tog); - return wrapper; - } - - (function() { - // To avoid checking on "rustdoc-item-attributes" value on every loop... - var itemAttributesFunc = function() {}; - if (getSettingValue("auto-hide-attributes") !== "false") { - itemAttributesFunc = function(x) { - collapseDocs(x.previousSibling.childNodes[0], "toggle"); - }; - } - var attributesToggle = createToggleWrapper(createSimpleToggle(false)); - onEachLazy(main.getElementsByClassName("attributes"), function(i_e) { - var attr_tog = attributesToggle.cloneNode(true); - if (hasClass(i_e, "top-attr") === true) { - addClass(attr_tog, "top-attr"); - } - i_e.parentNode.insertBefore(attr_tog, i_e); - itemAttributesFunc(i_e); - }); - }()); - (function() { // To avoid checking on "rustdoc-line-numbers" value on every loop... var lineNumbersFunc = function() {}; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 309e55670b1..64972bc2389 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -970,10 +970,6 @@ a.test-arrow:hover{ position: absolute; left: -23px; top: 0; - - /* The click event for this is defined on the document, - so bubbling does not work. See https://github.com/rust-lang/rust/issues/83332 */ - z-index: 10; } h3 > .collapse-toggle, h4 > .collapse-toggle { @@ -1058,11 +1054,6 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { margin-top: 3px; } -/* for hiding fields/variants/associated items */ -.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock, .union > .toggle-wrapper + .docblock, .trait > .toggle-wrapper + .docblock { - margin-left: 0px; -} - .docblock > .section-header:first-child { margin-left: 15px; margin-top: 0; @@ -1076,22 +1067,6 @@ h3 > .collapse-toggle, h4 > .collapse-toggle { display: block; } -.attributes { - display: block; - margin-top: 0px !important; - margin-right: 0px; - margin-bottom: 0px !important; - margin-left: 30px; -} -.toggle-attributes.collapsed { - margin-bottom: 0; -} -.impl-items > .toggle-attributes { - margin-left: 20px; -} -.impl-items .attributes { - font-weight: 500; -} :target > code { opacity: 1; @@ -1778,16 +1753,56 @@ div.name.expand::before { top: 2px; } -/* This part is to fix the "Expand attributes" part in the type declaration. */ -.type-decl > pre > .toggle-wrapper.toggle-attributes.top-attr { - margin-left: 0 !important; +/* The hideme class is used on summary tags that contain a span with + placeholder text shown only when the toggle is closed. For instance, + "Expand description" or "Show methods". */ +details > summary.hideme { + cursor: pointer; } -.type-decl > pre > .docblock.attributes.top-attr { - margin-left: 1.8em !important; + +details > summary::-webkit-details-marker { + display: none; } -.type-decl > pre .toggle-attributes { - margin-left: 2.2em; + +details > summary.hideme > span { + margin-left: 9px; + color: #999; } -.type-decl > pre > .docblock.attributes { - margin-left: 4em; + +details > summary::before { + content: "[+]"; + font-weight: 300; + font-size: 0.8em; + color: #999; + letter-spacing: 1px; +} + +details > summary.hideme::before { + position: relative; +} + +details > summary:not(.hideme)::before { + float: left; +} + +/* When a "hideme" summary is open and the "Expand description" or "Show + methods" text is hidden, we want the [-] toggle that remains to not + affect the layout of the items to its right. To do that, we use + absolute positioning. Note that we also set position: relative + on the parent
to make this work properly. */ +details[open] > summary.hideme { + position: absolute; +} + +details[open] { + position: relative; +} + +details[open] > summary.hideme > span { + display: none; +} + +details[open] > summary::before { + content: "[−]"; + display: inline; } diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index c68128516d2..2ed87fdedae 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -1,6 +1,5 @@ // From rust: /* global resourcesSuffix */ - var darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); window.mainTheme = document.getElementById("mainThemeStyle"); diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index 0404fa50b99..b24f4035ca8 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -218,7 +218,7 @@ a { color: #c5c5c5; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #39AFD7; diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 15b485a966f..e863ed03f51 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -176,7 +176,7 @@ a { color: #ddd; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #D2991D; diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 4c83879e234..9335dd96d29 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -174,7 +174,7 @@ a { color: #000; } -.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow):not(.collapse-toggle), +.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #3873AD; From 8e9882dbc4ed51a957c8abb0993f52f8b9f3ea26 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 27 Mar 2021 18:09:31 -0700 Subject: [PATCH 10/21] Add css classes --- src/librustdoc/html/render/mod.rs | 2 +- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/html/static/rustdoc.css | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index d0d9034f6e6..ece8f4905ec 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1030,7 +1030,7 @@ fn render_attributes_in_pre(w: &mut Buffer, it: &clean::Item, prefix: &str) { // a div to produce a newline after it. fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item) { for a in attributes(it) { - write!(w, "
{}
", a); + write!(w, "
{}
", a); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 03c4bb837f5..fec97d3ea55 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -140,7 +140,7 @@ fn should_hide_fields(n_fields: usize) -> bool { fn toggle_open(w: &mut Buffer, text: &str) { write!( w, - "
Show {}", + "
Show {}", text ); } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 64972bc2389..c84c045f75f 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1756,20 +1756,20 @@ div.name.expand::before { /* The hideme class is used on summary tags that contain a span with placeholder text shown only when the toggle is closed. For instance, "Expand description" or "Show methods". */ -details > summary.hideme { +details.rustdoc-toggle > summary.hideme { cursor: pointer; } -details > summary::-webkit-details-marker { +details.rustdoc-toggle > summary::-webkit-details-marker { display: none; } -details > summary.hideme > span { +details.rustdoc-toggle > summary.hideme > span { margin-left: 9px; color: #999; } -details > summary::before { +details.rustdoc-toggle > summary::before { content: "[+]"; font-weight: 300; font-size: 0.8em; @@ -1777,11 +1777,11 @@ details > summary::before { letter-spacing: 1px; } -details > summary.hideme::before { +details.rustdoc-toggle > summary.hideme::before { position: relative; } -details > summary:not(.hideme)::before { +details.rustdoc-toggle > summary:not(.hideme)::before { float: left; } @@ -1790,19 +1790,19 @@ details > summary:not(.hideme)::before { affect the layout of the items to its right. To do that, we use absolute positioning. Note that we also set position: relative on the parent
to make this work properly. */ -details[open] > summary.hideme { +details.rustdoc-toggle[open] > summary.hideme { position: absolute; } -details[open] { +details.rustdoc-toggle[open] { position: relative; } -details[open] > summary.hideme > span { +details.rustdoc-toggle[open] > summary.hideme > span { display: none; } -details[open] > summary::before { +details.rustdoc-toggle[open] > summary::before { content: "[−]"; display: inline; } From 01afa07fef09e60a979d582b52a62d94154369f5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 11:41:01 -0700 Subject: [PATCH 11/21] should_hide_fields > 12 --- src/librustdoc/html/render/print_item.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index fec97d3ea55..f6cce28ea2b 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -133,8 +133,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer) /// For large structs, enums, unions, etc, determine whether to hide their fields fn should_hide_fields(n_fields: usize) -> bool { - // todo: figure out what this should be - n_fields > 5 + n_fields > 12 } fn toggle_open(w: &mut Buffer, text: &str) { From b40bd5a9aaf8b20bdb394bf78a06490f60f13b57 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 12:14:41 -0700 Subject: [PATCH 12/21] Add test for item hiding --- src/test/rustdoc/item-hide-threshold.rs | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/test/rustdoc/item-hide-threshold.rs diff --git a/src/test/rustdoc/item-hide-threshold.rs b/src/test/rustdoc/item-hide-threshold.rs new file mode 100644 index 00000000000..616eef95662 --- /dev/null +++ b/src/test/rustdoc/item-hide-threshold.rs @@ -0,0 +1,155 @@ +#![allow(unused)] + +// @has 'item_hide_threshold/struct.PubStruct.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0 +pub struct PubStruct { + pub a: usize, + pub b: usize, +} + +// @has 'item_hide_threshold/struct.BigPubStruct.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields' +pub struct BigPubStruct { + pub a: usize, + pub b: usize, + pub c: usize, + pub d: usize, + pub e: usize, + pub f: usize, + pub g: usize, + pub h: usize, + pub i: usize, + pub j: usize, + pub k: usize, + pub l: usize, + pub m: usize, +} + +// @has 'item_hide_threshold/union.BigUnion.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields' +pub union BigUnion { + pub a: usize, + pub b: usize, + pub c: usize, + pub d: usize, + pub e: usize, + pub f: usize, + pub g: usize, + pub h: usize, + pub i: usize, + pub j: usize, + pub k: usize, + pub l: usize, + pub m: usize, +} + +// @has 'item_hide_threshold/union.Union.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0 +pub union Union { + pub a: usize, + pub b: usize, + pub c: usize, +} + +// @has 'item_hide_threshold/struct.PrivStruct.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0 +// @has - '//div[@class="docblock type-decl"]' 'fields omitted' +pub struct PrivStruct { + a: usize, + b: usize, +} + +// @has 'item_hide_threshold/enum.Enum.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0 +pub enum Enum { + A, B, C, + D { + a: u8, + b: u8 + } +} + +// @has 'item_hide_threshold/enum.LargeEnum.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show variants' +pub enum LargeEnum { + A, B, C, D, E, F(u8), G, H, I, J, K, L, M +} + +// @has 'item_hide_threshold/trait.Trait.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0 +pub trait Trait { + type A; + #[must_use] + fn foo(); + fn bar(); +} + +// @has 'item_hide_threshold/trait.GinormousTrait.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated items' +pub trait GinormousTrait { + type A; + type B; + type C; + type D; + type E; + type F; + type G; + type H; + type I; + type J; + type K; + type L; + type M; + const N: usize = 1; + #[must_use] + fn foo(); + fn bar(); +} + +// @has 'item_hide_threshold/trait.HugeTrait.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated constants and methods' +pub trait HugeTrait { + type A; + const M: usize = 1; + const N: usize = 1; + const O: usize = 1; + const P: usize = 1; + const Q: usize = 1; + const R: usize = 1; + const S: usize = 1; + const T: usize = 1; + const U: usize = 1; + const V: usize = 1; + const W: usize = 1; + const X: usize = 1; + #[must_use] + fn foo(); + fn bar(); +} + +// @has 'item_hide_threshold/trait.BigTrait.html' +// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show methods' +pub trait BigTrait { + type A; + #[must_use] + fn foo(); + fn bar(); + fn baz(); + fn quux(); + fn frob(); + fn greeble(); + fn blap(); + fn whoop(); + fn pow(); + fn bang(); + fn oomph(); + fn argh(); + fn wap(); + fn ouch(); +} From 97cd30d337e4e460efc77faf03ba68ce192b5648 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 12:27:37 -0700 Subject: [PATCH 13/21] Wrap toggle_open() --- src/librustdoc/html/render/print_item.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index f6cce28ea2b..ff3518ad7a1 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -139,7 +139,10 @@ fn should_hide_fields(n_fields: usize) -> bool { fn toggle_open(w: &mut Buffer, text: &str) { write!( w, - "
Show {}", + "
\ + \ + Show {}\ + ", text ); } From 05d1e723dcc00caed9f6768ea6d30962774c09f8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 12:40:20 -0700 Subject: [PATCH 14/21] & -> && --- src/librustdoc/html/render/print_item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ff3518ad7a1..ff9e4d031da 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -464,7 +464,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra // We also do this if the types + consts is large because otherwise we could // render a bunch of types and _then_ a bunch of consts just because both were // _just_ under the limit - if !toggle & should_hide_fields(types.len() + consts.len()) { + if !toggle && should_hide_fields(types.len() + consts.len()) { toggle = true; toggle_open(w, "associated constants and methods"); } @@ -475,7 +475,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx); w.write_str(";\n"); } - if !toggle & should_hide_fields(required.len() + provided.len()) { + if !toggle && should_hide_fields(required.len() + provided.len()) { toggle = true; toggle_open(w, "methods"); } From 942ed31c565c16d9401f0dc7f5a1fb56125edb71 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 12:42:13 -0700 Subject: [PATCH 15/21] Move color to themes --- src/librustdoc/html/static/rustdoc.css | 2 -- src/librustdoc/html/static/themes/ayu.css | 4 +++- src/librustdoc/html/static/themes/dark.css | 4 +++- src/librustdoc/html/static/themes/light.css | 4 +++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index c84c045f75f..0bac40b0f1b 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1766,14 +1766,12 @@ details.rustdoc-toggle > summary::-webkit-details-marker { details.rustdoc-toggle > summary.hideme > span { margin-left: 9px; - color: #999; } details.rustdoc-toggle > summary::before { content: "[+]"; font-weight: 300; font-size: 0.8em; - color: #999; letter-spacing: 1px; } diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index b24f4035ca8..5f6f3d66e57 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -224,7 +224,9 @@ a { color: #39AFD7; } -.collapse-toggle { +.collapse-toggle, +details.rustdoc-toggle > summary.hideme > span, +details.rustdoc-toggle > summary::before { color: #999; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index e863ed03f51..2ce6cf4cc45 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -186,7 +186,9 @@ a.test-arrow { color: #dedede; } -.collapse-toggle { +.collapse-toggle, +details.rustdoc-toggle > summary.hideme > span, +details.rustdoc-toggle > summary::before { color: #999; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 9335dd96d29..31b3562cfcb 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -184,7 +184,9 @@ a.test-arrow { color: #f5f5f5; } -.collapse-toggle { +.collapse-toggle, +details.rustdoc-toggle > summary.hideme > span, +details.rustdoc-toggle > summary::before { color: #999; } From 5c2820b913a2d40dc3c7178176896a6c70791bb9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 13:18:36 -0700 Subject: [PATCH 16/21] +ignore-tidy-filelength --- src/librustdoc/html/static/main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1b14f67fce1..d71cc15a457 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1,3 +1,4 @@ +// ignore-tidy-filelength // Local js definitions: /* global addClass, getSettingValue, hasClass */ /* global onEach, onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ @@ -2574,7 +2575,7 @@ function hideThemeButtonState() { var toggle = createSimpleToggle(false); var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; var hideImplementors = getSettingValue("auto-collapse-implementors") !== "false"; - let hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; + var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; var func = function(e) { var next = e.nextElementSibling; From 0174dd6f921cc63c7e2d9aa5c01aa591f9a26745 Mon Sep 17 00:00:00 2001 From: James Addison Date: Mon, 12 Apr 2021 23:29:09 +0100 Subject: [PATCH 17/21] Compiler error messages: reduce assertiveness of message E0384 This message is emitted as guidance by the compiler when a developer attempts to reassign a value to an immutable variable. Following the message will always currently work, but it may not always be the best course of action; following the 'consider ...' messaging pattern provides a hint to the developer that it could be wise to explore other alternatives. --- .../src/borrow_check/diagnostics/conflict_errors.rs | 2 +- src/test/ui/assign-imm-local-twice.rs | 2 +- src/test/ui/assign-imm-local-twice.stderr | 2 +- src/test/ui/async-await/issue-61452.stderr | 2 +- src/test/ui/borrowck/borrowck-asm.stderr | 4 ++-- .../borrowck-match-binding-is-assignment.stderr | 10 +++++----- src/test/ui/borrowck/immutable-arg.stderr | 2 +- src/test/ui/borrowck/issue-45199.rs | 6 +++--- src/test/ui/borrowck/issue-45199.stderr | 6 +++--- src/test/ui/command-line-diagnostics.stderr | 2 +- .../ex3-both-anon-regions-one-is-struct-2.nll.stderr | 2 +- .../liveness-assign-imm-local-notes.stderr | 8 ++++---- .../liveness-assign-imm-local-in-loop.rs | 2 +- .../liveness-assign-imm-local-in-loop.stderr | 2 +- .../liveness-assign-imm-local-in-op-eq.rs | 2 +- .../liveness-assign-imm-local-in-op-eq.stderr | 2 +- .../liveness-assign-imm-local-with-drop.rs | 2 +- .../liveness-assign-imm-local-with-drop.stderr | 2 +- .../liveness-assign-imm-local-with-init.rs | 2 +- .../liveness-assign-imm-local-with-init.stderr | 2 +- src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr | 2 +- src/test/ui/mut/mut-pattern-internal-mutability.stderr | 2 +- .../move-ref-patterns/borrowck-move-ref-pattern.stderr | 4 ++-- 23 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index 5fdf8a8d1ee..df6f1963923 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -1681,7 +1681,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if decl.can_be_made_mutable() { err.span_suggestion( decl.source_info.span, - "make this binding mutable", + "consider making this binding mutable", format!("mut {}", name), Applicability::MachineApplicable, ); diff --git a/src/test/ui/assign-imm-local-twice.rs b/src/test/ui/assign-imm-local-twice.rs index c1c9bf62819..b50f6ab5deb 100644 --- a/src/test/ui/assign-imm-local-twice.rs +++ b/src/test/ui/assign-imm-local-twice.rs @@ -1,6 +1,6 @@ fn test() { let v: isize; - //~^ HELP make this binding mutable + //~^ HELP consider making this binding mutable //~| SUGGESTION mut v v = 1; //~ NOTE first assignment println!("v={}", v); diff --git a/src/test/ui/assign-imm-local-twice.stderr b/src/test/ui/assign-imm-local-twice.stderr index df0f4c4d806..bba5d8dffe4 100644 --- a/src/test/ui/assign-imm-local-twice.stderr +++ b/src/test/ui/assign-imm-local-twice.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/assign-imm-local-twice.rs:7:5 | LL | let v: isize; - | - help: make this binding mutable: `mut v` + | - help: consider making this binding mutable: `mut v` ... LL | v = 1; | ----- first assignment to `v` diff --git a/src/test/ui/async-await/issue-61452.stderr b/src/test/ui/async-await/issue-61452.stderr index 5eb4b548717..f2dec87baf0 100644 --- a/src/test/ui/async-await/issue-61452.stderr +++ b/src/test/ui/async-await/issue-61452.stderr @@ -13,7 +13,7 @@ LL | pub async fn g(x: usize) { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/borrowck/borrowck-asm.stderr b/src/test/ui/borrowck/borrowck-asm.stderr index 3dccca78415..74cf5a55b70 100644 --- a/src/test/ui/borrowck/borrowck-asm.stderr +++ b/src/test/ui/borrowck/borrowck-asm.stderr @@ -29,7 +29,7 @@ LL | let x = 3; | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | unsafe { LL | llvm_asm!("nop" : "=r"(x)); | ^ cannot assign twice to immutable variable @@ -41,7 +41,7 @@ LL | let x = 3; | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | unsafe { LL | llvm_asm!("nop" : "+r"(x)); | ^ cannot assign twice to immutable variable diff --git a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.stderr b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.stderr index 5661ca52cba..dd22d7e2e2e 100644 --- a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.stderr +++ b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.stderr @@ -5,7 +5,7 @@ LL | x => { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable @@ -16,7 +16,7 @@ LL | E::Foo(x) => { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable @@ -27,7 +27,7 @@ LL | S { bar: x } => { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable @@ -38,7 +38,7 @@ LL | (x,) => { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable @@ -49,7 +49,7 @@ LL | [x,_,_] => { | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr index 7255ca327e7..bddb0633a0b 100644 --- a/src/test/ui/borrowck/immutable-arg.stderr +++ b/src/test/ui/borrowck/immutable-arg.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign to immutable argument `_x` --> $DIR/immutable-arg.rs:2:5 | LL | fn foo(_x: u32) { - | -- help: make this binding mutable: `mut _x` + | -- help: consider making this binding mutable: `mut _x` LL | _x = 4; | ^^^^^^ cannot assign to immutable argument diff --git a/src/test/ui/borrowck/issue-45199.rs b/src/test/ui/borrowck/issue-45199.rs index cbd45cbb619..ded46e56e34 100644 --- a/src/test/ui/borrowck/issue-45199.rs +++ b/src/test/ui/borrowck/issue-45199.rs @@ -1,6 +1,6 @@ fn test_drop_replace() { let b: Box; - //~^ HELP make this binding mutable + //~^ HELP consider making this binding mutable //~| SUGGESTION mut b b = Box::new(1); //~ NOTE first assignment b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` @@ -9,13 +9,13 @@ fn test_drop_replace() { fn test_call() { let b = Box::new(1); //~ NOTE first assignment - //~| HELP make this binding mutable + //~| HELP consider making this binding mutable //~| SUGGESTION mut b b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable } -fn test_args(b: Box) { //~ HELP make this binding mutable +fn test_args(b: Box) { //~ HELP consider making this binding mutable //~| SUGGESTION mut b b = Box::new(2); //~ ERROR cannot assign to immutable argument `b` //~| NOTE cannot assign to immutable argument diff --git a/src/test/ui/borrowck/issue-45199.stderr b/src/test/ui/borrowck/issue-45199.stderr index 83b634051bb..47aa3090827 100644 --- a/src/test/ui/borrowck/issue-45199.stderr +++ b/src/test/ui/borrowck/issue-45199.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `b` --> $DIR/issue-45199.rs:6:5 | LL | let b: Box; - | - help: make this binding mutable: `mut b` + | - help: consider making this binding mutable: `mut b` ... LL | b = Box::new(1); | - first assignment to `b` @@ -16,7 +16,7 @@ LL | let b = Box::new(1); | - | | | first assignment to `b` - | help: make this binding mutable: `mut b` + | help: consider making this binding mutable: `mut b` ... LL | b = Box::new(2); | ^ cannot assign twice to immutable variable @@ -25,7 +25,7 @@ error[E0384]: cannot assign to immutable argument `b` --> $DIR/issue-45199.rs:20:5 | LL | fn test_args(b: Box) { - | - help: make this binding mutable: `mut b` + | - help: consider making this binding mutable: `mut b` LL | LL | b = Box::new(2); | ^ cannot assign to immutable argument diff --git a/src/test/ui/command-line-diagnostics.stderr b/src/test/ui/command-line-diagnostics.stderr index b3f8d8a643f..6223ad880d6 100644 --- a/src/test/ui/command-line-diagnostics.stderr +++ b/src/test/ui/command-line-diagnostics.stderr @@ -5,7 +5,7 @@ LL | let x = 42; | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x = 43; | ^^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr index 5751c319489..bbd62902d9f 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.nll.stderr @@ -12,7 +12,7 @@ error[E0384]: cannot assign to immutable argument `y` --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5 | LL | fn foo(mut x: Ref, y: &u32) { - | - help: make this binding mutable: `mut y` + | - help: consider making this binding mutable: `mut y` LL | y = x.b; | ^^^^^^^ cannot assign to immutable argument diff --git a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr index c646912d3b6..b47a47d631e 100644 --- a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:10:9 | LL | let x; - | - help: make this binding mutable: `mut x` + | - help: consider making this binding mutable: `mut x` ... LL | x = 2; | ----- first assignment to `x` @@ -13,7 +13,7 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:21:13 | LL | let x; - | - help: make this binding mutable: `mut x` + | - help: consider making this binding mutable: `mut x` ... LL | x = 2; | ----- first assignment to `x` @@ -24,7 +24,7 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:30:13 | LL | let x; - | - help: make this binding mutable: `mut x` + | - help: consider making this binding mutable: `mut x` ... LL | x = 1; | ^^^^^ cannot assign twice to immutable variable @@ -33,7 +33,7 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/liveness-assign-imm-local-notes.rs:32:13 | LL | let x; - | - help: make this binding mutable: `mut x` + | - help: consider making this binding mutable: `mut x` ... LL | x = 1; | ----- first assignment to `x` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs index c9e1851b9a9..08911c5bde7 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.rs @@ -1,6 +1,6 @@ fn test() { let v: isize; - //~^ HELP make this binding mutable + //~^ HELP consider making this binding mutable //~| SUGGESTION mut v loop { v = 1; //~ ERROR cannot assign twice to immutable variable `v` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr index 69dff734ee4..66cdce7dacf 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/liveness-assign-imm-local-in-loop.rs:6:9 | LL | let v: isize; - | - help: make this binding mutable: `mut v` + | - help: consider making this binding mutable: `mut v` ... LL | v = 1; | ^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs index f24f7d2bcfc..1752d969086 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.rs @@ -1,6 +1,6 @@ fn test() { let v: isize; - //~^ HELP make this binding mutable + //~^ HELP consider making this binding mutable //~| SUGGESTION mut v v = 2; //~ NOTE first assignment v += 1; //~ ERROR cannot assign twice to immutable variable `v` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr index 182958dd492..5db9539cbf1 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `v` --> $DIR/liveness-assign-imm-local-in-op-eq.rs:6:5 | LL | let v: isize; - | - help: make this binding mutable: `mut v` + | - help: consider making this binding mutable: `mut v` ... LL | v = 2; | ----- first assignment to `v` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs index 8963e32717e..c9b16e43910 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs @@ -1,6 +1,6 @@ fn test() { let b = Box::new(1); //~ NOTE first assignment - //~| HELP make this binding mutable + //~| HELP consider making this binding mutable //~| SUGGESTION mut b drop(b); b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr index 7c4af624b27..bb7e7e27a4c 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.stderr @@ -5,7 +5,7 @@ LL | let b = Box::new(1); | - | | | first assignment to `b` - | help: make this binding mutable: `mut b` + | help: consider making this binding mutable: `mut b` ... LL | b = Box::new(2); | ^ cannot assign twice to immutable variable diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs index 4ab222af8d0..4bb2db27a16 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.rs @@ -1,6 +1,6 @@ fn test() { let v: isize = 1; //~ NOTE first assignment - //~| HELP make this binding mutable + //~| HELP consider making this binding mutable //~| SUGGESTION mut v v.clone(); v = 2; //~ ERROR cannot assign twice to immutable variable `v` diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr index 6f5d5574877..80458a70a01 100644 --- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr +++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.stderr @@ -5,7 +5,7 @@ LL | let v: isize = 1; | - | | | first assignment to `v` - | help: make this binding mutable: `mut v` + | help: consider making this binding mutable: `mut v` ... LL | v = 2; | ^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr index 9b0aa6be1e9..3e5893f68b6 100644 --- a/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr @@ -2,7 +2,7 @@ error[E0384]: cannot assign twice to immutable variable `x` --> $DIR/llvm-asm-out-assign-imm.rs:25:39 | LL | let x: isize; - | - help: make this binding mutable: `mut x` + | - help: consider making this binding mutable: `mut x` LL | x = 1; | ----- first assignment to `x` ... diff --git a/src/test/ui/mut/mut-pattern-internal-mutability.stderr b/src/test/ui/mut/mut-pattern-internal-mutability.stderr index eaa33453a75..6583546aa5c 100644 --- a/src/test/ui/mut/mut-pattern-internal-mutability.stderr +++ b/src/test/ui/mut/mut-pattern-internal-mutability.stderr @@ -5,7 +5,7 @@ LL | let &mut x = foo; | - | | | first assignment to `x` - | help: make this binding mutable: `mut x` + | help: consider making this binding mutable: `mut x` LL | x += 1; | ^^^^^^ cannot assign twice to immutable variable diff --git a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr index 285c203f382..d0726f05cc3 100644 --- a/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr +++ b/src/test/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern.stderr @@ -16,7 +16,7 @@ LL | let [ref _x0_hold, _x1, ref xs_hold @ ..] = arr; | --- | | | first assignment to `_x1` - | help: make this binding mutable: `mut _x1` + | help: consider making this binding mutable: `mut _x1` LL | _x1 = U; | ^^^^^^^ cannot assign twice to immutable variable @@ -74,7 +74,7 @@ LL | let (ref _x0, _x1, ref _x2, ..) = tup; | --- | | | first assignment to `_x1` - | help: make this binding mutable: `mut _x1` + | help: consider making this binding mutable: `mut _x1` LL | _x1 = U; | ^^^^^^^ cannot assign twice to immutable variable From 55b29443db473d49c1c64d469da5f6a50dc6beb7 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 12 Apr 2021 23:03:17 -0700 Subject: [PATCH 18/21] Update attribute tests --- src/test/rustdoc/attributes.rs | 10 +++++----- src/test/rustdoc/trait-attributes.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/rustdoc/attributes.rs b/src/test/rustdoc/attributes.rs index 54c5939f908..51cd4a6cbfd 100644 --- a/src/test/rustdoc/attributes.rs +++ b/src/test/rustdoc/attributes.rs @@ -1,21 +1,21 @@ #![crate_name = "foo"] -// @has foo/fn.f.html '//*[@class="docblock attributes"]' '#[no_mangle]' +// @has foo/fn.f.html '//*[@class="rust fn"]' '#[no_mangle]' #[no_mangle] pub extern "C" fn f() {} -// @has foo/fn.g.html '//*[@class="docblock attributes"]' '#[export_name = "bar"]' +// @has foo/fn.g.html '//*[@class="rust fn"]' '#[export_name = "bar"]' #[export_name = "bar"] pub extern "C" fn g() {} -// @matches foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' \ -// '(?m)\A#\[repr\(i64\)\]\n#\[must_use\]\Z' +// @matches foo/enum.Foo.html '//*[@class="rust enum"]' \ +// '#\[repr\(i64\)\]\n#\[must_use\]' #[repr(i64)] #[must_use] pub enum Foo { Bar, } -// @has foo/struct.Repr.html '//*[@class="docblock attributes top-attr"]' '#[repr(C, align(8))]' +// @has foo/struct.Repr.html '//*[@class="docblock type-decl"]' '#[repr(C, align(8))]' #[repr(C, align(8))] pub struct Repr; diff --git a/src/test/rustdoc/trait-attributes.rs b/src/test/rustdoc/trait-attributes.rs index 2a103509ae1..2bb24a82193 100644 --- a/src/test/rustdoc/trait-attributes.rs +++ b/src/test/rustdoc/trait-attributes.rs @@ -2,7 +2,7 @@ pub trait Foo { - // @has foo/trait.Foo.html '//h3[@id="tymethod.foo"]//span[@class="docblock attributes"]' '#[must_use]' + // @has foo/trait.Foo.html '//h3[@id="tymethod.foo"]//div[@class="code-attribute"]' '#[must_use]' #[must_use] fn foo(); } @@ -11,11 +11,11 @@ pub trait Foo { pub struct Bar; impl Bar { - // @has foo/struct.Bar.html '//h4[@id="method.bar"]//span[@class="docblock attributes"]' '#[must_use]' + // @has foo/struct.Bar.html '//h4[@id="method.bar"]//div[@class="code-attribute"]' '#[must_use]' #[must_use] pub fn bar() {} - // @has foo/struct.Bar.html '//h4[@id="method.bar2"]//span[@class="docblock attributes"]' '#[must_use]' + // @has foo/struct.Bar.html '//h4[@id="method.bar2"]//div[@class="code-attribute"]' '#[must_use]' #[must_use] pub fn bar2() {} } From bccbf9db1c799b4848c1742ddc6170e8fa94c965 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Tue, 13 Apr 2021 00:10:03 +0200 Subject: [PATCH 19/21] VecDeque: binary_search_by(): return right away if hit found at back.first() #78021 --- library/alloc/src/collections/vec_deque/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index d3e70991ad5..e6436016711 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2481,8 +2481,11 @@ impl VecDeque { F: FnMut(&'a T) -> Ordering, { let (front, back) = self.as_slices(); + let cmp_back = back.first().map(|elem| f(elem)); - if let Some(Ordering::Less | Ordering::Equal) = back.first().map(|elem| f(elem)) { + if let Some(Ordering::Equal) = cmp_back { + Ok(front.len()) + } else if let Some(Ordering::Less) = cmp_back { back.binary_search_by(f).map(|idx| idx + front.len()).map_err(|idx| idx + front.len()) } else { front.binary_search_by(f) From e68680d30db3ba492827979b44c9f28e574e2274 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Sun, 4 Apr 2021 14:50:44 +0200 Subject: [PATCH 20/21] VecDeque: Add partition_point() #78021 --- .../alloc/src/collections/vec_deque/mod.rs | 45 +++++++++++++++++++ library/alloc/tests/vec_deque.rs | 18 ++++++++ 2 files changed, 63 insertions(+) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index e6436016711..f8516bdab0c 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2534,6 +2534,51 @@ impl VecDeque { { self.binary_search_by(|k| f(k).cmp(b)) } + + /// Returns the index of the partition point according to the given predicate + /// (the index of the first element of the second partition). + /// + /// The deque is assumed to be partitioned according to the given predicate. + /// This means that all elements for which the predicate returns true are at the start of the deque + /// and all elements for which the predicate returns false are at the end. + /// For example, [7, 15, 3, 5, 4, 12, 6] is a partitioned under the predicate x % 2 != 0 + /// (all odd numbers are at the start, all even at the end). + /// + /// If this deque is not partitioned, the returned result is unspecified and meaningless, + /// as this method performs a kind of binary search. + /// + /// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`]. + /// + /// [`binary_search`]: slice::binary_search + /// [`binary_search_by`]: slice::binary_search_by + /// [`binary_search_by_key`]: slice::binary_search_by_key + /// + /// # Examples + /// + /// ``` + /// #![feature(vecdeque_binary_search)] + /// use std::collections::VecDeque; + /// + /// let deque: VecDeque<_> = vec![1, 2, 3, 3, 5, 6, 7].into(); + /// let i = deque.partition_point(|&x| x < 5); + /// + /// assert_eq!(i, 4); + /// assert!(deque.iter().take(i).all(|&x| x < 5)); + /// assert!(deque.iter().skip(i).all(|&x| !(x < 5))); + /// ``` + #[unstable(feature = "vecdeque_binary_search", issue = "78021")] + pub fn partition_point

(&self, mut pred: P) -> usize + where + P: FnMut(&T) -> bool, + { + let (front, back) = self.as_slices(); + + if let Some(true) = back.first().map(|v| pred(v)) { + back.partition_point(pred) + front.len() + } else { + front.partition_point(pred) + } + } } impl VecDeque { diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 0919b1325bc..d7140cf9759 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1699,6 +1699,24 @@ fn test_binary_search_by_key() { assert_eq!(deque.binary_search_by_key(&4, |&(v,)| v), Err(3)); } +#[test] +fn test_partition_point() { + // Contiguous (front only) search: + let deque: VecDeque<_> = vec![1, 2, 3, 5, 6].into(); + assert!(deque.as_slices().1.is_empty()); + assert_eq!(deque.partition_point(|&v| v <= 3), 3); + + // Split search (both front & back non-empty): + let mut deque: VecDeque<_> = vec![5, 6].into(); + deque.push_front(3); + deque.push_front(2); + deque.push_front(1); + deque.push_back(10); + assert!(!deque.as_slices().0.is_empty()); + assert!(!deque.as_slices().1.is_empty()); + assert_eq!(deque.partition_point(|&v| v <= 5), 4); +} + #[test] fn test_zero_sized_push() { const N: usize = 8; From 44be1c2aa0df6ef4ff22e4aa92be3f32daf036a9 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Thu, 15 Apr 2021 09:33:46 +0200 Subject: [PATCH 21/21] VecDeque: Improve doc comments in binary search fns Co-authored-by: Mara Bos --- .../alloc/src/collections/vec_deque/mod.rs | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f8516bdab0c..7d6fbf1c438 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2403,6 +2403,12 @@ impl VecDeque { /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`]. + /// + /// [`binary_search_by`]: VecDeque::binary_search_by + /// [`binary_search_by_key`]: VecDeque::binary_search_by_key + /// [`partition_point`]: VecDeque::partition_point + /// /// # Examples /// /// Looks up a series of four elements. The first is found, with a @@ -2457,6 +2463,12 @@ impl VecDeque { /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`]. + /// + /// [`binary_search`]: VecDeque::binary_search + /// [`binary_search_by_key`]: VecDeque::binary_search_by_key + /// [`partition_point`]: VecDeque::partition_point + /// /// # Examples /// /// Looks up a series of four elements. The first is found, with a @@ -2495,8 +2507,7 @@ impl VecDeque { /// Binary searches this sorted `VecDeque` with a key extraction function. /// /// Assumes that the `VecDeque` is sorted by the key, for instance with - /// [`make_contiguous().sort_by_key()`](#method.make_contiguous) using the same - /// key extraction function. + /// [`make_contiguous().sort_by_key()`] using the same key extraction function. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any @@ -2504,6 +2515,13 @@ impl VecDeque { /// [`Result::Err`] is returned, containing the index where a matching /// element could be inserted while maintaining sorted order. /// + /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`]. + /// + /// [`make_contiguous().sort_by_key()`]: VecDeque::make_contiguous + /// [`binary_search`]: VecDeque::binary_search + /// [`binary_search_by`]: VecDeque::binary_search_by + /// [`partition_point`]: VecDeque::partition_point + /// /// # Examples /// /// Looks up a series of four elements in a slice of pairs sorted by @@ -2549,9 +2567,9 @@ impl VecDeque { /// /// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`]. /// - /// [`binary_search`]: slice::binary_search - /// [`binary_search_by`]: slice::binary_search_by - /// [`binary_search_by_key`]: slice::binary_search_by_key + /// [`binary_search`]: VecDeque::binary_search + /// [`binary_search_by`]: VecDeque::binary_search_by + /// [`binary_search_by_key`]: VecDeque::binary_search_by_key /// /// # Examples ///