From caf6c5790a858893c1d32ed2054c9577d12e7493 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 23 Nov 2020 13:20:16 +0100 Subject: [PATCH 01/16] Rename "stability" CSS class to "item-info" --- src/librustdoc/html/render/mod.rs | 51 +++++++++++---------- src/librustdoc/html/static/main.js | 17 +++---- src/librustdoc/html/static/rustdoc.css | 18 ++++---- src/librustdoc/html/static/themes/ayu.css | 4 +- src/librustdoc/html/static/themes/dark.css | 4 +- src/librustdoc/html/static/themes/light.css | 4 +- src/test/rustdoc/doc-cfg.rs | 12 ++--- src/test/rustdoc/stability.rs | 2 +- 8 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 147a8d33765af..bd555f937aa24 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1844,7 +1844,7 @@ fn document(w: &mut Buffer, cx: &Context, item: &clean::Item, parent: Option<&cl if let Some(ref name) = item.name { info!("Documenting {}", name); } - document_stability(w, cx, item, false, parent); + document_item_info(w, cx, item, false, parent); document_full(w, item, cx, "", false); } @@ -1928,18 +1928,23 @@ fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, } } -fn document_stability( +/// Add extra information about an item such as: +/// +/// * Stability +/// * Deprecated +/// * Required features (through the `doc_cfg` feature) +fn document_item_info( w: &mut Buffer, cx: &Context, item: &clean::Item, is_hidden: bool, parent: Option<&clean::Item>, ) { - let stabilities = short_stability(item, cx, parent); - if !stabilities.is_empty() { - write!(w, "
", if is_hidden { " hidden" } else { "" }); - for stability in stabilities { - write!(w, "{}", stability); + let item_infos = short_item_info(item, cx, parent); + if !item_infos.is_empty() { + write!(w, "
", if is_hidden { " hidden" } else { "" }); + for info in item_infos { + write!(w, "{}", info); } write!(w, "
"); } @@ -2194,7 +2199,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: {stab_tags}{docs}\ ", name = *myitem.name.as_ref().unwrap(), - stab_tags = stability_tags(myitem, item), + stab_tags = extra_info_tags(myitem, item), docs = MarkdownSummaryLine(doc_value, &myitem.links()).into_string(), class = myitem.type_(), add = add, @@ -2216,9 +2221,9 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: } } -/// Render the stability and deprecation tags that are displayed in the item's summary at the -/// module level. -fn stability_tags(item: &clean::Item, parent: &clean::Item) -> String { +/// Render the stability, deprecation and portability tags that are displayed in the item's summary +/// at the module level. +fn extra_info_tags(item: &clean::Item, parent: &clean::Item) -> String { let mut tags = String::new(); fn tag_html(class: &str, title: &str, contents: &str) -> String { @@ -2271,10 +2276,10 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option{}
", cfg?.render_long_html())) } -/// Render the stability and/or deprecation warning that is displayed at the top of the item's -/// documentation. -fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec { - let mut stability = vec![]; +/// Render the stability, deprecation and portability information that is displayed at the top of +/// the item's documentation. +fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item>) -> Vec { + let mut extra_info = vec![]; let error_codes = cx.shared.codes; if let Some(Deprecation { ref note, ref since, is_since_rustc_version }) = item.deprecation { @@ -2301,7 +2306,7 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item ); message.push_str(&format!(": {}", html.into_string())); } - stability.push(format!( + extra_info.push(format!( "
👎 {}
", message, )); @@ -2345,14 +2350,14 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item ); } - stability.push(format!("
{}
", message)); + extra_info.push(format!("
{}
", message)); } if let Some(portability) = portability(item, parent) { - stability.push(portability); + extra_info.push(portability); } - stability + extra_info } fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) { @@ -3703,7 +3708,7 @@ fn render_impl( if trait_.is_some() { if let Some(portability) = portability(&i.impl_item, Some(parent)) { - write!(w, "
{}
", portability); + write!(w, "
{}
", portability); } } @@ -3801,7 +3806,7 @@ fn render_impl( if let Some(it) = t.items.iter().find(|i| i.name == item.name) { // We need the stability of the item from the trait // because impls can't have a stability. - document_stability(w, cx, it, is_hidden, Some(parent)); + document_item_info(w, cx, it, is_hidden, Some(parent)); if item.doc_value().is_some() { document_full(w, item, cx, "", is_hidden); } else if show_def_docs { @@ -3811,13 +3816,13 @@ fn render_impl( } } } else { - document_stability(w, cx, item, is_hidden, Some(parent)); + document_item_info(w, cx, item, is_hidden, Some(parent)); if show_def_docs { document_full(w, item, cx, "", is_hidden); } } } else { - document_stability(w, cx, item, is_hidden, Some(parent)); + document_item_info(w, cx, item, is_hidden, Some(parent)); if show_def_docs { document_short(w, item, link, "", is_hidden); } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b11bd66709327..7ca43684dced2 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2266,7 +2266,7 @@ function defocusSearchBar() { } } var ns = n.nextElementSibling; - while (ns && (hasClass(ns, "docblock") || hasClass(ns, "stability"))) { + while (ns && (hasClass(ns, "docblock") || hasClass(ns, "item-info"))) { if (addOrRemove) { addClass(ns, "hidden-by-impl-hider"); } else { @@ -2282,7 +2282,7 @@ function defocusSearchBar() { var action = mode; if (hasClass(toggle.parentNode, "impl") === false) { relatedDoc = toggle.parentNode.nextElementSibling; - if (hasClass(relatedDoc, "stability")) { + if (hasClass(relatedDoc, "item-info")) { relatedDoc = relatedDoc.nextElementSibling; } if (hasClass(relatedDoc, "docblock") || hasClass(relatedDoc, "sub-variant")) { @@ -2332,16 +2332,17 @@ function defocusSearchBar() { var dontApplyBlockRule = toggle.parentNode.parentNode.id !== "main"; if (action === "show") { removeClass(relatedDoc, "fns-now-collapsed"); - // Stability information is never hidden. - if (hasClass(docblock, "stability") === false) { + // Stability/deprecation/portability information is never hidden. + if (hasClass(docblock, "item-info") === false) { removeClass(docblock, "hidden-by-usual-hider"); } onEachLazy(toggle.childNodes, adjustToggle(false, dontApplyBlockRule)); onEachLazy(relatedDoc.childNodes, implHider(false, dontApplyBlockRule)); } else if (action === "hide") { addClass(relatedDoc, "fns-now-collapsed"); - // Stability information should be shown even when detailed info is hidden. - if (hasClass(docblock, "stability") === false) { + // Stability/deprecation/portability information should be shown even when detailed + // info is hidden. + if (hasClass(docblock, "item-info") === false) { addClass(docblock, "hidden-by-usual-hider"); } onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule)); @@ -2445,7 +2446,7 @@ function defocusSearchBar() { var func = function(e) { var next = e.nextElementSibling; - if (next && hasClass(next, "stability")) { + if (next && hasClass(next, "item-info")) { next = next.nextElementSibling; } if (!next) { @@ -2462,7 +2463,7 @@ function defocusSearchBar() { var funcImpl = function(e) { var next = e.nextElementSibling; - if (next && hasClass(next, "stability")) { + if (next && hasClass(next, "item-info")) { next = next.nextElementSibling; } if (next && hasClass(next, "docblock")) { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 7d22913b99de9..8eef65a231d0b 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -553,21 +553,21 @@ h4 > code, h3 > code, .invisible > code { border: none; } -.content .stability code { +.content .item-info code { font-size: 90%; } -.content .stability { +.content .item-info { position: relative; margin-left: 33px; margin-top: -13px; } -.sub-variant > div > .stability { +.sub-variant > div > .item-info { margin-top: initial; } -.content .stability::before { +.content .item-info::before { content: '⬑'; font-size: 25px; position: absolute; @@ -579,15 +579,15 @@ h4 > code, h3 > code, .invisible > code { margin-left: 20px; } -.content .impl-items .docblock, .content .impl-items .stability { +.content .impl-items .docblock, .content .impl-items .item-info { margin-bottom: .6em; } -.content .impl-items > .stability { +.content .impl-items > .item-info { margin-left: 40px; } -.methods > .stability, .content .impl-items > .stability { +.methods > .item-info, .content .impl-items > .item-info { margin-top: -8px; } @@ -595,7 +595,7 @@ h4 > code, h3 > code, .invisible > code { flex-basis: 100%; } -#main > .stability { +#main > .item-info { margin-top: 0; } @@ -655,7 +655,7 @@ a { } .docblock a:not(.srclink):not(.test-arrow):hover, -.docblock-short a:not(.srclink):not(.test-arrow):hover, .stability a { +.docblock-short a:not(.srclink):not(.test-arrow):hover, .item-info a { text-decoration: underline; } diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index d1cddf0d65657..c1f796f09e804 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -166,7 +166,7 @@ pre { color: #c5c5c5; } -.content .stability::before { color: #ccc; } +.content .item-info::before { color: #ccc; } .content span.foreigntype, .content a.foreigntype { color: #ef57ff; } .content span.union, .content a.union { color: #98a01c; } @@ -219,7 +219,7 @@ a { } .docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), -.docblock-short a:not(.srclink):not(.test-arrow), .stability a, +.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 3545943b3fd97..946ca0a40c9dc 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -136,7 +136,7 @@ pre { .content .highlighted.primitive { background-color: #00708a; } .content .highlighted.keyword { background-color: #884719; } -.content .stability::before { color: #ccc; } +.content .item-info::before { color: #ccc; } .content span.enum, .content a.enum, .block a.current.enum { color: #82b089; } .content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; } @@ -177,7 +177,7 @@ a { } .docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), -.docblock-short a:not(.srclink):not(.test-arrow), .stability a, +.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 4ce4b63e2c6c3..e0b9a04921a80 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -134,7 +134,7 @@ pre { .content .highlighted.primitive { background-color: #9aecff; } .content .highlighted.keyword { background-color: #f99650; } -.content .stability::before { color: #ccc; } +.content .item-info::before { color: #ccc; } .content span.enum, .content a.enum, .block a.current.enum { color: #508157; } .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; } @@ -175,7 +175,7 @@ a { } .docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), -.docblock-short a:not(.srclink):not(.test-arrow), .stability a, +.docblock-short a:not(.srclink):not(.test-arrow), .item-info a, #help a { color: #3873AD; } diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs index d7041ee2f1af8..f86541cd1181e 100644 --- a/src/test/rustdoc/doc-cfg.rs +++ b/src/test/rustdoc/doc-cfg.rs @@ -2,20 +2,20 @@ #![feature(target_feature, cfg_target_feature)] // @has doc_cfg/struct.Portable.html -// @!has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' '' +// @!has - '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' '' // @has - '//*[@id="method.unix_and_arm_only_function"]' 'fn unix_and_arm_only_function()' // @has - '//*[@class="stab portability"]' 'This is supported on Unix and ARM only.' pub struct Portable; // @has doc_cfg/unix_only/index.html \ -// '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'This is supported on Unix only.' // @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AARM\Z' // @count - '//*[@class="stab portability"]' 2 #[doc(cfg(unix))] pub mod unix_only { // @has doc_cfg/unix_only/fn.unix_only_function.html \ - // '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ + // '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'This is supported on Unix only.' // @count - '//*[@class="stab portability"]' 1 pub fn unix_only_function() { @@ -23,7 +23,7 @@ pub mod unix_only { } // @has doc_cfg/unix_only/trait.ArmOnly.html \ - // '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ + // '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'This is supported on Unix and ARM only.' // @count - '//*[@class="stab portability"]' 2 #[doc(cfg(target_arch = "arm"))] @@ -44,7 +44,7 @@ pub mod unix_only { // @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\Aavx\Z' // @has doc_cfg/fn.uses_target_feature.html -// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// @has - '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'This is supported with target feature avx only.' #[target_feature(enable = "avx")] pub unsafe fn uses_target_feature() { @@ -52,7 +52,7 @@ pub unsafe fn uses_target_feature() { } // @has doc_cfg/fn.uses_cfg_target_feature.html -// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// @has - '//*[@id="main"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'This is supported with target feature avx only.' #[doc(cfg(target_feature = "avx"))] pub fn uses_cfg_target_feature() { diff --git a/src/test/rustdoc/stability.rs b/src/test/rustdoc/stability.rs index b1b97fe134e4c..4ff06d9c9954e 100644 --- a/src/test/rustdoc/stability.rs +++ b/src/test/rustdoc/stability.rs @@ -4,7 +4,7 @@ pub struct Unstable { // @has stability/struct.Unstable.html \ - // '//div[@class="stability"]//div[@class="stab unstable"]' \ + // '//div[@class="item-info"]//div[@class="stab unstable"]' \ // 'This is a nightly-only experimental API' // @count stability/struct.Unstable.html '//span[@class="stab unstable"]' 0 pub foo: u32, From be0484b65def1c07aa2fbc456db0d02f59895b4a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Nov 2020 17:36:16 +0100 Subject: [PATCH 02/16] Clean up document_item_info calls --- src/librustdoc/html/render/mod.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index bd555f937aa24..bbd4be88e6a8b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1880,10 +1880,17 @@ fn render_markdown( fn document_short( w: &mut Buffer, item: &clean::Item, + cx: &Context, link: AssocItemLink<'_>, prefix: &str, is_hidden: bool, + parent: Option<&clean::Item>, + show_def_docs: bool, ) { + document_item_info(w, cx, item, is_hidden, parent); + if !show_def_docs { + return; + } if let Some(s) = item.doc_value() { let mut summary_html = MarkdownSummaryLine(s, &item.links()).into_string(); @@ -3806,13 +3813,22 @@ fn render_impl( if let Some(it) = t.items.iter().find(|i| i.name == item.name) { // We need the stability of the item from the trait // because impls can't have a stability. - document_item_info(w, cx, it, is_hidden, Some(parent)); if item.doc_value().is_some() { + document_item_info(w, cx, it, is_hidden, Some(parent)); document_full(w, item, cx, "", is_hidden); - } else if show_def_docs { + } else { // In case the item isn't documented, // provide short documentation from the trait. - document_short(w, it, link, "", is_hidden); + document_short( + w, + it, + cx, + link, + "", + is_hidden, + Some(parent), + show_def_docs, + ); } } } else { @@ -3822,10 +3838,7 @@ fn render_impl( } } } else { - document_item_info(w, cx, item, is_hidden, Some(parent)); - if show_def_docs { - document_short(w, item, link, "", is_hidden); - } + document_short(w, item, cx, link, "", is_hidden, Some(parent), show_def_docs); } } } From 37b97f095ccbb7dcea7c678f1bbc4210e72f4489 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Tue, 24 Nov 2020 17:35:53 -0800 Subject: [PATCH 03/16] Move src/test/ui/if to src/test/ui/expr/if --- src/test/ui/{ => expr}/if/expr-if-panic-fn.rs | 0 src/test/ui/{ => expr}/if/expr-if-panic.rs | 0 src/test/ui/{ => expr}/if/if-branch-types.rs | 0 src/test/ui/{ => expr}/if/if-branch-types.stderr | 0 src/test/ui/{ => expr}/if/if-check-panic.rs | 0 src/test/ui/{ => expr}/if/if-cond-bot.rs | 0 src/test/ui/{ => expr}/if/if-let-arm-types.rs | 0 src/test/ui/{ => expr}/if/if-let-arm-types.stderr | 0 src/test/ui/{ => expr}/if/if-let.rs | 0 src/test/ui/{ => expr}/if/if-let.stderr | 0 src/test/ui/{ => expr}/if/if-loop.rs | 0 src/test/ui/{ => expr}/if/if-no-match-bindings.rs | 0 src/test/ui/{ => expr}/if/if-no-match-bindings.stderr | 0 src/test/ui/{ => expr}/if/if-typeck.rs | 0 src/test/ui/{ => expr}/if/if-typeck.stderr | 0 src/test/ui/{ => expr}/if/if-without-block.rs | 0 src/test/ui/{ => expr}/if/if-without-block.stderr | 0 src/test/ui/{ => expr}/if/if-without-else-as-fn-expr.rs | 0 src/test/ui/{ => expr}/if/if-without-else-as-fn-expr.stderr | 0 src/test/ui/{ => expr}/if/if-without-else-result.rs | 0 src/test/ui/{ => expr}/if/if-without-else-result.stderr | 0 src/test/ui/{ => expr}/if/ifmt-bad-arg.rs | 0 src/test/ui/{ => expr}/if/ifmt-bad-arg.stderr | 0 src/test/ui/{ => expr}/if/ifmt-bad-format-args.rs | 0 src/test/ui/{ => expr}/if/ifmt-bad-format-args.stderr | 0 src/test/ui/{ => expr}/if/ifmt-unimpl.rs | 0 src/test/ui/{ => expr}/if/ifmt-unimpl.stderr | 0 src/test/ui/{ => expr}/if/ifmt-unknown-trait.rs | 0 src/test/ui/{ => expr}/if/ifmt-unknown-trait.stderr | 0 29 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{ => expr}/if/expr-if-panic-fn.rs (100%) rename src/test/ui/{ => expr}/if/expr-if-panic.rs (100%) rename src/test/ui/{ => expr}/if/if-branch-types.rs (100%) rename src/test/ui/{ => expr}/if/if-branch-types.stderr (100%) rename src/test/ui/{ => expr}/if/if-check-panic.rs (100%) rename src/test/ui/{ => expr}/if/if-cond-bot.rs (100%) rename src/test/ui/{ => expr}/if/if-let-arm-types.rs (100%) rename src/test/ui/{ => expr}/if/if-let-arm-types.stderr (100%) rename src/test/ui/{ => expr}/if/if-let.rs (100%) rename src/test/ui/{ => expr}/if/if-let.stderr (100%) rename src/test/ui/{ => expr}/if/if-loop.rs (100%) rename src/test/ui/{ => expr}/if/if-no-match-bindings.rs (100%) rename src/test/ui/{ => expr}/if/if-no-match-bindings.stderr (100%) rename src/test/ui/{ => expr}/if/if-typeck.rs (100%) rename src/test/ui/{ => expr}/if/if-typeck.stderr (100%) rename src/test/ui/{ => expr}/if/if-without-block.rs (100%) rename src/test/ui/{ => expr}/if/if-without-block.stderr (100%) rename src/test/ui/{ => expr}/if/if-without-else-as-fn-expr.rs (100%) rename src/test/ui/{ => expr}/if/if-without-else-as-fn-expr.stderr (100%) rename src/test/ui/{ => expr}/if/if-without-else-result.rs (100%) rename src/test/ui/{ => expr}/if/if-without-else-result.stderr (100%) rename src/test/ui/{ => expr}/if/ifmt-bad-arg.rs (100%) rename src/test/ui/{ => expr}/if/ifmt-bad-arg.stderr (100%) rename src/test/ui/{ => expr}/if/ifmt-bad-format-args.rs (100%) rename src/test/ui/{ => expr}/if/ifmt-bad-format-args.stderr (100%) rename src/test/ui/{ => expr}/if/ifmt-unimpl.rs (100%) rename src/test/ui/{ => expr}/if/ifmt-unimpl.stderr (100%) rename src/test/ui/{ => expr}/if/ifmt-unknown-trait.rs (100%) rename src/test/ui/{ => expr}/if/ifmt-unknown-trait.stderr (100%) diff --git a/src/test/ui/if/expr-if-panic-fn.rs b/src/test/ui/expr/if/expr-if-panic-fn.rs similarity index 100% rename from src/test/ui/if/expr-if-panic-fn.rs rename to src/test/ui/expr/if/expr-if-panic-fn.rs diff --git a/src/test/ui/if/expr-if-panic.rs b/src/test/ui/expr/if/expr-if-panic.rs similarity index 100% rename from src/test/ui/if/expr-if-panic.rs rename to src/test/ui/expr/if/expr-if-panic.rs diff --git a/src/test/ui/if/if-branch-types.rs b/src/test/ui/expr/if/if-branch-types.rs similarity index 100% rename from src/test/ui/if/if-branch-types.rs rename to src/test/ui/expr/if/if-branch-types.rs diff --git a/src/test/ui/if/if-branch-types.stderr b/src/test/ui/expr/if/if-branch-types.stderr similarity index 100% rename from src/test/ui/if/if-branch-types.stderr rename to src/test/ui/expr/if/if-branch-types.stderr diff --git a/src/test/ui/if/if-check-panic.rs b/src/test/ui/expr/if/if-check-panic.rs similarity index 100% rename from src/test/ui/if/if-check-panic.rs rename to src/test/ui/expr/if/if-check-panic.rs diff --git a/src/test/ui/if/if-cond-bot.rs b/src/test/ui/expr/if/if-cond-bot.rs similarity index 100% rename from src/test/ui/if/if-cond-bot.rs rename to src/test/ui/expr/if/if-cond-bot.rs diff --git a/src/test/ui/if/if-let-arm-types.rs b/src/test/ui/expr/if/if-let-arm-types.rs similarity index 100% rename from src/test/ui/if/if-let-arm-types.rs rename to src/test/ui/expr/if/if-let-arm-types.rs diff --git a/src/test/ui/if/if-let-arm-types.stderr b/src/test/ui/expr/if/if-let-arm-types.stderr similarity index 100% rename from src/test/ui/if/if-let-arm-types.stderr rename to src/test/ui/expr/if/if-let-arm-types.stderr diff --git a/src/test/ui/if/if-let.rs b/src/test/ui/expr/if/if-let.rs similarity index 100% rename from src/test/ui/if/if-let.rs rename to src/test/ui/expr/if/if-let.rs diff --git a/src/test/ui/if/if-let.stderr b/src/test/ui/expr/if/if-let.stderr similarity index 100% rename from src/test/ui/if/if-let.stderr rename to src/test/ui/expr/if/if-let.stderr diff --git a/src/test/ui/if/if-loop.rs b/src/test/ui/expr/if/if-loop.rs similarity index 100% rename from src/test/ui/if/if-loop.rs rename to src/test/ui/expr/if/if-loop.rs diff --git a/src/test/ui/if/if-no-match-bindings.rs b/src/test/ui/expr/if/if-no-match-bindings.rs similarity index 100% rename from src/test/ui/if/if-no-match-bindings.rs rename to src/test/ui/expr/if/if-no-match-bindings.rs diff --git a/src/test/ui/if/if-no-match-bindings.stderr b/src/test/ui/expr/if/if-no-match-bindings.stderr similarity index 100% rename from src/test/ui/if/if-no-match-bindings.stderr rename to src/test/ui/expr/if/if-no-match-bindings.stderr diff --git a/src/test/ui/if/if-typeck.rs b/src/test/ui/expr/if/if-typeck.rs similarity index 100% rename from src/test/ui/if/if-typeck.rs rename to src/test/ui/expr/if/if-typeck.rs diff --git a/src/test/ui/if/if-typeck.stderr b/src/test/ui/expr/if/if-typeck.stderr similarity index 100% rename from src/test/ui/if/if-typeck.stderr rename to src/test/ui/expr/if/if-typeck.stderr diff --git a/src/test/ui/if/if-without-block.rs b/src/test/ui/expr/if/if-without-block.rs similarity index 100% rename from src/test/ui/if/if-without-block.rs rename to src/test/ui/expr/if/if-without-block.rs diff --git a/src/test/ui/if/if-without-block.stderr b/src/test/ui/expr/if/if-without-block.stderr similarity index 100% rename from src/test/ui/if/if-without-block.stderr rename to src/test/ui/expr/if/if-without-block.stderr diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/expr/if/if-without-else-as-fn-expr.rs similarity index 100% rename from src/test/ui/if/if-without-else-as-fn-expr.rs rename to src/test/ui/expr/if/if-without-else-as-fn-expr.rs diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/expr/if/if-without-else-as-fn-expr.stderr similarity index 100% rename from src/test/ui/if/if-without-else-as-fn-expr.stderr rename to src/test/ui/expr/if/if-without-else-as-fn-expr.stderr diff --git a/src/test/ui/if/if-without-else-result.rs b/src/test/ui/expr/if/if-without-else-result.rs similarity index 100% rename from src/test/ui/if/if-without-else-result.rs rename to src/test/ui/expr/if/if-without-else-result.rs diff --git a/src/test/ui/if/if-without-else-result.stderr b/src/test/ui/expr/if/if-without-else-result.stderr similarity index 100% rename from src/test/ui/if/if-without-else-result.stderr rename to src/test/ui/expr/if/if-without-else-result.stderr diff --git a/src/test/ui/if/ifmt-bad-arg.rs b/src/test/ui/expr/if/ifmt-bad-arg.rs similarity index 100% rename from src/test/ui/if/ifmt-bad-arg.rs rename to src/test/ui/expr/if/ifmt-bad-arg.rs diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/expr/if/ifmt-bad-arg.stderr similarity index 100% rename from src/test/ui/if/ifmt-bad-arg.stderr rename to src/test/ui/expr/if/ifmt-bad-arg.stderr diff --git a/src/test/ui/if/ifmt-bad-format-args.rs b/src/test/ui/expr/if/ifmt-bad-format-args.rs similarity index 100% rename from src/test/ui/if/ifmt-bad-format-args.rs rename to src/test/ui/expr/if/ifmt-bad-format-args.rs diff --git a/src/test/ui/if/ifmt-bad-format-args.stderr b/src/test/ui/expr/if/ifmt-bad-format-args.stderr similarity index 100% rename from src/test/ui/if/ifmt-bad-format-args.stderr rename to src/test/ui/expr/if/ifmt-bad-format-args.stderr diff --git a/src/test/ui/if/ifmt-unimpl.rs b/src/test/ui/expr/if/ifmt-unimpl.rs similarity index 100% rename from src/test/ui/if/ifmt-unimpl.rs rename to src/test/ui/expr/if/ifmt-unimpl.rs diff --git a/src/test/ui/if/ifmt-unimpl.stderr b/src/test/ui/expr/if/ifmt-unimpl.stderr similarity index 100% rename from src/test/ui/if/ifmt-unimpl.stderr rename to src/test/ui/expr/if/ifmt-unimpl.stderr diff --git a/src/test/ui/if/ifmt-unknown-trait.rs b/src/test/ui/expr/if/ifmt-unknown-trait.rs similarity index 100% rename from src/test/ui/if/ifmt-unknown-trait.rs rename to src/test/ui/expr/if/ifmt-unknown-trait.rs diff --git a/src/test/ui/if/ifmt-unknown-trait.stderr b/src/test/ui/expr/if/ifmt-unknown-trait.stderr similarity index 100% rename from src/test/ui/if/ifmt-unknown-trait.stderr rename to src/test/ui/expr/if/ifmt-unknown-trait.stderr From 011bef8a84cbfea2458293fd367065bb20a9e7b4 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Tue, 24 Nov 2020 17:37:15 -0800 Subject: [PATCH 04/16] Move src/test/ui/if-attrs to src/test/ui/expr/if/attrs --- src/test/ui/{if-attrs => expr/if/attrs}/bad-cfg.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/bad-cfg.stderr | 0 src/test/ui/{if-attrs => expr/if/attrs}/builtin-if-attr.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/cfg-false-if-attr.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/else-attrs.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/else-attrs.stderr | 0 src/test/ui/{if-attrs => expr/if/attrs}/gate-whole-expr.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/let-chains-attr.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/let-chains-attr.stderr | 0 src/test/ui/{if-attrs => expr/if/attrs}/stmt-expr-gated.rs | 0 src/test/ui/{if-attrs => expr/if/attrs}/stmt-expr-gated.stderr | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{if-attrs => expr/if/attrs}/bad-cfg.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/bad-cfg.stderr (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/builtin-if-attr.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/cfg-false-if-attr.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/else-attrs.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/else-attrs.stderr (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/gate-whole-expr.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/let-chains-attr.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/let-chains-attr.stderr (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/stmt-expr-gated.rs (100%) rename src/test/ui/{if-attrs => expr/if/attrs}/stmt-expr-gated.stderr (100%) diff --git a/src/test/ui/if-attrs/bad-cfg.rs b/src/test/ui/expr/if/attrs/bad-cfg.rs similarity index 100% rename from src/test/ui/if-attrs/bad-cfg.rs rename to src/test/ui/expr/if/attrs/bad-cfg.rs diff --git a/src/test/ui/if-attrs/bad-cfg.stderr b/src/test/ui/expr/if/attrs/bad-cfg.stderr similarity index 100% rename from src/test/ui/if-attrs/bad-cfg.stderr rename to src/test/ui/expr/if/attrs/bad-cfg.stderr diff --git a/src/test/ui/if-attrs/builtin-if-attr.rs b/src/test/ui/expr/if/attrs/builtin-if-attr.rs similarity index 100% rename from src/test/ui/if-attrs/builtin-if-attr.rs rename to src/test/ui/expr/if/attrs/builtin-if-attr.rs diff --git a/src/test/ui/if-attrs/cfg-false-if-attr.rs b/src/test/ui/expr/if/attrs/cfg-false-if-attr.rs similarity index 100% rename from src/test/ui/if-attrs/cfg-false-if-attr.rs rename to src/test/ui/expr/if/attrs/cfg-false-if-attr.rs diff --git a/src/test/ui/if-attrs/else-attrs.rs b/src/test/ui/expr/if/attrs/else-attrs.rs similarity index 100% rename from src/test/ui/if-attrs/else-attrs.rs rename to src/test/ui/expr/if/attrs/else-attrs.rs diff --git a/src/test/ui/if-attrs/else-attrs.stderr b/src/test/ui/expr/if/attrs/else-attrs.stderr similarity index 100% rename from src/test/ui/if-attrs/else-attrs.stderr rename to src/test/ui/expr/if/attrs/else-attrs.stderr diff --git a/src/test/ui/if-attrs/gate-whole-expr.rs b/src/test/ui/expr/if/attrs/gate-whole-expr.rs similarity index 100% rename from src/test/ui/if-attrs/gate-whole-expr.rs rename to src/test/ui/expr/if/attrs/gate-whole-expr.rs diff --git a/src/test/ui/if-attrs/let-chains-attr.rs b/src/test/ui/expr/if/attrs/let-chains-attr.rs similarity index 100% rename from src/test/ui/if-attrs/let-chains-attr.rs rename to src/test/ui/expr/if/attrs/let-chains-attr.rs diff --git a/src/test/ui/if-attrs/let-chains-attr.stderr b/src/test/ui/expr/if/attrs/let-chains-attr.stderr similarity index 100% rename from src/test/ui/if-attrs/let-chains-attr.stderr rename to src/test/ui/expr/if/attrs/let-chains-attr.stderr diff --git a/src/test/ui/if-attrs/stmt-expr-gated.rs b/src/test/ui/expr/if/attrs/stmt-expr-gated.rs similarity index 100% rename from src/test/ui/if-attrs/stmt-expr-gated.rs rename to src/test/ui/expr/if/attrs/stmt-expr-gated.rs diff --git a/src/test/ui/if-attrs/stmt-expr-gated.stderr b/src/test/ui/expr/if/attrs/stmt-expr-gated.stderr similarity index 100% rename from src/test/ui/if-attrs/stmt-expr-gated.stderr rename to src/test/ui/expr/if/attrs/stmt-expr-gated.stderr From 6919a775c6301ff23fda9a93c8d116da4a7b4f0d Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Tue, 24 Nov 2020 17:53:39 -0800 Subject: [PATCH 05/16] Move src/test/ui/if-*.rs to src/test/expr/if/if-*.rs --- src/test/ui/{ => expr}/if-bot.rs | 0 src/test/ui/{ => expr/if}/if-check.rs | 0 src/test/ui/{ => expr/if}/if-else-type-mismatch.rs | 0 src/test/ui/{ => expr/if}/if-else-type-mismatch.stderr | 0 src/test/ui/{ => expr/if}/if-ret.rs | 0 src/test/ui/{ => expr/if}/if-ret.stderr | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{ => expr}/if-bot.rs (100%) rename src/test/ui/{ => expr/if}/if-check.rs (100%) rename src/test/ui/{ => expr/if}/if-else-type-mismatch.rs (100%) rename src/test/ui/{ => expr/if}/if-else-type-mismatch.stderr (100%) rename src/test/ui/{ => expr/if}/if-ret.rs (100%) rename src/test/ui/{ => expr/if}/if-ret.stderr (100%) diff --git a/src/test/ui/if-bot.rs b/src/test/ui/expr/if-bot.rs similarity index 100% rename from src/test/ui/if-bot.rs rename to src/test/ui/expr/if-bot.rs diff --git a/src/test/ui/if-check.rs b/src/test/ui/expr/if/if-check.rs similarity index 100% rename from src/test/ui/if-check.rs rename to src/test/ui/expr/if/if-check.rs diff --git a/src/test/ui/if-else-type-mismatch.rs b/src/test/ui/expr/if/if-else-type-mismatch.rs similarity index 100% rename from src/test/ui/if-else-type-mismatch.rs rename to src/test/ui/expr/if/if-else-type-mismatch.rs diff --git a/src/test/ui/if-else-type-mismatch.stderr b/src/test/ui/expr/if/if-else-type-mismatch.stderr similarity index 100% rename from src/test/ui/if-else-type-mismatch.stderr rename to src/test/ui/expr/if/if-else-type-mismatch.stderr diff --git a/src/test/ui/if-ret.rs b/src/test/ui/expr/if/if-ret.rs similarity index 100% rename from src/test/ui/if-ret.rs rename to src/test/ui/expr/if/if-ret.rs diff --git a/src/test/ui/if-ret.stderr b/src/test/ui/expr/if/if-ret.stderr similarity index 100% rename from src/test/ui/if-ret.stderr rename to src/test/ui/expr/if/if-ret.stderr From fa14f22fcb260ca0bc7dca395b456ea14bcde712 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 26 Nov 2020 14:02:01 +0100 Subject: [PATCH 06/16] Improve rustdoc JS tests error output --- src/tools/rustdoc-js/tester.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 139e6f73f4216..63f2d2f5d2f68 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -190,6 +190,30 @@ function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { return content; } +function contentToDiffLine(key, value) { + return `"${key}": "${value}",`; +} + +// This function is only called when no matching result was found and therefore will only display +// the diff between the two items. +function betterLookingDiff(entry, data) { + let output = ' {\n'; + let spaces = ' '; + for (let key in entry) { + if (!entry.hasOwnProperty(key)) { + continue; + } + let value = data[key]; + if (value !== entry[key]) { + output += '-' + spaces + contentToDiffLine(key, entry[key]) + '\n'; + output += '+' + spaces + contentToDiffLine(key, value) + '\n'; + } else { + output += spaces + contentToDiffLine(key, value) + '\n'; + } + } + return output + ' }'; +} + function lookForEntry(entry, data) { for (var i = 0; i < data.length; ++i) { var allGood = true; @@ -281,6 +305,13 @@ function runSearch(query, expected, index, loaded, loadedFile, queryName) { if (entry_pos === null) { error_text.push(queryName + "==> Result not found in '" + key + "': '" + JSON.stringify(entry[i]) + "'"); + // By default, we just compare the two first items. + let item_to_diff = 0; + if ((ignore_order === false || exact_check === true) && i < results[key].length) { + item_to_diff = i; + } + error_text.push("Diff of first error:\n" + + betterLookingDiff(entry[i], results[key][item_to_diff])); } else if (exact_check === true && prev_pos + 1 !== entry_pos) { error_text.push(queryName + "==> Exact check failed at position " + (prev_pos + 1) + ": expected '" + JSON.stringify(entry[i]) + "' but found '" + From f6630932220071a4ebe2fb3302d5af6a80ec8343 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Nov 2020 14:27:59 +0100 Subject: [PATCH 07/16] Allow to have any valid ident used as keyword in doc_keyword feature --- src/librustdoc/clean/mod.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e76ca1022a943..8babc90793a7c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -162,18 +162,30 @@ impl Clean for CrateNum { .collect() }; + let get_span = + |attr: &ast::NestedMetaItem| Some(attr.meta_item()?.name_value_literal()?.span); + let as_keyword = |res: Res| { if let Res::Def(DefKind::Mod, def_id) = res { let attrs = cx.tcx.get_attrs(def_id).clean(cx); let mut keyword = None; for attr in attrs.lists(sym::doc) { - if let Some(v) = attr.value_str() { - if attr.has_name(sym::keyword) { - if v.is_doc_keyword() { - keyword = Some(v.to_string()); - break; + if attr.has_name(sym::keyword) { + if let Some(v) = attr.value_str() { + let k = v.to_string(); + if !rustc_lexer::is_ident(&k) { + let sp = get_span(&attr).unwrap_or_else(|| attr.span()); + cx.tcx + .sess + .struct_span_err( + sp, + &format!("`{}` is not a valid identifier", v), + ) + .emit(); + } else { + keyword = Some(k); } - // FIXME: should warn on unknown keywords? + break; } } } From af2040ff95b35a1d70c329ee20d61356a898e3eb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Nov 2020 14:28:17 +0100 Subject: [PATCH 08/16] Add tests for doc_keyword feature extension --- src/test/rustdoc-ui/invalid-keyword.rs | 4 ++++ src/test/rustdoc-ui/invalid-keyword.stderr | 8 ++++++++ src/test/rustdoc/keyword.rs | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 src/test/rustdoc-ui/invalid-keyword.rs create mode 100644 src/test/rustdoc-ui/invalid-keyword.stderr diff --git a/src/test/rustdoc-ui/invalid-keyword.rs b/src/test/rustdoc-ui/invalid-keyword.rs new file mode 100644 index 0000000000000..ce2abc69bbd28 --- /dev/null +++ b/src/test/rustdoc-ui/invalid-keyword.rs @@ -0,0 +1,4 @@ +#![feature(doc_keyword)] + +#[doc(keyword = "foo df")] //~ ERROR +mod foo {} diff --git a/src/test/rustdoc-ui/invalid-keyword.stderr b/src/test/rustdoc-ui/invalid-keyword.stderr new file mode 100644 index 0000000000000..8658e3825782d --- /dev/null +++ b/src/test/rustdoc-ui/invalid-keyword.stderr @@ -0,0 +1,8 @@ +error: `foo df` is not a valid identifier + --> $DIR/invalid-keyword.rs:3:17 + | +LL | #[doc(keyword = "foo df")] + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/rustdoc/keyword.rs b/src/test/rustdoc/keyword.rs index db5d115c6da74..25e8b7912e772 100644 --- a/src/test/rustdoc/keyword.rs +++ b/src/test/rustdoc/keyword.rs @@ -14,3 +14,8 @@ #[doc(keyword = "match")] /// this is a test! mod foo{} + +// @has foo/keyword.foo.html '//section[@id="main"]//div[@class="docblock"]//p' 'hello' +#[doc(keyword = "foo")] +/// hello +mod bar {} From 482b3accdd2390b1cd0ffee850fe1c21468b6798 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Nov 2020 14:55:06 +0100 Subject: [PATCH 09/16] Remove unused is_doc_keyword function --- compiler/rustc_span/src/symbol.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 338ff005995d5..ad2c7d7609bb8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1589,11 +1589,6 @@ impl Symbol { self == kw::Try } - /// Used for sanity checking rustdoc keyword sections. - pub fn is_doc_keyword(self) -> bool { - self <= kw::Union - } - /// A keyword or reserved identifier that can be used as a path segment. pub fn is_path_segment_keyword(self) -> bool { self == kw::Super From 7e00222aab90df9f09e23be01c2c7fb6a5044e6a Mon Sep 17 00:00:00 2001 From: Sreehari S Date: Fri, 27 Nov 2020 14:21:23 -0800 Subject: [PATCH 10/16] add enable-full-tools to freebsd builds to prevent occasional link errors when compiling rust programs --- src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index 1075947c9cfa7..8413d775ac4c4 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -30,5 +30,10 @@ ENV \ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --enable-sanitizers --disable-docs +ENV RUST_CONFIGURE_ARGS \ + --enable-full-tools \ + --enable-extended \ + --enable-profiler \ + --enable-sanitizers \ + --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS From d1a2c0f99c079479009b879fd904859438b72f1e Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 5 Nov 2020 13:23:11 +0100 Subject: [PATCH 11/16] BTreeMap: try to enhance various comments & local identifiers --- .../alloc/src/collections/btree/map/entry.rs | 2 +- .../alloc/src/collections/btree/navigate.rs | 9 + library/alloc/src/collections/btree/node.rs | 168 ++++++++++-------- library/alloc/src/collections/btree/remove.rs | 2 +- library/alloc/src/collections/btree/search.rs | 20 ++- library/alloc/src/collections/btree/set.rs | 2 +- library/alloc/src/collections/btree/split.rs | 4 +- 7 files changed, 118 insertions(+), 89 deletions(-) diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs index 69926ac2aff6d..c92888cb8973c 100644 --- a/library/alloc/src/collections/btree/map/entry.rs +++ b/library/alloc/src/collections/btree/map/entry.rs @@ -459,7 +459,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { self.remove_kv().1 } - // Body of `remove_entry`, separate to keep the above implementations short. + // Body of `remove_entry`, probably separate because the name reflects the returned pair. pub(super) fn remove_kv(self) -> (K, V) { let mut emptied_internal_root = false; let (old_kv, _) = self.handle.remove_kv_tracking(|| emptied_internal_root = true); diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index ef6f888693fc8..cce8b21a2bc41 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -9,6 +9,9 @@ use super::search::{self, SearchResult}; use super::unwrap_unchecked; /// Finds the leaf edges delimiting a specified range in or underneath a node. +/// +/// The result is meaningful only if the tree is ordered by key, like the tree +/// in a `BTreeMap` is. fn range_search( root1: NodeRef, root2: NodeRef, @@ -122,6 +125,9 @@ fn full_range( impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { /// Creates a pair of leaf edges delimiting a specified range in or underneath a node. + /// + /// The result is meaningful only if the tree is ordered by key, like the tree + /// in a `BTreeMap` is. pub fn range_search( self, range: R, @@ -152,6 +158,9 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> /// Splits a unique reference into a pair of leaf edges delimiting a specified range. /// The result are non-unique references allowing (some) mutation, which must be used /// carefully. + /// + /// The result is meaningful only if the tree is ordered by key, like the tree + /// in a `BTreeMap` is. pub fn range_search( self, range: R, diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 6a8be441513a0..78be070a98382 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -27,6 +27,9 @@ // given node has exactly the same length. // - A node of length `n` has `n` keys, `n` values, and `n + 1` edges. // This implies that even an empty node has at least one edge. +// For a leaf node, "having an edge" only means we can identify a position in the node, +// since leaf edges are empty and need no data representation. In an internal node, +// an edge both identifies a position and contains a pointer to a child node. use core::cmp::Ordering; use core::marker::PhantomData; @@ -215,6 +218,8 @@ impl NodeRef { /// although insert methods allow a mutable pointer to a value to coexist. /// - When this is `Owned`, the `NodeRef` acts roughly like `Box`, /// but does not have a destructor, and must be cleaned up manually. +/// Since any `NodeRef` allows navigating through the tree, `BorrowType` +/// effectively applies to the entire tree, not just the node itself. /// - `K` and `V`: These are the types of keys and values stored in the nodes. /// - `Type`: This can be `Leaf`, `Internal`, or `LeafOrInternal`. When this is /// `Leaf`, the `NodeRef` points to a leaf node, when this is `Internal` the @@ -227,9 +232,9 @@ impl NodeRef { /// such restrictions: /// - For each type parameter, we can only define a method either generically /// or for one particular type. For example, we cannot define a method like -/// `key_at` generically for all `BorrowType`, because we want to return +/// `key_at` generically for all `BorrowType`, because we want it to return /// `&'a K` for most choices of `BorrowType`, but plain `K` for `Owned`. -/// We cannot define `key_at` once for all types that have a lifetime. +/// We cannot define `key_at` once for all types that carry a lifetime. /// Therefore, we define it only for the least powerful type `Immut<'a>`. /// - We cannot get implicit coercion from say `Mut<'a>` to `Immut<'a>`. /// Therefore, we have to explicitly call `reborrow` on a more powerfull @@ -240,16 +245,17 @@ impl NodeRef { /// That is irrelevant when `BorrowType` is `Immut<'a>`, but the rule does /// no harm because we make those `NodeRef` implicitly `Copy`. /// The rule also avoids implicitly returning the lifetime of `&self`, -/// instead of the lifetime contained in `BorrowType`. +/// instead of the lifetime carried by `BorrowType`. /// An exception to this rule are the insert functions. /// - Given the above, we need a `reborrow_mut` to explicitly copy a `Mut<'a>` /// `NodeRef` whenever we want to invoke a method returning an extra reference /// somewhere in the tree. pub struct NodeRef { - /// The number of levels below the node, a property of the node that cannot be - /// entirely described by `Type` and that the node does not store itself either. - /// Unconstrained if `Type` is `LeafOrInternal`, must be zero if `Type` is `Leaf`, - /// and must be non-zero if `Type` is `Internal`. + /// The number of levels that the node and the level of leaves are apart, a + /// constant of the node that cannot be entirely described by `Type`, and that + /// the node itself does not store. We only need to store the height of the root + /// node, and derive every other node's height from it. + /// Must be zero if `Type` is `Leaf` and non-zero if `Type` is `Internal`. height: usize, /// The pointer to the leaf or internal node. The definition of `InternalNode` /// ensures that the pointer is valid either way. @@ -317,8 +323,11 @@ impl NodeRef { unsafe { usize::from((*Self::as_leaf_ptr(self)).len) } } - /// Returns the height of this node with respect to the leaf level. Zero height means the - /// node is a leaf itself. + /// Returns the number of levels that the node and leaves are apart. Zero + /// height means the node is a leaf itself. If you picture trees with the + /// root on top, the number says at which elevation the node appears. + /// If you picture trees with leaves on top, the number says how high + /// the tree extends above the node. pub fn height(&self) -> usize { self.height } @@ -376,6 +385,8 @@ impl NodeRef { /// that points to the current node. Returns `Err(self)` if the current node has /// no parent, giving back the original `NodeRef`. /// + /// The method name assumes you picture trees with the root node on top. + /// /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should /// both, upon success, do nothing. pub fn ascend( @@ -576,7 +587,6 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { impl<'a, K, V, Type> NodeRef, K, V, Type> { /// # Safety /// - The node has more than `idx` initialized elements. - /// - The keys and values of the node must be initialized up to its current length. unsafe fn into_key_val_mut_at(mut self, idx: usize) -> (&'a K, &'a mut V) { // We only create a reference to the one element we are interested in, // to avoid aliasing with outstanding references to other elements, @@ -609,7 +619,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { unsafe { (*leaf).parent_idx.write(parent_idx as u16) }; } - /// Clear the node's link to its parent edge, freeing it from its tree. + /// Clear the node's link to its parent edge. /// This only makes sense when there are no other references to the node. fn clear_parent_link(&mut self) { let leaf = Self::as_leaf_mut(self); @@ -618,7 +628,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { - /// Adds a key/value pair to the end of the node. + /// Adds a key-value pair to the end of the node. pub fn push(&mut self, key: K, val: V) { let len = unsafe { self.reborrow_mut().into_len_mut() }; let idx = usize::from(*len); @@ -630,7 +640,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { } } - /// Adds a key/value pair to the beginning of the node. + /// Adds a key-value pair to the beginning of the node. fn push_front(&mut self, key: K, val: V) { assert!(self.len() < CAPACITY); @@ -659,7 +669,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { - /// Adds a key/value pair, and an edge to go to the right of that pair, + /// Adds a key-value pair, and an edge to go to the right of that pair, /// to the end of the node. pub fn push(&mut self, key: K, val: V, edge: Root) { assert!(edge.height == self.height - 1); @@ -676,7 +686,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { } } - /// Adds a key/value pair, and an edge to go to the left of that pair, + /// Adds a key-value pair, and an edge to go to the left of that pair, /// to the beginning of the node. fn push_front(&mut self, key: K, val: V, edge: Root) { assert!(edge.height == self.height - 1); @@ -694,7 +704,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { } impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { - /// Removes a key/value pair from the end of the node and returns the pair. + /// Removes a key-value pair from the end of the node and returns the pair. /// Also removes the edge that was to the right of that pair and, if the node /// is internal, returns the orphaned subtree that this edge owned. fn pop(&mut self) -> (K, V, Option>) { @@ -722,7 +732,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { } } - /// Removes a key/value pair from the beginning of the node and returns the pair. + /// Removes a key-value pair from the beginning of the node and returns the pair. /// Also removes the edge that was to the left of that pair and, if the node is /// internal, returns the orphaned subtree that this edge owned. fn pop_front(&mut self) -> (K, V, Option>) { @@ -786,12 +796,12 @@ impl NodeRef { } } -/// A reference to a specific key/value pair or edge within a node. The `Node` parameter -/// must be a `NodeRef`, while the `Type` can either be `KV` (signifying a handle on a key/value +/// A reference to a specific key-value pair or edge within a node. The `Node` parameter +/// must be a `NodeRef`, while the `Type` can either be `KV` (signifying a handle on a key-value /// pair) or `Edge` (signifying a handle on an edge). /// /// Note that even `Leaf` nodes can have `Edge` handles. Instead of representing a pointer to -/// a child node, these represent the spaces where child pointers would go between the key/value +/// a child node, these represent the spaces where child pointers would go between the key-value /// pairs. For example, in a node with length 2, there would be 3 possible edge locations - one /// to the left of the node, one between the two pairs, and one at the right of the node. pub struct Handle { @@ -810,7 +820,7 @@ impl Clone for Handle { } impl Handle { - /// Retrieves the node that contains the edge or key/value pair this handle points to. + /// Retrieves the node that contains the edge or key-value pair this handle points to. pub fn into_node(self) -> Node { self.node } @@ -822,7 +832,7 @@ impl Handle { } impl Handle, marker::KV> { - /// Creates a new handle to a key/value pair in `node`. + /// Creates a new handle to a key-value pair in `node`. /// Unsafe because the caller must ensure that `idx < node.len()`. pub unsafe fn new_kv(node: NodeRef, idx: usize) -> Self { debug_assert!(idx < node.len()); @@ -842,7 +852,7 @@ impl Handle, mar impl NodeRef { /// Could be a public implementation of PartialEq, but only used in this module. fn eq(&self, other: &Self) -> bool { - let Self { node, height, _marker: _ } = self; + let Self { node, height, _marker } = self; if node.eq(&other.node) { debug_assert_eq!(*height, other.height); true @@ -856,7 +866,7 @@ impl PartialEq for Handle, HandleType> { fn eq(&self, other: &Self) -> bool { - let Self { node, idx, _marker: _ } = self; + let Self { node, idx, _marker } = self; node.eq(&other.node) && *idx == other.idx } } @@ -865,7 +875,7 @@ impl PartialOrd for Handle, HandleType> { fn partial_cmp(&self, other: &Self) -> Option { - let Self { node, idx, _marker: _ } = self; + let Self { node, idx, _marker } = self; if node.eq(&other.node) { Some(idx.cmp(&other.idx)) } else { None } } } @@ -950,7 +960,7 @@ fn splitpoint(edge_idx: usize) -> (usize, LeftOrRight) { } impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, marker::Edge> { - /// Inserts a new key/value pair between the key/value pairs to the right and left of + /// Inserts a new key-value pair between the key-value pairs to the right and left of /// this edge. This method assumes that there is enough space in the node for the new /// pair to fit. /// @@ -969,7 +979,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark } impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, marker::Edge> { - /// Inserts a new key/value pair between the key/value pairs to the right and left of + /// Inserts a new key-value pair between the key-value pairs to the right and left of /// this edge. This method splits the node if there isn't enough room. /// /// The returned pointer points to the inserted value. @@ -997,8 +1007,8 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark } impl<'a, K, V> Handle, K, V, marker::Internal>, marker::Edge> { - /// Fixes the parent pointer and index in the child node below this edge. This is useful - /// when the ordering of edges has been changed, such as in the various `insert` methods. + /// Fixes the parent pointer and index in the child node that this edge + /// links to. This is useful when the ordering of edges has been changed, fn correct_parent_link(self) { // Create backpointer without invalidating other references to the node. let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) }; @@ -1009,8 +1019,8 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, marker::Edge> { - /// Inserts a new key/value pair and an edge that will go to the right of that new pair - /// between this edge and the key/value pair to the right of this edge. This method assumes + /// Inserts a new key-value pair and an edge that will go to the right of that new pair + /// between this edge and the key-value pair to the right of this edge. This method assumes /// that there is enough space in the node for the new pair to fit. fn insert_fit(&mut self, key: K, val: V, edge: Root) { debug_assert!(self.node.len() < CAPACITY); @@ -1026,8 +1036,8 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, } } - /// Inserts a new key/value pair and an edge that will go to the right of that new pair - /// between this edge and the key/value pair to the right of this edge. This method splits + /// Inserts a new key-value pair and an edge that will go to the right of that new pair + /// between this edge and the key-value pair to the right of this edge. This method splits /// the node if there isn't enough room. fn insert( mut self, @@ -1060,7 +1070,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, } impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, marker::Edge> { - /// Inserts a new key/value pair between the key/value pairs to the right and left of + /// Inserts a new key-value pair between the key-value pairs to the right and left of /// this edge. This method splits the node if there isn't enough room, and tries to /// insert the split off portion into the parent node recursively, until the root is reached. /// @@ -1098,6 +1108,8 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark impl Handle, marker::Edge> { /// Finds the node pointed to by this edge. /// + /// The method name assumes you picture trees with the root node on top. + /// /// `edge.descend().ascend().unwrap()` and `node.ascend().unwrap().descend()` should /// both, upon success, do nothing. pub fn descend(self) -> NodeRef { @@ -1186,10 +1198,10 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, marker::KV> { /// Splits the underlying node into three parts: /// - /// - The node is truncated to only contain the key/value pairs to the left of + /// - The node is truncated to only contain the key-value pairs to the left of /// this handle. /// - The key and value pointed to by this handle are extracted. - /// - All the key/value pairs to the right of this handle are put into a newly + /// - All the key-value pairs to the right of this handle are put into a newly /// allocated node. pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> { unsafe { @@ -1202,8 +1214,8 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark } } - /// Removes the key/value pair pointed to by this handle and returns it, along with the edge - /// that the key/value pair collapsed into. + /// Removes the key-value pair pointed to by this handle and returns it, along with the edge + /// that the key-value pair collapsed into. pub fn remove( mut self, ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { @@ -1219,10 +1231,10 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, marker::KV> { /// Splits the underlying node into three parts: /// - /// - The node is truncated to only contain the edges and key/value pairs to the + /// - The node is truncated to only contain the edges and key-value pairs to the /// left of this handle. /// - The key and value pointed to by this handle are extracted. - /// - All the edges and key/value pairs to the right of this handle are put into + /// - All the edges and key-value pairs to the right of this handle are put into /// a newly allocated node. pub fn split(mut self) -> SplitResult<'a, K, V, marker::Internal> { unsafe { @@ -1247,7 +1259,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, } /// Represents a session for evaluating and performing a balancing operation -/// around an internal key/value pair. +/// around an internal key-value pair. pub struct BalancingContext<'a, K, V> { parent: Handle, K, V, marker::Internal>, marker::KV>, left_child: NodeRef, K, V, marker::LeafOrInternal>, @@ -1320,14 +1332,14 @@ impl<'a, K, V> BalancingContext<'a, K, V> { /// Returns `true` if it is valid to call `.merge()` in the balancing context, /// i.e., whether there is enough room in a node to hold the combination of - /// both adjacent child nodes, along with the key/value pair in the parent. + /// both adjacent child nodes, along with the key-value pair in the parent. pub fn can_merge(&self) -> bool { self.left_child.len() + 1 + self.right_child.len() <= CAPACITY } } impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { - /// Merges the parent's key/value pair and both adjacent child nodes into + /// Merges the parent's key-value pair and both adjacent child nodes into /// the left node and returns an edge handle in that expanded left node. /// If `track_edge_idx` is given some value, the returned edge corresponds /// to where the edge in that child node ended up, @@ -1409,8 +1421,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { } } - /// Removes a key/value pair from the left child and places it in the key/value storage - /// of the parent, while pushing the old parent key/value pair into the right child. + /// Removes a key-value pair from the left child and places it in the key-value storage + /// of the parent, while pushing the old parent key-value pair into the right child. /// Returns a handle to the edge in the right child corresponding to where the original /// edge specified by `track_right_edge_idx` ended up. pub fn steal_left( @@ -1432,8 +1444,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { } } - /// Removes a key/value pair from the right child and places it in the key/value storage - /// of the parent, while pushing the old parent key/value pair onto the left child. + /// Removes a key-value pair from the right child and places it in the key-value storage + /// of the parent, while pushing the old parent key-value pair onto the left child. /// Returns a handle to the edge in the left child specified by `track_left_edge_idx`, /// which didn't move. pub fn steal_right( @@ -1459,17 +1471,17 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { pub fn bulk_steal_left(&mut self, count: usize) { unsafe { let left_node = &mut self.left_child; - let left_len = left_node.len(); + let old_left_len = left_node.len(); let right_node = &mut self.right_child; - let right_len = right_node.len(); + let old_right_len = right_node.len(); // Make sure that we may steal safely. - assert!(right_len + count <= CAPACITY); - assert!(left_len >= count); + assert!(old_right_len + count <= CAPACITY); + assert!(old_left_len >= count); - let new_left_len = left_len - count; + let new_left_len = old_left_len - count; - // Move data. + // Move leaf data. { let left_kv = left_node.reborrow_mut().into_kv_pointers_mut(); let right_kv = right_node.reborrow_mut().into_kv_pointers_mut(); @@ -1479,13 +1491,13 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { }; // Make room for stolen elements in the right child. - ptr::copy(right_kv.0, right_kv.0.add(count), right_len); - ptr::copy(right_kv.1, right_kv.1.add(count), right_len); + ptr::copy(right_kv.0, right_kv.0.add(count), old_right_len); + ptr::copy(right_kv.1, right_kv.1.add(count), old_right_len); // Move elements from the left child to the right one. move_kv(left_kv, new_left_len + 1, right_kv, 0, count - 1); - // Move parent's key/value pair to the right child. + // Move parent's key-value pair to the right child. move_kv(parent_kv, 0, right_kv, count - 1, 1); // Move the left-most stolen pair to the parent. @@ -1500,9 +1512,10 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { // Make room for stolen edges. let left = left.reborrow(); let right_edges = right.reborrow_mut().into_edge_area_slice().as_mut_ptr(); - ptr::copy(right_edges, right_edges.add(count), right_len + 1); - right.correct_childrens_parent_links(count..count + right_len + 1); + ptr::copy(right_edges, right_edges.add(count), old_right_len + 1); + right.correct_childrens_parent_links(count..count + old_right_len + 1); + // Steal edges. move_edges(left, new_left_len + 1, right, 0, count); } (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} @@ -1515,17 +1528,17 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { pub fn bulk_steal_right(&mut self, count: usize) { unsafe { let left_node = &mut self.left_child; - let left_len = left_node.len(); + let old_left_len = left_node.len(); let right_node = &mut self.right_child; - let right_len = right_node.len(); + let old_right_len = right_node.len(); // Make sure that we may steal safely. - assert!(left_len + count <= CAPACITY); - assert!(right_len >= count); + assert!(old_left_len + count <= CAPACITY); + assert!(old_right_len >= count); - let new_right_len = right_len - count; + let new_right_len = old_right_len - count; - // Move data. + // Move leaf data. { let left_kv = left_node.reborrow_mut().into_kv_pointers_mut(); let right_kv = right_node.reborrow_mut().into_kv_pointers_mut(); @@ -1534,16 +1547,16 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { (kv.0 as *mut K, kv.1 as *mut V) }; - // Move parent's key/value pair to the left child. - move_kv(parent_kv, 0, left_kv, left_len, 1); + // Move parent's key-value pair to the left child. + move_kv(parent_kv, 0, left_kv, old_left_len, 1); // Move elements from the right child to the left one. - move_kv(right_kv, 0, left_kv, left_len + 1, count - 1); + move_kv(right_kv, 0, left_kv, old_left_len + 1, count - 1); // Move the right-most stolen pair to the parent. move_kv(right_kv, count - 1, parent_kv, 0, 1); - // Fix right indexing + // Fill gap where stolen elements used to be. ptr::copy(right_kv.0.add(count), right_kv.0, new_right_len); ptr::copy(right_kv.1.add(count), right_kv.1, new_right_len); } @@ -1553,9 +1566,10 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) { (ForceResult::Internal(left), ForceResult::Internal(mut right)) => { - move_edges(right.reborrow(), 0, left, left_len + 1, count); + // Steal edges. + move_edges(right.reborrow(), 0, left, old_left_len + 1, count); - // Fix right indexing. + // Fill gap where stolen edges used to be. let right_edges = right.reborrow_mut().into_edge_area_slice().as_mut_ptr(); ptr::copy(right_edges.add(count), right_edges, new_right_len + 1); right.correct_childrens_parent_links(0..=new_right_len); @@ -1671,28 +1685,28 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma right: &mut NodeRef, K, V, marker::LeafOrInternal>, ) { unsafe { - let left_new_len = self.idx; + let new_left_len = self.idx; let mut left_node = self.reborrow_mut().into_node(); - let right_new_len = left_node.len() - left_new_len; + let new_right_len = left_node.len() - new_left_len; let mut right_node = right.reborrow_mut(); assert!(right_node.len() == 0); assert!(left_node.height == right_node.height); - if right_new_len > 0 { + if new_right_len > 0 { let left_kv = left_node.reborrow_mut().into_kv_pointers_mut(); let right_kv = right_node.reborrow_mut().into_kv_pointers_mut(); - move_kv(left_kv, left_new_len, right_kv, 0, right_new_len); + move_kv(left_kv, new_left_len, right_kv, 0, new_right_len); - *left_node.reborrow_mut().into_len_mut() = left_new_len as u16; - *right_node.reborrow_mut().into_len_mut() = right_new_len as u16; + *left_node.reborrow_mut().into_len_mut() = new_left_len as u16; + *right_node.reborrow_mut().into_len_mut() = new_right_len as u16; match (left_node.force(), right_node.force()) { (ForceResult::Internal(left), ForceResult::Internal(right)) => { let left = left.reborrow(); - move_edges(left, left_new_len + 1, right, 1, right_new_len); + move_edges(left, new_left_len + 1, right, 1, new_right_len); } (ForceResult::Leaf(_), ForceResult::Leaf(_)) => {} _ => unreachable!(), diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs index c4253d4221b3b..5ae1c1fcab803 100644 --- a/library/alloc/src/collections/btree/remove.rs +++ b/library/alloc/src/collections/btree/remove.rs @@ -4,7 +4,7 @@ use super::unwrap_unchecked; use core::mem; impl<'a, K: 'a, V: 'a> Handle, K, V, marker::LeafOrInternal>, marker::KV> { - /// Removes a key/value-pair from the tree, and returns that pair, as well as + /// Removes a key-value pair from the tree, and returns that pair, as well as /// the leaf edge corresponding to that former pair. It's possible this empties /// a root node that is internal, which the caller should pop from the map /// holding the tree. The caller should also decrement the map's length. diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs index 93de2d829ac8d..ed7f95fe632fa 100644 --- a/library/alloc/src/collections/btree/search.rs +++ b/library/alloc/src/collections/btree/search.rs @@ -14,6 +14,9 @@ pub enum SearchResult { /// Returns a `Found` with the handle of the matching KV, if any. Otherwise, /// returns a `GoDown` with the handle of the possible leaf edge where the key /// belongs. +/// +/// The result is meaningful only if the tree is ordered by key, like the tree +/// in a `BTreeMap` is. pub fn search_tree( mut node: NodeRef, key: &Q, @@ -38,8 +41,11 @@ where /// Looks up a given key in a given node, without recursion. /// Returns a `Found` with the handle of the matching KV, if any. Otherwise, -/// returns a `GoDown` with the handle of the edge where the key might be found. -/// If the node is a leaf, a `GoDown` edge is not an actual edge but a possible edge. +/// returns a `GoDown` with the handle of the edge where the key might be found +/// (if the node is internal) or where the key can be inserted. +/// +/// The result is meaningful only if the tree is ordered by key, like the tree +/// in a `BTreeMap` is. pub fn search_node( node: NodeRef, key: &Q, @@ -54,11 +60,11 @@ where } } -/// Returns the index in the node at which the key (or an equivalent) exists -/// or could exist, and whether it exists in the node itself. If it doesn't -/// exist in the node itself, it may exist in the subtree with that index -/// (if the node has subtrees). If the key doesn't exist in node or subtree, -/// the returned index is the position or subtree where the key belongs. +/// Returns either the KV index in the node at which the key (or an equivalent) +/// exists and `true`, or the edge index where the key belongs and `false`. +/// +/// The result is meaningful only if the tree is ordered by key, like the tree +/// in a `BTreeMap` is. fn search_linear( node: &NodeRef, key: &Q, diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index f4046e87b99a8..d8ce47ed77d1f 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -214,7 +214,7 @@ impl fmt::Debug for Union<'_, T> { // This constant is used by functions that compare two sets. // It estimates the relative size at which searching performs better // than iterating, based on the benchmarks in -// https://github.com/ssomers/rust_bench_btreeset_intersection; +// https://github.com/ssomers/rust_bench_btreeset_intersection. // It's used to divide rather than multiply sizes, to rule out overflow, // and it's a power of two to make that division cheap. const ITER_PERFORMANCE_TIPPING_SIZE_DIFF: usize = 16; diff --git a/library/alloc/src/collections/btree/split.rs b/library/alloc/src/collections/btree/split.rs index 701f36c37ee88..6108c139bb3a6 100644 --- a/library/alloc/src/collections/btree/split.rs +++ b/library/alloc/src/collections/btree/split.rs @@ -23,8 +23,8 @@ impl Root { loop { let mut split_edge = match search_node(left_node, key) { // key is going to the right tree - Found(handle) => handle.left_edge(), - GoDown(handle) => handle, + Found(kv) => kv.left_edge(), + GoDown(edge) => edge, }; split_edge.move_suffix(&mut right_node); From 7387f48e506456b8ca336d5036e380cd61e8c8c7 Mon Sep 17 00:00:00 2001 From: Tim Diekmann Date: Sat, 28 Nov 2020 15:24:30 +0100 Subject: [PATCH 12/16] Require allocator to be static for boxed `Pin`-API --- library/alloc/src/boxed.rs | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index f56e3af4ff29d..d814c525ceb6e 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -327,7 +327,10 @@ impl Box { /// `x` will be pinned in memory and unable to be moved. #[unstable(feature = "allocator_api", issue = "32838")] #[inline(always)] - pub fn pin_in(x: T, alloc: A) -> Pin { + pub fn pin_in(x: T, alloc: A) -> Pin + where + A: 'static, + { Self::new_in(x, alloc).into() } @@ -802,7 +805,10 @@ impl Box { /// /// This is also available via [`From`]. #[unstable(feature = "box_into_pin", issue = "62370")] - pub fn into_pin(boxed: Self) -> Pin { + pub fn into_pin(boxed: Self) -> Pin + where + A: 'static, + { // It's not possible to move or replace the insides of a `Pin>` // when `T: !Unpin`, so it's safe to pin it directly without any // additional requirements. @@ -1010,7 +1016,10 @@ impl From for Box { } #[stable(feature = "pin", since = "1.33.0")] -impl From> for Pin> { +impl From> for Pin> +where + A: 'static, +{ /// Converts a `Box` into a `Pin>` /// /// This conversion does not allocate on the heap and happens in place. @@ -1413,10 +1422,13 @@ impl AsMut for Box { * could have a method to project a Pin from it. */ #[stable(feature = "pin", since = "1.33.0")] -impl Unpin for Box {} +impl Unpin for Box where A: 'static {} #[unstable(feature = "generator_trait", issue = "43122")] -impl + Unpin, R, A: AllocRef> Generator for Box { +impl + Unpin, R, A: AllocRef> Generator for Box +where + A: 'static, +{ type Yield = G::Yield; type Return = G::Return; @@ -1426,7 +1438,10 @@ impl + Unpin, R, A: AllocRef> Generator for Box, R, A: AllocRef> Generator for Pin> { +impl, R, A: AllocRef> Generator for Pin> +where + A: 'static, +{ type Yield = G::Yield; type Return = G::Return; @@ -1436,7 +1451,10 @@ impl, R, A: AllocRef> Generator for Pin> { } #[stable(feature = "futures_api", since = "1.36.0")] -impl Future for Box { +impl Future for Box +where + A: 'static, +{ type Output = F::Output; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { From 30d331ffb664a321ff091c50d2b816804c6257db Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 28 Nov 2020 17:47:34 +0300 Subject: [PATCH 13/16] Cleanup: shorter and faster code --- compiler/rustc_lint/src/nonstandard_style.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index dd2627f7bc15c..2720c376774e8 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -94,9 +94,9 @@ fn to_camel_case(s: &str) -> String { } if new_word { - camel_cased_component.push_str(&c.to_uppercase().to_string()); + camel_cased_component.extend(c.to_uppercase()); } else { - camel_cased_component.push_str(&c.to_lowercase().to_string()); + camel_cased_component.extend(c.to_lowercase()); } prev_is_lower_case = c.is_lowercase(); From 1fa43257ebb2ad0e5681b2cdcfc4d7d79ede770f Mon Sep 17 00:00:00 2001 From: Julian Wollersberger Date: Sat, 28 Nov 2020 19:44:31 +0100 Subject: [PATCH 14/16] Add test for issue #54121: "simple type inference fails depending on order of trait bounds" --- .../order-dependent-bounds-issue-54121.rs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/test/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs diff --git a/src/test/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs b/src/test/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs new file mode 100644 index 0000000000000..77e4bd4d6f528 --- /dev/null +++ b/src/test/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs @@ -0,0 +1,47 @@ +// check-pass + +// From https://github.com/rust-lang/rust/issues/54121/ +// +// Whether the code compiled depended on the order of the trait bounds in +// `type T: Tr + Tr` +// But both should compile as order shouldn't matter. + +trait Tr { + fn exec(a: A, b: B); +} + +trait P { + // This compiled successfully + type T: Tr + Tr; +} + +trait Q { + // This didn't compile + type T: Tr + Tr; +} + +#[allow(dead_code)] +fn f() { + ::T::exec(0u8, 0u8) +} + +#[allow(dead_code)] +fn g() { + // A mismatched types error was emitted on this line. + ::T::exec(0u8, 0u8) +} + +// Another reproduction of the same issue +trait Trait { + type Type: Into + Into + Copy; + type Type1; + type Type2; +} + +#[allow(dead_code)] +fn foo(x: T::Type) { + let _1: T::Type1 = x.into(); + let _2: T::Type2 = x.into(); +} + +fn main() { } From 870a041262259e92ebde0c3f0effbf8b7199c225 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 28 Nov 2020 14:52:25 -0500 Subject: [PATCH 15/16] Remove unnecessary `mut` binding --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5b31998b7d33f..74b6652981a8b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -833,11 +833,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// - it also appears in the backtrace at some position `X`, /// - all the predicates at positions `X..` between `X` and the top are /// also defaulted traits. - pub fn coinductive_match(&mut self, cycle: I) -> bool + pub fn coinductive_match(&mut self, mut cycle: I) -> bool where I: Iterator>, { - let mut cycle = cycle; cycle.all(|predicate| self.coinductive_predicate(predicate)) } From 331d52643a9742604553d470e2161f6460bb0799 Mon Sep 17 00:00:00 2001 From: nooberfsh Date: Sun, 29 Nov 2020 10:02:24 +0800 Subject: [PATCH 16/16] Fix a bootstrap comment --- src/bootstrap/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9fcbe8e1e3564..fb2c6d1f92a80 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -551,7 +551,7 @@ impl Config { config.deny_warnings = true; config.missing_tools = false; - // set by bootstrap.py + // set by build.rs config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); // Undo `src/bootstrap`