diff --git a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
index c88c5bd35a526..bc41d33a609e3 100644
--- a/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/smart_ptr.rs
@@ -11,7 +11,6 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_expand::base::{Annotatable, ExtCtxt};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::{Span, Symbol};
-use smallvec::{smallvec, SmallVec};
 use thin_vec::{thin_vec, ThinVec};
 
 macro_rules! path {
@@ -68,43 +67,63 @@ pub(crate) fn expand_deriving_smart_ptr(
     };
 
     // Convert generic parameters (from the struct) into generic args.
-    let mut pointee_param = None;
-    let mut multiple_pointee_diag: SmallVec<[_; 2]> = smallvec![];
-    let self_params = generics
+    let self_params: Vec<_> = generics
         .params
         .iter()
-        .enumerate()
-        .map(|(idx, p)| match p.kind {
+        .map(|p| match p.kind {
             GenericParamKind::Lifetime => GenericArg::Lifetime(cx.lifetime(p.span(), p.ident)),
-            GenericParamKind::Type { .. } => {
-                if p.attrs().iter().any(|attr| attr.has_name(sym::pointee)) {
-                    if pointee_param.is_some() {
-                        multiple_pointee_diag.push(cx.dcx().struct_span_err(
-                            p.span(),
-                            "`SmartPointer` can only admit one type as pointee",
-                        ));
-                    } else {
-                        pointee_param = Some(idx);
-                    }
-                }
-                GenericArg::Type(cx.ty_ident(p.span(), p.ident))
-            }
+            GenericParamKind::Type { .. } => GenericArg::Type(cx.ty_ident(p.span(), p.ident)),
             GenericParamKind::Const { .. } => GenericArg::Const(cx.const_ident(p.span(), p.ident)),
         })
-        .collect::<Vec<_>>();
-    let Some(pointee_param_idx) = pointee_param else {
+        .collect();
+    let type_params: Vec<_> = generics
+        .params
+        .iter()
+        .enumerate()
+        .filter_map(|(idx, p)| {
+            if let GenericParamKind::Type { .. } = p.kind {
+                Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::pointee))))
+            } else {
+                None
+            }
+        })
+        .collect();
+
+    let pointee_param_idx = if type_params.is_empty() {
+        // `#[derive(SmartPointer)]` requires at least one generic type on the target `struct`
         cx.dcx().struct_span_err(
             span,
-            "At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits",
+            "`SmartPointer` can only be derived on `struct`s that are generic over at least one type",
         ).emit();
         return;
-    };
-    if !multiple_pointee_diag.is_empty() {
-        for diag in multiple_pointee_diag {
-            diag.emit();
+    } else if type_params.len() == 1 {
+        // Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
+        type_params[0].0
+    } else {
+        let mut pointees = type_params
+            .iter()
+            .filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
+            .fuse();
+        match (pointees.next(), pointees.next()) {
+            (Some((idx, _span)), None) => idx,
+            (None, _) => {
+                cx.dcx().struct_span_err(
+                    span,
+                    "exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits",
+                ).emit();
+                return;
+            }
+            (Some((_, one)), Some((_, another))) => {
+                cx.dcx()
+                    .struct_span_err(
+                        vec![one, another],
+                        "only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits",
+                    )
+                    .emit();
+                return;
+            }
         }
-        return;
-    }
+    };
 
     // Create the type of `self`.
     let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 4d19425255faf..e8143b9a5f38f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2,7 +2,7 @@ use std::collections::BTreeSet;
 use std::ffi::OsString;
 use std::fs::{read, File, OpenOptions};
 use std::io::{BufWriter, Write};
-use std::ops::Deref;
+use std::ops::{ControlFlow, Deref};
 use std::path::{Path, PathBuf};
 use std::process::{ExitStatus, Output, Stdio};
 use std::{env, fmt, fs, io, mem, str};
@@ -18,8 +18,8 @@ use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, FatalError};
 use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
-use rustc_metadata::find_native_static_library;
 use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
+use rustc_metadata::{find_native_static_library, walk_native_lib_search_dirs};
 use rustc_middle::bug;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
 use rustc_middle::middle::dependency_format::Linkage;
@@ -2110,50 +2110,19 @@ fn add_library_search_dirs(
         return;
     }
 
-    // Library search paths explicitly supplied by user (`-L` on the command line).
-    for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
-        cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir));
-    }
-    for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
-        // Contrary to the `-L` docs only framework-specific paths are considered here.
-        if search_path.kind != PathKind::All {
-            cmd.framework_path(&search_path.dir);
-        }
-    }
-
-    // The toolchain ships some native library components and self-contained linking was enabled.
-    // Add the self-contained library directory to search paths.
-    if self_contained_components.intersects(
-        LinkSelfContainedComponents::LIBC
-            | LinkSelfContainedComponents::UNWIND
-            | LinkSelfContainedComponents::MINGW,
-    ) {
-        let lib_path = sess.target_tlib_path.dir.join("self-contained");
-        cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
-    }
-
-    // Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
-    // library directory instead of the self-contained directories.
-    // Sanitizer libraries have the same issue and are also linked by name on Apple targets.
-    // The targets here should be in sync with `copy_third_party_objects` in bootstrap.
-    // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
-    // and sanitizers to self-contained directory, and stop adding this search path.
-    if sess.target.vendor == "fortanix"
-        || sess.target.os == "linux"
-        || sess.target.os == "fuchsia"
-        || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
-    {
-        cmd.include_path(&fix_windows_verbatim_for_gcc(&sess.target_tlib_path.dir));
-    }
-
-    // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
-    // we must have the support library stubs in the library search path (#121430).
-    if let Some(sdk_root) = apple_sdk_root
-        && sess.target.llvm_target.contains("macabi")
-    {
-        cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
-        cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
-    }
+    walk_native_lib_search_dirs(
+        sess,
+        self_contained_components,
+        apple_sdk_root,
+        |dir, is_framework| {
+            if is_framework {
+                cmd.framework_path(dir);
+            } else {
+                cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
+            }
+            ControlFlow::<()>::Continue(())
+        },
+    );
 }
 
 /// Add options making relocation sections in the produced ELF files read-only
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index fbab988a32b08..cb266247e0dde 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -7,7 +7,7 @@ use std::{env, iter, mem, str};
 
 use cc::windows_registry;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
-use rustc_metadata::find_native_static_library;
+use rustc_metadata::{find_native_static_library, try_find_native_static_library};
 use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols;
@@ -891,9 +891,15 @@ impl<'a> Linker for MsvcLinker<'a> {
     }
 
     fn link_staticlib_by_name(&mut self, name: &str, verbatim: bool, whole_archive: bool) {
-        let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
-        let suffix = if verbatim { "" } else { ".lib" };
-        self.link_arg(format!("{prefix}{name}{suffix}"));
+        // On MSVC-like targets rustc supports static libraries using alternative naming
+        // scheme (`libfoo.a`) unsupported by linker, search for such libraries manually.
+        if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
+            self.link_staticlib_by_path(&path, whole_archive);
+        } else {
+            let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
+            let suffix = if verbatim { "" } else { ".lib" };
+            self.link_arg(format!("{prefix}{name}{suffix}"));
+        }
     }
 
     fn link_staticlib_by_path(&mut self, path: &Path, whole_archive: bool) {
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index 5da1cbc2283b6..a60fc0ffbbb3b 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -265,8 +265,6 @@ fn structurally_same_type_impl<'tcx>(
     } else {
         // Do a full, depth-first comparison between the two.
         use rustc_type_ir::TyKind::*;
-        let a_kind = a.kind();
-        let b_kind = b.kind();
 
         let compare_layouts = |a, b| -> Result<bool, &'tcx LayoutError<'tcx>> {
             debug!("compare_layouts({:?}, {:?})", a, b);
@@ -281,12 +279,11 @@ fn structurally_same_type_impl<'tcx>(
             Ok(a_layout == b_layout)
         };
 
-        #[allow(rustc::usage_of_ty_tykind)]
         let is_primitive_or_pointer =
-            |kind: &ty::TyKind<'_>| kind.is_primitive() || matches!(kind, RawPtr(..) | Ref(..));
+            |ty: Ty<'tcx>| ty.is_primitive() || matches!(ty.kind(), RawPtr(..) | Ref(..));
 
         ensure_sufficient_stack(|| {
-            match (a_kind, b_kind) {
+            match (a.kind(), b.kind()) {
                 (Adt(a_def, _), Adt(b_def, _)) => {
                     // We can immediately rule out these types as structurally same if
                     // their layouts differ.
@@ -382,17 +379,21 @@ fn structurally_same_type_impl<'tcx>(
 
                 // An Adt and a primitive or pointer type. This can be FFI-safe if non-null
                 // enum layout optimisation is being applied.
-                (Adt(..), other_kind) | (other_kind, Adt(..))
-                    if is_primitive_or_pointer(other_kind) =>
-                {
-                    let (primitive, adt) =
-                        if is_primitive_or_pointer(a.kind()) { (a, b) } else { (b, a) };
-                    if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, adt, ckind) {
-                        ty == primitive
+                (Adt(..), _) if is_primitive_or_pointer(b) => {
+                    if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, a, ckind) {
+                        ty == b
                     } else {
                         compare_layouts(a, b).unwrap_or(false)
                     }
                 }
+                (_, Adt(..)) if is_primitive_or_pointer(a) => {
+                    if let Some(ty) = types::repr_nullable_ptr(tcx, param_env, b, ckind) {
+                        ty == a
+                    } else {
+                        compare_layouts(a, b).unwrap_or(false)
+                    }
+                }
+
                 // Otherwise, just compare the layouts. This may fail to lint for some
                 // incompatible types, but at the very least, will stop reads into
                 // uninitialised memory.
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index acaf9fb0fc32a..d530a7cd9d4bc 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -3,6 +3,7 @@
 #![allow(rustc::potential_query_instability)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
+#![feature(control_flow_enum)]
 #![feature(coroutines)]
 #![feature(decl_macro)]
 #![feature(error_iter)]
@@ -34,7 +35,9 @@ pub mod locator;
 
 pub use creader::{load_symbol_from_dylib, DylibError};
 pub use fs::{emit_wrapper_file, METADATA_FILENAME};
-pub use native_libs::find_native_static_library;
+pub use native_libs::{
+    find_native_static_library, try_find_native_static_library, walk_native_lib_search_dirs,
+};
 pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
 
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 34497f5ac53f8..a6ad449cb53e8 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -1,4 +1,5 @@
-use std::path::PathBuf;
+use std::ops::ControlFlow;
+use std::path::{Path, PathBuf};
 
 use rustc_ast::{NestedMetaItem, CRATE_NODE_ID};
 use rustc_attr as attr;
@@ -16,10 +17,68 @@ use rustc_session::Session;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::symbol::{sym, Symbol};
 use rustc_target::spec::abi::Abi;
+use rustc_target::spec::LinkSelfContainedComponents;
 
 use crate::{errors, fluent_generated};
 
-pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
+pub fn walk_native_lib_search_dirs<R>(
+    sess: &Session,
+    self_contained_components: LinkSelfContainedComponents,
+    apple_sdk_root: Option<&Path>,
+    mut f: impl FnMut(&Path, bool /*is_framework*/) -> ControlFlow<R>,
+) -> ControlFlow<R> {
+    // Library search paths explicitly supplied by user (`-L` on the command line).
+    for search_path in sess.target_filesearch(PathKind::Native).cli_search_paths() {
+        f(&search_path.dir, false)?;
+    }
+    for search_path in sess.target_filesearch(PathKind::Framework).cli_search_paths() {
+        // Frameworks are looked up strictly in framework-specific paths.
+        if search_path.kind != PathKind::All {
+            f(&search_path.dir, true)?;
+        }
+    }
+
+    // The toolchain ships some native library components and self-contained linking was enabled.
+    // Add the self-contained library directory to search paths.
+    if self_contained_components.intersects(
+        LinkSelfContainedComponents::LIBC
+            | LinkSelfContainedComponents::UNWIND
+            | LinkSelfContainedComponents::MINGW,
+    ) {
+        f(&sess.target_tlib_path.dir.join("self-contained"), false)?;
+    }
+
+    // Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot
+    // library directory instead of the self-contained directories.
+    // Sanitizer libraries have the same issue and are also linked by name on Apple targets.
+    // The targets here should be in sync with `copy_third_party_objects` in bootstrap.
+    // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
+    // and sanitizers to self-contained directory, and stop adding this search path.
+    if sess.target.vendor == "fortanix"
+        || sess.target.os == "linux"
+        || sess.target.os == "fuchsia"
+        || sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
+    {
+        f(&sess.target_tlib_path.dir, false)?;
+    }
+
+    // Mac Catalyst uses the macOS SDK, but to link to iOS-specific frameworks
+    // we must have the support library stubs in the library search path (#121430).
+    if let Some(sdk_root) = apple_sdk_root
+        && sess.target.llvm_target.contains("macabi")
+    {
+        f(&sdk_root.join("System/iOSSupport/usr/lib"), false)?;
+        f(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"), true)?;
+    }
+
+    ControlFlow::Continue(())
+}
+
+pub fn try_find_native_static_library(
+    sess: &Session,
+    name: &str,
+    verbatim: bool,
+) -> Option<PathBuf> {
     let formats = if verbatim {
         vec![("".into(), "".into())]
     } else {
@@ -30,16 +89,29 @@ pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) ->
         if os == unix { vec![os] } else { vec![os, unix] }
     };
 
-    for path in sess.target_filesearch(PathKind::Native).search_paths() {
-        for (prefix, suffix) in &formats {
-            let test = path.dir.join(format!("{prefix}{name}{suffix}"));
-            if test.exists() {
-                return test;
+    // FIXME: Account for self-contained linking settings and Apple SDK.
+    walk_native_lib_search_dirs(
+        sess,
+        LinkSelfContainedComponents::empty(),
+        None,
+        |dir, is_framework| {
+            if !is_framework {
+                for (prefix, suffix) in &formats {
+                    let test = dir.join(format!("{prefix}{name}{suffix}"));
+                    if test.exists() {
+                        return ControlFlow::Break(test);
+                    }
+                }
             }
-        }
-    }
+            ControlFlow::Continue(())
+        },
+    )
+    .break_value()
+}
 
-    sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim));
+pub fn find_native_static_library(name: &str, verbatim: bool, sess: &Session) -> PathBuf {
+    try_find_native_static_library(sess, name, verbatim)
+        .unwrap_or_else(|| sess.dcx().emit_fatal(errors::MissingNativeLibrary::new(name, verbatim)))
 }
 
 fn find_bundled_library(
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index a13eac08c9fd2..7321e2c760cef 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -962,7 +962,7 @@ impl CrateRoot {
     }
 }
 
-impl<'a, 'tcx> CrateMetadataRef<'a> {
+impl<'a> CrateMetadataRef<'a> {
     fn missing(self, descr: &str, id: DefIndex) -> ! {
         bug!("missing `{descr}` for {:?}", self.local_def_id(id))
     }
@@ -1036,7 +1036,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, sess))
     }
 
-    fn load_proc_macro(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
+    fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension {
         let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
@@ -1070,7 +1070,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_explicit_item_bounds(
+    fn get_explicit_item_bounds<'tcx>(
         self,
         index: DefIndex,
         tcx: TyCtxt<'tcx>,
@@ -1084,7 +1084,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         ty::EarlyBinder::bind(&*output)
     }
 
-    fn get_explicit_item_super_predicates(
+    fn get_explicit_item_super_predicates<'tcx>(
         self,
         index: DefIndex,
         tcx: TyCtxt<'tcx>,
@@ -1141,7 +1141,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
+    fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> {
         let kind = self.def_kind(item_id);
         let did = self.local_def_id(item_id);
 
@@ -1225,12 +1225,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     /// Iterates over the stability implications in the given crate (when a `#[unstable]` attribute
     /// has an `implied_by` meta item, then the mapping from the implied feature to the actual
     /// feature is a stability implication).
-    fn get_stability_implications(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] {
+    fn get_stability_implications<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] {
         tcx.arena.alloc_from_iter(self.root.stability_implications.decode(self))
     }
 
     /// Iterates over the lang items in the given crate.
-    fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
+    fn get_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
         tcx.arena.alloc_from_iter(
             self.root
                 .lang_items
@@ -1239,7 +1239,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_stripped_cfg_items(self, cnum: CrateNum, tcx: TyCtxt<'tcx>) -> &'tcx [StrippedCfgItem] {
+    fn get_stripped_cfg_items<'tcx>(
+        self,
+        cnum: CrateNum,
+        tcx: TyCtxt<'tcx>,
+    ) -> &'tcx [StrippedCfgItem] {
         let item_names = self
             .root
             .stripped_cfg_items
@@ -1412,7 +1416,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .decode((self, sess))
     }
 
-    fn get_inherent_implementations_for_type(
+    fn get_inherent_implementations_for_type<'tcx>(
         self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
@@ -1439,7 +1443,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         })
     }
 
-    fn get_incoherent_impls(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] {
+    fn get_incoherent_impls<'tcx>(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] {
         if let Some(impls) = self.cdata.incoherent_impls.get(&simp) {
             tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx)))
         } else {
@@ -1447,7 +1451,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         }
     }
 
-    fn get_implementations_of_trait(
+    fn get_implementations_of_trait<'tcx>(
         self,
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
@@ -1491,7 +1495,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         self.root.foreign_modules.decode((self, sess))
     }
 
-    fn get_dylib_dependency_formats(
+    fn get_dylib_dependency_formats<'tcx>(
         self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(CrateNum, LinkagePreference)] {
@@ -1503,11 +1507,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         )
     }
 
-    fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
+    fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
         tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
     }
 
-    fn exported_symbols(
+    fn exported_symbols<'tcx>(
         self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d60bfb9faa1aa..c6621a7a64331 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1000,7 +1000,7 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn is_primitive(self) -> bool {
-        self.kind().is_primitive()
+        matches!(self.kind(), Bool | Char | Int(_) | Uint(_) | Float(_))
     }
 
     #[inline]
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 328b6739d9756..80c3565911e9a 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -254,13 +254,6 @@ pub enum TyKind<I: Interner> {
     Error(I::ErrorGuaranteed),
 }
 
-impl<I: Interner> TyKind<I> {
-    #[inline]
-    pub fn is_primitive(&self) -> bool {
-        matches!(self, Bool | Char | Int(_) | Uint(_) | Float(_))
-    }
-}
-
 // This is manually implemented because a derive would require `I: Debug`
 impl<I: Interner> fmt::Debug for TyKind<I> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs
index 50d7bae21db72..aeae866e9d344 100644
--- a/compiler/stable_mir/src/mir/visit.rs
+++ b/compiler/stable_mir/src/mir/visit.rs
@@ -465,6 +465,22 @@ impl Location {
     }
 }
 
+/// Location of the statement at the given index for a given basic block. Assumes that `stmt_idx`
+/// and `bb_idx` are valid for a given body.
+pub fn statement_location(body: &Body, bb_idx: &BasicBlockIdx, stmt_idx: usize) -> Location {
+    let bb = &body.blocks[*bb_idx];
+    let stmt = &bb.statements[stmt_idx];
+    Location(stmt.span)
+}
+
+/// Location of the terminator for a given basic block. Assumes that `bb_idx` is valid for a given
+/// body.
+pub fn terminator_location(body: &Body, bb_idx: &BasicBlockIdx) -> Location {
+    let bb = &body.blocks[*bb_idx];
+    let terminator = &bb.terminator;
+    Location(terminator.span)
+}
+
 /// Reference to a place used to represent a partial projection.
 pub struct PlaceRef<'a> {
     pub local: Local,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 4a3522f1a641b..1948d3e10c53e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -335,7 +335,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Weak<U, A>> f
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
 
 #[stable(feature = "arc_weak", since = "1.4.0")]
-impl<T: ?Sized> fmt::Debug for Weak<T> {
+impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "(Weak)")
     }
diff --git a/library/core/benches/lib.rs b/library/core/benches/lib.rs
index 32d15c386cb1b..3f1c58bbd7204 100644
--- a/library/core/benches/lib.rs
+++ b/library/core/benches/lib.rs
@@ -8,6 +8,7 @@
 #![feature(iter_array_chunks)]
 #![feature(iter_next_chunk)]
 #![feature(iter_advance_by)]
+#![feature(isqrt)]
 
 extern crate test;
 
diff --git a/library/core/benches/num/int_sqrt/mod.rs b/library/core/benches/num/int_sqrt/mod.rs
new file mode 100644
index 0000000000000..3c9d173e456a1
--- /dev/null
+++ b/library/core/benches/num/int_sqrt/mod.rs
@@ -0,0 +1,62 @@
+use rand::Rng;
+use test::{black_box, Bencher};
+
+macro_rules! int_sqrt_bench {
+    ($t:ty, $predictable:ident, $random:ident, $random_small:ident, $random_uniform:ident) => {
+        #[bench]
+        fn $predictable(bench: &mut Bencher) {
+            bench.iter(|| {
+                for n in 0..(<$t>::BITS / 8) {
+                    for i in 1..=(100 as $t) {
+                        let x = black_box(i << (n * 8));
+                        black_box(x.isqrt());
+                    }
+                }
+            });
+        }
+
+        #[bench]
+        fn $random(bench: &mut Bencher) {
+            let mut rng = crate::bench_rng();
+            /* Exponentially distributed random numbers from the whole range of the type.  */
+            let numbers: Vec<$t> =
+                (0..256).map(|_| rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS)).collect();
+            bench.iter(|| {
+                for x in &numbers {
+                    black_box(black_box(x).isqrt());
+                }
+            });
+        }
+
+        #[bench]
+        fn $random_small(bench: &mut Bencher) {
+            let mut rng = crate::bench_rng();
+            /* Exponentially distributed random numbers from the range 0..256.  */
+            let numbers: Vec<$t> =
+                (0..256).map(|_| (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t).collect();
+            bench.iter(|| {
+                for x in &numbers {
+                    black_box(black_box(x).isqrt());
+                }
+            });
+        }
+
+        #[bench]
+        fn $random_uniform(bench: &mut Bencher) {
+            let mut rng = crate::bench_rng();
+            /* Exponentially distributed random numbers from the whole range of the type.  */
+            let numbers: Vec<$t> = (0..256).map(|_| rng.gen::<$t>()).collect();
+            bench.iter(|| {
+                for x in &numbers {
+                    black_box(black_box(x).isqrt());
+                }
+            });
+        }
+    };
+}
+
+int_sqrt_bench! {u8, u8_sqrt_predictable, u8_sqrt_random, u8_sqrt_random_small, u8_sqrt_uniform}
+int_sqrt_bench! {u16, u16_sqrt_predictable, u16_sqrt_random, u16_sqrt_random_small, u16_sqrt_uniform}
+int_sqrt_bench! {u32, u32_sqrt_predictable, u32_sqrt_random, u32_sqrt_random_small, u32_sqrt_uniform}
+int_sqrt_bench! {u64, u64_sqrt_predictable, u64_sqrt_random, u64_sqrt_random_small, u64_sqrt_uniform}
+int_sqrt_bench! {u128, u128_sqrt_predictable, u128_sqrt_random, u128_sqrt_random_small, u128_sqrt_uniform}
diff --git a/library/core/benches/num/mod.rs b/library/core/benches/num/mod.rs
index c1dc3a3062256..7ff7443cfa7fe 100644
--- a/library/core/benches/num/mod.rs
+++ b/library/core/benches/num/mod.rs
@@ -2,6 +2,7 @@ mod dec2flt;
 mod flt2dec;
 mod int_log;
 mod int_pow;
+mod int_sqrt;
 
 use std::str::FromStr;
 
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 42461a3345be9..878a911dde50d 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1641,7 +1641,33 @@ macro_rules! int_impl {
             if self < 0 {
                 None
             } else {
-                Some((self as $UnsignedT).isqrt() as Self)
+                // SAFETY: Input is nonnegative in this `else` branch.
+                let result = unsafe {
+                    crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
+                };
+
+                // Inform the optimizer what the range of outputs is. If
+                // testing `core` crashes with no panic message and a
+                // `num::int_sqrt::i*` test failed, it's because your edits
+                // caused these assertions to become false.
+                //
+                // SAFETY: Integer square root is a monotonically nondecreasing
+                // function, which means that increasing the input will never
+                // cause the output to decrease. Thus, since the input for
+                // nonnegative signed integers is bounded by
+                // `[0, <$ActualT>::MAX]`, sqrt(n) will be bounded by
+                // `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
+                unsafe {
+                    // SAFETY: `<$ActualT>::MAX` is nonnegative.
+                    const MAX_RESULT: $SelfT = unsafe {
+                        crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
+                    };
+
+                    crate::hint::assert_unchecked(result >= 0);
+                    crate::hint::assert_unchecked(result <= MAX_RESULT);
+                }
+
+                Some(result)
             }
         }
 
@@ -2862,15 +2888,11 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
+        #[track_caller]
         pub const fn isqrt(self) -> Self {
-            // I would like to implement it as
-            // ```
-            // self.checked_isqrt().expect("argument of integer square root must be non-negative")
-            // ```
-            // but `expect` is not yet stable as a `const fn`.
             match self.checked_isqrt() {
                 Some(sqrt) => sqrt,
-                None => panic!("argument of integer square root must be non-negative"),
+                None => crate::num::int_sqrt::panic_for_negative_argument(),
             }
         }
 
diff --git a/library/core/src/num/int_sqrt.rs b/library/core/src/num/int_sqrt.rs
new file mode 100644
index 0000000000000..601e81f69930f
--- /dev/null
+++ b/library/core/src/num/int_sqrt.rs
@@ -0,0 +1,316 @@
+//! These functions use the [Karatsuba square root algorithm][1] to compute the
+//! [integer square root](https://en.wikipedia.org/wiki/Integer_square_root)
+//! for the primitive integer types.
+//!
+//! The signed integer functions can only handle **nonnegative** inputs, so
+//! that must be checked before calling those.
+//!
+//! [1]: <https://web.archive.org/web/20230511212802/https://inria.hal.science/inria-00072854v1/file/RR-3805.pdf>
+//! "Paul Zimmermann. Karatsuba Square Root. \[Research Report\] RR-3805,
+//! INRIA. 1999, pp.8. (inria-00072854)"
+
+/// This array stores the [integer square roots](
+/// https://en.wikipedia.org/wiki/Integer_square_root) and remainders of each
+/// [`u8`](prim@u8) value. For example, `U8_ISQRT_WITH_REMAINDER[17]` will be
+/// `(4, 1)` because the integer square root of 17 is 4 and because 17 is 1
+/// higher than 4 squared.
+const U8_ISQRT_WITH_REMAINDER: [(u8, u8); 256] = {
+    let mut result = [(0, 0); 256];
+
+    let mut n: usize = 0;
+    let mut isqrt_n: usize = 0;
+    while n < result.len() {
+        result[n] = (isqrt_n as u8, (n - isqrt_n.pow(2)) as u8);
+
+        n += 1;
+        if n == (isqrt_n + 1).pow(2) {
+            isqrt_n += 1;
+        }
+    }
+
+    result
+};
+
+/// Returns the [integer square root](
+/// https://en.wikipedia.org/wiki/Integer_square_root) of any [`u8`](prim@u8)
+/// input.
+#[must_use = "this returns the result of the operation, \
+              without modifying the original"]
+#[inline]
+pub const fn u8(n: u8) -> u8 {
+    U8_ISQRT_WITH_REMAINDER[n as usize].0
+}
+
+/// Generates an `i*` function that returns the [integer square root](
+/// https://en.wikipedia.org/wiki/Integer_square_root) of any **nonnegative**
+/// input of a specific signed integer type.
+macro_rules! signed_fn {
+    ($SignedT:ident, $UnsignedT:ident) => {
+        /// Returns the [integer square root](
+        /// https://en.wikipedia.org/wiki/Integer_square_root) of any
+        /// **nonnegative**
+        #[doc = concat!("[`", stringify!($SignedT), "`](prim@", stringify!($SignedT), ")")]
+        /// input.
+        ///
+        /// # Safety
+        ///
+        /// This results in undefined behavior when the input is negative.
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
+            debug_assert!(n >= 0, "Negative input inside `isqrt`.");
+            $UnsignedT(n as $UnsignedT) as $SignedT
+        }
+    };
+}
+
+signed_fn!(i8, u8);
+signed_fn!(i16, u16);
+signed_fn!(i32, u32);
+signed_fn!(i64, u64);
+signed_fn!(i128, u128);
+
+/// Generates a `u*` function that returns the [integer square root](
+/// https://en.wikipedia.org/wiki/Integer_square_root) of any input of
+/// a specific unsigned integer type.
+macro_rules! unsigned_fn {
+    ($UnsignedT:ident, $HalfBitsT:ident, $stages:ident) => {
+        /// Returns the [integer square root](
+        /// https://en.wikipedia.org/wiki/Integer_square_root) of any
+        #[doc = concat!("[`", stringify!($UnsignedT), "`](prim@", stringify!($UnsignedT), ")")]
+        /// input.
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
+            if n <= <$HalfBitsT>::MAX as $UnsignedT {
+                $HalfBitsT(n as $HalfBitsT) as $UnsignedT
+            } else {
+                // The normalization shift satisfies the Karatsuba square root
+                // algorithm precondition "a₃ ≥ b/4" where a₃ is the most
+                // significant quarter of `n`'s bits and b is the number of
+                // values that can be represented by that quarter of the bits.
+                //
+                // b/4 would then be all 0s except the second most significant
+                // bit (010...0) in binary. Since a₃ must be at least b/4, a₃'s
+                // most significant bit or its neighbor must be a 1. Since a₃'s
+                // most significant bits are `n`'s most significant bits, the
+                // same applies to `n`.
+                //
+                // The reason to shift by an even number of bits is because an
+                // even number of bits produces the square root shifted to the
+                // left by half of the normalization shift:
+                //
+                // sqrt(n << (2 * p))
+                // sqrt(2.pow(2 * p) * n)
+                // sqrt(2.pow(2 * p)) * sqrt(n)
+                // 2.pow(p) * sqrt(n)
+                // sqrt(n) << p
+                //
+                // Shifting by an odd number of bits leaves an ugly sqrt(2)
+                // multiplied in:
+                //
+                // sqrt(n << (2 * p + 1))
+                // sqrt(2.pow(2 * p + 1) * n)
+                // sqrt(2 * 2.pow(2 * p) * n)
+                // sqrt(2) * sqrt(2.pow(2 * p)) * sqrt(n)
+                // sqrt(2) * 2.pow(p) * sqrt(n)
+                // sqrt(2) * (sqrt(n) << p)
+                const EVEN_MAKING_BITMASK: u32 = !1;
+                let normalization_shift = n.leading_zeros() & EVEN_MAKING_BITMASK;
+                n <<= normalization_shift;
+
+                let s = $stages(n);
+
+                let denormalization_shift = normalization_shift >> 1;
+                s >> denormalization_shift
+            }
+        }
+    };
+}
+
+/// Generates the first stage of the computation after normalization.
+///
+/// # Safety
+///
+/// `$n` must be nonzero.
+macro_rules! first_stage {
+    ($original_bits:literal, $n:ident) => {{
+        debug_assert!($n != 0, "`$n` is  zero in `first_stage!`.");
+
+        const N_SHIFT: u32 = $original_bits - 8;
+        let n = $n >> N_SHIFT;
+
+        let (s, r) = U8_ISQRT_WITH_REMAINDER[n as usize];
+
+        // Inform the optimizer that `s` is nonzero. This will allow it to
+        // avoid generating code to handle division-by-zero panics in the next
+        // stage.
+        //
+        // SAFETY: If the original `$n` is zero, the top of the `unsigned_fn`
+        // macro recurses instead of continuing to this point, so the original
+        // `$n` wasn't a 0 if we've reached here.
+        //
+        // Then the `unsigned_fn` macro normalizes `$n` so that at least one of
+        // its two most-significant bits is a 1.
+        //
+        // Then this stage puts the eight most-significant bits of `$n` into
+        // `n`. This means that `n` here has at least one 1 bit in its two
+        // most-significant bits, making `n` nonzero.
+        //
+        // `U8_ISQRT_WITH_REMAINDER[n as usize]` will give a nonzero `s` when
+        // given a nonzero `n`.
+        unsafe { crate::hint::assert_unchecked(s != 0) };
+        (s, r)
+    }};
+}
+
+/// Generates a middle stage of the computation.
+///
+/// # Safety
+///
+/// `$s` must be nonzero.
+macro_rules! middle_stage {
+    ($original_bits:literal, $ty:ty, $n:ident, $s:ident, $r:ident) => {{
+        debug_assert!($s != 0, "`$s` is  zero in `middle_stage!`.");
+
+        const N_SHIFT: u32 = $original_bits - <$ty>::BITS;
+        let n = ($n >> N_SHIFT) as $ty;
+
+        const HALF_BITS: u32 = <$ty>::BITS >> 1;
+        const QUARTER_BITS: u32 = <$ty>::BITS >> 2;
+        const LOWER_HALF_1_BITS: $ty = (1 << HALF_BITS) - 1;
+        const LOWEST_QUARTER_1_BITS: $ty = (1 << QUARTER_BITS) - 1;
+
+        let lo = n & LOWER_HALF_1_BITS;
+        let numerator = (($r as $ty) << QUARTER_BITS) | (lo >> QUARTER_BITS);
+        let denominator = ($s as $ty) << 1;
+        let q = numerator / denominator;
+        let u = numerator % denominator;
+
+        let mut s = ($s << QUARTER_BITS) as $ty + q;
+        let (mut r, overflow) =
+            ((u << QUARTER_BITS) | (lo & LOWEST_QUARTER_1_BITS)).overflowing_sub(q * q);
+        if overflow {
+            r = r.wrapping_add(2 * s - 1);
+            s -= 1;
+        }
+
+        // Inform the optimizer that `s` is nonzero. This will allow it to
+        // avoid generating code to handle division-by-zero panics in the next
+        // stage.
+        //
+        // SAFETY: If the original `$n` is zero, the top of the `unsigned_fn`
+        // macro recurses instead of continuing to this point, so the original
+        // `$n` wasn't a 0 if we've reached here.
+        //
+        // Then the `unsigned_fn` macro normalizes `$n` so that at least one of
+        // its two most-significant bits is a 1.
+        //
+        // Then these stages take as many of the most-significant bits of `$n`
+        // as will fit in this stage's type. For example, the stage that
+        // handles `u32` deals with the 32 most-significant bits of `$n`. This
+        // means that each stage has at least one 1 bit in `n`'s two
+        // most-significant bits, making `n` nonzero.
+        //
+        // Then this stage will produce the correct integer square root for
+        // that `n` value. Since `n` is nonzero, `s` will also be nonzero.
+        unsafe { crate::hint::assert_unchecked(s != 0) };
+        (s, r)
+    }};
+}
+
+/// Generates the last stage of the computation before denormalization.
+///
+/// # Safety
+///
+/// `$s` must be nonzero.
+macro_rules! last_stage {
+    ($ty:ty, $n:ident, $s:ident, $r:ident) => {{
+        debug_assert!($s != 0, "`$s` is  zero in `last_stage!`.");
+
+        const HALF_BITS: u32 = <$ty>::BITS >> 1;
+        const QUARTER_BITS: u32 = <$ty>::BITS >> 2;
+        const LOWER_HALF_1_BITS: $ty = (1 << HALF_BITS) - 1;
+
+        let lo = $n & LOWER_HALF_1_BITS;
+        let numerator = (($r as $ty) << QUARTER_BITS) | (lo >> QUARTER_BITS);
+        let denominator = ($s as $ty) << 1;
+
+        let q = numerator / denominator;
+        let mut s = ($s << QUARTER_BITS) as $ty + q;
+        let (s_squared, overflow) = s.overflowing_mul(s);
+        if overflow || s_squared > $n {
+            s -= 1;
+        }
+        s
+    }};
+}
+
+/// Takes the normalized [`u16`](prim@u16) input and gets its normalized
+/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
+///
+/// # Safety
+///
+/// `n` must be nonzero.
+#[inline]
+const fn u16_stages(n: u16) -> u16 {
+    let (s, r) = first_stage!(16, n);
+    last_stage!(u16, n, s, r)
+}
+
+/// Takes the normalized [`u32`](prim@u32) input and gets its normalized
+/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
+///
+/// # Safety
+///
+/// `n` must be nonzero.
+#[inline]
+const fn u32_stages(n: u32) -> u32 {
+    let (s, r) = first_stage!(32, n);
+    let (s, r) = middle_stage!(32, u16, n, s, r);
+    last_stage!(u32, n, s, r)
+}
+
+/// Takes the normalized [`u64`](prim@u64) input and gets its normalized
+/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
+///
+/// # Safety
+///
+/// `n` must be nonzero.
+#[inline]
+const fn u64_stages(n: u64) -> u64 {
+    let (s, r) = first_stage!(64, n);
+    let (s, r) = middle_stage!(64, u16, n, s, r);
+    let (s, r) = middle_stage!(64, u32, n, s, r);
+    last_stage!(u64, n, s, r)
+}
+
+/// Takes the normalized [`u128`](prim@u128) input and gets its normalized
+/// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root).
+///
+/// # Safety
+///
+/// `n` must be nonzero.
+#[inline]
+const fn u128_stages(n: u128) -> u128 {
+    let (s, r) = first_stage!(128, n);
+    let (s, r) = middle_stage!(128, u16, n, s, r);
+    let (s, r) = middle_stage!(128, u32, n, s, r);
+    let (s, r) = middle_stage!(128, u64, n, s, r);
+    last_stage!(u128, n, s, r)
+}
+
+unsigned_fn!(u16, u8, u16_stages);
+unsigned_fn!(u32, u16, u32_stages);
+unsigned_fn!(u64, u32, u64_stages);
+unsigned_fn!(u128, u64, u128_stages);
+
+/// Instantiate this panic logic once, rather than for all the isqrt methods
+/// on every single primitive type.
+#[cold]
+#[track_caller]
+pub const fn panic_for_negative_argument() -> ! {
+    panic!("argument of integer square root cannot be negative")
+}
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 309e1ba958aee..e9e5324666ada 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -41,6 +41,7 @@ mod uint_macros; // import uint_impl!
 
 mod error;
 mod int_log10;
+mod int_sqrt;
 mod nonzero;
 mod overflow_panic;
 mod saturating;
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index c6e9c249048a7..8b888f12da0b1 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -7,7 +7,7 @@ use crate::marker::{Freeze, StructuralPartialEq};
 use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
 use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::str::FromStr;
-use crate::{fmt, hint, intrinsics, ptr, ub_checks};
+use crate::{fmt, intrinsics, ptr, ub_checks};
 
 /// A marker trait for primitive types which can be zero.
 ///
@@ -1545,31 +1545,14 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
                       without modifying the original"]
         #[inline]
         pub const fn isqrt(self) -> Self {
-            // The algorithm is based on the one presented in
-            // <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
-            // which cites as source the following C code:
-            // <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
-
-            let mut op = self.get();
-            let mut res = 0;
-            let mut one = 1 << (self.ilog2() & !1);
-
-            while one != 0 {
-                if op >= res + one {
-                    op -= res + one;
-                    res = (res >> 1) + one;
-                } else {
-                    res >>= 1;
-                }
-                one >>= 2;
-            }
+            let result = self.get().isqrt();
 
-            // SAFETY: The result fits in an integer with half as many bits.
-            // Inform the optimizer about it.
-            unsafe { hint::assert_unchecked(res < 1 << (Self::BITS / 2)) };
-
-            // SAFETY: The square root of an integer >= 1 is always >= 1.
-            unsafe { Self::new_unchecked(res) }
+            // SAFETY: Integer square root is a monotonically nondecreasing
+            // function, which means that increasing the input will never cause
+            // the output to decrease. Thus, since the input for nonzero
+            // unsigned integers has a lower bound of 1, the lower bound of the
+            // results will be sqrt(1), which is 1, so a result can't be zero.
+            unsafe { Self::new_unchecked(result) }
         }
     };
 
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 0d0bbc5256f78..d9036abecc592 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2762,10 +2762,24 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn isqrt(self) -> Self {
-            match NonZero::new(self) {
-                Some(x) => x.isqrt().get(),
-                None => 0,
+            let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
+
+            // Inform the optimizer what the range of outputs is. If testing
+            // `core` crashes with no panic message and a `num::int_sqrt::u*`
+            // test failed, it's because your edits caused these assertions or
+            // the assertions in `fn isqrt` of `nonzero.rs` to become false.
+            //
+            // SAFETY: Integer square root is a monotonically nondecreasing
+            // function, which means that increasing the input will never
+            // cause the output to decrease. Thus, since the input for unsigned
+            // integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
+            // bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
+            unsafe {
+                const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
+                crate::hint::assert_unchecked(result <= MAX_RESULT);
             }
+
+            result
         }
 
         /// Performs Euclidean division.
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 7cd3b54e3f39a..830a96204ca03 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -288,38 +288,6 @@ macro_rules! int_module {
             assert_eq!(r.saturating_pow(0), 1 as $T);
         }
 
-        #[test]
-        fn test_isqrt() {
-            assert_eq!($T::MIN.checked_isqrt(), None);
-            assert_eq!((-1 as $T).checked_isqrt(), None);
-            assert_eq!((0 as $T).isqrt(), 0 as $T);
-            assert_eq!((1 as $T).isqrt(), 1 as $T);
-            assert_eq!((2 as $T).isqrt(), 1 as $T);
-            assert_eq!((99 as $T).isqrt(), 9 as $T);
-            assert_eq!((100 as $T).isqrt(), 10 as $T);
-        }
-
-        #[cfg(not(miri))] // Miri is too slow
-        #[test]
-        fn test_lots_of_isqrt() {
-            let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
-            for n in 0..=n_max {
-                let isqrt: $T = n.isqrt();
-
-                assert!(isqrt.pow(2) <= n);
-                let (square, overflow) = (isqrt + 1).overflowing_pow(2);
-                assert!(overflow || square > n);
-            }
-
-            for n in ($T::MAX - 127)..=$T::MAX {
-                let isqrt: $T = n.isqrt();
-
-                assert!(isqrt.pow(2) <= n);
-                let (square, overflow) = (isqrt + 1).overflowing_pow(2);
-                assert!(overflow || square > n);
-            }
-        }
-
         #[test]
         fn test_div_floor() {
             let a: $T = 8;
diff --git a/library/core/tests/num/int_sqrt.rs b/library/core/tests/num/int_sqrt.rs
new file mode 100644
index 0000000000000..4c126615d4b0b
--- /dev/null
+++ b/library/core/tests/num/int_sqrt.rs
@@ -0,0 +1,239 @@
+macro_rules! tests {
+    ($isqrt_consistency_check_fn_macro:ident : $($T:ident)+) => {
+        $(
+            mod $T {
+                $isqrt_consistency_check_fn_macro!($T);
+
+                // Check that the following produce the correct values from
+                // `isqrt`:
+                //
+                // * the first and last 128 nonnegative values
+                // * powers of two, minus one
+                // * powers of two
+                //
+                // For signed types, check that `checked_isqrt` and `isqrt`
+                // either produce the same numeric value or respectively
+                // produce `None` and a panic. Make sure to do a consistency
+                // check for `<$T>::MIN` as well, as no nonnegative values
+                // negate to it.
+                //
+                // For unsigned types check that `isqrt` produces the same
+                // numeric value for `$T` and `NonZero<$T>`.
+                #[test]
+                fn isqrt() {
+                    isqrt_consistency_check(<$T>::MIN);
+
+                    for n in (0..=127)
+                        .chain(<$T>::MAX - 127..=<$T>::MAX)
+                        .chain((0..<$T>::MAX.count_ones()).map(|exponent| (1 << exponent) - 1))
+                        .chain((0..<$T>::MAX.count_ones()).map(|exponent| 1 << exponent))
+                    {
+                        isqrt_consistency_check(n);
+
+                        let isqrt_n = n.isqrt();
+                        assert!(
+                            isqrt_n
+                                .checked_mul(isqrt_n)
+                                .map(|isqrt_n_squared| isqrt_n_squared <= n)
+                                .unwrap_or(false),
+                            "`{n}.isqrt()` should be lower than {isqrt_n}."
+                        );
+                        assert!(
+                            (isqrt_n + 1)
+                                .checked_mul(isqrt_n + 1)
+                                .map(|isqrt_n_plus_1_squared| n < isqrt_n_plus_1_squared)
+                                .unwrap_or(true),
+                            "`{n}.isqrt()` should be higher than {isqrt_n})."
+                        );
+                    }
+                }
+
+                // Check the square roots of:
+                //
+                // * the first 1,024 perfect squares
+                // * halfway between each of the first 1,024 perfect squares
+                //   and the next perfect square
+                // * the next perfect square after the each of the first 1,024
+                //   perfect squares, minus one
+                // * the last 1,024 perfect squares
+                // * the last 1,024 perfect squares, minus one
+                // * halfway between each of the last 1,024 perfect squares
+                //   and the previous perfect square
+                #[test]
+                // Skip this test on Miri, as it takes too long to run.
+                #[cfg(not(miri))]
+                fn isqrt_extended() {
+                    // The correct value is worked out by using the fact that
+                    // the nth nonzero perfect square is the sum of the first n
+                    // odd numbers:
+                    //
+                    //  1 = 1
+                    //  4 = 1 + 3
+                    //  9 = 1 + 3 + 5
+                    // 16 = 1 + 3 + 5 + 7
+                    //
+                    // Note also that the last odd number added in is two times
+                    // the square root of the previous perfect square, plus
+                    // one:
+                    //
+                    // 1 = 2*0 + 1
+                    // 3 = 2*1 + 1
+                    // 5 = 2*2 + 1
+                    // 7 = 2*3 + 1
+                    //
+                    // That means we can add the square root of this perfect
+                    // square once to get about halfway to the next perfect
+                    // square, then we can add the square root of this perfect
+                    // square again to get to the next perfect square, minus
+                    // one, then we can add one to get to the next perfect
+                    // square.
+                    //
+                    // This allows us to, for each of the first 1,024 perfect
+                    // squares, test that the square roots of the following are
+                    // all correct and equal to each other:
+                    //
+                    // * the current perfect square
+                    // * about halfway to the next perfect square
+                    // * the next perfect square, minus one
+                    let mut n: $T = 0;
+                    for sqrt_n in 0..1_024.min((1_u128 << (<$T>::MAX.count_ones()/2)) - 1) as $T {
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n,
+                            "`{sqrt_n}.pow(2).isqrt()` should be {sqrt_n}."
+                        );
+
+                        n += sqrt_n;
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n,
+                            "{n} is about halfway between `{sqrt_n}.pow(2)` and `{}.pow(2)`, so `{n}.isqrt()` should be {sqrt_n}.",
+                            sqrt_n + 1
+                        );
+
+                        n += sqrt_n;
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n,
+                            "`({}.pow(2) - 1).isqrt()` should be {sqrt_n}.",
+                            sqrt_n + 1
+                        );
+
+                        n += 1;
+                    }
+
+                    // Similarly, for each of the last 1,024 perfect squares,
+                    // check:
+                    //
+                    // * the current perfect square
+                    // * the current perfect square, minus one
+                    // * about halfway to the previous perfect square
+                    //
+                    // `MAX`'s `isqrt` return value is verified in the `isqrt`
+                    // test function above.
+                    let maximum_sqrt = <$T>::MAX.isqrt();
+                    let mut n = maximum_sqrt * maximum_sqrt;
+
+                    for sqrt_n in (maximum_sqrt - 1_024.min((1_u128 << (<$T>::MAX.count_ones()/2)) - 1) as $T..maximum_sqrt).rev() {
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n + 1,
+                            "`{0}.pow(2).isqrt()` should be {0}.",
+                            sqrt_n + 1
+                        );
+
+                        n -= 1;
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n,
+                            "`({}.pow(2) - 1).isqrt()` should be {sqrt_n}.",
+                            sqrt_n + 1
+                        );
+
+                        n -= sqrt_n;
+                        isqrt_consistency_check(n);
+                        assert_eq!(
+                            n.isqrt(),
+                            sqrt_n,
+                            "{n} is about halfway between `{sqrt_n}.pow(2)` and `{}.pow(2)`, so `{n}.isqrt()` should be {sqrt_n}.",
+                            sqrt_n + 1
+                        );
+
+                        n -= sqrt_n;
+                    }
+                }
+            }
+        )*
+    };
+}
+
+macro_rules! signed_check {
+    ($T:ident) => {
+        /// This takes an input and, if it's nonnegative or
+        #[doc = concat!("`", stringify!($T), "::MIN`,")]
+        /// checks that `isqrt` and `checked_isqrt` produce equivalent results
+        /// for that input and for the negative of that input.
+        fn isqrt_consistency_check(n: $T) {
+            // `<$T>::MIN` will be negative, so ignore it in this nonnegative
+            // section.
+            if n >= 0 {
+                assert_eq!(
+                    Some(n.isqrt()),
+                    n.checked_isqrt(),
+                    "`{n}.checked_isqrt()` should match `Some({n}.isqrt())`.",
+                );
+            }
+
+            // `wrapping_neg` so that `<$T>::MIN` will negate to itself rather
+            // than panicking.
+            let negative_n = n.wrapping_neg();
+
+            // Zero negated will still be nonnegative, so ignore it in this
+            // negative section.
+            if negative_n < 0 {
+                assert_eq!(
+                    negative_n.checked_isqrt(),
+                    None,
+                    "`({negative_n}).checked_isqrt()` should be `None`, as {negative_n} is negative.",
+                );
+
+                std::panic::catch_unwind(core::panic::AssertUnwindSafe(|| (-n).isqrt())).expect_err(
+                    &format!("`({negative_n}).isqrt()` should have panicked, as {negative_n} is negative.")
+                );
+            }
+        }
+    };
+}
+
+macro_rules! unsigned_check {
+    ($T:ident) => {
+        /// This takes an input and, if it's nonzero, checks that `isqrt`
+        /// produces the same numeric value for both
+        #[doc = concat!("`", stringify!($T), "` and ")]
+        #[doc = concat!("`NonZero<", stringify!($T), ">`.")]
+        fn isqrt_consistency_check(n: $T) {
+            // Zero cannot be turned into a `NonZero` value, so ignore it in
+            // this nonzero section.
+            if n > 0 {
+                assert_eq!(
+                    n.isqrt(),
+                    core::num::NonZero::<$T>::new(n)
+                        .expect(
+                            "Was not able to create a new `NonZero` value from a nonzero number."
+                        )
+                        .isqrt()
+                        .get(),
+                    "`{n}.isqrt` should match `NonZero`'s `{n}.isqrt().get()`.",
+                );
+            }
+        }
+    };
+}
+
+tests!(signed_check: i8 i16 i32 i64 i128);
+tests!(unsigned_check: u8 u16 u32 u64 u128);
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index dad46ad88fe19..b14fe0b22c311 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -27,6 +27,7 @@ mod const_from;
 mod dec2flt;
 mod flt2dec;
 mod int_log;
+mod int_sqrt;
 mod ops;
 mod wrapping;
 
diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs
index 506d708d0d2eb..b436fe9929c36 100644
--- a/library/std/src/f128.rs
+++ b/library/std/src/f128.rs
@@ -250,9 +250,14 @@ impl f128 {
     ///
     /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
     /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations
-    /// is not generally guaranteed. See [specification of NaN bit
-    /// patterns](primitive@f32#nan-bit-patterns) for more info.
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs
index 033a3d4500932..b2cd5fae9d04a 100644
--- a/library/std/src/f16.rs
+++ b/library/std/src/f16.rs
@@ -249,9 +249,14 @@ impl f16 {
     ///
     /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
     /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations
-    /// is not generally guaranteed. See [specification of NaN bit
-    /// patterns](primitive@f32#nan-bit-patterns) for more info.
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 35c2a77b5338d..cafbe9761da19 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -228,9 +228,14 @@ impl f32 {
     ///
     /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
     /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations
-    /// is not generally guaranteed. See [specification of NaN bit
-    /// patterns](primitive@f32#nan-bit-patterns) for more info.
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index c177f74a97e15..fba283e3a44bc 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -228,9 +228,14 @@ impl f64 {
     ///
     /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`.
     /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is
-    /// returned. Note, however, that conserving the sign bit on NaN across arithmetical operations
-    /// is not generally guaranteed. See [specification of NaN bit
-    /// patterns](primitive@f32#nan-bit-patterns) for more info.
+    /// returned.
+    ///
+    /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note
+    /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust
+    /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the
+    /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable
+    /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more
+    /// info.
     ///
     /// # Examples
     ///
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index 4ee9fbc314263..a2bb03cd5ac81 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -313,7 +313,7 @@ lint_any!(
     RemoteTestServer, "src/tools/remote-test-server", "remote-test-server";
     Rls, "src/tools/rls", "rls";
     RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer";
-    Rustdoc, "src/tools/rustdoc", "clippy";
+    Rustdoc, "src/librustdoc", "clippy";
     Rustfmt, "src/tools/rustfmt", "rustfmt";
     RustInstaller, "src/tools/rust-installer", "rust-installer";
     Tidy, "src/tools/tidy", "tidy";
diff --git a/src/doc/book b/src/doc/book
index 04bc1396bb857..e7d217be2a75e 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 04bc1396bb857f35b5dda1d773c9571e1f253304
+Subproject commit e7d217be2a75ef1753f0988d6ccaba4d7e376259
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
index aeeb287d41a03..eeba2cb9c37ab 160000
--- a/src/doc/edition-guide
+++ b/src/doc/edition-guide
@@ -1 +1 @@
-Subproject commit aeeb287d41a0332c210da122bea8e0e91844ab3e
+Subproject commit eeba2cb9c37ab74118a4fb5e5233f7397e4a91f8
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
index 019f3928d8b93..ff5d61d56f11e 160000
--- a/src/doc/embedded-book
+++ b/src/doc/embedded-book
@@ -1 +1 @@
-Subproject commit 019f3928d8b939ec71b63722dcc2e46330156441
+Subproject commit ff5d61d56f11e1986bfa9652c6aff7731576c37d
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 6ecf95c5f2bfa..14649f15d232d 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 6ecf95c5f2bfa0e6314dfe282bf775fd1405f7e9
+Subproject commit 14649f15d232d509478206ee9ed5105641aa60d0
diff --git a/src/doc/reference b/src/doc/reference
index 62cd0df95061b..0668397076da3 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 62cd0df95061ba0ac886333f5cd7f3012f149da1
+Subproject commit 0668397076da350c404dadcf07b6cbc433ad3743
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 8f94061936e49..859786c5bc993 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 8f94061936e492159f4f6c09c0f917a7521893ff
+Subproject commit 859786c5bc99301bbc22fc631a5c2b341860da08
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
index 43d83780db545..fa928a6d19e16 160000
--- a/src/doc/rustc-dev-guide
+++ b/src/doc/rustc-dev-guide
@@ -1 +1 @@
-Subproject commit 43d83780db545a1ed6d45773312fc578987e3968
+Subproject commit fa928a6d19e1666d8d811dfe3fd35cdad3b4e459
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index fa23e3e414d90..e5631ba42741a 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -47,7 +47,7 @@ KIND=PATH` where `KIND` may be one of:
   directory.
 - `native` — Only search for native libraries in this directory.
 - `framework` — Only search for macOS frameworks in this directory.
-- `all` — Search for all library kinds in this directory. This is the default
+- `all` — Search for all library kinds in this directory, except frameworks. This is the default
   if `KIND` is not specified.
 
 <a id="option-l-link-lib"></a>
diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock
index 3b859fe98c5ab..1394675a9dc60 100644
--- a/src/tools/rustbook/Cargo.lock
+++ b/src/tools/rustbook/Cargo.lock
@@ -690,6 +690,7 @@ dependencies = [
  "mdbook",
  "once_cell",
  "pathdiff",
+ "pulldown-cmark",
  "regex",
  "semver",
  "serde_json",
diff --git a/tests/run-make/native-lib-alt-naming/native.rs b/tests/run-make/native-lib-alt-naming/native.rs
new file mode 100644
index 0000000000000..6c869e74cd269
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/native.rs
@@ -0,0 +1,2 @@
+#[no_mangle]
+pub extern "C" fn native_lib_alt_naming() {}
diff --git a/tests/run-make/native-lib-alt-naming/rmake.rs b/tests/run-make/native-lib-alt-naming/rmake.rs
new file mode 100644
index 0000000000000..d1ea0fc868767
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/rmake.rs
@@ -0,0 +1,15 @@
+// On MSVC the alternative naming format for static libraries (`libfoo.a`) is accepted in addition
+// to the default format (`foo.lib`).
+
+//REMOVE@ only-msvc
+
+use run_make_support::rustc;
+
+fn main() {
+    // Prepare the native library.
+    rustc().input("native.rs").crate_type("staticlib").output("libnative.a").run();
+
+    // Try to link to it from both a rlib and a bin.
+    rustc().input("rust.rs").crate_type("rlib").arg("-lstatic=native").run();
+    rustc().input("rust.rs").crate_type("bin").arg("-lstatic=native").run();
+}
diff --git a/tests/run-make/native-lib-alt-naming/rust.rs b/tests/run-make/native-lib-alt-naming/rust.rs
new file mode 100644
index 0000000000000..da0f5d925d107
--- /dev/null
+++ b/tests/run-make/native-lib-alt-naming/rust.rs
@@ -0,0 +1 @@
+pub fn main() {}
diff --git a/tests/ui/deriving/deriving-smart-pointer-expanded.rs b/tests/ui/deriving/deriving-smart-pointer-expanded.rs
index b78258c25290e..e48ad3dd4bc6c 100644
--- a/tests/ui/deriving/deriving-smart-pointer-expanded.rs
+++ b/tests/ui/deriving/deriving-smart-pointer-expanded.rs
@@ -20,3 +20,9 @@ where
     data: &'a mut T,
     x: core::marker::PhantomData<X>,
 }
+
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct MyPointerWithoutPointee<'a, T: ?Sized> {
+    ptr: &'a T,
+}
diff --git a/tests/ui/deriving/deriving-smart-pointer-expanded.stdout b/tests/ui/deriving/deriving-smart-pointer-expanded.stdout
index 3c7e719818042..68ef17f2b0547 100644
--- a/tests/ui/deriving/deriving-smart-pointer-expanded.stdout
+++ b/tests/ui/deriving/deriving-smart-pointer-expanded.stdout
@@ -42,3 +42,18 @@ impl<'a, Y, Z: MyTrait<T> + MyTrait<__S>, T: ?Sized + MyTrait<T> +
     MyTrait<__S>> ::core::ops::CoerceUnsized<MyPointer2<'a, Y, Z, __S, X>> for
     MyPointer2<'a, Y, Z, T, X> where Y: MyTrait<T>, Y: MyTrait<__S> {
 }
+
+#[repr(transparent)]
+struct MyPointerWithoutPointee<'a, T: ?Sized> {
+    ptr: &'a T,
+}
+#[automatically_derived]
+impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
+    ::core::ops::DispatchFromDyn<MyPointerWithoutPointee<'a, __S>> for
+    MyPointerWithoutPointee<'a, T> {
+}
+#[automatically_derived]
+impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
+    ::core::ops::CoerceUnsized<MyPointerWithoutPointee<'a, __S>> for
+    MyPointerWithoutPointee<'a, T> {
+}
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.rs b/tests/ui/deriving/deriving-smart-pointer-neg.rs
index 04f52a154fe42..f02fb56130fa7 100644
--- a/tests/ui/deriving/deriving-smart-pointer-neg.rs
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.rs
@@ -9,13 +9,6 @@ enum NotStruct<'a, T: ?Sized> {
     Variant(&'a T),
 }
 
-#[derive(SmartPointer)]
-//~^ ERROR: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
-#[repr(transparent)]
-struct NoPointee<'a, T: ?Sized> {
-    ptr: &'a T,
-}
-
 #[derive(SmartPointer)]
 //~^ ERROR: `SmartPointer` can only be derived on `struct`s with at least one field
 #[repr(transparent)]
@@ -30,6 +23,23 @@ struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
 //~^ ERROR: lifetime parameter `'a` is never used
 //~| ERROR: type parameter `T` is never used
 
+#[derive(SmartPointer)]
+//~^ ERROR: `SmartPointer` can only be derived on `struct`s that are generic over at least one type
+#[repr(transparent)]
+struct NoGeneric<'a>(&'a u8);
+
+#[derive(SmartPointer)]
+//~^ ERROR: exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits
+#[repr(transparent)]
+struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
+    a: (&'a T1, &'a T2),
+}
+
+#[derive(SmartPointer)]
+#[repr(transparent)]
+struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
+//~^ ERROR: only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits
+
 #[derive(SmartPointer)]
 //~^ ERROR: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
 struct NotTransparent<'a, #[pointee] T: ?Sized> {
diff --git a/tests/ui/deriving/deriving-smart-pointer-neg.stderr b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
index 8b0f91d41fb88..e7c2afc8b00c7 100644
--- a/tests/ui/deriving/deriving-smart-pointer-neg.stderr
+++ b/tests/ui/deriving/deriving-smart-pointer-neg.stderr
@@ -6,7 +6,7 @@ LL | #[derive(SmartPointer)]
    |
    = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: At least one generic type should be designated as `#[pointee]` in order to derive `SmartPointer` traits
+error: `SmartPointer` can only be derived on `struct`s with at least one field
   --> $DIR/deriving-smart-pointer-neg.rs:12:10
    |
 LL | #[derive(SmartPointer)]
@@ -22,7 +22,7 @@ LL | #[derive(SmartPointer)]
    |
    = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: `SmartPointer` can only be derived on `struct`s with at least one field
+error: `SmartPointer` can only be derived on `struct`s that are generic over at least one type
   --> $DIR/deriving-smart-pointer-neg.rs:26:10
    |
 LL | #[derive(SmartPointer)]
@@ -30,8 +30,22 @@ LL | #[derive(SmartPointer)]
    |
    = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error: exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits
+  --> $DIR/deriving-smart-pointer-neg.rs:31:10
+   |
+LL | #[derive(SmartPointer)]
+   |          ^^^^^^^^^^^^
+   |
+   = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits
+  --> $DIR/deriving-smart-pointer-neg.rs:40:39
+   |
+LL | struct TooManyPointees<'a, #[pointee] A: ?Sized, #[pointee] B: ?Sized>((&'a A, &'a B));
+   |                                       ^                     ^
+
 error: `SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`
-  --> $DIR/deriving-smart-pointer-neg.rs:33:10
+  --> $DIR/deriving-smart-pointer-neg.rs:43:10
    |
 LL | #[derive(SmartPointer)]
    |          ^^^^^^^^^^^^
@@ -39,13 +53,13 @@ LL | #[derive(SmartPointer)]
    = note: this error originates in the derive macro `SmartPointer` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `derive(SmartPointer)` requires T to be marked `?Sized`
-  --> $DIR/deriving-smart-pointer-neg.rs:41:36
+  --> $DIR/deriving-smart-pointer-neg.rs:51:36
    |
 LL | struct NoMaybeSized<'a, #[pointee] T> {
    |                                    ^
 
 error[E0392]: lifetime parameter `'a` is never used
-  --> $DIR/deriving-smart-pointer-neg.rs:22:16
+  --> $DIR/deriving-smart-pointer-neg.rs:15:16
    |
 LL | struct NoField<'a, #[pointee] T: ?Sized> {}
    |                ^^ unused lifetime parameter
@@ -53,7 +67,7 @@ LL | struct NoField<'a, #[pointee] T: ?Sized> {}
    = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/deriving-smart-pointer-neg.rs:22:31
+  --> $DIR/deriving-smart-pointer-neg.rs:15:31
    |
 LL | struct NoField<'a, #[pointee] T: ?Sized> {}
    |                               ^ unused type parameter
@@ -61,7 +75,7 @@ LL | struct NoField<'a, #[pointee] T: ?Sized> {}
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0392]: lifetime parameter `'a` is never used
-  --> $DIR/deriving-smart-pointer-neg.rs:29:20
+  --> $DIR/deriving-smart-pointer-neg.rs:22:20
    |
 LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
    |                    ^^ unused lifetime parameter
@@ -69,13 +83,13 @@ LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
    = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
 
 error[E0392]: type parameter `T` is never used
-  --> $DIR/deriving-smart-pointer-neg.rs:29:35
+  --> $DIR/deriving-smart-pointer-neg.rs:22:35
    |
 LL | struct NoFieldUnit<'a, #[pointee] T: ?Sized>();
    |                                   ^ unused type parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/threads-sendsync/child-outlives-parent.rs b/tests/ui/threads-sendsync/child-outlives-parent.rs
index 213fd008cd3de..e965bac5713ce 100644
--- a/tests/ui/threads-sendsync/child-outlives-parent.rs
+++ b/tests/ui/threads-sendsync/child-outlives-parent.rs
@@ -6,8 +6,8 @@
 
 use std::thread;
 
-fn child2(_s: String) { }
+fn child2(_s: String) {}
 
 pub fn main() {
-    let _x = thread::spawn(move|| child2("hi".to_string()));
+    let _x = thread::spawn(move || child2("hi".to_string()));
 }
diff --git a/tests/ui/threads-sendsync/clone-with-exterior.rs b/tests/ui/threads-sendsync/clone-with-exterior.rs
index 67790367e27e4..9d5ac4b16aa66 100644
--- a/tests/ui/threads-sendsync/clone-with-exterior.rs
+++ b/tests/ui/threads-sendsync/clone-with-exterior.rs
@@ -7,14 +7,15 @@ use std::thread;
 
 struct Pair {
     a: isize,
-    b: isize
+    b: isize,
 }
 
 pub fn main() {
-    let z: Box<_> = Box::new(Pair { a : 10, b : 12});
+    let z: Box<_> = Box::new(Pair { a: 10, b: 12 });
 
-    thread::spawn(move|| {
+    thread::spawn(move || {
         assert_eq!(z.a, 10);
         assert_eq!(z.b, 12);
-    }).join();
+    })
+    .join();
 }
diff --git a/tests/ui/threads-sendsync/comm.rs b/tests/ui/threads-sendsync/comm.rs
index 0c37fda8a3931..3eb68707e78f1 100644
--- a/tests/ui/threads-sendsync/comm.rs
+++ b/tests/ui/threads-sendsync/comm.rs
@@ -2,12 +2,12 @@
 #![allow(unused_must_use)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel();
-    let t = thread::spawn(move || { child(&tx) });
+    let t = thread::spawn(move || child(&tx));
     let y = rx.recv().unwrap();
     println!("received");
     println!("{}", y);
diff --git a/tests/ui/threads-sendsync/issue-24313.rs b/tests/ui/threads-sendsync/issue-24313.rs
index 1ea862f1e7d6b..99c6c4a5e12de 100644
--- a/tests/ui/threads-sendsync/issue-24313.rs
+++ b/tests/ui/threads-sendsync/issue-24313.rs
@@ -2,14 +2,15 @@
 //@ needs-threads
 //@ ignore-sgx no processes
 
-use std::thread;
-use std::env;
 use std::process::Command;
+use std::{env, thread};
 
 struct Handle(i32);
 
 impl Drop for Handle {
-    fn drop(&mut self) { panic!(); }
+    fn drop(&mut self) {
+        panic!();
+    }
 }
 
 thread_local!(static HANDLE: Handle = Handle(0));
@@ -19,14 +20,15 @@ fn main() {
     if args.len() == 1 {
         let out = Command::new(&args[0]).arg("test").output().unwrap();
         let stderr = std::str::from_utf8(&out.stderr).unwrap();
-        assert!(stderr.contains("explicit panic"),
-                "bad failure message:\n{}\n", stderr);
+        assert!(stderr.contains("explicit panic"), "bad failure message:\n{}\n", stderr);
     } else {
         // TLS dtors are not always run on process exit
         thread::spawn(|| {
             HANDLE.with(|h| {
                 println!("{}", h.0);
             });
-        }).join().unwrap();
+        })
+        .join()
+        .unwrap();
     }
 }
diff --git a/tests/ui/threads-sendsync/issue-29488.rs b/tests/ui/threads-sendsync/issue-29488.rs
index fbbd6b02a067d..5ce27faed7635 100644
--- a/tests/ui/threads-sendsync/issue-29488.rs
+++ b/tests/ui/threads-sendsync/issue-29488.rs
@@ -19,5 +19,7 @@ fn main() {
     thread::spawn(|| {
         FOO.with(|_| {});
         println!("test1");
-    }).join().unwrap();
+    })
+    .join()
+    .unwrap();
 }
diff --git a/tests/ui/threads-sendsync/issue-4446.rs b/tests/ui/threads-sendsync/issue-4446.rs
index aa2de51974b37..5652ad7de55b5 100644
--- a/tests/ui/threads-sendsync/issue-4446.rs
+++ b/tests/ui/threads-sendsync/issue-4446.rs
@@ -9,7 +9,10 @@ pub fn main() {
 
     tx.send("hello, world").unwrap();
 
-    thread::spawn(move|| {
+    thread::spawn(move || {
         println!("{}", rx.recv().unwrap());
-    }).join().ok().unwrap();
+    })
+    .join()
+    .ok()
+    .unwrap();
 }
diff --git a/tests/ui/threads-sendsync/issue-4448.rs b/tests/ui/threads-sendsync/issue-4448.rs
index b8324a8c43fb5..1adebd1e25286 100644
--- a/tests/ui/threads-sendsync/issue-4448.rs
+++ b/tests/ui/threads-sendsync/issue-4448.rs
@@ -7,7 +7,7 @@ use std::thread;
 pub fn main() {
     let (tx, rx) = channel::<&'static str>();
 
-    let t = thread::spawn(move|| {
+    let t = thread::spawn(move || {
         assert_eq!(rx.recv().unwrap(), "hello, world");
     });
 
diff --git a/tests/ui/threads-sendsync/issue-8827.rs b/tests/ui/threads-sendsync/issue-8827.rs
index fa07a4ebc7d6d..57fc87db76869 100644
--- a/tests/ui/threads-sendsync/issue-8827.rs
+++ b/tests/ui/threads-sendsync/issue-8827.rs
@@ -1,12 +1,12 @@
 //@ run-pass
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Receiver};
+use std::thread;
 
 fn periodical(n: isize) -> Receiver<bool> {
     let (chan, port) = channel();
-    thread::spawn(move|| {
+    thread::spawn(move || {
         loop {
             for _ in 1..n {
                 match chan.send(false) {
@@ -16,7 +16,7 @@ fn periodical(n: isize) -> Receiver<bool> {
             }
             match chan.send(true) {
                 Ok(()) => {}
-                Err(..) => break
+                Err(..) => break,
             }
         }
     });
@@ -25,7 +25,7 @@ fn periodical(n: isize) -> Receiver<bool> {
 
 fn integers() -> Receiver<isize> {
     let (chan, port) = channel();
-    thread::spawn(move|| {
+    thread::spawn(move || {
         let mut i = 1;
         loop {
             match chan.send(i) {
@@ -47,7 +47,7 @@ fn main() {
             (_, true, true) => println!("FizzBuzz"),
             (_, true, false) => println!("Fizz"),
             (_, false, true) => println!("Buzz"),
-            (i, false, false) => println!("{}", i)
+            (i, false, false) => println!("{}", i),
         }
     }
 }
diff --git a/tests/ui/threads-sendsync/issue-9396.rs b/tests/ui/threads-sendsync/issue-9396.rs
index 6b5907e5c1d09..b532ddf104dfd 100644
--- a/tests/ui/threads-sendsync/issue-9396.rs
+++ b/tests/ui/threads-sendsync/issue-9396.rs
@@ -3,12 +3,12 @@
 #![allow(deprecated)]
 //@ needs-threads
 
-use std::sync::mpsc::{TryRecvError, channel};
+use std::sync::mpsc::{channel, TryRecvError};
 use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel();
-    let t = thread::spawn(move||{
+    let t = thread::spawn(move || {
         thread::sleep_ms(10);
         tx.send(()).unwrap();
     });
@@ -16,7 +16,7 @@ pub fn main() {
         match rx.try_recv() {
             Ok(()) => break,
             Err(TryRecvError::Empty) => {}
-            Err(TryRecvError::Disconnected) => unreachable!()
+            Err(TryRecvError::Disconnected) => unreachable!(),
         }
     }
     t.join();
diff --git a/tests/ui/threads-sendsync/mpsc_stress.rs b/tests/ui/threads-sendsync/mpsc_stress.rs
index f5354c60bfce9..fe0b47f3a842e 100644
--- a/tests/ui/threads-sendsync/mpsc_stress.rs
+++ b/tests/ui/threads-sendsync/mpsc_stress.rs
@@ -2,18 +2,12 @@
 //@ compile-flags:--test
 //@ needs-threads
 
-use std::sync::mpsc::channel;
-use std::sync::mpsc::TryRecvError;
-use std::sync::mpsc::RecvError;
-use std::sync::mpsc::RecvTimeoutError;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::mpsc::{channel, RecvError, RecvTimeoutError, TryRecvError};
 use std::sync::Arc;
-use std::sync::atomic::AtomicUsize;
-use std::sync::atomic::Ordering;
-
 use std::thread;
 use std::time::Duration;
 
-
 /// Simple thread synchronization utility
 struct Barrier {
     // Not using mutex/condvar for precision
@@ -42,7 +36,6 @@ impl Barrier {
     }
 }
 
-
 fn shared_close_sender_does_not_lose_messages_iter() {
     let (tb, rb) = Barrier::new2();
 
@@ -71,7 +64,6 @@ fn shared_close_sender_does_not_lose_messages() {
     });
 }
 
-
 // https://github.com/rust-lang/rust/issues/39364
 fn concurrent_recv_timeout_and_upgrade_iter() {
     // 1 us
@@ -85,8 +77,8 @@ fn concurrent_recv_timeout_and_upgrade_iter() {
             match rx.recv_timeout(sleep) {
                 Ok(_) => {
                     break;
-                },
-                Err(_) => {},
+                }
+                Err(_) => {}
             }
         }
     });
@@ -105,7 +97,6 @@ fn concurrent_recv_timeout_and_upgrade() {
     });
 }
 
-
 fn concurrent_writes_iter() {
     const THREADS: usize = 4;
     const PER_THR: usize = 100;
diff --git a/tests/ui/threads-sendsync/send-is-not-static-par-for.rs b/tests/ui/threads-sendsync/send-is-not-static-par-for.rs
index b943b0c433da7..dd02166c0fa01 100644
--- a/tests/ui/threads-sendsync/send-is-not-static-par-for.rs
+++ b/tests/ui/threads-sendsync/send-is-not-static-par-for.rs
@@ -1,12 +1,13 @@
 //@ run-pass
 #![allow(unused_imports)]
-use std::thread;
 use std::sync::Mutex;
+use std::thread;
 
 fn par_for<I, F>(iter: I, f: F)
-    where I: Iterator,
-          I::Item: Send,
-          F: Fn(I::Item) + Sync
+where
+    I: Iterator,
+    I::Item: Send,
+    F: Fn(I::Item) + Sync,
 {
     for item in iter {
         f(item)
@@ -15,9 +16,7 @@ fn par_for<I, F>(iter: I, f: F)
 
 fn sum(x: &[i32]) {
     let sum_lengths = Mutex::new(0);
-    par_for(x.windows(4), |x| {
-        *sum_lengths.lock().unwrap() += x.len()
-    });
+    par_for(x.windows(4), |x| *sum_lengths.lock().unwrap() += x.len());
 
     assert_eq!(*sum_lengths.lock().unwrap(), (x.len() - 3) * 4);
 }
@@ -26,9 +25,7 @@ fn main() {
     let mut elements = [0; 20];
 
     // iterators over references into this stack frame
-    par_for(elements.iter_mut().enumerate(), |(i, x)| {
-        *x = i as i32
-    });
+    par_for(elements.iter_mut().enumerate(), |(i, x)| *x = i as i32);
 
     sum(&elements)
 }
diff --git a/tests/ui/threads-sendsync/send-resource.rs b/tests/ui/threads-sendsync/send-resource.rs
index 3e1532b3132ee..c02a3717d3d75 100644
--- a/tests/ui/threads-sendsync/send-resource.rs
+++ b/tests/ui/threads-sendsync/send-resource.rs
@@ -6,11 +6,11 @@
 //@ pretty-expanded FIXME #23616
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::channel;
+use std::thread;
 
 struct test {
-  f: isize,
+    f: isize,
 }
 
 impl Drop for test {
@@ -18,15 +18,13 @@ impl Drop for test {
 }
 
 fn test(f: isize) -> test {
-    test {
-        f: f
-    }
+    test { f: f }
 }
 
 pub fn main() {
     let (tx, rx) = channel();
 
-    let t = thread::spawn(move|| {
+    let t = thread::spawn(move || {
         let (tx2, rx2) = channel();
         tx.send(tx2).unwrap();
 
diff --git a/tests/ui/threads-sendsync/send-type-inference.rs b/tests/ui/threads-sendsync/send-type-inference.rs
index 287b3d567aec8..7608c19b5758e 100644
--- a/tests/ui/threads-sendsync/send-type-inference.rs
+++ b/tests/ui/threads-sendsync/send-type-inference.rs
@@ -9,11 +9,11 @@ use std::sync::mpsc::{channel, Sender};
 // tests that ctrl's type gets inferred properly
 struct Command<K, V> {
     key: K,
-    val: V
+    val: V,
 }
 
-fn cache_server<K:Send+'static,V:Send+'static>(mut tx: Sender<Sender<Command<K, V>>>) {
+fn cache_server<K: Send + 'static, V: Send + 'static>(mut tx: Sender<Sender<Command<K, V>>>) {
     let (tx1, _rx) = channel();
     tx.send(tx1);
 }
-pub fn main() { }
+pub fn main() {}
diff --git a/tests/ui/threads-sendsync/send_str_hashmap.rs b/tests/ui/threads-sendsync/send_str_hashmap.rs
index 9cbb0bed4473f..2675b16219094 100644
--- a/tests/ui/threads-sendsync/send_str_hashmap.rs
+++ b/tests/ui/threads-sendsync/send_str_hashmap.rs
@@ -1,9 +1,7 @@
 //@ run-pass
-use std::collections::HashMap;
 use std::borrow::Cow;
-
-use std::borrow::Cow::Borrowed as B;
-use std::borrow::Cow::Owned as O;
+use std::borrow::Cow::{Borrowed as B, Owned as O};
+use std::collections::HashMap;
 
 type SendStr = Cow<'static, str>;
 
diff --git a/tests/ui/threads-sendsync/send_str_treemap.rs b/tests/ui/threads-sendsync/send_str_treemap.rs
index cc1f560f69b2f..3e0eace339953 100644
--- a/tests/ui/threads-sendsync/send_str_treemap.rs
+++ b/tests/ui/threads-sendsync/send_str_treemap.rs
@@ -1,8 +1,7 @@
 //@ run-pass
-use std::collections::BTreeMap;
 use std::borrow::Cow;
-
-use std::borrow::Cow::{Owned as O, Borrowed as B};
+use std::borrow::Cow::{Borrowed as B, Owned as O};
+use std::collections::BTreeMap;
 
 type SendStr = Cow<'static, str>;
 
@@ -51,8 +50,8 @@ fn main() {
     assert_eq!(map.get(&O("def".to_string())), Some(&d));
 
     assert!(map.remove(&B("foo")).is_some());
-    assert_eq!(map.into_iter().map(|(k, v)| format!("{}{}", k, v))
-                              .collect::<Vec<String>>()
-                              .concat(),
-               "abc50bcd51cde52def53".to_string());
+    assert_eq!(
+        map.into_iter().map(|(k, v)| format!("{}{}", k, v)).collect::<Vec<String>>().concat(),
+        "abc50bcd51cde52def53".to_string()
+    );
 }
diff --git a/tests/ui/threads-sendsync/sendable-class.rs b/tests/ui/threads-sendsync/sendable-class.rs
index 3ee1b60a04a99..8e5e76d826a06 100644
--- a/tests/ui/threads-sendsync/sendable-class.rs
+++ b/tests/ui/threads-sendsync/sendable-class.rs
@@ -11,15 +11,12 @@
 use std::sync::mpsc::channel;
 
 struct foo {
-  i: isize,
-  j: char,
+    i: isize,
+    j: char,
 }
 
-fn foo(i:isize, j: char) -> foo {
-    foo {
-        i: i,
-        j: j
-    }
+fn foo(i: isize, j: char) -> foo {
+    foo { i: i, j: j }
 }
 
 pub fn main() {
diff --git a/tests/ui/threads-sendsync/sendfn-is-a-block.rs b/tests/ui/threads-sendsync/sendfn-is-a-block.rs
index f01b440424aaf..9afa1c47b65d9 100644
--- a/tests/ui/threads-sendsync/sendfn-is-a-block.rs
+++ b/tests/ui/threads-sendsync/sendfn-is-a-block.rs
@@ -1,7 +1,9 @@
 //@ run-pass
 
-
-fn test<F>(f: F) -> usize where F: FnOnce(usize) -> usize {
+fn test<F>(f: F) -> usize
+where
+    F: FnOnce(usize) -> usize,
+{
     return f(22);
 }
 
diff --git a/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
index 63cf3ff40490d..79a71e968f98b 100644
--- a/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
+++ b/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
@@ -3,19 +3,24 @@
 
 use std::thread;
 
-pub fn main() { test05(); }
+pub fn main() {
+    test05();
+}
 
-fn test05_start<F:FnOnce(isize)>(f: F) {
+fn test05_start<F: FnOnce(isize)>(f: F) {
     f(22);
 }
 
 fn test05() {
     let three: Box<_> = Box::new(3);
-    let fn_to_send = move|n:isize| {
+    let fn_to_send = move |n: isize| {
         println!("{}", *three + n); // will copy x into the closure
         assert_eq!(*three, 3);
     };
-    thread::spawn(move|| {
+    thread::spawn(move || {
         test05_start(fn_to_send);
-    }).join().ok().unwrap();
+    })
+    .join()
+    .ok()
+    .unwrap();
 }
diff --git a/tests/ui/threads-sendsync/spawn-fn.rs b/tests/ui/threads-sendsync/spawn-fn.rs
index e4d83b53f3cfa..558c2d515aace 100644
--- a/tests/ui/threads-sendsync/spawn-fn.rs
+++ b/tests/ui/threads-sendsync/spawn-fn.rs
@@ -10,9 +10,9 @@ fn x(s: String, n: isize) {
 }
 
 pub fn main() {
-    let t1 = thread::spawn(|| x("hello from first spawned fn".to_string(), 65) );
-    let t2 = thread::spawn(|| x("hello from second spawned fn".to_string(), 66) );
-    let t3 = thread::spawn(|| x("hello from third spawned fn".to_string(), 67) );
+    let t1 = thread::spawn(|| x("hello from first spawned fn".to_string(), 65));
+    let t2 = thread::spawn(|| x("hello from second spawned fn".to_string(), 66));
+    let t3 = thread::spawn(|| x("hello from third spawned fn".to_string(), 67));
     let mut i = 30;
     while i > 0 {
         i = i - 1;
diff --git a/tests/ui/threads-sendsync/spawn-types.rs b/tests/ui/threads-sendsync/spawn-types.rs
index 2a7a9e2f49732..e53385aa7149b 100644
--- a/tests/ui/threads-sendsync/spawn-types.rs
+++ b/tests/ui/threads-sendsync/spawn-types.rs
@@ -4,13 +4,13 @@
 //@ needs-threads
 
 /*
-  Make sure we can spawn tasks that take different types of
-  parameters. This is based on a test case for #520 provided by Rob
-  Arnold.
- */
+ Make sure we can spawn tasks that take different types of
+ parameters. This is based on a test case for #520 provided by Rob
+ Arnold.
+*/
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
 type ctx = Sender<isize>;
 
@@ -20,6 +20,6 @@ fn iotask(_tx: &ctx, ip: String) {
 
 pub fn main() {
     let (tx, _rx) = channel::<isize>();
-    let t = thread::spawn(move|| iotask(&tx, "localhost".to_string()) );
+    let t = thread::spawn(move || iotask(&tx, "localhost".to_string()));
     t.join().ok().unwrap();
 }
diff --git a/tests/ui/threads-sendsync/spawn.rs b/tests/ui/threads-sendsync/spawn.rs
index c7b344b9f7581..c9f7c40ddb886 100644
--- a/tests/ui/threads-sendsync/spawn.rs
+++ b/tests/ui/threads-sendsync/spawn.rs
@@ -4,7 +4,10 @@
 use std::thread;
 
 pub fn main() {
-    thread::spawn(move|| child(10)).join().ok().unwrap();
+    thread::spawn(move || child(10)).join().ok().unwrap();
 }
 
-fn child(i: isize) { println!("{}", i); assert_eq!(i, 10); }
+fn child(i: isize) {
+    println!("{}", i);
+    assert_eq!(i, 10);
+}
diff --git a/tests/ui/threads-sendsync/spawn2.rs b/tests/ui/threads-sendsync/spawn2.rs
index 8278fec1885b9..02dff2a3483dd 100644
--- a/tests/ui/threads-sendsync/spawn2.rs
+++ b/tests/ui/threads-sendsync/spawn2.rs
@@ -4,7 +4,7 @@
 use std::thread;
 
 pub fn main() {
-    let t = thread::spawn(move|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) );
+    let t = thread::spawn(move || child((10, 20, 30, 40, 50, 60, 70, 80, 90)));
     t.join().ok().unwrap(); // forget Err value, since it doesn't implement Debug
 }
 
diff --git a/tests/ui/threads-sendsync/sync-send-in-std.rs b/tests/ui/threads-sendsync/sync-send-in-std.rs
index 3a97cbb0c6843..ddf026236a8ed 100644
--- a/tests/ui/threads-sendsync/sync-send-in-std.rs
+++ b/tests/ui/threads-sendsync/sync-send-in-std.rs
@@ -6,8 +6,16 @@
 
 use std::net::ToSocketAddrs;
 
-fn is_sync<T>(_: T) where T: Sync {}
-fn is_send<T>(_: T) where T: Send {}
+fn is_sync<T>(_: T)
+where
+    T: Sync,
+{
+}
+fn is_send<T>(_: T)
+where
+    T: Send,
+{
+}
 
 macro_rules! all_sync_send {
     ($ctor:expr, $($iter:ident),+) => ({
diff --git a/tests/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs b/tests/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs
index 3b8fdb60acf5f..51d5e294b38aa 100644
--- a/tests/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs
+++ b/tests/ui/threads-sendsync/sync-send-iterators-in-libcollections.rs
@@ -3,18 +3,20 @@
 #![allow(warnings)]
 #![feature(drain, collections_bound, btree_range)]
 
-use std::collections::BinaryHeap;
-use std::collections::{BTreeMap, BTreeSet};
-use std::collections::LinkedList;
-use std::collections::VecDeque;
-use std::collections::HashMap;
-use std::collections::HashSet;
-
+use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
 use std::mem;
 use std::ops::Bound::Included;
 
-fn is_sync<T>(_: T) where T: Sync {}
-fn is_send<T>(_: T) where T: Send {}
+fn is_sync<T>(_: T)
+where
+    T: Sync,
+{
+}
+fn is_send<T>(_: T)
+where
+    T: Send,
+{
+}
 
 macro_rules! all_sync_send {
     ($ctor:expr, $($iter:ident),+) => ({
diff --git a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
index 4c77b5d2ad889..512c81a85fcaf 100644
--- a/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
+++ b/tests/ui/threads-sendsync/sync-send-iterators-in-libcore.rs
@@ -5,8 +5,16 @@
 
 use std::iter::{empty, once, repeat};
 
-fn is_sync<T>(_: T) where T: Sync {}
-fn is_send<T>(_: T) where T: Send {}
+fn is_sync<T>(_: T)
+where
+    T: Sync,
+{
+}
+fn is_send<T>(_: T)
+where
+    T: Send,
+{
+}
 
 macro_rules! all_sync_send {
     ($ctor:expr, $iter:ident) => ({
@@ -43,12 +51,12 @@ macro_rules! all_sync_send_mutable_ref {
 }
 
 macro_rules! is_sync_send {
-    ($ctor:expr) => ({
+    ($ctor:expr) => {{
         let x = $ctor;
         is_sync(x);
         let y = $ctor;
         is_send(y);
-    })
+    }};
 }
 
 fn main() {
@@ -63,24 +71,26 @@ fn main() {
 
     let a = [1];
     let b = [2];
-    all_sync_send!(a.iter(),
-                   cloned,
-                   cycle,
-                   chain([2].iter()),
-                   zip([2].iter()),
-                   map(|_| 1),
-                   filter(|_| true),
-                   filter_map(|_| Some(1)),
-                   enumerate,
-                   peekable,
-                   skip_while(|_| true),
-                   take_while(|_| true),
-                   skip(1),
-                   take(1),
-                   scan(1, |_, _| Some(1)),
-                   flat_map(|_| b.iter()),
-                   fuse,
-                   inspect(|_| ()));
+    all_sync_send!(
+        a.iter(),
+        cloned,
+        cycle,
+        chain([2].iter()),
+        zip([2].iter()),
+        map(|_| 1),
+        filter(|_| true),
+        filter_map(|_| Some(1)),
+        enumerate,
+        peekable,
+        skip_while(|_| true),
+        take_while(|_| true),
+        skip(1),
+        take(1),
+        scan(1, |_, _| Some(1)),
+        flat_map(|_| b.iter()),
+        fuse,
+        inspect(|_| ())
+    );
 
     is_sync_send!((1..).step_by(2));
     is_sync_send!((1..2).step_by(2));
diff --git a/tests/ui/threads-sendsync/task-comm-0.rs b/tests/ui/threads-sendsync/task-comm-0.rs
index 50f2b59189481..c4fe36e770d17 100644
--- a/tests/ui/threads-sendsync/task-comm-0.rs
+++ b/tests/ui/threads-sendsync/task-comm-0.rs
@@ -2,12 +2,14 @@
 #![allow(unused_must_use)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
-pub fn main() { test05(); }
+pub fn main() {
+    test05();
+}
 
-fn test05_start(tx : &Sender<isize>) {
+fn test05_start(tx: &Sender<isize>) {
     tx.send(10).unwrap();
     println!("sent 10");
     tx.send(20).unwrap();
@@ -18,7 +20,7 @@ fn test05_start(tx : &Sender<isize>) {
 
 fn test05() {
     let (tx, rx) = channel();
-    let t = thread::spawn(move|| { test05_start(&tx) });
+    let t = thread::spawn(move || test05_start(&tx));
     let mut value: isize = rx.recv().unwrap();
     println!("{}", value);
     value = rx.recv().unwrap();
diff --git a/tests/ui/threads-sendsync/task-comm-1.rs b/tests/ui/threads-sendsync/task-comm-1.rs
index 41592bd916b4e..75d9e887cd124 100644
--- a/tests/ui/threads-sendsync/task-comm-1.rs
+++ b/tests/ui/threads-sendsync/task-comm-1.rs
@@ -4,11 +4,15 @@
 
 use std::thread;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
-fn start() { println!("Started / Finished task."); }
+fn start() {
+    println!("Started / Finished task.");
+}
 
 fn test00() {
-    thread::spawn(move|| start() ).join();
+    thread::spawn(move || start()).join();
     println!("Completing.");
 }
diff --git a/tests/ui/threads-sendsync/task-comm-10.rs b/tests/ui/threads-sendsync/task-comm-10.rs
index 844652c0dde49..44c31aeed7765 100644
--- a/tests/ui/threads-sendsync/task-comm-10.rs
+++ b/tests/ui/threads-sendsync/task-comm-10.rs
@@ -3,8 +3,8 @@
 #![allow(unused_mut)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
 fn start(tx: &Sender<Sender<String>>) {
     let (tx2, rx) = channel();
@@ -22,7 +22,7 @@ fn start(tx: &Sender<Sender<String>>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let child = thread::spawn(move|| { start(&tx) });
+    let child = thread::spawn(move || start(&tx));
 
     let mut c = rx.recv().unwrap();
     c.send("A".to_string()).unwrap();
diff --git a/tests/ui/threads-sendsync/task-comm-11.rs b/tests/ui/threads-sendsync/task-comm-11.rs
index 199082fda96de..7c349c716fa35 100644
--- a/tests/ui/threads-sendsync/task-comm-11.rs
+++ b/tests/ui/threads-sendsync/task-comm-11.rs
@@ -13,9 +13,7 @@ fn start(tx: &Sender<Sender<isize>>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let child = thread::spawn(move|| {
-        start(&tx)
-    });
+    let child = thread::spawn(move || start(&tx));
     let _tx = rx.recv().unwrap();
     child.join();
 }
diff --git a/tests/ui/threads-sendsync/task-comm-12.rs b/tests/ui/threads-sendsync/task-comm-12.rs
index 7be7ec4c988b1..95c5d5c45efc6 100644
--- a/tests/ui/threads-sendsync/task-comm-12.rs
+++ b/tests/ui/threads-sendsync/task-comm-12.rs
@@ -5,15 +5,17 @@
 
 use std::thread;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
-fn start(_task_number: isize) { println!("Started / Finished task."); }
+fn start(_task_number: isize) {
+    println!("Started / Finished task.");
+}
 
 fn test00() {
     let i: isize = 0;
-    let mut result = thread::spawn(move|| {
-        start(i)
-    });
+    let mut result = thread::spawn(move || start(i));
 
     // Sleep long enough for the thread to finish.
     let mut i = 0_usize;
diff --git a/tests/ui/threads-sendsync/task-comm-13.rs b/tests/ui/threads-sendsync/task-comm-13.rs
index 414e6e0db76da..88ea3cbff0815 100644
--- a/tests/ui/threads-sendsync/task-comm-13.rs
+++ b/tests/ui/threads-sendsync/task-comm-13.rs
@@ -7,12 +7,15 @@ use std::thread;
 
 fn start(tx: &Sender<isize>, start: isize, number_of_messages: isize) {
     let mut i: isize = 0;
-    while i< number_of_messages { tx.send(start + i).unwrap(); i += 1; }
+    while i < number_of_messages {
+        tx.send(start + i).unwrap();
+        i += 1;
+    }
 }
 
 pub fn main() {
     println!("Check that we don't deadlock.");
     let (tx, rx) = channel();
-    let _ = thread::spawn(move|| { start(&tx, 0, 10) }).join();
+    let _ = thread::spawn(move || start(&tx, 0, 10)).join();
     println!("Joined task");
 }
diff --git a/tests/ui/threads-sendsync/task-comm-14.rs b/tests/ui/threads-sendsync/task-comm-14.rs
index 54deb221294ae..ff4ffd2968da3 100644
--- a/tests/ui/threads-sendsync/task-comm-14.rs
+++ b/tests/ui/threads-sendsync/task-comm-14.rs
@@ -13,7 +13,10 @@ pub fn main() {
     while (i > 0) {
         println!("{}", i);
         let tx = tx.clone();
-        thread::spawn({let i = i; move|| { child(i, &tx) }});
+        thread::spawn({
+            let i = i;
+            move || child(i, &tx)
+        });
         i = i - 1;
     }
 
diff --git a/tests/ui/threads-sendsync/task-comm-15.rs b/tests/ui/threads-sendsync/task-comm-15.rs
index f487bf3cc84b3..1308446893b86 100644
--- a/tests/ui/threads-sendsync/task-comm-15.rs
+++ b/tests/ui/threads-sendsync/task-comm-15.rs
@@ -20,9 +20,7 @@ pub fn main() {
     // the child's point of view the receiver may die. We should
     // drop messages on the floor in this case, and not crash!
     let (tx, rx) = channel();
-    let t = thread::spawn(move|| {
-        start(&tx, 10)
-    });
+    let t = thread::spawn(move || start(&tx, 10));
     rx.recv();
     t.join();
 }
diff --git a/tests/ui/threads-sendsync/task-comm-16.rs b/tests/ui/threads-sendsync/task-comm-16.rs
index 3b0fec11acd1b..e76f7bedc93f1 100644
--- a/tests/ui/threads-sendsync/task-comm-16.rs
+++ b/tests/ui/threads-sendsync/task-comm-16.rs
@@ -3,15 +3,19 @@
 #![allow(unused_parens)]
 #![allow(non_camel_case_types)]
 
-use std::sync::mpsc::channel;
 use std::cmp;
+use std::sync::mpsc::channel;
 
 // Tests of ports and channels on various types
 fn test_rec() {
-    struct R {val0: isize, val1: u8, val2: char}
+    struct R {
+        val0: isize,
+        val1: u8,
+        val2: char,
+    }
 
     let (tx, rx) = channel();
-    let r0: R = R {val0: 0, val1: 1, val2: '2'};
+    let r0: R = R { val0: 0, val1: 1, val2: '2' };
     tx.send(r0).unwrap();
     let mut r1: R;
     r1 = rx.recv().unwrap();
@@ -45,34 +49,29 @@ fn test_str() {
 enum t {
     tag1,
     tag2(isize),
-    tag3(isize, u8, char)
+    tag3(isize, u8, char),
 }
 
 impl cmp::PartialEq for t {
     fn eq(&self, other: &t) -> bool {
         match *self {
-            t::tag1 => {
-                match (*other) {
-                    t::tag1 => true,
-                    _ => false
-                }
-            }
-            t::tag2(e0a) => {
-                match (*other) {
-                    t::tag2(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            t::tag3(e0a, e1a, e2a) => {
-                match (*other) {
-                    t::tag3(e0b, e1b, e2b) =>
-                        e0a == e0b && e1a == e1b && e2a == e2b,
-                    _ => false
-                }
-            }
+            t::tag1 => match (*other) {
+                t::tag1 => true,
+                _ => false,
+            },
+            t::tag2(e0a) => match (*other) {
+                t::tag2(e0b) => e0a == e0b,
+                _ => false,
+            },
+            t::tag3(e0a, e1a, e2a) => match (*other) {
+                t::tag3(e0b, e1b, e2b) => e0a == e0b && e1a == e1b && e2a == e2b,
+                _ => false,
+            },
         }
     }
-    fn ne(&self, other: &t) -> bool { !(*self).eq(other) }
+    fn ne(&self, other: &t) -> bool {
+        !(*self).eq(other)
+    }
 }
 
 fn test_tag() {
diff --git a/tests/ui/threads-sendsync/task-comm-17.rs b/tests/ui/threads-sendsync/task-comm-17.rs
index 687322d4dc963..a545beee59913 100644
--- a/tests/ui/threads-sendsync/task-comm-17.rs
+++ b/tests/ui/threads-sendsync/task-comm-17.rs
@@ -9,9 +9,8 @@
 
 use std::thread;
 
-fn f() {
-}
+fn f() {}
 
 pub fn main() {
-    thread::spawn(move|| f() ).join();
+    thread::spawn(move || f()).join();
 }
diff --git a/tests/ui/threads-sendsync/task-comm-3.rs b/tests/ui/threads-sendsync/task-comm-3.rs
index 26f3eaf9dc6c4..565d97596c76b 100644
--- a/tests/ui/threads-sendsync/task-comm-3.rs
+++ b/tests/ui/threads-sendsync/task-comm-3.rs
@@ -2,10 +2,13 @@
 #![allow(unused_must_use)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
-pub fn main() { println!("===== WITHOUT THREADS ====="); test00(); }
+pub fn main() {
+    println!("===== WITHOUT THREADS =====");
+    test00();
+}
 
 fn test00_start(ch: &Sender<isize>, message: isize, count: isize) {
     println!("Starting test00_start");
@@ -34,9 +37,7 @@ fn test00() {
         let tx = tx.clone();
         results.push(thread::spawn({
             let i = i;
-            move|| {
-                test00_start(&tx, i, number_of_messages)
-            }
+            move || test00_start(&tx, i, number_of_messages)
         }));
         i = i + 1;
     }
@@ -53,7 +54,9 @@ fn test00() {
     }
 
     // Join spawned threads...
-    for r in results { r.join(); }
+    for r in results {
+        r.join();
+    }
 
     println!("Completed: Final number is: ");
     println!("{}", sum);
diff --git a/tests/ui/threads-sendsync/task-comm-4.rs b/tests/ui/threads-sendsync/task-comm-4.rs
index 1210cee558211..6223f6a1ded11 100644
--- a/tests/ui/threads-sendsync/task-comm-4.rs
+++ b/tests/ui/threads-sendsync/task-comm-4.rs
@@ -3,7 +3,9 @@
 
 use std::sync::mpsc::channel;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
 fn test00() {
     let mut r: isize = 0;
diff --git a/tests/ui/threads-sendsync/task-comm-5.rs b/tests/ui/threads-sendsync/task-comm-5.rs
index e07aa18c24dff..e008b28f56ca6 100644
--- a/tests/ui/threads-sendsync/task-comm-5.rs
+++ b/tests/ui/threads-sendsync/task-comm-5.rs
@@ -2,7 +2,9 @@
 
 use std::sync::mpsc::channel;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
 fn test00() {
     let _r: isize = 0;
@@ -10,8 +12,14 @@ fn test00() {
     let (tx, rx) = channel();
     let number_of_messages: isize = 1000;
     let mut i: isize = 0;
-    while i < number_of_messages { tx.send(i + 0).unwrap(); i += 1; }
+    while i < number_of_messages {
+        tx.send(i + 0).unwrap();
+        i += 1;
+    }
     i = 0;
-    while i < number_of_messages { sum += rx.recv().unwrap(); i += 1; }
+    while i < number_of_messages {
+        sum += rx.recv().unwrap();
+        i += 1;
+    }
     assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
 }
diff --git a/tests/ui/threads-sendsync/task-comm-6.rs b/tests/ui/threads-sendsync/task-comm-6.rs
index 6a7dea63993d0..60697c908af47 100644
--- a/tests/ui/threads-sendsync/task-comm-6.rs
+++ b/tests/ui/threads-sendsync/task-comm-6.rs
@@ -4,7 +4,9 @@
 
 use std::sync::mpsc::channel;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
 fn test00() {
     let mut r: isize = 0;
@@ -38,5 +40,4 @@ fn test00() {
     assert_eq!(sum, 1998000);
     // assert (sum == 4 * ((number_of_messages *
     //                   (number_of_messages - 1)) / 2));
-
 }
diff --git a/tests/ui/threads-sendsync/task-comm-7.rs b/tests/ui/threads-sendsync/task-comm-7.rs
index d9b322daa66bf..bb59e4b4a722a 100644
--- a/tests/ui/threads-sendsync/task-comm-7.rs
+++ b/tests/ui/threads-sendsync/task-comm-7.rs
@@ -6,12 +6,16 @@
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
-fn test00_start(c: &Sender<isize>, start: isize,
-                number_of_messages: isize) {
+fn test00_start(c: &Sender<isize>, start: isize, number_of_messages: isize) {
     let mut i: isize = 0;
-    while i < number_of_messages { c.send(start + i).unwrap(); i += 1; }
+    while i < number_of_messages {
+        c.send(start + i).unwrap();
+        i += 1;
+    }
 }
 
 fn test00() {
@@ -21,19 +25,19 @@ fn test00() {
     let number_of_messages: isize = 10;
 
     let tx2 = tx.clone();
-    let t1 = thread::spawn(move|| {
+    let t1 = thread::spawn(move || {
         test00_start(&tx2, number_of_messages * 0, number_of_messages);
     });
     let tx2 = tx.clone();
-    let t2 = thread::spawn(move|| {
+    let t2 = thread::spawn(move || {
         test00_start(&tx2, number_of_messages * 1, number_of_messages);
     });
     let tx2 = tx.clone();
-    let t3 = thread::spawn(move|| {
+    let t3 = thread::spawn(move || {
         test00_start(&tx2, number_of_messages * 2, number_of_messages);
     });
     let tx2 = tx.clone();
-    let t4 = thread::spawn(move|| {
+    let t4 = thread::spawn(move || {
         test00_start(&tx2, number_of_messages * 3, number_of_messages);
     });
 
diff --git a/tests/ui/threads-sendsync/task-comm-9.rs b/tests/ui/threads-sendsync/task-comm-9.rs
index 3e617e4a40c28..2e1f3cb673aa3 100644
--- a/tests/ui/threads-sendsync/task-comm-9.rs
+++ b/tests/ui/threads-sendsync/task-comm-9.rs
@@ -2,14 +2,19 @@
 #![allow(unused_must_use)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::{channel, Sender};
+use std::thread;
 
-pub fn main() { test00(); }
+pub fn main() {
+    test00();
+}
 
 fn test00_start(c: &Sender<isize>, number_of_messages: isize) {
     let mut i: isize = 0;
-    while i < number_of_messages { c.send(i + 0).unwrap(); i += 1; }
+    while i < number_of_messages {
+        c.send(i + 0).unwrap();
+        i += 1;
+    }
 }
 
 fn test00() {
@@ -18,7 +23,7 @@ fn test00() {
     let (tx, rx) = channel();
     let number_of_messages: isize = 10;
 
-    let result = thread::spawn(move|| {
+    let result = thread::spawn(move || {
         test00_start(&tx, number_of_messages);
     });
 
diff --git a/tests/ui/threads-sendsync/task-life-0.rs b/tests/ui/threads-sendsync/task-life-0.rs
index d3eca5d371fb8..f08a281e76c6d 100644
--- a/tests/ui/threads-sendsync/task-life-0.rs
+++ b/tests/ui/threads-sendsync/task-life-0.rs
@@ -6,9 +6,7 @@
 use std::thread;
 
 pub fn main() {
-    thread::spawn(move|| child("Hello".to_string()) ).join();
+    thread::spawn(move || child("Hello".to_string())).join();
 }
 
-fn child(_s: String) {
-
-}
+fn child(_s: String) {}
diff --git a/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs b/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
index ea1c6a9b1081b..07d1a3d5c36ef 100644
--- a/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
+++ b/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
@@ -2,8 +2,8 @@
 #![allow(unused_must_use)]
 //@ needs-threads
 
-use std::thread;
 use std::sync::mpsc::channel;
+use std::thread;
 
 pub fn main() {
     let (tx, rx) = channel::<usize>();
diff --git a/tests/ui/threads-sendsync/task-stderr.rs b/tests/ui/threads-sendsync/task-stderr.rs
index cad10c7a7922c..3934084e02a0a 100644
--- a/tests/ui/threads-sendsync/task-stderr.rs
+++ b/tests/ui/threads-sendsync/task-stderr.rs
@@ -4,20 +4,21 @@
 
 #![feature(internal_output_capture)]
 
-use std::io;
-use std::str;
 use std::sync::{Arc, Mutex};
-use std::thread;
+use std::{io, str, thread};
 
 fn main() {
     let data = Arc::new(Mutex::new(Vec::new()));
-    let res = thread::Builder::new().spawn({
-        let data = data.clone();
-        move || {
-            io::set_output_capture(Some(data));
-            panic!("Hello, world!")
-        }
-    }).unwrap().join();
+    let res = thread::Builder::new()
+        .spawn({
+            let data = data.clone();
+            move || {
+                io::set_output_capture(Some(data));
+                panic!("Hello, world!")
+            }
+        })
+        .unwrap()
+        .join();
     assert!(res.is_err());
 
     let output = data.lock().unwrap();
diff --git a/tests/ui/threads-sendsync/tcp-stress.rs b/tests/ui/threads-sendsync/tcp-stress.rs
index 429a465731408..b2f76a55fb976 100644
--- a/tests/ui/threads-sendsync/tcp-stress.rs
+++ b/tests/ui/threads-sendsync/tcp-stress.rs
@@ -8,14 +8,14 @@ use std::io::prelude::*;
 use std::net::{TcpListener, TcpStream};
 use std::process;
 use std::sync::mpsc::channel;
-use std::time::Duration;
 use std::thread::{self, Builder};
+use std::time::Duration;
 
 const TARGET_CNT: usize = 200;
 
 fn main() {
     // This test has a chance to time out, try to not let it time out
-    thread::spawn(move|| -> () {
+    thread::spawn(move || -> () {
         thread::sleep(Duration::from_secs(30));
         process::exit(1);
     });
@@ -38,12 +38,12 @@ fn main() {
     let mut spawned_cnt = 0;
     for _ in 0..TARGET_CNT {
         let tx = tx.clone();
-        let res = Builder::new().stack_size(64 * 1024).spawn(move|| {
+        let res = Builder::new().stack_size(64 * 1024).spawn(move || {
             match TcpStream::connect(addr) {
                 Ok(mut stream) => {
                     let _ = stream.write(&[1]);
                     let _ = stream.read(&mut [0]);
-                },
+                }
                 Err(..) => {}
             }
             tx.send(()).unwrap();
diff --git a/tests/ui/threads-sendsync/threads.rs b/tests/ui/threads-sendsync/threads.rs
index f3ed7890364b5..ad4e4774ea058 100644
--- a/tests/ui/threads-sendsync/threads.rs
+++ b/tests/ui/threads-sendsync/threads.rs
@@ -7,10 +7,16 @@ use std::thread;
 pub fn main() {
     let mut i = 10;
     while i > 0 {
-        thread::spawn({let i = i; move|| child(i)}).join();
+        thread::spawn({
+            let i = i;
+            move || child(i)
+        })
+        .join();
         i = i - 1;
     }
     println!("main thread exiting");
 }
 
-fn child(x: isize) { println!("{}", x); }
+fn child(x: isize) {
+    println!("{}", x);
+}
diff --git a/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
index 8417665941232..983028681cde8 100644
--- a/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
+++ b/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
@@ -8,7 +8,9 @@ struct Foo;
 
 impl Drop for Foo {
     fn drop(&mut self) {
-        unsafe { HIT = true; }
+        unsafe {
+            HIT = true;
+        }
     }
 }
 
@@ -17,6 +19,8 @@ thread_local!(static FOO: Foo = Foo);
 fn main() {
     std::thread::spawn(|| {
         FOO.with(|_| {});
-    }).join().unwrap();
+    })
+    .join()
+    .unwrap();
     assert!(unsafe { HIT });
 }
diff --git a/tests/ui/threads-sendsync/tls-init-on-init.rs b/tests/ui/threads-sendsync/tls-init-on-init.rs
index fd764669e7f61..1cae19aae86c7 100644
--- a/tests/ui/threads-sendsync/tls-init-on-init.rs
+++ b/tests/ui/threads-sendsync/tls-init-on-init.rs
@@ -1,14 +1,14 @@
 //@ run-pass
 #![allow(stable_features)]
-
 //@ needs-threads
-
 #![feature(thread_local_try_with)]
 
-use std::thread;
 use std::sync::atomic::{AtomicUsize, Ordering};
+use std::thread;
 
-struct Foo { cnt: usize }
+struct Foo {
+    cnt: usize,
+}
 
 thread_local!(static FOO: Foo = Foo::init());
 
@@ -40,5 +40,7 @@ impl Drop for Foo {
 fn main() {
     thread::spawn(|| {
         FOO.with(|_| {});
-    }).join().unwrap();
+    })
+    .join()
+    .unwrap();
 }
diff --git a/tests/ui/threads-sendsync/tls-try-with.rs b/tests/ui/threads-sendsync/tls-try-with.rs
index 72cee219a0abd..04071e77daa48 100644
--- a/tests/ui/threads-sendsync/tls-try-with.rs
+++ b/tests/ui/threads-sendsync/tls-try-with.rs
@@ -1,8 +1,6 @@
 //@ run-pass
 #![allow(stable_features)]
-
 //@ needs-threads
-
 #![feature(thread_local_try_with)]
 
 use std::thread;
@@ -16,15 +14,17 @@ thread_local!(static FOO: Foo = Foo {});
 impl Drop for Foo {
     fn drop(&mut self) {
         assert!(FOO.try_with(|_| panic!("`try_with` closure run")).is_err());
-        unsafe { DROP_RUN = true; }
+        unsafe {
+            DROP_RUN = true;
+        }
     }
 }
 
 fn main() {
     thread::spawn(|| {
-        assert_eq!(FOO.try_with(|_| {
-            132
-        }).expect("`try_with` failed"), 132);
-    }).join().unwrap();
+        assert_eq!(FOO.try_with(|_| { 132 }).expect("`try_with` failed"), 132);
+    })
+    .join()
+    .unwrap();
     assert!(unsafe { DROP_RUN });
 }
diff --git a/tests/ui/threads-sendsync/trivial-message.rs b/tests/ui/threads-sendsync/trivial-message.rs
index 8165737364384..d76ba0009dca2 100644
--- a/tests/ui/threads-sendsync/trivial-message.rs
+++ b/tests/ui/threads-sendsync/trivial-message.rs
@@ -2,9 +2,9 @@
 
 #![allow(unused_must_use)]
 /*
-  This is about the simplest program that can successfully send a
-  message.
- */
+ This is about the simplest program that can successfully send a
+ message.
+*/
 
 use std::sync::mpsc::channel;
 
diff --git a/tests/ui/threads-sendsync/unwind-resource.rs b/tests/ui/threads-sendsync/unwind-resource.rs
index 3b1ab57b46e3e..ec27a1846fef2 100644
--- a/tests/ui/threads-sendsync/unwind-resource.rs
+++ b/tests/ui/threads-sendsync/unwind-resource.rs
@@ -21,9 +21,7 @@ impl Drop for complainer {
 
 fn complainer(tx: Sender<bool>) -> complainer {
     println!("Hello!");
-    complainer {
-        tx: tx
-    }
+    complainer { tx: tx }
 }
 
 fn f(tx: Sender<bool>) {
@@ -33,7 +31,7 @@ fn f(tx: Sender<bool>) {
 
 pub fn main() {
     let (tx, rx) = channel();
-    let t = thread::spawn(move|| f(tx.clone()));
+    let t = thread::spawn(move || f(tx.clone()));
     println!("hiiiiiiiii");
     assert!(rx.recv().unwrap());
     drop(t.join());
diff --git a/tests/ui/threads-sendsync/yield.rs b/tests/ui/threads-sendsync/yield.rs
index 99d14bd92eaa5..c2b10b901cf82 100644
--- a/tests/ui/threads-sendsync/yield.rs
+++ b/tests/ui/threads-sendsync/yield.rs
@@ -17,5 +17,9 @@ pub fn main() {
 }
 
 fn child() {
-    println!("4"); thread::yield_now(); println!("5"); thread::yield_now(); println!("6");
+    println!("4");
+    thread::yield_now();
+    println!("5");
+    thread::yield_now();
+    println!("6");
 }
diff --git a/tests/ui/threads-sendsync/yield1.rs b/tests/ui/threads-sendsync/yield1.rs
index c965d2fc3033e..441e93ecf9065 100644
--- a/tests/ui/threads-sendsync/yield1.rs
+++ b/tests/ui/threads-sendsync/yield1.rs
@@ -13,4 +13,6 @@ pub fn main() {
     result.join();
 }
 
-fn child() { println!("2"); }
+fn child() {
+    println!("2");
+}
diff --git a/tests/ui/threads-sendsync/yield2.rs b/tests/ui/threads-sendsync/yield2.rs
index 9502f0d33da51..2c24df44af249 100644
--- a/tests/ui/threads-sendsync/yield2.rs
+++ b/tests/ui/threads-sendsync/yield2.rs
@@ -4,5 +4,9 @@ use std::thread;
 
 pub fn main() {
     let mut i: isize = 0;
-    while i < 100 { i = i + 1; println!("{}", i); thread::yield_now(); }
+    while i < 100 {
+        i = i + 1;
+        println!("{}", i);
+        thread::yield_now();
+    }
 }