about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-29 02:45:48 +0000
committerbors <bors@rust-lang.org>2020-11-29 02:45:48 +0000
commit40d7efad5e581c60a81171d96d78696b7ed65009 (patch)
tree0c3dd0515d51cffbc95d215fe966856253ad48fe
parent914d07ae5f90f01f138e66807873295fceaa9a26 (diff)
parentd0515ce7ef9662cef5333d31085831c07b67404a (diff)
downloadrust-40d7efad5e581c60a81171d96d78696b7ed65009.tar.gz
rust-40d7efad5e581c60a81171d96d78696b7ed65009.zip
Auto merge of #79529 - Dylan-DPC:rollup-6k20msr, r=Dylan-DPC
Rollup of 11 pull requests

Successful merges:

 - #79327 (Require allocator to be static for boxed `Pin`-API)
 - #79340 (Rename "stability" CSS class to "item-info" and combine `document_stability` with `document_short`)
 - #79363 (BTreeMap: try to enhance various comments)
 - #79395 (Move ui if tests from top-level into `expr/if`)
 - #79443 (Improve rustdoc JS tests error output)
 - #79464 (Extend doc keyword feature by allowing any ident)
 - #79484 (add enable-full-tools to freebsd builds to prevent occasional link er…)
 - #79505 (Cleanup: shorter and faster code)
 - #79514 (Add test for issue #54121: order dependent trait bounds)
 - #79516 (Remove unnecessary `mut` binding)
 - #79528 (Fix a bootstrap comment)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_lint/src/nonstandard_style.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs3
-rw-r--r--library/alloc/src/boxed.rs32
-rw-r--r--library/alloc/src/collections/btree/map/entry.rs2
-rw-r--r--library/alloc/src/collections/btree/navigate.rs9
-rw-r--r--library/alloc/src/collections/btree/node.rs168
-rw-r--r--library/alloc/src/collections/btree/remove.rs2
-rw-r--r--library/alloc/src/collections/btree/search.rs20
-rw-r--r--library/alloc/src/collections/btree/set.rs2
-rw-r--r--library/alloc/src/collections/btree/split.rs4
-rw-r--r--src/bootstrap/config.rs2
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile7
-rw-r--r--src/librustdoc/clean/mod.rs24
-rw-r--r--src/librustdoc/html/render/mod.rs74
-rw-r--r--src/librustdoc/html/static/main.js17
-rw-r--r--src/librustdoc/html/static/rustdoc.css18
-rw-r--r--src/librustdoc/html/static/themes/ayu.css4
-rw-r--r--src/librustdoc/html/static/themes/dark.css4
-rw-r--r--src/librustdoc/html/static/themes/light.css4
-rw-r--r--src/test/rustdoc-ui/invalid-keyword.rs4
-rw-r--r--src/test/rustdoc-ui/invalid-keyword.stderr8
-rw-r--r--src/test/rustdoc/doc-cfg.rs12
-rw-r--r--src/test/rustdoc/keyword.rs5
-rw-r--r--src/test/rustdoc/stability.rs2
-rw-r--r--src/test/ui/associated-type-bounds/order-dependent-bounds-issue-54121.rs47
-rw-r--r--src/test/ui/expr/if-bot.rs (renamed from src/test/ui/if-bot.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/bad-cfg.rs (renamed from src/test/ui/if-attrs/bad-cfg.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/bad-cfg.stderr (renamed from src/test/ui/if-attrs/bad-cfg.stderr)0
-rw-r--r--src/test/ui/expr/if/attrs/builtin-if-attr.rs (renamed from src/test/ui/if-attrs/builtin-if-attr.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/cfg-false-if-attr.rs (renamed from src/test/ui/if-attrs/cfg-false-if-attr.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/else-attrs.rs (renamed from src/test/ui/if-attrs/else-attrs.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/else-attrs.stderr (renamed from src/test/ui/if-attrs/else-attrs.stderr)0
-rw-r--r--src/test/ui/expr/if/attrs/gate-whole-expr.rs (renamed from src/test/ui/if-attrs/gate-whole-expr.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/let-chains-attr.rs (renamed from src/test/ui/if-attrs/let-chains-attr.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/let-chains-attr.stderr (renamed from src/test/ui/if-attrs/let-chains-attr.stderr)0
-rw-r--r--src/test/ui/expr/if/attrs/stmt-expr-gated.rs (renamed from src/test/ui/if-attrs/stmt-expr-gated.rs)0
-rw-r--r--src/test/ui/expr/if/attrs/stmt-expr-gated.stderr (renamed from src/test/ui/if-attrs/stmt-expr-gated.stderr)0
-rw-r--r--src/test/ui/expr/if/expr-if-panic-fn.rs (renamed from src/test/ui/if/expr-if-panic-fn.rs)0
-rw-r--r--src/test/ui/expr/if/expr-if-panic.rs (renamed from src/test/ui/if/expr-if-panic.rs)0
-rw-r--r--src/test/ui/expr/if/if-branch-types.rs (renamed from src/test/ui/if/if-branch-types.rs)0
-rw-r--r--src/test/ui/expr/if/if-branch-types.stderr (renamed from src/test/ui/if/if-branch-types.stderr)0
-rw-r--r--src/test/ui/expr/if/if-check-panic.rs (renamed from src/test/ui/if/if-check-panic.rs)0
-rw-r--r--src/test/ui/expr/if/if-check.rs (renamed from src/test/ui/if-check.rs)0
-rw-r--r--src/test/ui/expr/if/if-cond-bot.rs (renamed from src/test/ui/if/if-cond-bot.rs)0
-rw-r--r--src/test/ui/expr/if/if-else-type-mismatch.rs (renamed from src/test/ui/if-else-type-mismatch.rs)0
-rw-r--r--src/test/ui/expr/if/if-else-type-mismatch.stderr (renamed from src/test/ui/if-else-type-mismatch.stderr)0
-rw-r--r--src/test/ui/expr/if/if-let-arm-types.rs (renamed from src/test/ui/if/if-let-arm-types.rs)0
-rw-r--r--src/test/ui/expr/if/if-let-arm-types.stderr (renamed from src/test/ui/if/if-let-arm-types.stderr)0
-rw-r--r--src/test/ui/expr/if/if-let.rs (renamed from src/test/ui/if/if-let.rs)0
-rw-r--r--src/test/ui/expr/if/if-let.stderr (renamed from src/test/ui/if/if-let.stderr)0
-rw-r--r--src/test/ui/expr/if/if-loop.rs (renamed from src/test/ui/if/if-loop.rs)0
-rw-r--r--src/test/ui/expr/if/if-no-match-bindings.rs (renamed from src/test/ui/if/if-no-match-bindings.rs)0
-rw-r--r--src/test/ui/expr/if/if-no-match-bindings.stderr (renamed from src/test/ui/if/if-no-match-bindings.stderr)0
-rw-r--r--src/test/ui/expr/if/if-ret.rs (renamed from src/test/ui/if-ret.rs)0
-rw-r--r--src/test/ui/expr/if/if-ret.stderr (renamed from src/test/ui/if-ret.stderr)0
-rw-r--r--src/test/ui/expr/if/if-typeck.rs (renamed from src/test/ui/if/if-typeck.rs)0
-rw-r--r--src/test/ui/expr/if/if-typeck.stderr (renamed from src/test/ui/if/if-typeck.stderr)0
-rw-r--r--src/test/ui/expr/if/if-without-block.rs (renamed from src/test/ui/if/if-without-block.rs)0
-rw-r--r--src/test/ui/expr/if/if-without-block.stderr (renamed from src/test/ui/if/if-without-block.stderr)0
-rw-r--r--src/test/ui/expr/if/if-without-else-as-fn-expr.rs (renamed from src/test/ui/if/if-without-else-as-fn-expr.rs)0
-rw-r--r--src/test/ui/expr/if/if-without-else-as-fn-expr.stderr (renamed from src/test/ui/if/if-without-else-as-fn-expr.stderr)0
-rw-r--r--src/test/ui/expr/if/if-without-else-result.rs (renamed from src/test/ui/if/if-without-else-result.rs)0
-rw-r--r--src/test/ui/expr/if/if-without-else-result.stderr (renamed from src/test/ui/if/if-without-else-result.stderr)0
-rw-r--r--src/test/ui/expr/if/ifmt-bad-arg.rs (renamed from src/test/ui/if/ifmt-bad-arg.rs)0
-rw-r--r--src/test/ui/expr/if/ifmt-bad-arg.stderr (renamed from src/test/ui/if/ifmt-bad-arg.stderr)0
-rw-r--r--src/test/ui/expr/if/ifmt-bad-format-args.rs (renamed from src/test/ui/if/ifmt-bad-format-args.rs)0
-rw-r--r--src/test/ui/expr/if/ifmt-bad-format-args.stderr (renamed from src/test/ui/if/ifmt-bad-format-args.stderr)0
-rw-r--r--src/test/ui/expr/if/ifmt-unimpl.rs (renamed from src/test/ui/if/ifmt-unimpl.rs)0
-rw-r--r--src/test/ui/expr/if/ifmt-unimpl.stderr (renamed from src/test/ui/if/ifmt-unimpl.stderr)0
-rw-r--r--src/test/ui/expr/if/ifmt-unknown-trait.rs (renamed from src/test/ui/if/ifmt-unknown-trait.rs)0
-rw-r--r--src/test/ui/expr/if/ifmt-unknown-trait.stderr (renamed from src/test/ui/if/ifmt-unknown-trait.stderr)0
-rw-r--r--src/tools/rustdoc-js/tester.js31
73 files changed, 343 insertions, 171 deletions
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index dd2627f7bc1..2720c376774 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();
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d5fccdeb189..523628b7058 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1590,11 +1590,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
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 5b31998b7d3..74b6652981a 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<I>(&mut self, cycle: I) -> bool
+    pub fn coinductive_match<I>(&mut self, mut cycle: I) -> bool
     where
         I: Iterator<Item = ty::Predicate<'tcx>>,
     {
-        let mut cycle = cycle;
         cycle.all(|predicate| self.coinductive_predicate(predicate))
     }
 
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index f56e3af4ff2..d814c525ceb 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -327,7 +327,10 @@ impl<T, A: AllocRef> Box<T, A> {
     /// `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<Self> {
+    pub fn pin_in(x: T, alloc: A) -> Pin<Self>
+    where
+        A: 'static,
+    {
         Self::new_in(x, alloc).into()
     }
 
@@ -802,7 +805,10 @@ impl<T: ?Sized, A: AllocRef> Box<T, A> {
     ///
     /// This is also available via [`From`].
     #[unstable(feature = "box_into_pin", issue = "62370")]
-    pub fn into_pin(boxed: Self) -> Pin<Self> {
+    pub fn into_pin(boxed: Self) -> Pin<Self>
+    where
+        A: 'static,
+    {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
         // when `T: !Unpin`,  so it's safe to pin it directly without any
         // additional requirements.
@@ -1010,7 +1016,10 @@ impl<T> From<T> for Box<T> {
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized, A: AllocRef> From<Box<T, A>> for Pin<Box<T, A>> {
+impl<T: ?Sized, A: AllocRef> From<Box<T, A>> for Pin<Box<T, A>>
+where
+    A: 'static,
+{
     /// Converts a `Box<T>` into a `Pin<Box<T>>`
     ///
     /// This conversion does not allocate on the heap and happens in place.
@@ -1413,10 +1422,13 @@ impl<T: ?Sized, A: AllocRef> AsMut<T> for Box<T, A> {
  *  could have a method to project a Pin<T> from it.
  */
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized, A: AllocRef> Unpin for Box<T, A> {}
+impl<T: ?Sized, A: AllocRef> Unpin for Box<T, A> where A: 'static {}
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A> {
+impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A>
+where
+    A: 'static,
+{
     type Yield = G::Yield;
     type Return = G::Return;
 
@@ -1426,7 +1438,10 @@ impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> {
+impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>>
+where
+    A: 'static,
+{
     type Yield = G::Yield;
     type Return = G::Return;
 
@@ -1436,7 +1451,10 @@ impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> {
 }
 
 #[stable(feature = "futures_api", since = "1.36.0")]
-impl<F: ?Sized + Future + Unpin, A: AllocRef> Future for Box<F, A> {
+impl<F: ?Sized + Future + Unpin, A: AllocRef> Future for Box<F, A>
+where
+    A: 'static,
+{
     type Output = F::Output;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
diff --git a/library/alloc/src/collections/btree/map/entry.rs b/library/alloc/src/collections/btree/map/entry.rs
index 69926ac2aff..c92888cb897 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 ef6f888693f..cce8b21a2bc 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<BorrowType, K, V, Q, R>(
     root1: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
     root2: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
@@ -122,6 +125,9 @@ fn full_range<BorrowType, K, V>(
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Immut<'a>, 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<Q, R>(
         self,
         range: R,
@@ -152,6 +158,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::ValMut<'a>, 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<Q, R>(
         self,
         range: R,
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 6a8be441513..78be070a983 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<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
 ///      although insert methods allow a mutable pointer to a value to coexist.
 ///    - When this is `Owned`, the `NodeRef` acts roughly like `Box<Node>`,
 ///      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<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
 /// 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<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
 ///   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<BorrowType, K, V, Type> {
-    /// 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<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
         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<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
     /// 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<marker::Mut<'a>, K, V, marker::Internal> {
 impl<'a, K, V, Type> NodeRef<marker::ValMut<'a>, 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<marker::Mut<'a>, 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<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
 }
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, 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<marker::Mut<'a>, 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<marker::Mut<'a>, K, V, marker::Internal> {
 }
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, 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<K, V>) {
         assert!(edge.height == self.height - 1);
@@ -676,7 +686,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, 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<K, V>) {
         assert!(edge.height == self.height - 1);
@@ -694,7 +704,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
 }
 
 impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, 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<Root<K, V>>) {
@@ -722,7 +732,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, 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<Root<K, V>>) {
@@ -786,12 +796,12 @@ impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::LeafOrInternal> {
     }
 }
 
-/// 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<Node, Type> {
@@ -810,7 +820,7 @@ impl<Node: Copy, Type> Clone for Handle<Node, Type> {
 }
 
 impl<Node, Type> Handle<Node, Type> {
-    /// 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<Node, Type> Handle<Node, Type> {
 }
 
 impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, 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<BorrowType, K, V, NodeType>, idx: usize) -> Self {
         debug_assert!(idx < node.len());
@@ -842,7 +852,7 @@ impl<BorrowType, K, V, NodeType> Handle<NodeRef<BorrowType, K, V, NodeType>, mar
 impl<BorrowType, K, V, NodeType> NodeRef<BorrowType, K, V, NodeType> {
     /// 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<BorrowType, K, V, NodeType, HandleType> PartialEq
     for Handle<NodeRef<BorrowType, K, V, NodeType>, 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<BorrowType, K, V, NodeType, HandleType> PartialOrd
     for Handle<NodeRef<BorrowType, K, V, NodeType>, HandleType>
 {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        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<usize>) {
 }
 
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
 }
 
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
 }
 
 impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
 }
 
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<K, V>) {
         debug_assert!(self.node.len() < CAPACITY);
@@ -1026,8 +1036,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
 }
 
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
 impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Internal>, 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<BorrowType, K, V, marker::LeafOrInternal> {
@@ -1186,10 +1198,10 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
@@ -1219,10 +1231,10 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
 impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV>,
     left_child: NodeRef<marker::Mut<'a>, 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<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, ma
         right: &mut NodeRef<marker::Mut<'a>, 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 c4253d4221b..5ae1c1fcab8 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<NodeRef<marker::Mut<'a>, 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 93de2d829ac..ed7f95fe632 100644
--- a/library/alloc/src/collections/btree/search.rs
+++ b/library/alloc/src/collections/btree/search.rs
@@ -14,6 +14,9 @@ pub enum SearchResult<BorrowType, K, V, FoundType, GoDownType> {
 /// 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<BorrowType, K, V, Q: ?Sized>(
     mut node: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
     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<BorrowType, K, V, Type, Q: ?Sized>(
     node: NodeRef<BorrowType, K, V, Type>,
     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<BorrowType, K, V, Type, Q: ?Sized>(
     node: &NodeRef<BorrowType, K, V, Type>,
     key: &Q,
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index f4046e87b99..d8ce47ed77d 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -214,7 +214,7 @@ impl<T: fmt::Debug> 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 701f36c37ee..6108c139bb3 100644
--- a/library/alloc/src/collections/btree/split.rs
+++ b/library/alloc/src/collections/btree/split.rs
@@ -23,8 +23,8 @@ impl<K, V> Root<K, V> {
             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);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 9fcbe8e1e35..fb2c6d1f92a 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`
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 1075947c9cf..8413d775ac4 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
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 13643fbf3d3..221c818736e 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -162,18 +162,30 @@ impl Clean<ExternalCrate> 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;
                         }
                     }
                 }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 147a8d33765..bbd4be88e6a 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);
 }
 
@@ -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();
 
@@ -1928,18 +1935,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, "<div class=\"stability{}\">", 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, "<div class=\"item-info{}\">", if is_hidden { " hidden" } else { "" });
+        for info in item_infos {
+            write!(w, "{}", info);
         }
         write!(w, "</div>");
     }
@@ -2194,7 +2206,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
                          <td class=\"docblock-short\">{stab_tags}{docs}</td>\
                      </tr>",
                     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 +2228,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 +2283,10 @@ fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<Strin
     Some(format!("<div class=\"stab portability\">{}</div>", 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<String> {
-    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<String> {
+    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 +2313,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!(
             "<div class=\"stab deprecated\"><span class=\"emoji\">👎</span> {}</div>",
             message,
         ));
@@ -2345,14 +2357,14 @@ fn short_stability(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
             );
         }
 
-        stability.push(format!("<div class=\"stab unstable\">{}</div>", message));
+        extra_info.push(format!("<div class=\"stab unstable\">{}</div>", 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 +3715,7 @@ fn render_impl(
 
         if trait_.is_some() {
             if let Some(portability) = portability(&i.impl_item, Some(parent)) {
-                write!(w, "<div class=\"stability\">{}</div>", portability);
+                write!(w, "<div class=\"item-info\">{}</div>", portability);
             }
         }
 
@@ -3801,26 +3813,32 @@ 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));
                         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 {
-                    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));
-                if show_def_docs {
-                    document_short(w, item, link, "", is_hidden);
-                }
+                document_short(w, item, cx, link, "", is_hidden, Some(parent), show_def_docs);
             }
         }
     }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index b11bd667093..7ca43684dce 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 7d22913b99d..8eef65a231d 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 d1cddf0d656..c1f796f09e8 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 3545943b3fd..946ca0a40c9 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 4ce4b63e2c6..e0b9a04921a 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-ui/invalid-keyword.rs b/src/test/rustdoc-ui/invalid-keyword.rs
new file mode 100644
index 00000000000..ce2abc69bbd
--- /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 00000000000..8658e382578
--- /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/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs
index d7041ee2f1a..f86541cd118 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/keyword.rs b/src/test/rustdoc/keyword.rs
index db5d115c6da..25e8b7912e7 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 {}
diff --git a/src/test/rustdoc/stability.rs b/src/test/rustdoc/stability.rs
index b1b97fe134e..4ff06d9c995 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,
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 00000000000..77e4bd4d6f5
--- /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<u8, u8> + Tr<u16, u16>`
+// But both should compile as order shouldn't matter.
+
+trait Tr<A, B> {
+    fn exec(a: A, b: B);
+}
+
+trait P {
+    // This compiled successfully
+    type T: Tr<u16, u16> + Tr<u8, u8>;
+}
+
+trait Q {
+    // This didn't compile
+    type T: Tr<u8, u8> + Tr<u16, u16>;
+}
+
+#[allow(dead_code)]
+fn f<S: P>() {
+    <S as P>::T::exec(0u8, 0u8)
+}
+
+#[allow(dead_code)]
+fn g<S: Q>() {
+    // A mismatched types error was emitted on this line.
+    <S as Q>::T::exec(0u8, 0u8)
+}
+
+// Another reproduction of the same issue
+trait Trait {
+    type Type: Into<Self::Type1> + Into<Self::Type2> + Copy;
+    type Type1;
+    type Type2;
+}
+
+#[allow(dead_code)]
+fn foo<T: Trait>(x: T::Type) {
+    let _1: T::Type1 = x.into();
+    let _2: T::Type2 = x.into();
+}
+
+fn main() { }
diff --git a/src/test/ui/if-bot.rs b/src/test/ui/expr/if-bot.rs
index 0f09db530d4..0f09db530d4 100644
--- a/src/test/ui/if-bot.rs
+++ b/src/test/ui/expr/if-bot.rs
diff --git a/src/test/ui/if-attrs/bad-cfg.rs b/src/test/ui/expr/if/attrs/bad-cfg.rs
index 3f84929a00e..3f84929a00e 100644
--- a/src/test/ui/if-attrs/bad-cfg.rs
+++ b/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
index 8a2890886a1..8a2890886a1 100644
--- a/src/test/ui/if-attrs/bad-cfg.stderr
+++ b/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
index 7e290661501..7e290661501 100644
--- a/src/test/ui/if-attrs/builtin-if-attr.rs
+++ b/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
index 1f77a1bb342..1f77a1bb342 100644
--- a/src/test/ui/if-attrs/cfg-false-if-attr.rs
+++ b/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
index 85da7cf6bb8..85da7cf6bb8 100644
--- a/src/test/ui/if-attrs/else-attrs.rs
+++ b/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
index 2733377054d..2733377054d 100644
--- a/src/test/ui/if-attrs/else-attrs.stderr
+++ b/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
index 63772d54b53..63772d54b53 100644
--- a/src/test/ui/if-attrs/gate-whole-expr.rs
+++ b/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
index 5237a9ff396..5237a9ff396 100644
--- a/src/test/ui/if-attrs/let-chains-attr.rs
+++ b/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
index 8b987471534..8b987471534 100644
--- a/src/test/ui/if-attrs/let-chains-attr.stderr
+++ b/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
index 38599c8e67c..38599c8e67c 100644
--- a/src/test/ui/if-attrs/stmt-expr-gated.rs
+++ b/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
index 47dac39a9ae..47dac39a9ae 100644
--- a/src/test/ui/if-attrs/stmt-expr-gated.stderr
+++ b/src/test/ui/expr/if/attrs/stmt-expr-gated.stderr
diff --git a/src/test/ui/if/expr-if-panic-fn.rs b/src/test/ui/expr/if/expr-if-panic-fn.rs
index 36e49785a49..36e49785a49 100644
--- a/src/test/ui/if/expr-if-panic-fn.rs
+++ b/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
index 520ee0870ee..520ee0870ee 100644
--- a/src/test/ui/if/expr-if-panic.rs
+++ b/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
index c125ba30606..c125ba30606 100644
--- a/src/test/ui/if/if-branch-types.rs
+++ b/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
index 14f02163a83..14f02163a83 100644
--- a/src/test/ui/if/if-branch-types.stderr
+++ b/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
index 037cd427ccf..037cd427ccf 100644
--- a/src/test/ui/if/if-check-panic.rs
+++ b/src/test/ui/expr/if/if-check-panic.rs
diff --git a/src/test/ui/if-check.rs b/src/test/ui/expr/if/if-check.rs
index 6593225e7dd..6593225e7dd 100644
--- a/src/test/ui/if-check.rs
+++ b/src/test/ui/expr/if/if-check.rs
diff --git a/src/test/ui/if/if-cond-bot.rs b/src/test/ui/expr/if/if-cond-bot.rs
index bcd11467852..bcd11467852 100644
--- a/src/test/ui/if/if-cond-bot.rs
+++ b/src/test/ui/expr/if/if-cond-bot.rs
diff --git a/src/test/ui/if-else-type-mismatch.rs b/src/test/ui/expr/if/if-else-type-mismatch.rs
index 1a0a36df2ad..1a0a36df2ad 100644
--- a/src/test/ui/if-else-type-mismatch.rs
+++ b/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
index 9fa190d6c9d..9fa190d6c9d 100644
--- a/src/test/ui/if-else-type-mismatch.stderr
+++ b/src/test/ui/expr/if/if-else-type-mismatch.stderr
diff --git a/src/test/ui/if/if-let-arm-types.rs b/src/test/ui/expr/if/if-let-arm-types.rs
index 1e8260a017d..1e8260a017d 100644
--- a/src/test/ui/if/if-let-arm-types.rs
+++ b/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
index b40a0f479d3..b40a0f479d3 100644
--- a/src/test/ui/if/if-let-arm-types.stderr
+++ b/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
index 2ab0f9fed3f..2ab0f9fed3f 100644
--- a/src/test/ui/if/if-let.rs
+++ b/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
index ee2b78af3b8..ee2b78af3b8 100644
--- a/src/test/ui/if/if-let.stderr
+++ b/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
index 06d0bdf456c..06d0bdf456c 100644
--- a/src/test/ui/if/if-loop.rs
+++ b/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
index ca3df0fdde4..ca3df0fdde4 100644
--- a/src/test/ui/if/if-no-match-bindings.rs
+++ b/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
index 3f382e023a7..3f382e023a7 100644
--- a/src/test/ui/if/if-no-match-bindings.stderr
+++ b/src/test/ui/expr/if/if-no-match-bindings.stderr
diff --git a/src/test/ui/if-ret.rs b/src/test/ui/expr/if/if-ret.rs
index 6bb0141848a..6bb0141848a 100644
--- a/src/test/ui/if-ret.rs
+++ b/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
index 41bbd791862..41bbd791862 100644
--- a/src/test/ui/if-ret.stderr
+++ b/src/test/ui/expr/if/if-ret.stderr
diff --git a/src/test/ui/if/if-typeck.rs b/src/test/ui/expr/if/if-typeck.rs
index d8c262bd6b3..d8c262bd6b3 100644
--- a/src/test/ui/if/if-typeck.rs
+++ b/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
index 74ed0ed0ae6..74ed0ed0ae6 100644
--- a/src/test/ui/if/if-typeck.stderr
+++ b/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
index 8a4c59f3261..8a4c59f3261 100644
--- a/src/test/ui/if/if-without-block.rs
+++ b/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
index ee2bb62e2bb..ee2bb62e2bb 100644
--- a/src/test/ui/if/if-without-block.stderr
+++ b/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
index 19fbfb27ba6..19fbfb27ba6 100644
--- 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
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
index 4daf27493c1..4daf27493c1 100644
--- 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
diff --git a/src/test/ui/if/if-without-else-result.rs b/src/test/ui/expr/if/if-without-else-result.rs
index cf84a99e53f..cf84a99e53f 100644
--- a/src/test/ui/if/if-without-else-result.rs
+++ b/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
index 821635d3768..821635d3768 100644
--- a/src/test/ui/if/if-without-else-result.stderr
+++ b/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
index a0b0a8fb985..a0b0a8fb985 100644
--- a/src/test/ui/if/ifmt-bad-arg.rs
+++ b/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
index 0ff478826f7..0ff478826f7 100644
--- a/src/test/ui/if/ifmt-bad-arg.stderr
+++ b/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
index ba7301561bd..ba7301561bd 100644
--- a/src/test/ui/if/ifmt-bad-format-args.rs
+++ b/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
index 8bb0d40629f..8bb0d40629f 100644
--- a/src/test/ui/if/ifmt-bad-format-args.stderr
+++ b/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
index 258f4eea509..258f4eea509 100644
--- a/src/test/ui/if/ifmt-unimpl.rs
+++ b/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
index 65b0f4a09b3..65b0f4a09b3 100644
--- a/src/test/ui/if/ifmt-unimpl.stderr
+++ b/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
index 158152c89a4..158152c89a4 100644
--- a/src/test/ui/if/ifmt-unknown-trait.rs
+++ b/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
index 459432bf4e4..459432bf4e4 100644
--- a/src/test/ui/if/ifmt-unknown-trait.stderr
+++ b/src/test/ui/expr/if/ifmt-unknown-trait.stderr
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 139e6f73f42..63f2d2f5d2f 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 '" +