about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs4
-rw-r--r--compiler/rustc_llvm/build.rs36
-rw-r--r--compiler/rustc_mir/src/interpret/machine.rs10
-rw-r--r--compiler/rustc_mir/src/interpret/traits.rs9
-rw-r--r--compiler/rustc_mir/src/transform/coverage/debug.rs4
-rw-r--r--compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml3
-rw-r--r--compiler/rustc_mir/src/transform/early_otherwise_branch.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs5
-rw-r--r--compiler/rustc_session/src/session.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs41
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs4
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs21
-rw-r--r--compiler/rustc_typeck/src/collect.rs7
-rw-r--r--library/alloc/src/collections/linked_list.rs62
-rw-r--r--library/core/src/iter/mod.rs45
-rw-r--r--library/std/src/keyword_docs.rs10
-rw-r--r--src/bootstrap/bootstrap.py25
-rw-r--r--src/bootstrap/builder.rs5
-rw-r--r--src/bootstrap/dist.rs2
-rw-r--r--src/bootstrap/doc.rs5
-rw-r--r--src/bootstrap/sanity.rs44
-rw-r--r--src/librustdoc/html/layout.rs2
-rw-r--r--src/librustdoc/html/markdown.rs4
-rw-r--r--src/librustdoc/html/static/themes/light.css2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs3
28 files changed, 187 insertions, 188 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 59525a29a80..12f9e19cf18 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -725,9 +725,6 @@ checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6"
 [[package]]
 name = "coverage_test_macros"
 version = "0.0.0"
-dependencies = [
- "proc-macro2",
-]
 
 [[package]]
 name = "cpuid-bool"
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index a767de53dae..68c11868af8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -597,10 +597,7 @@ impl<'a> TraitDef<'a> {
 
             let mut ty_params = params
                 .iter()
-                .filter_map(|param| match param.kind {
-                    ast::GenericParamKind::Type { .. } => Some(param),
-                    _ => None,
-                })
+                .filter(|param| matches!(param.kind,  ast::GenericParamKind::Type{..}))
                 .peekable();
 
             if ty_params.peek().is_some() {
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index ec557b7a682..bf0d499e6c4 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -854,8 +854,8 @@ fn generic_simd_intrinsic(
         ));
     }
 
-    if name_str.starts_with("simd_shuffle") {
-        let n: u64 = name_str["simd_shuffle".len()..].parse().unwrap_or_else(|_| {
+    if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
+        let n: u64 = stripped.parse().unwrap_or_else(|_| {
             span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
         });
 
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 54b22ca49a2..621363bed80 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -201,10 +201,10 @@ fn main() {
     cmd.args(&components);
 
     for lib in output(&mut cmd).split_whitespace() {
-        let name = if lib.starts_with("-l") {
-            &lib[2..]
-        } else if lib.starts_with('-') {
-            &lib[1..]
+        let name = if let Some(stripped) = lib.strip_prefix("-l") {
+            stripped
+        } else if let Some(stripped) = lib.strip_prefix('-') {
+            stripped
         } else if Path::new(lib).exists() {
             // On MSVC llvm-config will print the full name to libraries, but
             // we're only interested in the name part
@@ -241,17 +241,17 @@ fn main() {
     cmd.arg(llvm_link_arg).arg("--ldflags");
     for lib in output(&mut cmd).split_whitespace() {
         if is_crossed {
-            if lib.starts_with("-LIBPATH:") {
-                println!("cargo:rustc-link-search=native={}", lib[9..].replace(&host, &target));
-            } else if lib.starts_with("-L") {
-                println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target));
+            if let Some(stripped) = lib.strip_prefix("-LIBPATH:") {
+                println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target));
+            } else if let Some(stripped) = lib.strip_prefix("-L") {
+                println!("cargo:rustc-link-search=native={}", stripped.replace(&host, &target));
             }
-        } else if lib.starts_with("-LIBPATH:") {
-            println!("cargo:rustc-link-search=native={}", &lib[9..]);
-        } else if lib.starts_with("-l") {
-            println!("cargo:rustc-link-lib={}", &lib[2..]);
-        } else if lib.starts_with("-L") {
-            println!("cargo:rustc-link-search=native={}", &lib[2..]);
+        } else if let Some(stripped) = lib.strip_prefix("-LIBPATH:") {
+            println!("cargo:rustc-link-search=native={}", stripped);
+        } else if let Some(stripped) = lib.strip_prefix("-l") {
+            println!("cargo:rustc-link-lib={}", stripped);
+        } else if let Some(stripped) = lib.strip_prefix("-L") {
+            println!("cargo:rustc-link-search=native={}", stripped);
         }
     }
 
@@ -262,10 +262,10 @@ fn main() {
     let llvm_linker_flags = tracked_env_var_os("LLVM_LINKER_FLAGS");
     if let Some(s) = llvm_linker_flags {
         for lib in s.into_string().unwrap().split_whitespace() {
-            if lib.starts_with("-l") {
-                println!("cargo:rustc-link-lib={}", &lib[2..]);
-            } else if lib.starts_with("-L") {
-                println!("cargo:rustc-link-search=native={}", &lib[2..]);
+            if let Some(stripped) = lib.strip_prefix("-l") {
+                println!("cargo:rustc-link-lib={}", stripped);
+            } else if let Some(stripped) = lib.strip_prefix("-L") {
+                println!("cargo:rustc-link-search=native={}", stripped);
             }
         }
     }
diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs
index 74625569432..f50cc6c16ea 100644
--- a/compiler/rustc_mir/src/interpret/machine.rs
+++ b/compiler/rustc_mir/src/interpret/machine.rs
@@ -9,6 +9,7 @@ use std::hash::Hash;
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::def_id::DefId;
+use rustc_target::abi::Size;
 
 use super::{
     AllocId, Allocation, AllocationExtra, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult,
@@ -299,6 +300,15 @@ pub trait Machine<'mir, 'tcx>: Sized {
         Ok(())
     }
 
+    /// Called after initializing static memory using the interpreter.
+    fn after_static_mem_initialized(
+        _ecx: &mut InterpCx<'mir, 'tcx, Self>,
+        _ptr: Pointer<Self::PointerTag>,
+        _size: Size,
+    ) -> InterpResult<'tcx> {
+        Ok(())
+    }
+
     /// Executes a retagging operation
     #[inline]
     fn retag(
diff --git a/compiler/rustc_mir/src/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs
index fa7036f4e5b..09ce6bc0fb7 100644
--- a/compiler/rustc_mir/src/interpret/traits.rs
+++ b/compiler/rustc_mir/src/interpret/traits.rs
@@ -56,11 +56,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // If you touch this code, be sure to also make the corresponding changes to
         // `get_vtable` in `rust_codegen_llvm/meth.rs`.
         // /////////////////////////////////////////////////////////////////////////////////////////
-        let vtable = self.memory.allocate(
-            ptr_size * u64::try_from(methods.len()).unwrap().checked_add(3).unwrap(),
-            ptr_align,
-            MemoryKind::Vtable,
-        );
+        let vtable_size = ptr_size * u64::try_from(methods.len()).unwrap().checked_add(3).unwrap();
+        let vtable = self.memory.allocate(vtable_size, ptr_align, MemoryKind::Vtable);
 
         let drop = Instance::resolve_drop_in_place(tcx, ty);
         let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
@@ -93,6 +90,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
         }
 
+        M::after_static_mem_initialized(self, vtable, vtable_size)?;
+
         self.memory.mark_immutable(vtable.alloc_id)?;
         assert!(self.vtables.insert((ty, poly_trait_ref), vtable).is_none());
 
diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs
index af81d9af0e2..b66e37436a6 100644
--- a/compiler/rustc_mir/src/transform/coverage/debug.rs
+++ b/compiler/rustc_mir/src/transform/coverage/debug.rs
@@ -285,7 +285,7 @@ impl DebugCounters {
                 ),
             };
             counters
-                .insert(id.into(), DebugCounter::new(counter_kind.clone(), some_block_label))
+                .insert(id, DebugCounter::new(counter_kind.clone(), some_block_label))
                 .expect_none(
                     "attempt to add the same counter_kind to DebugCounters more than once",
                 );
@@ -340,7 +340,7 @@ impl DebugCounters {
         if self.some_counters.is_some() && (counter_format.block || !counter_format.id) {
             let counters = self.some_counters.as_ref().unwrap();
             if let Some(DebugCounter { some_block_label: Some(block_label), .. }) =
-                counters.get(&id.into())
+                counters.get(&id)
             {
                 return if counter_format.id {
                     format!("{}#{}", block_label, id.index())
diff --git a/compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml b/compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml
index a9d6f0c803d..eda1ced001c 100644
--- a/compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml
+++ b/compiler/rustc_mir/src/transform/coverage/test_macros/Cargo.toml
@@ -7,6 +7,3 @@ edition = "2018"
 [lib]
 proc-macro = true
 doctest = false
-
-[dependencies]
-proc-macro2 = "1"
diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
index f91477911a4..6fbcc140978 100644
--- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
+++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
@@ -216,9 +216,10 @@ impl<'a, 'tcx> Helper<'a, 'tcx> {
         let discr = self.find_switch_discriminant_info(bb, switch)?;
 
         // go through each target, finding a discriminant read, and a switch
-        let results = discr.targets_with_values.iter().map(|(value, target)| {
-            self.find_discriminant_switch_pairing(&discr, target.clone(), value.clone())
-        });
+        let results = discr
+            .targets_with_values
+            .iter()
+            .map(|(value, target)| self.find_discriminant_switch_pairing(&discr, *target, *value));
 
         // if the optimization did not apply for one of the targets, then abort
         if results.clone().any(|x| x.is_none()) || results.len() == 0 {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index e137f77ffbb..0edd44d4bf1 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -616,8 +616,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 debug!("stmt_expr Break val block_context.push(SubExpr)");
                 self.block_context.push(BlockFrame::SubExpr);
                 unpack!(block = self.into(destination, dest_scope, block, value));
-                dest_scope
-                    .map(|scope| self.unschedule_drop(scope, destination.as_local().unwrap()));
+                if let Some(scope) = dest_scope {
+                    self.unschedule_drop(scope, destination.as_local().unwrap())
+                };
                 self.block_context.pop();
             } else {
                 self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx())
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 4e269f3172c..75faab12e3e 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1109,10 +1109,7 @@ impl Session {
     }
 
     pub fn link_dead_code(&self) -> bool {
-        match self.opts.cg.link_dead_code {
-            Some(explicitly_set) => explicitly_set,
-            None => false,
-        }
+        self.opts.cg.link_dead_code.unwrap_or(false)
     }
 
     pub fn mark_attr_known(&self, attr: &Attribute) {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 095483aa5a2..5c185dc4a9f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1448,31 +1448,30 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             });
         };
 
-        typeck_results
+        if let Some(cause) = typeck_results
             .generator_interior_types
             .iter()
             .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty))
-            .map(|cause| {
-                // Check to see if any awaited expressions have the target type.
-                let from_awaited_ty = visitor
-                    .awaits
-                    .into_iter()
-                    .map(|id| hir.expect_expr(id))
-                    .find(|await_expr| {
-                        let ty = typeck_results.expr_ty_adjusted(&await_expr);
-                        debug!(
-                            "maybe_note_obligation_cause_for_async_await: await_expr={:?}",
-                            await_expr
-                        );
-                        ty_matches(ty)
-                    })
-                    .map(|expr| expr.span);
-                let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
-                    cause;
+        {
+            // Check to see if any awaited expressions have the target type.
+            let from_awaited_ty = visitor
+                .awaits
+                .into_iter()
+                .map(|id| hir.expect_expr(id))
+                .find(|await_expr| {
+                    let ty = typeck_results.expr_ty_adjusted(&await_expr);
+                    debug!(
+                        "maybe_note_obligation_cause_for_async_await: await_expr={:?}",
+                        await_expr
+                    );
+                    ty_matches(ty)
+                })
+                .map(|expr| expr.span);
+            let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
 
-                interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span));
-                interior_extra_info = Some((*scope_span, *yield_span, *expr, from_awaited_ty));
-            });
+            interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span));
+            interior_extra_info = Some((*scope_span, *yield_span, *expr, from_awaited_ty));
+        };
 
         debug!(
             "maybe_note_obligation_cause_for_async_await: interior_or_upvar={:?} \
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index a42c8021346..ed22d5849e2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -447,7 +447,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 );
                 nested.push(Obligation::new(
                     obligation.cause.clone(),
-                    obligation.param_env.clone(),
+                    obligation.param_env,
                     normalized_super_trait,
                 ));
             }
@@ -485,7 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 );
                 nested.push(Obligation::new(
                     obligation.cause.clone(),
-                    obligation.param_env.clone(),
+                    obligation.param_env,
                     normalized_bound,
                 ));
             }
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 1c9475f7a66..37abb4496ac 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -119,7 +119,7 @@ rustc_index::newtype_index! {
     /// Bruijn index of 0, meaning "the innermost binder" (in this case, a
     /// fn). The region `'a` that appears in the second argument type (`&'a
     /// isize`) would then be assigned a De Bruijn index of 1, meaning "the
-    /// second-innermost binder". (These indices are written on the arrays
+    /// second-innermost binder". (These indices are written on the arrows
     /// in the diagram).
     ///
     /// What is interesting is that De Bruijn index attached to a particular
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 30b4682296c..0f084c5c11f 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -294,17 +294,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     closure_captures.insert(*var_hir_id, upvar_id);
 
-                    let new_capture_kind = if let Some(capture_kind) =
-                        upvar_capture_map.get(&upvar_id)
-                    {
-                        // upvar_capture_map only stores the UpvarCapture (CaptureKind),
-                        // so we create a fake capture info with no expression.
-                        let fake_capture_info =
-                            ty::CaptureInfo { expr_id: None, capture_kind: capture_kind.clone() };
-                        determine_capture_info(fake_capture_info, capture_info).capture_kind
-                    } else {
-                        capture_info.capture_kind
-                    };
+                    let new_capture_kind =
+                        if let Some(capture_kind) = upvar_capture_map.get(&upvar_id) {
+                            // upvar_capture_map only stores the UpvarCapture (CaptureKind),
+                            // so we create a fake capture info with no expression.
+                            let fake_capture_info =
+                                ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind };
+                            determine_capture_info(fake_capture_info, capture_info).capture_kind
+                        } else {
+                            capture_info.capture_kind
+                        };
                     upvar_capture_map.insert(upvar_id, new_capture_kind);
                 }
             }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 38da1e5ea03..c70554cc627 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2141,13 +2141,8 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
             // * It must be an associated type for this trait (*not* a
             //   supertrait).
             if let ty::Projection(projection) = ty.kind() {
-                if projection.substs == trait_identity_substs
+                projection.substs == trait_identity_substs
                     && tcx.associated_item(projection.item_def_id).container.id() == def_id
-                {
-                    true
-                } else {
-                    false
-                }
             } else {
                 false
             }
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 412c65681e6..4707f129401 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1099,68 +1099,6 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {}
 #[stable(feature = "fused", since = "1.26.0")]
 impl<T> FusedIterator for IterMut<'_, T> {}
 
-impl<T> IterMut<'_, T> {
-    /// Inserts the given element just after the element most recently returned by `.next()`.
-    /// The inserted element does not appear in the iteration.
-    ///
-    /// This method will be removed soon.
-    #[inline]
-    #[unstable(
-        feature = "linked_list_extras",
-        reason = "this is probably better handled by a cursor type -- we'll see",
-        issue = "27794"
-    )]
-    #[rustc_deprecated(
-        reason = "Deprecated in favor of CursorMut methods. This method will be removed soon.",
-        since = "1.47.0"
-    )]
-    pub fn insert_next(&mut self, element: T) {
-        match self.head {
-            // `push_back` is okay with aliasing `element` references
-            None => self.list.push_back(element),
-            Some(head) => unsafe {
-                let prev = match head.as_ref().prev {
-                    // `push_front` is okay with aliasing nodes
-                    None => return self.list.push_front(element),
-                    Some(prev) => prev,
-                };
-
-                let node = Some(
-                    Box::leak(box Node { next: Some(head), prev: Some(prev), element }).into(),
-                );
-
-                // Not creating references to entire nodes to not invalidate the
-                // reference to `element` we handed to the user.
-                (*prev.as_ptr()).next = node;
-                (*head.as_ptr()).prev = node;
-
-                self.list.len += 1;
-            },
-        }
-    }
-
-    /// Provides a reference to the next element, without changing the iterator.
-    ///
-    /// This method will be removed soon.
-    #[inline]
-    #[unstable(
-        feature = "linked_list_extras",
-        reason = "this is probably better handled by a cursor type -- we'll see",
-        issue = "27794"
-    )]
-    #[rustc_deprecated(
-        reason = "Deprecated in favor of CursorMut methods. This method will be removed soon.",
-        since = "1.47.0"
-    )]
-    pub fn peek_next(&mut self) -> Option<&mut T> {
-        if self.len == 0 {
-            None
-        } else {
-            unsafe { self.head.as_mut().map(|node| &mut node.as_mut().element) }
-        }
-    }
-}
-
 /// A cursor over a `LinkedList`.
 ///
 /// A `Cursor` is like an iterator, except that it can freely seek back-and-forth.
diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
index 072373c00f6..3e74637b49f 100644
--- a/library/core/src/iter/mod.rs
+++ b/library/core/src/iter/mod.rs
@@ -206,6 +206,51 @@
 //! 2. If you're creating a collection, implementing [`IntoIterator`] for it
 //!    will allow your collection to be used with the `for` loop.
 //!
+//! # Iterating by reference
+//!
+//! Since [`into_iter()`] takes `self` by value, using a `for` loop to iterate
+//! over a collection consumes that collection. Often, you may want to iterate
+//! over a collection without consuming it. Many collections offer methods that
+//! provide iterators over references, conventionally called `iter()` and
+//! `iter_mut()` respectively:
+//!
+//! ```
+//! let mut values = vec![41];
+//! for x in values.iter_mut() {
+//!     *x += 1;
+//! }
+//! for x in values.iter() {
+//!     assert_eq!(*x, 42);
+//! }
+//! assert_eq!(values.len(), 1); // `values` is still owned by this function.
+//! ```
+//!
+//! If a collection type `C` provides `iter()`, it usually also implements
+//! `IntoIterator` for `&C`, with an implementation that just calls `iter()`.
+//! Likewise, a collection `C` that provides `iter_mut()` generally implements
+//! `IntoIterator` for `&mut C` by delegating to `iter_mut()`. This enables a
+//! convenient shorthand:
+//!
+//! ```
+//! let mut values = vec![41];
+//! for x in &mut values { // same as `values.iter_mut()`
+//!     *x += 1;
+//! }
+//! for x in &values { // same as `values.iter()`
+//!     assert_eq!(*x, 42);
+//! }
+//! assert_eq!(values.len(), 1);
+//! ```
+//!
+//! While many collections offer `iter()`, not all offer `iter_mut()`. For
+//! example, mutating the keys of a [`HashSet<T>`] or [`HashMap<K, V>`] could
+//! put the collection into an inconsistent state if the key hashes change, so
+//! these collections only offer `iter()`.
+//!
+//! [`into_iter()`]: IntoIterator::into_iter
+//! [`HashSet<T>`]: ../../std/collections/struct.HashSet.html
+//! [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
+//!
 //! # Adapters
 //!
 //! Functions which take an [`Iterator`] and return another [`Iterator`] are
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index dad3add5c55..8174cf5c373 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -565,8 +565,12 @@ mod fn_keyword {}
 ///
 /// For more information on for-loops, see the [Rust book] or the [Reference].
 ///
+/// See also, [`loop`], [`while`].
+///
 /// [`in`]: keyword.in.html
 /// [`impl`]: keyword.impl.html
+/// [`loop`]: keyword.loop.html
+/// [`while`]: keyword.while.html
 /// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
 /// [Rust book]:
 /// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
@@ -842,6 +846,8 @@ mod let_keyword {}
 ///
 /// For more information on `while` and loops in general, see the [reference].
 ///
+/// See also, [`for`], [`loop`].
+///
 /// [`for`]: keyword.for.html
 /// [`loop`]: keyword.loop.html
 /// [reference]: ../reference/expressions/loop-expr.html#predicate-loops
@@ -890,6 +896,10 @@ mod while_keyword {}
 ///
 /// For more information on `loop` and loops in general, see the [Reference].
 ///
+/// See also, [`for`], [`while`].
+///
+/// [`for`]: keyword.for.html
+/// [`while`]: keyword.while.html
 /// [Reference]: ../reference/expressions/loop-expr.html
 mod loop_keyword {}
 
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index a819e1b6e2f..97f40815b87 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -192,8 +192,10 @@ def default_build_triple(verbose):
     # If the user already has a host build triple with an existing `rustc`
     # install, use their preference. This fixes most issues with Windows builds
     # being detected as GNU instead of MSVC.
+    default_encoding = sys.getdefaultencoding()
     try:
         version = subprocess.check_output(["rustc", "--version", "--verbose"])
+        version = version.decode(default_encoding)
         host = next(x for x in version.split('\n') if x.startswith("host: "))
         triple = host.split("host: ")[1]
         if verbose:
@@ -204,7 +206,6 @@ def default_build_triple(verbose):
             print("rustup not detected: {}".format(e))
             print("falling back to auto-detect")
 
-    default_encoding = sys.getdefaultencoding()
     required = sys.platform != 'win32'
     ostype = require(["uname", "-s"], exit=required)
     cputype = require(['uname', '-m'], exit=required)
@@ -794,7 +795,7 @@ class RustBuild(object):
         env.setdefault("RUSTFLAGS", "")
         env["RUSTFLAGS"] += " -Cdebuginfo=2"
 
-        build_section = "target.{}".format(self.build_triple())
+        build_section = "target.{}".format(self.build)
         target_features = []
         if self.get_toml("crt-static", build_section) == "true":
             target_features += ["+crt-static"]
@@ -825,7 +826,11 @@ class RustBuild(object):
         run(args, env=env, verbose=self.verbose)
 
     def build_triple(self):
-        """Build triple as in LLVM"""
+        """Build triple as in LLVM
+
+        Note that `default_build_triple` is moderately expensive,
+        so use `self.build` where possible.
+        """
         config = self.get_toml('build')
         if config:
             return config
@@ -892,13 +897,17 @@ class RustBuild(object):
         filtered_submodules = []
         submodules_names = []
         llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git"))
+        external_llvm_provided = self.get_toml('llvm-config') or self.downloading_llvm()
+        llvm_needed = not self.get_toml('codegen-backends', 'rust') \
+            or "llvm" in self.get_toml('codegen-backends', 'rust')
         for module in submodules:
             if module.endswith("llvm-project"):
-                # Don't sync the llvm-project submodule either if an external LLVM
-                # was provided, or if we are downloading LLVM. Also, if the
-                # submodule has been initialized already, sync it anyways so that
-                # it doesn't mess up contributor pull requests.
-                if self.get_toml('llvm-config') or self.downloading_llvm():
+                # Don't sync the llvm-project submodule if an external LLVM was
+                # provided, if we are downloading LLVM or if the LLVM backend is
+                # not being built. Also, if the submodule has been initialized
+                # already, sync it anyways so that it doesn't mess up contributor
+                # pull requests.
+                if external_llvm_provided or not llvm_needed:
                     if self.get_toml('lld') != 'true' and not llvm_checked_out:
                         continue
             check = self.check_submodule(module, slow_submodules)
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 6d97943548d..9af79e20630 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -732,11 +732,14 @@ impl<'a> Builder<'a> {
             .env("CFG_RELEASE_CHANNEL", &self.config.channel)
             .env("RUSTDOC_REAL", self.rustdoc(compiler))
             .env("RUSTC_BOOTSTRAP", "1")
-            .arg("-Znormalize_docs")
             .arg("-Winvalid_codeblock_attributes");
         if self.config.deny_warnings {
             cmd.arg("-Dwarnings");
         }
+        // cfg(not(bootstrap)), can be removed on the next beta bump
+        if compiler.stage != 0 {
+            cmd.arg("-Znormalize-docs");
+        }
 
         // Remove make-related flags that can cause jobserver problems.
         cmd.env_remove("MAKEFLAGS");
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 354be109cf2..360e51ed2bb 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1186,7 +1186,7 @@ pub fn sanitize_sh(path: &Path) -> String {
     return change_drive(unc_to_lfs(&path)).unwrap_or(path);
 
     fn unc_to_lfs(s: &str) -> &str {
-        if s.starts_with("//?/") { &s[4..] } else { s }
+        s.strip_prefix("//?/").unwrap_or(s)
     }
 
     fn change_drive(s: &str) -> Option<String> {
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index a296a1fe3f4..8cacc2512ef 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -527,7 +527,10 @@ impl Step for Rustc {
         cargo.rustdocflag("--document-private-items");
         cargo.rustdocflag("--enable-index-page");
         cargo.rustdocflag("-Zunstable-options");
-        cargo.rustdocflag("-Znormalize-docs");
+        // cfg(not(bootstrap)), can be removed on the next beta bump
+        if stage != 0 {
+            cargo.rustdocflag("-Znormalize-docs");
+        }
         compile::rustc_cargo(builder, &mut cargo, target);
 
         // Only include compiler crates, no dependencies of those, such as `libc`.
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 4cfcf6ca407..acb941d9540 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -17,6 +17,7 @@ use std::process::Command;
 
 use build_helper::{output, t};
 
+use crate::cache::INTERNER;
 use crate::config::Target;
 use crate::Build;
 
@@ -79,18 +80,19 @@ pub fn check(build: &mut Build) {
     }
 
     // We need cmake, but only if we're actually building LLVM or sanitizers.
-    let building_llvm = build
-        .hosts
-        .iter()
-        .map(|host| {
-            build
-                .config
-                .target_config
-                .get(host)
-                .map(|config| config.llvm_config.is_none())
-                .unwrap_or(true)
-        })
-        .any(|build_llvm_ourselves| build_llvm_ourselves);
+    let building_llvm = build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
+        && build
+            .hosts
+            .iter()
+            .map(|host| {
+                build
+                    .config
+                    .target_config
+                    .get(host)
+                    .map(|config| config.llvm_config.is_none())
+                    .unwrap_or(true)
+            })
+            .any(|build_llvm_ourselves| build_llvm_ourselves);
     if building_llvm || build.config.any_sanitizers_enabled() {
         cmd_finder.must_have("cmake");
     }
@@ -147,10 +149,12 @@ pub fn check(build: &mut Build) {
         }
     }
 
-    // Externally configured LLVM requires FileCheck to exist
-    let filecheck = build.llvm_filecheck(build.build);
-    if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
-        panic!("FileCheck executable {:?} does not exist", filecheck);
+    if build.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
+        // Externally configured LLVM requires FileCheck to exist
+        let filecheck = build.llvm_filecheck(build.build);
+        if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
+            panic!("FileCheck executable {:?} does not exist", filecheck);
+        }
     }
 
     for target in &build.targets {
@@ -159,11 +163,7 @@ pub fn check(build: &mut Build) {
             panic!("the iOS target is only supported on macOS");
         }
 
-        build
-            .config
-            .target_config
-            .entry(target.clone())
-            .or_insert(Target::from_triple(&target.triple));
+        build.config.target_config.entry(*target).or_insert(Target::from_triple(&target.triple));
 
         if target.contains("-none-") || target.contains("nvptx") {
             if build.no_std(*target) == Some(false) {
@@ -176,7 +176,7 @@ pub fn check(build: &mut Build) {
             // If this is a native target (host is also musl) and no musl-root is given,
             // fall back to the system toolchain in /usr before giving up
             if build.musl_root(*target).is_none() && build.config.build == *target {
-                let target = build.config.target_config.entry(target.clone()).or_default();
+                let target = build.config.target_config.entry(*target).or_default();
                 target.musl_root = Some("/usr".into());
             }
             match build.musl_libdir(*target) {
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index f2c74c46d7d..b5169b05997 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -98,7 +98,7 @@ crate fn render<T: Print, S: Print>(
                            placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                            type=\"search\">\
                 </div>\
-                <button class=\"help-button\">?</button>
+                <button type=\"button\" class=\"help-button\">?</button>
                 <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
                     <img src=\"{static_root_path}wheel{suffix}.svg\" \
                          width=\"18\" \
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index bdbb90837c7..22096203d4c 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -139,9 +139,9 @@ fn map_line(s: &str) -> Line<'_> {
     let trimmed = s.trim();
     if trimmed.starts_with("##") {
         Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
-    } else if trimmed.starts_with("# ") {
+    } else if let Some(stripped) = trimmed.strip_prefix("# ") {
         // # text
-        Line::Hidden(&trimmed[2..])
+        Line::Hidden(&stripped)
     } else if trimmed == "#" {
         // We cannot handle '#text' because it could be #[attr].
         Line::Hidden("")
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index 52cfdf6f7a3..997e1f00f85 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -349,8 +349,8 @@ pre.ignore:hover, .information:hover + pre.ignore {
 }
 
 #titles > button:hover, #titles > button.selected {
+	background-color: #ffffff;
 	border-top-color: #0089ff;
-	background-color: #353535;
 }
 
 #titles > button > div.count {
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index e2fdf369087..7358eae6edc 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1012,7 +1012,6 @@ impl LinkCollector<'_, '_> {
         } else {
             // This is a bug.
             debug!("attempting to resolve item without parent module: {}", path_str);
-            let err_kind = ResolutionFailure::NoParentItem.into();
             resolution_failure(
                 self,
                 &item,
@@ -1020,7 +1019,7 @@ impl LinkCollector<'_, '_> {
                 disambiguator,
                 dox,
                 link_range,
-                smallvec![err_kind],
+                smallvec![ResolutionFailure::NoParentItem],
             );
             return None;
         };