diff --git a/compiler/rustc_data_structures/src/base_n/tests.rs b/compiler/rustc_data_structures/src/base_n/tests.rs
index b68ef1eb7f4c4..2be2f0532c99c 100644
--- a/compiler/rustc_data_structures/src/base_n/tests.rs
+++ b/compiler/rustc_data_structures/src/base_n/tests.rs
@@ -15,7 +15,9 @@ fn test_encode() {
         test(u64::MAX as u128, base);
         test(u128::MAX, base);
 
-        for i in 0..1_000 {
+        const N: u128 = if cfg!(miri) { 10 } else { 1000 };
+
+        for i in 0..N {
             test(i * 983, base);
         }
     }
diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs
index 364005e67e63f..9940fee60d7d8 100644
--- a/compiler/rustc_data_structures/src/graph/scc/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs
@@ -156,7 +156,10 @@ fn test_deep_linear() {
     v
     …
      */
+    #[cfg(not(miri))]
     const NR_NODES: usize = 1 << 14;
+    #[cfg(miri)]
+    const NR_NODES: usize = 1 << 3;
     let mut nodes = vec![];
     for i in 1..NR_NODES {
         nodes.push((i - 1, i));
diff --git a/compiler/rustc_data_structures/src/owning_ref/tests.rs b/compiler/rustc_data_structures/src/owning_ref/tests.rs
index 7b8179e90bd07..320c03d5139f4 100644
--- a/compiler/rustc_data_structures/src/owning_ref/tests.rs
+++ b/compiler/rustc_data_structures/src/owning_ref/tests.rs
@@ -1,3 +1,5 @@
+// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
+#[cfg(not(miri))]
 mod owning_ref {
     use super::super::OwningRef;
     use super::super::{BoxRef, Erased, ErasedBoxRef, RcRef};
@@ -361,6 +363,8 @@ mod owning_handle {
     }
 }
 
+// FIXME: owning_ref is not sound under stacked borrows. Preferably, get rid of it.
+#[cfg(not(miri))]
 mod owning_ref_mut {
     use super::super::BoxRef;
     use super::super::{BoxRefMut, Erased, ErasedBoxRefMut, OwningRefMut};
diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs
index abd25f46ad54f..90793a97ed0d8 100644
--- a/compiler/rustc_data_structures/src/sip128.rs
+++ b/compiler/rustc_data_structures/src/sip128.rs
@@ -255,8 +255,9 @@ impl SipHasher128 {
         // elements from spill (at most LEN - 1 bytes could have overflowed
         // into the spill). The memcpy call is optimized away because the size
         // is known. And the whole copy is optimized away for LEN == 1.
+        let dst = self.buf.as_mut_ptr() as *mut u8;
         let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8;
-        ptr::copy_nonoverlapping(src, self.buf.as_mut_ptr() as *mut u8, LEN - 1);
+        ptr::copy_nonoverlapping(src, dst, LEN - 1);
 
         // This function should only be called when the write fills the buffer.
         // Therefore, when LEN == 1, the new `self.nbuf` must be zero.
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 899d6c7e490a6..24531e461896b 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1728,8 +1728,8 @@ rustc_queries! {
     query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
         desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }
     }
-    query maybe_unused_trait_import(def_id: LocalDefId) -> bool {
-        desc { |tcx| "maybe_unused_trait_import for `{}`", tcx.def_path_str(def_id.to_def_id()) }
+    query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet<LocalDefId> {
+        desc { "fetching potentially unused trait imports" }
     }
     query maybe_unused_extern_crates(_: ()) -> &'tcx [(LocalDefId, Span)] {
         desc { "looking up all possibly unused extern crates" }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 72e2beb372d3c..ac71146303ac2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2893,8 +2893,8 @@ pub fn provide(providers: &mut ty::query::Providers) {
         assert_eq!(id, LOCAL_CRATE);
         tcx.crate_name
     };
-    providers.maybe_unused_trait_import =
-        |tcx, id| tcx.resolutions(()).maybe_unused_trait_imports.contains(&id);
+    providers.maybe_unused_trait_imports =
+        |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports;
     providers.maybe_unused_extern_crates =
         |tcx, ()| &tcx.resolutions(()).maybe_unused_extern_crates[..];
     providers.names_imported_by_glob_use = |tcx, id| {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a493aaac276b1..3a2d3408b9d93 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -28,7 +28,7 @@ pub use generics::*;
 use rustc_ast as ast;
 use rustc_attr as attr;
 use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::{Interned, WithStableHash};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
@@ -138,7 +138,7 @@ pub struct ResolverOutputs {
     pub has_pub_restricted: bool,
     pub access_levels: AccessLevels,
     pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
-    pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
+    pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
     pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
     pub reexport_map: FxHashMap<LocalDefId, Vec<ModChild>>,
     pub glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 64c63e3d567d0..08879afa64a0e 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2190,34 +2190,40 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         // this is not *quite* right and changes the ordering of some output
         // anyways.
         let (new_value, map) = if self.tcx().sess.verbose() {
-            // anon index + 1 (BrEnv takes 0) -> name
-            let mut region_map: FxHashMap<_, _> = Default::default();
-            let bound_vars = value.bound_vars();
-            for var in bound_vars {
-                let ty::BoundVariableKind::Region(var) = var else { continue };
-                match var {
-                    ty::BrAnon(_) | ty::BrEnv => {
-                        start_or_continue(&mut self, "for<", ", ");
-                        let name = next_name(&self);
-                        do_continue(&mut self, name);
-                        region_map.insert(var, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name));
-                    }
-                    ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
-                        start_or_continue(&mut self, "for<", ", ");
-                        let name = next_name(&self);
-                        do_continue(&mut self, name);
-                        region_map.insert(var, ty::BrNamed(def_id, name));
-                    }
-                    ty::BrNamed(_, name) => {
-                        start_or_continue(&mut self, "for<", ", ");
-                        do_continue(&mut self, name);
+            let regions: Vec<_> = value
+                .bound_vars()
+                .into_iter()
+                .map(|var| {
+                    let ty::BoundVariableKind::Region(var) = var else {
+                    // This doesn't really matter because it doesn't get used,
+                    // it's just an empty value
+                    return ty::BrAnon(0);
+                };
+                    match var {
+                        ty::BrAnon(_) | ty::BrEnv => {
+                            start_or_continue(&mut self, "for<", ", ");
+                            let name = next_name(&self);
+                            do_continue(&mut self, name);
+                            ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
+                        }
+                        ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
+                            start_or_continue(&mut self, "for<", ", ");
+                            let name = next_name(&self);
+                            do_continue(&mut self, name);
+                            ty::BrNamed(def_id, name)
+                        }
+                        ty::BrNamed(def_id, name) => {
+                            start_or_continue(&mut self, "for<", ", ");
+                            do_continue(&mut self, name);
+                            ty::BrNamed(def_id, name)
+                        }
                     }
-                }
-            }
+                })
+                .collect();
             start_or_continue(&mut self, "", "> ");
 
             self.tcx.replace_late_bound_regions(value.clone(), |br| {
-                let kind = region_map[&br.kind];
+                let kind = regions[br.var.as_usize()];
                 self.tcx.mk_region(ty::ReLateBound(
                     ty::INNERMOST,
                     ty::BoundRegion { var: br.var, kind },
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 65f41c5266d17..59794c4d3f0d8 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -37,7 +37,7 @@ use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, T
 use rustc_ast as ast;
 use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::Lrc;
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 73c8a9d28bd5f..49c15d2c9ef1f 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -28,7 +28,7 @@ use rustc_ast::node_id::NodeMap;
 use rustc_ast::{self as ast, NodeId, CRATE_NODE_ID};
 use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, Path};
 use rustc_ast_lowering::{LifetimeRes, ResolverAstLowering};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed};
@@ -941,7 +941,7 @@ pub struct Resolver<'a> {
     visibilities: FxHashMap<LocalDefId, ty::Visibility>,
     has_pub_restricted: bool,
     used_imports: FxHashSet<NodeId>,
-    maybe_unused_trait_imports: FxHashSet<LocalDefId>,
+    maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
     maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,
 
     /// Privacy errors are delayed until the end in order to deduplicate them.
diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs
index 00f0d1e6f02a9..f28184c74d355 100644
--- a/compiler/rustc_typeck/src/check_unused.rs
+++ b/compiler/rustc_typeck/src/check_unused.rs
@@ -16,48 +16,32 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         used_trait_imports.extend(imports.iter());
     }
 
-    for id in tcx.hir().items() {
-        if matches!(tcx.def_kind(id.def_id), DefKind::Use) {
-            if tcx.visibility(id.def_id).is_public() {
-                continue;
-            }
-            let item = tcx.hir().item(id);
-            if item.span.is_dummy() {
-                continue;
-            }
-            if let hir::ItemKind::Use(path, _) = item.kind {
-                check_import(tcx, &mut used_trait_imports, item.item_id(), path.span);
-            }
+    for &id in tcx.maybe_unused_trait_imports(()) {
+        debug_assert_eq!(tcx.def_kind(id), DefKind::Use);
+        if tcx.visibility(id).is_public() {
+            continue;
+        }
+        if used_trait_imports.contains(&id) {
+            continue;
         }
+        let item = tcx.hir().expect_item(id);
+        if item.span.is_dummy() {
+            continue;
+        }
+        let hir::ItemKind::Use(path, _) = item.kind else { unreachable!() };
+        tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| {
+            let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) {
+                format!("unused import: `{}`", snippet)
+            } else {
+                "unused import".to_owned()
+            };
+            lint.build(&msg).emit();
+        });
     }
 
     unused_crates_lint(tcx);
 }
 
-fn check_import<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    used_trait_imports: &mut FxHashSet<LocalDefId>,
-    item_id: hir::ItemId,
-    span: Span,
-) {
-    if !tcx.maybe_unused_trait_import(item_id.def_id) {
-        return;
-    }
-
-    if used_trait_imports.contains(&item_id.def_id) {
-        return;
-    }
-
-    tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item_id.hir_id(), span, |lint| {
-        let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
-            format!("unused import: `{}`", snippet)
-        } else {
-            "unused import".to_owned()
-        };
-        lint.build(&msg).emit();
-    });
-}
-
 fn unused_crates_lint(tcx: TyCtxt<'_>) {
     let lint = lint::builtin::UNUSED_EXTERN_CRATES;
 
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 7e9d7d2710180..9505ec31609f5 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -84,6 +84,7 @@
 #![feature(const_option)]
 #![feature(const_option_ext)]
 #![feature(const_result)]
+#![feature(const_intrinsic_copy)]
 #![feature(integer_atomics)]
 #![feature(int_roundings)]
 #![feature(slice_group_by)]
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index c5242ad04de84..40b2b49bdbd7d 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -1,4 +1,5 @@
 use core::cell::RefCell;
+use core::mem::{self, MaybeUninit};
 use core::num::NonZeroUsize;
 use core::ptr;
 use core::ptr::*;
@@ -781,3 +782,42 @@ fn nonnull_tagged_pointer_with_provenance() {
         }
     }
 }
+
+#[test]
+fn test_const_copy() {
+    const {
+        let ptr1 = &1;
+        let mut ptr2 = &666;
+
+        // Copy ptr1 to ptr2, bytewise.
+        unsafe {
+            ptr::copy(
+                &ptr1 as *const _ as *const MaybeUninit<u8>,
+                &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
+                mem::size_of::<&i32>(),
+            );
+        }
+
+        // Make sure they still work.
+        assert!(*ptr1 == 1);
+        assert!(*ptr2 == 1);
+    };
+
+    const {
+        let ptr1 = &1;
+        let mut ptr2 = &666;
+
+        // Copy ptr1 to ptr2, bytewise.
+        unsafe {
+            ptr::copy_nonoverlapping(
+                &ptr1 as *const _ as *const MaybeUninit<u8>,
+                &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
+                mem::size_of::<&i32>(),
+            );
+        }
+
+        // Make sure they still work.
+        assert!(*ptr1 == 1);
+        assert!(*ptr2 == 1);
+    };
+}
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 9f26ccc74d182..b236bd7be4f0c 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
 pub(crate) use renderer::{run_format, FormatRenderer};
 
 use crate::clean::{self, ItemId};
-use cache::Cache;
+use crate::html::render::Context;
 
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
@@ -65,7 +65,8 @@ impl Impl {
     // Returns true if this is an implementation on a "local" type, meaning:
     // the type is in the current crate, or the type and the trait are both
     // re-exported by the current crate.
-    pub(crate) fn is_on_local_type(&self, cache: &Cache) -> bool {
+    pub(crate) fn is_on_local_type(&self, cx: &Context<'_>) -> bool {
+        let cache = cx.cache();
         let for_type = &self.inner_impl().for_;
         if let Some(for_type_did) = for_type.def_id(cache) {
             // The "for" type is local if it's in the paths for the current crate.
@@ -80,6 +81,18 @@ impl Impl {
                 if for_type_did.krate == trait_did.krate {
                     return true;
                 }
+                // Hack: many traits and types in std are re-exported from
+                // core or alloc. In general, rustdoc is capable of recognizing
+                // these implementations as being on local types. However, in at
+                // least one case (https://github.com/rust-lang/rust/issues/97610),
+                // rustdoc gets confused and labels an implementation as being on
+                // a foreign type. To make sure that confusion doesn't pass on to
+                // the reader, consider all implementations in std, core, and alloc
+                // to be on local types.
+                let crate_name = cx.tcx().crate_name(trait_did.krate);
+                if matches!(crate_name.as_str(), "std" | "core" | "alloc") {
+                    return true;
+                }
             }
             return false;
         };
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 0b801a20995d3..23ce634cf286b 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2281,11 +2281,10 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean
         |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method),
     );
 
-    let cache = cx.cache();
-    if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
+    if let Some(implementors) = cx.cache().implementors.get(&it.item_id.expect_def_id()) {
         let mut res = implementors
             .iter()
-            .filter(|i| !i.is_on_local_type(cache))
+            .filter(|i| !i.is_on_local_type(cx))
             .filter_map(|i| extract_for_impl_name(&i.impl_item, cx))
             .collect::<Vec<_>>();
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 8683e6dfcd99e..d115185562ce4 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -823,7 +823,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
         }
 
         let (local, foreign) =
-            implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cache));
+            implementors.iter().partition::<Vec<_>, _>(|i| i.is_on_local_type(cx));
 
         let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
             local.iter().partition(|i| i.inner_impl().kind.is_auto());
diff --git a/src/test/ui/generator/issue-87142.rs b/src/test/ui/generator/issue-87142.rs
new file mode 100644
index 0000000000000..fc10d04d46cfb
--- /dev/null
+++ b/src/test/ui/generator/issue-87142.rs
@@ -0,0 +1,32 @@
+// compile-flags: -Cdebuginfo=2
+// build-pass
+
+// Regression test for #87142
+// This test needs the above flags and the "lib" crate type.
+
+#![feature(type_alias_impl_trait, generator_trait, generators)]
+#![crate_type = "lib"]
+
+use std::ops::Generator;
+
+pub trait GeneratorProviderAlt: Sized {
+    type Gen: Generator<(), Return = (), Yield = ()>;
+
+    fn start(ctx: Context<Self>) -> Self::Gen;
+}
+
+pub struct Context<G: 'static + GeneratorProviderAlt> {
+    pub link: Box<G::Gen>,
+}
+
+impl GeneratorProviderAlt for () {
+    type Gen = impl Generator<(), Return = (), Yield = ()>;
+    fn start(ctx: Context<Self>) -> Self::Gen {
+        move || {
+            match ctx {
+                _ => (),
+            }
+            yield ();
+        }
+    }
+}