about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock13
-rw-r--r--compiler/rustc_abi/src/lib.rs4
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs6
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs96
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs50
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/back/profiling.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs224
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs259
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs71
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/lto.rs2
-rw-r--r--compiler/rustc_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context/tls.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs25
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs33
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs109
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs4
-rw-r--r--compiler/rustc_type_ir/src/visit.rs45
-rw-r--r--library/std/src/sys/pal/teeos/alloc.rs18
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs2
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs28
-rw-r--r--library/std/src/sys/sync/condvar/teeos.rs8
-rw-r--r--src/bootstrap/src/core/builder.rs1
-rw-r--r--src/tools/run-make-support/Cargo.toml2
-rw-r--r--tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs18
-rw-r--r--tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr61
30 files changed, 643 insertions, 500 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cafc623c185..68478d55e23 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1619,6 +1619,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "gimli"
+version = "0.31.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
+dependencies = [
+ "fallible-iterator",
+ "indexmap",
+ "stable_deref_trait",
+]
+
+[[package]]
 name = "glob"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3421,7 +3432,7 @@ dependencies = [
  "ar",
  "bstr",
  "build_helper",
- "gimli 0.28.1",
+ "gimli 0.31.0",
  "object 0.34.0",
  "regex",
  "similar",
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 78332d66f03..52ec41f643c 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -627,7 +627,7 @@ impl Step for Size {
 
     #[inline]
     unsafe fn forward_unchecked(start: Self, count: usize) -> Self {
-        Self::from_bytes(u64::forward_unchecked(start.bytes(), count))
+        Self::from_bytes(unsafe { u64::forward_unchecked(start.bytes(), count) })
     }
 
     #[inline]
@@ -642,7 +642,7 @@ impl Step for Size {
 
     #[inline]
     unsafe fn backward_unchecked(start: Self, count: usize) -> Self {
-        Self::from_bytes(u64::backward_unchecked(start.bytes(), count))
+        Self::from_bytes(unsafe { u64::backward_unchecked(start.bytes(), count) })
     }
 }
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 1c1163551db..39d0f2c7305 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -482,7 +482,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
         TyKind::Slice(ty) => vis.visit_ty(ty),
         TyKind::Ptr(mt) => vis.visit_mt(mt),
         TyKind::Ref(lt, mt) => {
-            visit_opt(lt, |lt| noop_visit_lifetime(lt, vis));
+            visit_opt(lt, |lt| vis.visit_lifetime(lt));
             vis.visit_mt(mt);
         }
         TyKind::BareFn(bft) => {
@@ -925,7 +925,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
     vis.visit_id(id);
     visit_attrs(attrs, vis);
     vis.visit_ident(ident);
-    visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
+    visit_vec(bounds, |bound| vis.visit_param_bound(bound));
     match kind {
         GenericParamKind::Lifetime => {}
         GenericParamKind::Type { default } => {
@@ -983,7 +983,7 @@ fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mu
         }
         WherePredicate::RegionPredicate(rp) => {
             let WhereRegionPredicate { span, lifetime, bounds } = rp;
-            noop_visit_lifetime(lifetime, vis);
+            vis.visit_lifetime(lifetime);
             visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
             vis.visit_span(span);
         }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index dd0d904c52c..e6cc2e4069b 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -38,7 +38,7 @@ use std::mem;
 use std::ops::{Deref, DerefMut};
 use thin_vec::thin_vec;
 
-use crate::errors;
+use crate::errors::{self, TildeConstReason};
 
 /// Is `self` allowed semantically as the first parameter in an `FnDecl`?
 enum SelfSemantic {
@@ -46,27 +46,12 @@ enum SelfSemantic {
     No,
 }
 
-/// What is the context that prevents using `~const`?
-// FIXME(effects): Consider getting rid of this in favor of `errors::TildeConstReason`, they're
-// almost identical. This gets rid of an abstraction layer which might be considered bad.
-enum DisallowTildeConstContext<'a> {
-    TraitObject,
-    Fn(FnKind<'a>),
-    Trait(Span),
-    TraitImpl(Span),
-    Impl(Span),
-    TraitAssocTy(Span),
-    TraitImplAssocTy(Span),
-    InherentAssocTy(Span),
-    Item,
-}
-
-enum TraitOrTraitImpl<'a> {
+enum TraitOrTraitImpl {
     Trait { span: Span, constness: Option<Span> },
-    TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: &'a TraitRef },
+    TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: Span },
 }
 
-impl<'a> TraitOrTraitImpl<'a> {
+impl TraitOrTraitImpl {
     fn constness(&self) -> Option<Span> {
         match self {
             Self::Trait { constness: Some(span), .. }
@@ -81,9 +66,9 @@ struct AstValidator<'a> {
     features: &'a Features,
 
     /// The span of the `extern` in an `extern { ... }` block, if any.
-    extern_mod: Option<&'a Item>,
+    extern_mod: Option<Span>,
 
-    outer_trait_or_trait_impl: Option<TraitOrTraitImpl<'a>>,
+    outer_trait_or_trait_impl: Option<TraitOrTraitImpl>,
 
     has_proc_macro_decls: bool,
 
@@ -92,7 +77,7 @@ struct AstValidator<'a> {
     /// e.g., `impl Iterator<Item = impl Debug>`.
     outer_impl_trait: Option<Span>,
 
-    disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
+    disallow_tilde_const: Option<TildeConstReason>,
 
     /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
     /// or `Foo::Bar<impl Trait>`
@@ -115,7 +100,7 @@ impl<'a> AstValidator<'a> {
             trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl {
                 constness,
                 polarity,
-                trait_ref,
+                trait_ref: trait_ref.path.span,
             }),
         );
         f(self);
@@ -145,7 +130,7 @@ impl<'a> AstValidator<'a> {
 
     fn with_tilde_const(
         &mut self,
-        disallowed: Option<DisallowTildeConstContext<'a>>,
+        disallowed: Option<TildeConstReason>,
         f: impl FnOnce(&mut Self),
     ) {
         let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
@@ -224,7 +209,7 @@ impl<'a> AstValidator<'a> {
                 }
             }
             TyKind::TraitObject(..) => self
-                .with_tilde_const(Some(DisallowTildeConstContext::TraitObject), |this| {
+                .with_tilde_const(Some(TildeConstReason::TraitObject), |this| {
                     visit::walk_ty(this, t)
                 }),
             TyKind::Path(qself, path) => {
@@ -354,7 +339,7 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'a>) {
+    fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
         let Const::Yes(span) = constness else {
             return;
         };
@@ -367,7 +352,7 @@ impl<'a> AstValidator<'a> {
                 ..
             } = parent
         {
-            Some(trait_ref.path.span.shrink_to_lo())
+            Some(trait_ref.shrink_to_lo())
         } else {
             None
         };
@@ -579,7 +564,7 @@ impl<'a> AstValidator<'a> {
     }
 
     fn current_extern_span(&self) -> Span {
-        self.session.source_map().guess_head_span(self.extern_mod.unwrap().span)
+        self.session.source_map().guess_head_span(self.extern_mod.unwrap())
     }
 
     /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
@@ -980,7 +965,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     this.visit_vis(&item.vis);
                     this.visit_ident(item.ident);
                     let disallowed = matches!(constness, Const::No)
-                        .then(|| DisallowTildeConstContext::TraitImpl(item.span));
+                        .then(|| TildeConstReason::TraitImpl { span: item.span });
                     this.with_tilde_const(disallowed, |this| this.visit_generics(generics));
                     this.visit_trait_ref(t);
                     this.visit_ty(self_ty);
@@ -1035,7 +1020,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     this.visit_vis(&item.vis);
                     this.visit_ident(item.ident);
                     this.with_tilde_const(
-                        Some(DisallowTildeConstContext::Impl(item.span)),
+                        Some(TildeConstReason::Impl { span: item.span }),
                         |this| this.visit_generics(generics),
                     );
                     this.visit_ty(self_ty);
@@ -1080,7 +1065,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
                 self.with_in_extern_mod(*safety, |this| {
-                    let old_item = mem::replace(&mut this.extern_mod, Some(item));
+                    let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
                     this.visibility_not_permitted(
                         &item.vis,
                         errors::VisibilityNotPermittedNote::IndividualForeignItems,
@@ -1154,7 +1139,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     this.visit_ident(item.ident);
                     let disallowed = is_const_trait
                         .is_none()
-                        .then(|| DisallowTildeConstContext::Trait(item.span));
+                        .then(|| TildeConstReason::Trait { span: item.span });
                     this.with_tilde_const(disallowed, |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
@@ -1399,40 +1384,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         self.dcx().emit_err(errors::ConstBoundTraitObject { span: trait_ref.span });
                     }
                     (_, BoundConstness::Maybe(span), BoundPolarity::Positive)
-                        if let Some(reason) = &self.disallow_tilde_const =>
+                        if let Some(reason) = self.disallow_tilde_const =>
                     {
-                        let reason = match reason {
-                            DisallowTildeConstContext::Fn(FnKind::Closure(..)) => {
-                                errors::TildeConstReason::Closure
-                            }
-                            DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
-                                errors::TildeConstReason::Function { ident: ident.span }
-                            }
-                            &DisallowTildeConstContext::Trait(span) => {
-                                errors::TildeConstReason::Trait { span }
-                            }
-                            &DisallowTildeConstContext::TraitImpl(span) => {
-                                errors::TildeConstReason::TraitImpl { span }
-                            }
-                            &DisallowTildeConstContext::Impl(span) => {
-                                // FIXME(effects): Consider providing a help message or even a structured
-                                // suggestion for moving such bounds to the assoc const fns if available.
-                                errors::TildeConstReason::Impl { span }
-                            }
-                            &DisallowTildeConstContext::TraitAssocTy(span) => {
-                                errors::TildeConstReason::TraitAssocTy { span }
-                            }
-                            &DisallowTildeConstContext::TraitImplAssocTy(span) => {
-                                errors::TildeConstReason::TraitImplAssocTy { span }
-                            }
-                            &DisallowTildeConstContext::InherentAssocTy(span) => {
-                                errors::TildeConstReason::InherentAssocTy { span }
-                            }
-                            DisallowTildeConstContext::TraitObject => {
-                                errors::TildeConstReason::TraitObject
-                            }
-                            DisallowTildeConstContext::Item => errors::TildeConstReason::Item,
-                        };
                         self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
                     }
                     (
@@ -1569,7 +1522,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         .and_then(TraitOrTraitImpl::constness)
                         .is_some();
 
-        let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
+        let disallowed = (!tilde_const_allowed).then(|| match fk {
+            FnKind::Fn(_, ident, _, _, _, _) => TildeConstReason::Function { ident: ident.span },
+            FnKind::Closure(_, _, _) => TildeConstReason::Closure,
+        });
         self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
     }
 
@@ -1664,12 +1620,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             AssocItemKind::Type(_) => {
                 let disallowed = (!parent_is_const).then(|| match self.outer_trait_or_trait_impl {
                     Some(TraitOrTraitImpl::Trait { .. }) => {
-                        DisallowTildeConstContext::TraitAssocTy(item.span)
+                        TildeConstReason::TraitAssocTy { span: item.span }
                     }
                     Some(TraitOrTraitImpl::TraitImpl { .. }) => {
-                        DisallowTildeConstContext::TraitImplAssocTy(item.span)
+                        TildeConstReason::TraitImplAssocTy { span: item.span }
                     }
-                    None => DisallowTildeConstContext::InherentAssocTy(item.span),
+                    None => TildeConstReason::InherentAssocTy { span: item.span },
                 });
                 self.with_tilde_const(disallowed, |this| {
                     this.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt))
@@ -1852,7 +1808,7 @@ pub fn check_crate(
         outer_trait_or_trait_impl: None,
         has_proc_macro_decls: false,
         outer_impl_trait: None,
-        disallow_tilde_const: Some(DisallowTildeConstContext::Item),
+        disallow_tilde_const: Some(TildeConstReason::Item),
         is_impl_trait_banned: false,
         extern_mod_safety: None,
         lint_buffer: lints,
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index bfb90476450..2c18b47f0f7 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -612,7 +612,7 @@ pub struct TildeConstDisallowed {
     pub reason: TildeConstReason,
 }
 
-#[derive(Subdiagnostic)]
+#[derive(Subdiagnostic, Copy, Clone)]
 pub enum TildeConstReason {
     #[note(ast_passes_closure)]
     Closure,
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index ca376029735..5969d9b9144 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -21,14 +21,16 @@ pub(crate) unsafe fn codegen(
 ) {
     let llcx = &*module_llvm.llcx;
     let llmod = module_llvm.llmod();
-    let usize = match tcx.sess.target.pointer_width {
-        16 => llvm::LLVMInt16TypeInContext(llcx),
-        32 => llvm::LLVMInt32TypeInContext(llcx),
-        64 => llvm::LLVMInt64TypeInContext(llcx),
-        tws => bug!("Unsupported target word size for int: {}", tws),
+    let usize = unsafe {
+        match tcx.sess.target.pointer_width {
+            16 => llvm::LLVMInt16TypeInContext(llcx),
+            32 => llvm::LLVMInt32TypeInContext(llcx),
+            64 => llvm::LLVMInt64TypeInContext(llcx),
+            tws => bug!("Unsupported target word size for int: {}", tws),
+        }
     };
-    let i8 = llvm::LLVMInt8TypeInContext(llcx);
-    let i8p = llvm::LLVMPointerTypeInContext(llcx, 0);
+    let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) };
+    let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) };
 
     if kind == AllocatorKind::Default {
         for method in ALLOCATOR_METHODS {
@@ -73,23 +75,25 @@ pub(crate) unsafe fn codegen(
         true,
     );
 
-    // __rust_alloc_error_handler_should_panic
-    let name = OomStrategy::SYMBOL;
-    let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
-    if tcx.sess.default_hidden_visibility() {
-        llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
-    }
-    let val = tcx.sess.opts.unstable_opts.oom.should_panic();
-    let llval = llvm::LLVMConstInt(i8, val as u64, False);
-    llvm::LLVMSetInitializer(ll_g, llval);
-
-    let name = NO_ALLOC_SHIM_IS_UNSTABLE;
-    let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
-    if tcx.sess.default_hidden_visibility() {
-        llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
+    unsafe {
+        // __rust_alloc_error_handler_should_panic
+        let name = OomStrategy::SYMBOL;
+        let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
+        if tcx.sess.default_hidden_visibility() {
+            llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
+        }
+        let val = tcx.sess.opts.unstable_opts.oom.should_panic();
+        let llval = llvm::LLVMConstInt(i8, val as u64, False);
+        llvm::LLVMSetInitializer(ll_g, llval);
+
+        let name = NO_ALLOC_SHIM_IS_UNSTABLE;
+        let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
+        if tcx.sess.default_hidden_visibility() {
+            llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
+        }
+        let llval = llvm::LLVMConstInt(i8, 0, False);
+        llvm::LLVMSetInitializer(ll_g, llval);
     }
-    let llval = llvm::LLVMConstInt(i8, 0, False);
-    llvm::LLVMSetInitializer(ll_g, llval);
 
     if tcx.sess.opts.debuginfo != DebugInfo::None {
         let dbg_cx = debuginfo::CodegenUnitDebugContext::new(llmod);
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index aff3e3d7076..aef672631c8 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -727,7 +727,7 @@ pub unsafe fn optimize_thin_module(
     // into that context. One day, however, we may do this for upstream
     // crates but for locally codegened modules we may be able to reuse
     // that LLVM Context and Module.
-    let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
+    let llcx = unsafe { llvm::LLVMRustContextCreate(cgcx.fewer_names) };
     let llmod_raw = parse_module(llcx, module_name, thin_module.data(), dcx)? as *const _;
     let mut module = ModuleCodegen {
         module_llvm: ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) },
@@ -750,7 +750,9 @@ pub unsafe fn optimize_thin_module(
         {
             let _timer =
                 cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
-            if !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) {
+            if unsafe {
+                !llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target)
+            } {
                 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
             }
             save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
@@ -760,7 +762,8 @@ pub unsafe fn optimize_thin_module(
             let _timer = cgcx
                 .prof
                 .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name());
-            if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) {
+            if unsafe { !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) }
+            {
                 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
             }
             save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve");
@@ -770,7 +773,8 @@ pub unsafe fn optimize_thin_module(
             let _timer = cgcx
                 .prof
                 .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name());
-            if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) {
+            if unsafe { !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) }
+            {
                 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
             }
             save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize");
@@ -779,7 +783,9 @@ pub unsafe fn optimize_thin_module(
         {
             let _timer =
                 cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
-            if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) {
+            if unsafe {
+                !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
+            } {
                 return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
             }
             save_temp_bitcode(cgcx, &module, "thin-lto-after-import");
diff --git a/compiler/rustc_codegen_llvm/src/back/profiling.rs b/compiler/rustc_codegen_llvm/src/back/profiling.rs
index 2741f7d848e..2eee9f8c5a3 100644
--- a/compiler/rustc_codegen_llvm/src/back/profiling.rs
+++ b/compiler/rustc_codegen_llvm/src/back/profiling.rs
@@ -46,13 +46,15 @@ pub unsafe extern "C" fn selfprofile_before_pass_callback(
     pass_name: *const c_char,
     ir_name: *const c_char,
 ) {
-    let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
-    let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
-    let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
-    llvm_self_profiler.before_pass_callback(pass_name, ir_name);
+    unsafe {
+        let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
+        let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
+        let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
+        llvm_self_profiler.before_pass_callback(pass_name, ir_name);
+    }
 }
 
 pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
-    let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
+    let llvm_self_profiler = unsafe { &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>) };
     llvm_self_profiler.after_pass_callback();
 }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 2fda19bf0c9..ddd52e80edf 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -428,9 +428,10 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
     if user.is_null() {
         return;
     }
-    let (cgcx, dcx) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'_>));
+    let (cgcx, dcx) =
+        unsafe { *(user as *const (&CodegenContext<LlvmCodegenBackend>, DiagCtxtHandle<'_>)) };
 
-    match llvm::diagnostic::Diagnostic::unpack(info) {
+    match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } {
         llvm::diagnostic::InlineAsm(inline) => {
             report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source);
         }
@@ -454,14 +455,14 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
             });
         }
         llvm::diagnostic::PGO(diagnostic_ref) | llvm::diagnostic::Linker(diagnostic_ref) => {
-            let message = llvm::build_string(|s| {
+            let message = llvm::build_string(|s| unsafe {
                 llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
             })
             .expect("non-UTF8 diagnostic");
             dcx.emit_warn(FromLlvmDiag { message });
         }
         llvm::diagnostic::Unsupported(diagnostic_ref) => {
-            let message = llvm::build_string(|s| {
+            let message = llvm::build_string(|s| unsafe {
                 llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s)
             })
             .expect("non-UTF8 diagnostic");
@@ -564,37 +565,39 @@ pub(crate) unsafe fn llvm_optimize(
 
     let llvm_plugins = config.llvm_plugins.join(",");
 
-    let result = llvm::LLVMRustOptimize(
-        module.module_llvm.llmod(),
-        &*module.module_llvm.tm,
-        to_pass_builder_opt_level(opt_level),
-        opt_stage,
-        cgcx.opts.cg.linker_plugin_lto.enabled(),
-        config.no_prepopulate_passes,
-        config.verify_llvm_ir,
-        using_thin_buffers,
-        config.merge_functions,
-        unroll_loops,
-        config.vectorize_slp,
-        config.vectorize_loop,
-        config.no_builtins,
-        config.emit_lifetime_markers,
-        sanitizer_options.as_ref(),
-        pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-        pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-        config.instrument_coverage,
-        instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-        config.instrument_gcov,
-        pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-        config.debug_info_for_profiling,
-        llvm_selfprofiler,
-        selfprofile_before_pass_callback,
-        selfprofile_after_pass_callback,
-        extra_passes.as_ptr().cast(),
-        extra_passes.len(),
-        llvm_plugins.as_ptr().cast(),
-        llvm_plugins.len(),
-    );
+    let result = unsafe {
+        llvm::LLVMRustOptimize(
+            module.module_llvm.llmod(),
+            &*module.module_llvm.tm,
+            to_pass_builder_opt_level(opt_level),
+            opt_stage,
+            cgcx.opts.cg.linker_plugin_lto.enabled(),
+            config.no_prepopulate_passes,
+            config.verify_llvm_ir,
+            using_thin_buffers,
+            config.merge_functions,
+            unroll_loops,
+            config.vectorize_slp,
+            config.vectorize_loop,
+            config.no_builtins,
+            config.emit_lifetime_markers,
+            sanitizer_options.as_ref(),
+            pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
+            pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
+            config.instrument_coverage,
+            instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
+            config.instrument_gcov,
+            pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
+            config.debug_info_for_profiling,
+            llvm_selfprofiler,
+            selfprofile_before_pass_callback,
+            selfprofile_after_pass_callback,
+            extra_passes.as_ptr().cast(),
+            extra_passes.len(),
+            llvm_plugins.as_ptr().cast(),
+            llvm_plugins.len(),
+        )
+    };
     result.into_result().map_err(|()| llvm_err(dcx, LlvmError::RunLlvmPasses))
 }
 
@@ -617,7 +620,7 @@ pub(crate) unsafe fn optimize(
     if config.emit_no_opt_bc {
         let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
         let out = path_to_c_string(&out);
-        llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
+        unsafe { llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr()) };
     }
 
     if let Some(opt_level) = config.opt_level {
@@ -627,7 +630,7 @@ pub(crate) unsafe fn optimize(
             _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
             _ => llvm::OptStage::PreLinkNoLTO,
         };
-        return llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage);
+        return unsafe { llvm_optimize(cgcx, dcx, module, config, opt_level, opt_stage) };
     }
     Ok(())
 }
@@ -692,10 +695,12 @@ pub(crate) unsafe fn codegen(
         where
             F: FnOnce(&'ll mut PassManager<'ll>) -> R,
         {
-            let cpm = llvm::LLVMCreatePassManager();
-            llvm::LLVMAddAnalysisPasses(tm, cpm);
-            llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
-            f(cpm)
+            unsafe {
+                let cpm = llvm::LLVMCreatePassManager();
+                llvm::LLVMAddAnalysisPasses(tm, cpm);
+                llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
+                f(cpm)
+            }
         }
 
         // Two things to note:
@@ -757,7 +762,9 @@ pub(crate) unsafe fn codegen(
                 let _timer = cgcx
                     .prof
                     .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name);
-                embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
+                unsafe {
+                    embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);
+                }
             }
         }
 
@@ -793,7 +800,8 @@ pub(crate) unsafe fn codegen(
                 cursor.position() as size_t
             }
 
-            let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
+            let result =
+                unsafe { llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback) };
 
             if result == llvm::LLVMRustResult::Success {
                 record_artifact_size(&cgcx.prof, "llvm_ir", &out);
@@ -812,22 +820,24 @@ pub(crate) unsafe fn codegen(
             // binaries. So we must clone the module to produce the asm output
             // if we are also producing object code.
             let llmod = if let EmitObj::ObjectCode(_) = config.emit_obj {
-                llvm::LLVMCloneModule(llmod)
+                unsafe { llvm::LLVMCloneModule(llmod) }
             } else {
                 llmod
             };
-            with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                write_output_file(
-                    dcx,
-                    tm,
-                    cpm,
-                    llmod,
-                    &path,
-                    None,
-                    llvm::FileType::AssemblyFile,
-                    &cgcx.prof,
-                )
-            })?;
+            unsafe {
+                with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                    write_output_file(
+                        dcx,
+                        tm,
+                        cpm,
+                        llmod,
+                        &path,
+                        None,
+                        llvm::FileType::AssemblyFile,
+                        &cgcx.prof,
+                    )
+                })?;
+            }
         }
 
         match config.emit_obj {
@@ -851,18 +861,20 @@ pub(crate) unsafe fn codegen(
                     (_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
                 };
 
-                with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                    write_output_file(
-                        dcx,
-                        tm,
-                        cpm,
-                        llmod,
-                        &obj_out,
-                        dwo_out,
-                        llvm::FileType::ObjectFile,
-                        &cgcx.prof,
-                    )
-                })?;
+                unsafe {
+                    with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                        write_output_file(
+                            dcx,
+                            tm,
+                            cpm,
+                            llmod,
+                            &obj_out,
+                            dwo_out,
+                            llvm::FileType::ObjectFile,
+                            &cgcx.prof,
+                        )
+                    })?;
+                }
             }
 
             EmitObj::Bitcode => {
@@ -1013,44 +1025,46 @@ unsafe fn embed_bitcode(
     // reason (see issue #90326 for historical background).
     let is_aix = target_is_aix(cgcx);
     let is_apple = target_is_apple(cgcx);
-    if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
-        // We don't need custom section flags, create LLVM globals.
-        let llconst = common::bytes_in_context(llcx, bitcode);
-        let llglobal = llvm::LLVMAddGlobal(
-            llmod,
-            common::val_ty(llconst),
-            c"rustc.embedded.module".as_ptr().cast(),
-        );
-        llvm::LLVMSetInitializer(llglobal, llconst);
-
-        let section = bitcode_section_name(cgcx);
-        llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
-        llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
-        llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
-
-        let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
-        let llglobal = llvm::LLVMAddGlobal(
-            llmod,
-            common::val_ty(llconst),
-            c"rustc.embedded.cmdline".as_ptr().cast(),
-        );
-        llvm::LLVMSetInitializer(llglobal, llconst);
-        let section = if is_apple {
-            c"__LLVM,__cmdline"
-        } else if is_aix {
-            c".info"
+    unsafe {
+        if is_apple || is_aix || cgcx.opts.target_triple.triple().starts_with("wasm") {
+            // We don't need custom section flags, create LLVM globals.
+            let llconst = common::bytes_in_context(llcx, bitcode);
+            let llglobal = llvm::LLVMAddGlobal(
+                llmod,
+                common::val_ty(llconst),
+                c"rustc.embedded.module".as_ptr().cast(),
+            );
+            llvm::LLVMSetInitializer(llglobal, llconst);
+
+            let section = bitcode_section_name(cgcx);
+            llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
+            llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
+            llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
+
+            let llconst = common::bytes_in_context(llcx, cmdline.as_bytes());
+            let llglobal = llvm::LLVMAddGlobal(
+                llmod,
+                common::val_ty(llconst),
+                c"rustc.embedded.cmdline".as_ptr().cast(),
+            );
+            llvm::LLVMSetInitializer(llglobal, llconst);
+            let section = if is_apple {
+                c"__LLVM,__cmdline"
+            } else if is_aix {
+                c".info"
+            } else {
+                c".llvmcmd"
+            };
+            llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
+            llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
         } else {
-            c".llvmcmd"
-        };
-        llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
-        llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
-    } else {
-        // We need custom section flags, so emit module-level inline assembly.
-        let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
-        let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
-        llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
-        let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
-        llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
+            // We need custom section flags, so emit module-level inline assembly.
+            let section_flags = if cgcx.is_pe_coff { "n" } else { "e" };
+            let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode);
+            llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
+            let asm = create_section_with_flags_asm(".llvmcmd", section_flags, cmdline.as_bytes());
+            llvm::LLVMAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
+        }
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 77beb9a6bb3..49677dcf12f 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -120,7 +120,7 @@ pub unsafe fn create_module<'ll>(
 ) -> &'ll llvm::Module {
     let sess = tcx.sess;
     let mod_name = SmallCStr::new(mod_name);
-    let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
+    let llmod = unsafe { llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx) };
 
     let mut target_data_layout = sess.target.data_layout.to_string();
     let llvm_version = llvm_util::get_version();
@@ -153,11 +153,14 @@ pub unsafe fn create_module<'ll>(
     // Ensure the data-layout values hardcoded remain the defaults.
     {
         let tm = crate::back::write::create_informational_target_machine(tcx.sess);
-        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
+        unsafe {
+            llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
+        }
 
-        let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
-        let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
-            .expect("got a non-UTF8 data-layout from LLVM");
+        let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
+        let llvm_data_layout =
+            str::from_utf8(unsafe { CStr::from_ptr(llvm_data_layout) }.to_bytes())
+                .expect("got a non-UTF8 data-layout from LLVM");
 
         if target_data_layout != llvm_data_layout {
             tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
@@ -170,20 +173,28 @@ pub unsafe fn create_module<'ll>(
     }
 
     let data_layout = SmallCStr::new(&target_data_layout);
-    llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
+    unsafe {
+        llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
+    }
 
     let llvm_target = SmallCStr::new(&sess.target.llvm_target);
-    llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
+    unsafe {
+        llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
+    }
 
     let reloc_model = sess.relocation_model();
     if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) {
-        llvm::LLVMRustSetModulePICLevel(llmod);
+        unsafe {
+            llvm::LLVMRustSetModulePICLevel(llmod);
+        }
         // PIE is potentially more effective than PIC, but can only be used in executables.
         // If all our outputs are executables, then we can relax PIC to PIE.
         if reloc_model == RelocModel::Pie
             || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
         {
-            llvm::LLVMRustSetModulePIELevel(llmod);
+            unsafe {
+                llvm::LLVMRustSetModulePIELevel(llmod);
+            }
         }
     }
 
@@ -192,95 +203,109 @@ pub unsafe fn create_module<'ll>(
     // longer jumps) if a larger code model is used with a smaller one.
     //
     // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
-    llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
+    unsafe {
+        llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
+    }
 
     // If skipping the PLT is enabled, we need to add some module metadata
     // to ensure intrinsic calls don't use it.
     if !sess.needs_plt() {
         let avoid_plt = c"RtLibUseGOT".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Warning, avoid_plt, 1);
+        }
     }
 
     // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
     if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
         let canonical_jump_tables = c"CFI Canonical Jump Tables".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            canonical_jump_tables,
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                canonical_jump_tables,
+                1,
+            );
+        }
     }
 
     // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
         let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            enable_split_lto_unit,
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                enable_split_lto_unit,
+                1,
+            );
+        }
     }
 
     // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
     if sess.is_sanitizer_kcfi_enabled() {
         let kcfi = c"kcfi".as_ptr().cast();
-        llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(llmod, llvm::LLVMModFlagBehavior::Override, kcfi, 1);
+        }
     }
 
     // Control Flow Guard is currently only supported by the MSVC linker on Windows.
     if sess.target.is_like_msvc {
-        match sess.opts.cg.control_flow_guard {
-            CFGuard::Disabled => {}
-            CFGuard::NoChecks => {
-                // Set `cfguard=1` module flag to emit metadata only.
-                llvm::LLVMRustAddModuleFlagU32(
-                    llmod,
-                    llvm::LLVMModFlagBehavior::Warning,
-                    c"cfguard".as_ptr() as *const _,
-                    1,
-                )
-            }
-            CFGuard::Checks => {
-                // Set `cfguard=2` module flag to emit metadata and checks.
-                llvm::LLVMRustAddModuleFlagU32(
-                    llmod,
-                    llvm::LLVMModFlagBehavior::Warning,
-                    c"cfguard".as_ptr() as *const _,
-                    2,
-                )
+        unsafe {
+            match sess.opts.cg.control_flow_guard {
+                CFGuard::Disabled => {}
+                CFGuard::NoChecks => {
+                    // Set `cfguard=1` module flag to emit metadata only.
+                    llvm::LLVMRustAddModuleFlagU32(
+                        llmod,
+                        llvm::LLVMModFlagBehavior::Warning,
+                        c"cfguard".as_ptr() as *const _,
+                        1,
+                    )
+                }
+                CFGuard::Checks => {
+                    // Set `cfguard=2` module flag to emit metadata and checks.
+                    llvm::LLVMRustAddModuleFlagU32(
+                        llmod,
+                        llvm::LLVMModFlagBehavior::Warning,
+                        c"cfguard".as_ptr() as *const _,
+                        2,
+                    )
+                }
             }
         }
     }
 
     if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection {
         if sess.target.arch == "aarch64" {
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"branch-target-enforcement".as_ptr().cast(),
-                bti.into(),
-            );
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address".as_ptr().cast(),
-                pac_ret.is_some().into(),
-            );
-            let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address-all".as_ptr().cast(),
-                pac_opts.leaf.into(),
-            );
-            llvm::LLVMRustAddModuleFlagU32(
-                llmod,
-                llvm::LLVMModFlagBehavior::Min,
-                c"sign-return-address-with-bkey".as_ptr().cast(),
-                u32::from(pac_opts.key == PAuthKey::B),
-            );
+            unsafe {
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"branch-target-enforcement".as_ptr().cast(),
+                    bti.into(),
+                );
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address".as_ptr().cast(),
+                    pac_ret.is_some().into(),
+                );
+                let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, key: PAuthKey::A });
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address-all".as_ptr().cast(),
+                    pac_opts.leaf.into(),
+                );
+                llvm::LLVMRustAddModuleFlagU32(
+                    llmod,
+                    llvm::LLVMModFlagBehavior::Min,
+                    c"sign-return-address-with-bkey".as_ptr().cast(),
+                    u32::from(pac_opts.key == PAuthKey::B),
+                );
+            }
         } else {
             bug!(
                 "branch-protection used on non-AArch64 target; \
@@ -291,39 +316,47 @@ pub unsafe fn create_module<'ll>(
 
     // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
     if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            c"cf-protection-branch".as_ptr().cast(),
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                c"cf-protection-branch".as_ptr().cast(),
+                1,
+            );
+        }
     }
     if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Override,
-            c"cf-protection-return".as_ptr().cast(),
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Override,
+                c"cf-protection-return".as_ptr().cast(),
+                1,
+            );
+        }
     }
 
     if sess.opts.unstable_opts.virtual_function_elimination {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Error,
-            c"Virtual Function Elim".as_ptr().cast(),
-            1,
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Error,
+                c"Virtual Function Elim".as_ptr().cast(),
+                1,
+            );
+        }
     }
 
     // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
     if sess.opts.unstable_opts.ehcont_guard {
-        llvm::LLVMRustAddModuleFlagU32(
-            llmod,
-            llvm::LLVMModFlagBehavior::Warning,
-            c"ehcontguard".as_ptr() as *const _,
-            1,
-        )
+        unsafe {
+            llvm::LLVMRustAddModuleFlagU32(
+                llmod,
+                llvm::LLVMModFlagBehavior::Warning,
+                c"ehcontguard".as_ptr() as *const _,
+                1,
+            )
+        }
     }
 
     // Insert `llvm.ident` metadata.
@@ -333,16 +366,20 @@ pub unsafe fn create_module<'ll>(
     #[allow(clippy::option_env_unwrap)]
     let rustc_producer =
         format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"));
-    let name_metadata = llvm::LLVMMDStringInContext(
-        llcx,
-        rustc_producer.as_ptr().cast(),
-        rustc_producer.as_bytes().len() as c_uint,
-    );
-    llvm::LLVMAddNamedMetadataOperand(
-        llmod,
-        c"llvm.ident".as_ptr(),
-        llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
-    );
+    let name_metadata = unsafe {
+        llvm::LLVMMDStringInContext(
+            llcx,
+            rustc_producer.as_ptr().cast(),
+            rustc_producer.as_bytes().len() as c_uint,
+        )
+    };
+    unsafe {
+        llvm::LLVMAddNamedMetadataOperand(
+            llmod,
+            c"llvm.ident".as_ptr(),
+            llvm::LLVMMDNodeInContext(llcx, &name_metadata, 1),
+        );
+    }
 
     // Emit RISC-V specific target-abi metadata
     // to workaround lld as the LTO plugin not
@@ -351,13 +388,15 @@ pub unsafe fn create_module<'ll>(
     // If llvm_abiname is empty, emit nothing.
     let llvm_abiname = &sess.target.options.llvm_abiname;
     if matches!(sess.target.arch.as_ref(), "riscv32" | "riscv64") && !llvm_abiname.is_empty() {
-        llvm::LLVMRustAddModuleFlagString(
-            llmod,
-            llvm::LLVMModFlagBehavior::Error,
-            c"target-abi".as_ptr(),
-            llvm_abiname.as_ptr().cast(),
-            llvm_abiname.len(),
-        );
+        unsafe {
+            llvm::LLVMRustAddModuleFlagString(
+                llmod,
+                llvm::LLVMModFlagBehavior::Error,
+                c"target-abi".as_ptr(),
+                llvm_abiname.as_ptr().cast(),
+                llvm_abiname.len(),
+            );
+        }
     }
 
     // Add module flags specified via -Z llvm_module_flag
@@ -375,7 +414,7 @@ pub unsafe fn create_module<'ll>(
             // We already checked this during option parsing
             _ => unreachable!(),
         };
-        llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value)
+        unsafe { llvm::LLVMRustAddModuleFlagU32(llmod, behavior, key.as_ptr().cast(), *value) }
     }
 
     llmod
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index ed0989a0ba4..a96993b9aba 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -216,7 +216,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
         module: &ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
     ) -> Result<(), FatalError> {
-        back::write::optimize(cgcx, dcx, module, config)
+        unsafe { back::write::optimize(cgcx, dcx, module, config) }
     }
     fn optimize_fat(
         cgcx: &CodegenContext<Self>,
@@ -230,7 +230,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
         cgcx: &CodegenContext<Self>,
         thin: ThinModule<Self>,
     ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
-        back::lto::optimize_thin_module(thin, cgcx)
+        unsafe { back::lto::optimize_thin_module(thin, cgcx) }
     }
     unsafe fn codegen(
         cgcx: &CodegenContext<Self>,
@@ -238,7 +238,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
         module: ModuleCodegen<Self::Module>,
         config: &ModuleConfig,
     ) -> Result<CompiledModule, FatalError> {
-        back::write::codegen(cgcx, dcx, module, config)
+        unsafe { back::write::codegen(cgcx, dcx, module, config) }
     }
     fn prepare_thin(
         module: ModuleCodegen<Self::Module>,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
index f9b28178ddb..73e1b08a3d7 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
@@ -40,7 +40,7 @@ impl<'ll> OptimizationDiagnostic<'ll> {
         let mut filename = None;
         let pass_name = super::build_string(|pass_name| {
             message = super::build_string(|message| {
-                filename = super::build_string(|filename| {
+                filename = super::build_string(|filename| unsafe {
                     super::LLVMRustUnpackOptimizationDiagnostic(
                         di,
                         pass_name,
@@ -91,7 +91,7 @@ impl SrcMgrDiagnostic {
         let mut ranges = [0; 8];
         let mut num_ranges = ranges.len() / 2;
         let message = super::build_string(|message| {
-            buffer = super::build_string(|buffer| {
+            buffer = super::build_string(|buffer| unsafe {
                 have_source = super::LLVMRustUnpackSMDiagnostic(
                     diag,
                     message,
@@ -134,7 +134,9 @@ impl InlineAsmDiagnostic {
         let mut message = None;
         let mut level = super::DiagnosticLevel::Error;
 
-        super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
+        unsafe {
+            super::LLVMRustUnpackInlineAsmDiagnostic(di, &mut level, &mut cookie, &mut message);
+        }
 
         InlineAsmDiagnostic {
             level,
@@ -146,7 +148,8 @@ impl InlineAsmDiagnostic {
 
     unsafe fn unpackSrcMgr(di: &DiagnosticInfo) -> Self {
         let mut cookie = 0;
-        let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
+        let smdiag =
+            unsafe { SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie)) };
         InlineAsmDiagnostic {
             level: smdiag.level,
             cookie: cookie.into(),
@@ -170,44 +173,46 @@ pub enum Diagnostic<'ll> {
 impl<'ll> Diagnostic<'ll> {
     pub unsafe fn unpack(di: &'ll DiagnosticInfo) -> Self {
         use super::DiagnosticKind as Dk;
-        let kind = super::LLVMRustGetDiagInfoKind(di);
 
-        match kind {
-            Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
+        unsafe {
+            let kind = super::LLVMRustGetDiagInfoKind(di);
+            match kind {
+                Dk::InlineAsm => InlineAsm(InlineAsmDiagnostic::unpackInlineAsm(di)),
 
-            Dk::OptimizationRemark => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
-            }
-            Dk::OptimizationRemarkOther => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
-            }
-            Dk::OptimizationRemarkMissed => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
-            }
+                Dk::OptimizationRemark => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationRemark, di))
+                }
+                Dk::OptimizationRemarkOther => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationRemarkOther, di))
+                }
+                Dk::OptimizationRemarkMissed => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationMissed, di))
+                }
 
-            Dk::OptimizationRemarkAnalysis => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
-            }
+                Dk::OptimizationRemarkAnalysis => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysis, di))
+                }
 
-            Dk::OptimizationRemarkAnalysisFPCommute => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
-            }
+                Dk::OptimizationRemarkAnalysisFPCommute => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisFPCommute, di))
+                }
 
-            Dk::OptimizationRemarkAnalysisAliasing => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
-            }
+                Dk::OptimizationRemarkAnalysisAliasing => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationAnalysisAliasing, di))
+                }
 
-            Dk::OptimizationFailure => {
-                Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
-            }
+                Dk::OptimizationFailure => {
+                    Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di))
+                }
 
-            Dk::PGOProfile => PGO(di),
-            Dk::Linker => Linker(di),
-            Dk::Unsupported => Unsupported(di),
+                Dk::PGOProfile => PGO(di),
+                Dk::Linker => Linker(di),
+                Dk::Unsupported => Unsupported(di),
 
-            Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
+                Dk::SrcMgr => InlineAsm(InlineAsmDiagnostic::unpackSrcMgr(di)),
 
-            _ => UnknownDiagnostic(di),
+                _ => UnknownDiagnostic(di),
+            }
         }
     }
 }
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 0e89e66be49..98dc8ac86d2 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -49,12 +49,16 @@ unsafe fn configure_llvm(sess: &Session) {
     let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
     let mut llvm_args = Vec::with_capacity(n_args + 1);
 
-    llvm::LLVMRustInstallErrorHandlers();
+    unsafe {
+        llvm::LLVMRustInstallErrorHandlers();
+    }
     // On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
     // box for the purpose of launching a debugger. However, on CI this will
     // cause it to hang until it times out, which can take several hours.
     if std::env::var_os("CI").is_some() {
-        llvm::LLVMRustDisableSystemDialogsOnCrash();
+        unsafe {
+            llvm::LLVMRustDisableSystemDialogsOnCrash();
+        }
     }
 
     fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
@@ -124,12 +128,12 @@ unsafe fn configure_llvm(sess: &Session) {
     }
 
     if sess.opts.unstable_opts.llvm_time_trace {
-        llvm::LLVMRustTimeTraceProfilerInitialize();
+        unsafe { llvm::LLVMRustTimeTraceProfilerInitialize() };
     }
 
     rustc_llvm::initialize_available_targets();
 
-    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
+    unsafe { llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr()) };
 }
 
 pub fn time_trace_profiler_finish(file_name: &Path) {
@@ -442,8 +446,8 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
             let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
                 .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
             unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
-                let out = &mut *(out as *mut &mut String);
-                let bytes = slice::from_raw_parts(string as *const u8, len);
+                let out = unsafe { &mut *(out as *mut &mut String) };
+                let bytes = unsafe { slice::from_raw_parts(string as *const u8, len) };
                 write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap();
             }
             unsafe {
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index a7df08421a3..282a186be99 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -108,8 +108,8 @@ impl CodegenCx<'_, '_> {
         llval: &llvm::Value,
         is_declaration: bool,
     ) -> bool {
-        let linkage = llvm::LLVMRustGetLinkage(llval);
-        let visibility = llvm::LLVMRustGetVisibility(llval);
+        let linkage = unsafe { llvm::LLVMRustGetLinkage(llval) };
+        let visibility = unsafe { llvm::LLVMRustGetVisibility(llval) };
 
         if matches!(linkage, llvm::Linkage::InternalLinkage | llvm::Linkage::PrivateLinkage) {
             return true;
@@ -145,8 +145,8 @@ impl CodegenCx<'_, '_> {
         }
 
         // Thread-local variables generally don't support copy relocations.
-        let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
-            .is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
+        let is_thread_local_var = unsafe { llvm::LLVMIsAGlobalVariable(llval) }
+            .is_some_and(|v| unsafe { llvm::LLVMIsThreadLocal(v) } == llvm::True);
         if is_thread_local_var {
             return false;
         }
diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs
index cb6244050df..5291cad148e 100644
--- a/compiler/rustc_codegen_ssa/src/back/lto.rs
+++ b/compiler/rustc_codegen_ssa/src/back/lto.rs
@@ -72,7 +72,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
                 B::optimize_fat(cgcx, &mut module)?;
                 Ok(module)
             }
-            LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin),
+            LtoModuleCodegen::Thin(thin) => unsafe { B::optimize_thin(cgcx, thin) },
         }
     }
 
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index e5366c9b518..1365afbce1c 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -33,7 +33,7 @@ pub unsafe extern "C" fn LLVMRustStringWriteImpl(
     ptr: *const c_char,
     size: size_t,
 ) {
-    let slice = slice::from_raw_parts(ptr as *const u8, size);
+    let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) };
 
     sr.bytes.borrow_mut().extend_from_slice(slice);
 }
diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs
index 5e256dc8d26..7b5ccae3568 100644
--- a/compiler/rustc_middle/src/ty/context/tls.rs
+++ b/compiler/rustc_middle/src/ty/context/tls.rs
@@ -67,7 +67,7 @@ fn erase(context: &ImplicitCtxt<'_, '_>) -> *const () {
 
 #[inline]
 unsafe fn downcast<'a, 'tcx>(context: *const ()) -> &'a ImplicitCtxt<'a, 'tcx> {
-    &*(context as *const ImplicitCtxt<'a, 'tcx>)
+    unsafe { &*(context as *const ImplicitCtxt<'a, 'tcx>) }
 }
 
 /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index a9dca47ab43..00ea87690c1 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -257,7 +257,6 @@ TrivialTypeTraversalImpls! {
     crate::ty::adjustment::PointerCoercion,
     ::rustc_span::Span,
     ::rustc_span::symbol::Ident,
-    ::rustc_errors::ErrorGuaranteed,
     ty::BoundVar,
     ty::ValTree<'tcx>,
 }
@@ -443,13 +442,14 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
                 pat.visit_with(visitor)
             }
 
+            ty::Error(guar) => guar.visit_with(visitor),
+
             ty::Bool
             | ty::Char
             | ty::Str
             | ty::Int(_)
             | ty::Uint(_)
             | ty::Float(_)
-            | ty::Error(_)
             | ty::Infer(_)
             | ty::Bound(..)
             | ty::Placeholder(..)
@@ -602,6 +602,21 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
     }
 }
 
+impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
+    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
+        visitor.visit_error(*self)
+    }
+}
+
+impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
+    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
+        self,
+        _folder: &mut F,
+    ) -> Result<Self, F::Error> {
+        Ok(self)
+    }
+}
+
 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
     fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
         self,
@@ -617,12 +632,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
     }
 }
 
-impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
-    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
-        self.args.visit_with(visitor)
-    }
-}
-
 impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
     fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
         visitor.visit_ty(self.ty)
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 98de4df3ce3..fc4e9ebec0a 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1547,10 +1547,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         start_block: BasicBlock,
         candidates: &'b mut [&'c mut Candidate<'pat, 'tcx>],
     ) -> BlockAnd<&'b mut [&'c mut Candidate<'pat, 'tcx>]> {
-        // We can't expand or-patterns freely. The rule is: if the candidate has an
-        // or-pattern as its only remaining match pair, we can expand it freely. If it has
-        // other match pairs, we can expand it but we can't process more candidates after
-        // it.
+        // We can't expand or-patterns freely. The rule is:
+        // - If a candidate doesn't start with an or-pattern, we include it in
+        //   the expansion list as-is (i.e. it "expands" to itself).
+        // - If a candidate has an or-pattern as its only remaining match pair,
+        //   we can expand it.
+        // - If it starts with an or-pattern but also has other match pairs,
+        //   we can expand it, but we can't process more candidates after it.
         //
         // If we didn't stop, the `otherwise` cases could get mixed up. E.g. in the
         // following, or-pattern simplification (in `merge_trivial_subcandidates`) makes it
@@ -1567,17 +1570,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // }
         // ```
         //
-        // We therefore split the `candidates` slice in two, expand or-patterns in the first half,
+        // We therefore split the `candidates` slice in two, expand or-patterns in the first part,
         // and process the rest separately.
-        let mut expand_until = 0;
-        for (i, candidate) in candidates.iter().enumerate() {
-            expand_until = i + 1;
-            if candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern() {
-                // The candidate has an or-pattern as well as more match pairs: we must
-                // split the candidates list here.
-                break;
-            }
-        }
+        let expand_until = candidates
+            .iter()
+            .position(|candidate| {
+                // If a candidate starts with an or-pattern and has more match pairs,
+                // we can expand it, but we must stop expanding _after_ it.
+                candidate.match_pairs.len() > 1 && candidate.starts_with_or_pattern()
+            })
+            .map(|pos| pos + 1) // Stop _after_ the found candidate
+            .unwrap_or(candidates.len()); // Otherwise, include all candidates
         let (candidates_to_expand, remaining_candidates) = candidates.split_at_mut(expand_until);
 
         // Expand one level of or-patterns for each candidate in `candidates_to_expand`.
@@ -1592,6 +1595,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     expanded_candidates.push(subcandidate);
                 }
             } else {
+                // A candidate that doesn't start with an or-pattern has nothing to
+                // expand, so it is included in the post-expansion list as-is.
                 expanded_candidates.push(candidate);
             }
         }
diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index 7da7dc610ec..d9e1ebaf0bc 100644
--- a/compiler/rustc_span/src/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
@@ -35,25 +35,25 @@ pub fn analyze_source_file(
 
 cfg_match! {
     cfg(any(target_arch = "x86", target_arch = "x86_64")) => {
-        fn analyze_source_file_dispatch(src: &str,
-                                    lines: &mut Vec<RelativeBytePos>,
-                                    multi_byte_chars: &mut Vec<MultiByteChar>,
-                                    non_narrow_chars: &mut Vec<NonNarrowChar>) {
+        fn analyze_source_file_dispatch(
+            src: &str,
+            lines: &mut Vec<RelativeBytePos>,
+            multi_byte_chars: &mut Vec<MultiByteChar>,
+            non_narrow_chars: &mut Vec<NonNarrowChar>,
+        ) {
             if is_x86_feature_detected!("sse2") {
                 unsafe {
-                    analyze_source_file_sse2(src,
-                                         lines,
-                                         multi_byte_chars,
-                                         non_narrow_chars);
+                    analyze_source_file_sse2(src, lines, multi_byte_chars, non_narrow_chars);
                 }
             } else {
-                analyze_source_file_generic(src,
-                                        src.len(),
-                                        RelativeBytePos::from_u32(0),
-                                        lines,
-                                        multi_byte_chars,
-                                        non_narrow_chars);
-
+                analyze_source_file_generic(
+                    src,
+                    src.len(),
+                    RelativeBytePos::from_u32(0),
+                    lines,
+                    multi_byte_chars,
+                    non_narrow_chars,
+                );
             }
         }
 
@@ -62,10 +62,12 @@ cfg_match! {
         /// function falls back to the generic implementation. Otherwise it uses
         /// SSE2 intrinsics to quickly find all newlines.
         #[target_feature(enable = "sse2")]
-        unsafe fn analyze_source_file_sse2(src: &str,
-                                       lines: &mut Vec<RelativeBytePos>,
-                                       multi_byte_chars: &mut Vec<MultiByteChar>,
-                                       non_narrow_chars: &mut Vec<NonNarrowChar>) {
+        unsafe fn analyze_source_file_sse2(
+            src: &str,
+            lines: &mut Vec<RelativeBytePos>,
+            multi_byte_chars: &mut Vec<MultiByteChar>,
+            non_narrow_chars: &mut Vec<NonNarrowChar>,
+        ) {
             #[cfg(target_arch = "x86")]
             use std::arch::x86::*;
             #[cfg(target_arch = "x86_64")]
@@ -83,17 +85,17 @@ cfg_match! {
             // handled it.
             let mut intra_chunk_offset = 0;
 
-            for chunk_index in 0 .. chunk_count {
+            for chunk_index in 0..chunk_count {
                 let ptr = src_bytes.as_ptr() as *const __m128i;
                 // We don't know if the pointer is aligned to 16 bytes, so we
                 // use `loadu`, which supports unaligned loading.
-                let chunk = _mm_loadu_si128(ptr.add(chunk_index));
+                let chunk = unsafe { _mm_loadu_si128(ptr.add(chunk_index)) };
 
                 // For character in the chunk, see if its byte value is < 0, which
                 // indicates that it's part of a UTF-8 char.
-                let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
+                let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
                 // Create a bit mask from the comparison results.
-                let multibyte_mask = _mm_movemask_epi8(multibyte_test);
+                let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
 
                 // If the bit mask is all zero, we only have ASCII chars here:
                 if multibyte_mask == 0 {
@@ -102,19 +104,19 @@ cfg_match! {
                     // Check if there are any control characters in the chunk. All
                     // control characters that we can encounter at this point have a
                     // byte value less than 32 or ...
-                    let control_char_test0 = _mm_cmplt_epi8(chunk, _mm_set1_epi8(32));
-                    let control_char_mask0 = _mm_movemask_epi8(control_char_test0);
+                    let control_char_test0 = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(32)) };
+                    let control_char_mask0 = unsafe { _mm_movemask_epi8(control_char_test0) };
 
                     // ... it's the ASCII 'DEL' character with a value of 127.
-                    let control_char_test1 = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127));
-                    let control_char_mask1 = _mm_movemask_epi8(control_char_test1);
+                    let control_char_test1 = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(127)) };
+                    let control_char_mask1 = unsafe { _mm_movemask_epi8(control_char_test1) };
 
                     let control_char_mask = control_char_mask0 | control_char_mask1;
 
                     if control_char_mask != 0 {
                         // Check for newlines in the chunk
-                        let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
-                        let newlines_mask = _mm_movemask_epi8(newlines_test);
+                        let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
+                        let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
 
                         if control_char_mask == newlines_mask {
                             // All control characters are newlines, record them
@@ -126,7 +128,7 @@ cfg_match! {
 
                                 if index >= CHUNK_SIZE as u32 {
                                     // We have arrived at the end of the chunk.
-                                    break
+                                    break;
                                 }
 
                                 lines.push(RelativeBytePos(index) + output_offset);
@@ -137,14 +139,14 @@ cfg_match! {
 
                             // We are done for this chunk. All control characters were
                             // newlines and we took care of those.
-                            continue
+                            continue;
                         } else {
                             // Some of the control characters are not newlines,
                             // fall through to the slow path below.
                         }
                     } else {
                         // No control characters, nothing to record for this chunk
-                        continue
+                        continue;
                     }
                 }
 
@@ -152,43 +154,48 @@ cfg_match! {
                 // There are control chars in here, fallback to generic decoding.
                 let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset;
                 intra_chunk_offset = analyze_source_file_generic(
-                    &src[scan_start .. ],
+                    &src[scan_start..],
                     CHUNK_SIZE - intra_chunk_offset,
                     RelativeBytePos::from_usize(scan_start),
                     lines,
                     multi_byte_chars,
-                    non_narrow_chars
+                    non_narrow_chars,
                 );
             }
 
             // There might still be a tail left to analyze
             let tail_start = chunk_count * CHUNK_SIZE + intra_chunk_offset;
             if tail_start < src.len() {
-                analyze_source_file_generic(&src[tail_start ..],
-                                        src.len() - tail_start,
-                                        RelativeBytePos::from_usize(tail_start),
-                                        lines,
-                                        multi_byte_chars,
-                                        non_narrow_chars);
+                analyze_source_file_generic(
+                    &src[tail_start..],
+                    src.len() - tail_start,
+                    RelativeBytePos::from_usize(tail_start),
+                    lines,
+                    multi_byte_chars,
+                    non_narrow_chars,
+                );
             }
         }
     }
     _ => {
         // The target (or compiler version) does not support SSE2 ...
-        fn analyze_source_file_dispatch(src: &str,
-                                    lines: &mut Vec<RelativeBytePos>,
-                                    multi_byte_chars: &mut Vec<MultiByteChar>,
-                                    non_narrow_chars: &mut Vec<NonNarrowChar>) {
-            analyze_source_file_generic(src,
-                                    src.len(),
-                                    RelativeBytePos::from_u32(0),
-                                    lines,
-                                    multi_byte_chars,
-                                    non_narrow_chars);
+        fn analyze_source_file_dispatch(
+            src: &str,
+            lines: &mut Vec<RelativeBytePos>,
+            multi_byte_chars: &mut Vec<MultiByteChar>,
+            non_narrow_chars: &mut Vec<NonNarrowChar>,
+        ) {
+            analyze_source_file_generic(
+                src,
+                src.len(),
+                RelativeBytePos::from_u32(0),
+                lines,
+                multi_byte_chars,
+                non_narrow_chars,
+            );
         }
     }
 }
-
 // `scan_len` determines the number of bytes in `src` to scan. Note that the
 // function can read past `scan_len` if a multi-byte character start within the
 // range but extends past it. The overflow is returned by the function.
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index f8843b892db..2bf582dcfb1 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -466,7 +466,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             && let Some(arg_ty) = typeck_results.expr_ty_adjusted_opt(expr)
         {
             // Suggest dereferencing the argument to a function/method call if possible
-
             let mut real_trait_pred = trait_pred;
             while let Some((parent_code, parent_trait_pred)) = code.parent() {
                 code = parent_code;
@@ -553,6 +552,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         );
                         if self.predicate_may_hold(&obligation)
                             && self.predicate_must_hold_modulo_regions(&sized_obligation)
+                            // Do not suggest * if it is already a reference,
+                            // will suggest removing the borrow instead in that case.
+                            && !matches!(expr.kind, hir::ExprKind::AddrOf(..))
                         {
                             let call_node = self.tcx.hir_node(*call_hir_id);
                             let msg = "consider dereferencing here";
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 25eb56fe3fb..6ec38b78fc2 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -101,8 +101,12 @@ pub trait TypeVisitor<I: Interner>: Sized {
 
     // The default region visitor is a no-op because `Region` is non-recursive
     // and has no `super_visit_with` method to call.
-    fn visit_region(&mut self, _r: I::Region) -> Self::Result {
-        Self::Result::output()
+    fn visit_region(&mut self, r: I::Region) -> Self::Result {
+        if let ty::ReError(guar) = r.kind() {
+            self.visit_error(guar)
+        } else {
+            Self::Result::output()
+        }
     }
 
     fn visit_const(&mut self, c: I::Const) -> Self::Result {
@@ -116,6 +120,10 @@ pub trait TypeVisitor<I: Interner>: Sized {
     fn visit_clauses(&mut self, p: I::Clauses) -> Self::Result {
         p.super_visit_with(self)
     }
+
+    fn visit_error(&mut self, _guar: I::ErrorGuaranteed) -> Self::Result {
+        Self::Result::output()
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -439,6 +447,15 @@ impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
             ControlFlow::Continue(())
         }
     }
+
+    #[inline]
+    fn visit_error(&mut self, _guar: <I as Interner>::ErrorGuaranteed) -> Self::Result {
+        if self.flags.intersects(TypeFlags::HAS_ERROR) {
+            ControlFlow::Break(FoundFlags)
+        } else {
+            ControlFlow::Continue(())
+        }
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
@@ -547,27 +564,7 @@ struct HasErrorVisitor;
 impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
     type Result = ControlFlow<I::ErrorGuaranteed>;
 
-    fn visit_ty(&mut self, t: <I as Interner>::Ty) -> Self::Result {
-        if let ty::Error(guar) = t.kind() {
-            ControlFlow::Break(guar)
-        } else {
-            t.super_visit_with(self)
-        }
-    }
-
-    fn visit_const(&mut self, c: <I as Interner>::Const) -> Self::Result {
-        if let ty::ConstKind::Error(guar) = c.kind() {
-            ControlFlow::Break(guar)
-        } else {
-            c.super_visit_with(self)
-        }
-    }
-
-    fn visit_region(&mut self, r: <I as Interner>::Region) -> Self::Result {
-        if let ty::ReError(guar) = r.kind() {
-            ControlFlow::Break(guar)
-        } else {
-            ControlFlow::Continue(())
-        }
+    fn visit_error(&mut self, guar: <I as Interner>::ErrorGuaranteed) -> Self::Result {
+        ControlFlow::Break(guar)
     }
 }
diff --git a/library/std/src/sys/pal/teeos/alloc.rs b/library/std/src/sys/pal/teeos/alloc.rs
index e236819aa23..b280d1dd76f 100644
--- a/library/std/src/sys/pal/teeos/alloc.rs
+++ b/library/std/src/sys/pal/teeos/alloc.rs
@@ -11,9 +11,9 @@ unsafe impl GlobalAlloc for System {
         // Also see <https://github.com/rust-lang/rust/issues/45955> and
         // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::malloc(layout.size()) as *mut u8
+            unsafe { libc::malloc(layout.size()) as *mut u8 }
         } else {
-            aligned_malloc(&layout)
+            unsafe { aligned_malloc(&layout) }
         }
     }
 
@@ -21,11 +21,11 @@ unsafe impl GlobalAlloc for System {
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
         // See the comment above in `alloc` for why this check looks the way it does.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-            libc::calloc(layout.size(), 1) as *mut u8
+            unsafe { libc::calloc(layout.size(), 1) as *mut u8 }
         } else {
-            let ptr = self.alloc(layout);
+            let ptr = unsafe { self.alloc(layout) };
             if !ptr.is_null() {
-                ptr::write_bytes(ptr, 0, layout.size());
+                unsafe { ptr::write_bytes(ptr, 0, layout.size()) };
             }
             ptr
         }
@@ -33,15 +33,15 @@ unsafe impl GlobalAlloc for System {
 
     #[inline]
     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-        libc::free(ptr as *mut libc::c_void)
+        unsafe { libc::free(ptr as *mut libc::c_void) }
     }
 
     #[inline]
     unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
         if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
-            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
+            unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 }
         } else {
-            realloc_fallback(self, ptr, layout, new_size)
+            unsafe { realloc_fallback(self, ptr, layout, new_size) }
         }
     }
 }
@@ -52,6 +52,6 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
     // Since these are all powers of 2, we can just use max.
     let align = layout.align().max(crate::mem::size_of::<usize>());
-    let ret = libc::posix_memalign(&mut out, align, layout.size());
+    let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
     if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
 }
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index 2a789e72722..adefd1bb42c 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! This module contains the facade (aka platform-specific) implementations of
 //! OS level functionality for Teeos.
-#![allow(unsafe_op_in_unsafe_fn)]
+#![deny(unsafe_op_in_unsafe_fn)]
 #![allow(unused_variables)]
 #![allow(dead_code)]
 
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index f4723b2ea46..7a27d749f1c 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -28,22 +28,24 @@ impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
         let p = Box::into_raw(Box::new(p));
-        let mut native: libc::pthread_t = mem::zeroed();
-        let mut attr: libc::pthread_attr_t = mem::zeroed();
-        assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+        let mut native: libc::pthread_t = unsafe { mem::zeroed() };
+        let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() };
+        assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0);
         assert_eq!(
-            libc::pthread_attr_settee(
-                &mut attr,
-                libc::TEESMP_THREAD_ATTR_CA_INHERIT,
-                libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT,
-                libc::TEESMP_THREAD_ATTR_HAS_SHADOW,
-            ),
+            unsafe {
+                libc::pthread_attr_settee(
+                    &mut attr,
+                    libc::TEESMP_THREAD_ATTR_CA_INHERIT,
+                    libc::TEESMP_THREAD_ATTR_TASK_ID_INHERIT,
+                    libc::TEESMP_THREAD_ATTR_HAS_SHADOW,
+                )
+            },
             0,
         );
 
         let stack_size = cmp::max(stack, min_stack_size(&attr));
 
-        match libc::pthread_attr_setstacksize(&mut attr, stack_size) {
+        match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } {
             0 => {}
             n => {
                 assert_eq!(n, libc::EINVAL);
@@ -54,7 +56,7 @@ impl Thread {
                 let page_size = os::page_size();
                 let stack_size =
                     (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1);
-                assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0);
+                assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0);
             }
         };
 
@@ -62,12 +64,12 @@ impl Thread {
         // Note: if the thread creation fails and this assert fails, then p will
         // be leaked. However, an alternative design could cause double-free
         // which is clearly worse.
-        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        assert_eq!(unsafe { libc::pthread_attr_destroy(&mut attr) }, 0);
 
         return if ret != 0 {
             // The thread failed to start and as a result p was not consumed. Therefore, it is
             // safe to reconstruct the box so that it gets deallocated.
-            drop(Box::from_raw(p));
+            drop(unsafe { Box::from_raw(p) });
             Err(io::Error::from_raw_os_error(ret))
         } else {
             // The new thread will start running earliest after the next yield.
diff --git a/library/std/src/sys/sync/condvar/teeos.rs b/library/std/src/sys/sync/condvar/teeos.rs
index 0a931f407d2..6457da91c2a 100644
--- a/library/std/src/sys/sync/condvar/teeos.rs
+++ b/library/std/src/sys/sync/condvar/teeos.rs
@@ -76,16 +76,16 @@ impl Condvar {
 
     #[inline]
     pub unsafe fn wait(&self, mutex: &Mutex) {
-        let mutex = mutex::raw(mutex);
+        let mutex = unsafe { mutex::raw(mutex) };
         self.verify(mutex);
-        let r = libc::pthread_cond_wait(raw(self), mutex);
+        let r = unsafe { libc::pthread_cond_wait(raw(self), mutex) };
         debug_assert_eq!(r, 0);
     }
 
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::sys::time::Timespec;
 
-        let mutex = mutex::raw(mutex);
+        let mutex = unsafe { mutex::raw(mutex) };
         self.verify(mutex);
 
         let timeout = Timespec::now(libc::CLOCK_MONOTONIC)
@@ -93,7 +93,7 @@ impl Condvar {
             .and_then(|t| t.to_timespec())
             .unwrap_or(TIMESPEC_MAX);
 
-        let r = pthread_cond_timedwait(raw(self), mutex, &timeout);
+        let r = unsafe { pthread_cond_timedwait(raw(self), mutex, &timeout) };
         assert!(r == libc::ETIMEDOUT || r == 0);
         r == 0
     }
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index ebd62bb032f..71009d56366 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -2001,6 +2001,7 @@ impl<'a> Builder<'a> {
             // FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
             // of the individual lints are satisfied.
             rustflags.arg("-Wkeyword_idents_2024");
+            rustflags.arg("-Wunsafe_op_in_unsafe_fn");
         }
 
         if self.config.rust_frame_pointers {
diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml
index 969552dec84..681284b1a48 100644
--- a/src/tools/run-make-support/Cargo.toml
+++ b/src/tools/run-make-support/Cargo.toml
@@ -9,7 +9,7 @@ object = "0.34.0"
 similar = "2.5.0"
 wasmparser = "0.118.2"
 regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace
-gimli = "0.28.1"
+gimli = "0.31.0"
 ar = "0.9.0"
 
 build_helper = { path = "../build_helper" }
diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs
new file mode 100644
index 00000000000..a71657316ae
--- /dev/null
+++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.rs
@@ -0,0 +1,18 @@
+fn main() {
+    let fields = vec![1];
+    let variant = vec![2];
+
+    // should not suggest `*&variant.iter()`
+    for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
+        //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
+        //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
+        eprintln!("{} {}", src, dest);
+    }
+
+    // don't suggest add `variant.iter().clone().clone()`
+    for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
+        //~^ ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
+        //~| ERROR `&std::slice::Iter<'_, {integer}>` is not an iterator
+        eprintln!("{} {}", src, dest);
+    }
+}
diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr
new file mode 100644
index 00000000000..a3ed51ace08
--- /dev/null
+++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr
@@ -0,0 +1,61 @@
+error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
+  --> $DIR/invalid-suggest-deref-issue-127590.rs:6:54
+   |
+LL |     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
+   |                        --------------                ^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
+   |                        |
+   |                        required by a bound introduced by this call
+   |
+   = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
+   = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
+note: required by a bound in `std::iter::zip`
+  --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
+help: consider removing the leading `&`-reference
+   |
+LL -     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
+LL +     for (src, dest) in std::iter::zip(fields.iter(), variant.iter()) {
+   |
+
+error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
+  --> $DIR/invalid-suggest-deref-issue-127590.rs:6:24
+   |
+LL |     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) {
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
+   = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
+   = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
+   = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
+
+error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
+  --> $DIR/invalid-suggest-deref-issue-127590.rs:13:54
+   |
+LL |     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
+   |                        --------------                ^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
+   |                        |
+   |                        required by a bound introduced by this call
+   |
+   = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `&std::slice::Iter<'_, {integer}>: IntoIterator`
+   = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator`
+note: required by a bound in `std::iter::zip`
+  --> $SRC_DIR/core/src/iter/adapters/zip.rs:LL:COL
+help: consider removing the leading `&`-reference
+   |
+LL -     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
+LL +     for (src, dest) in std::iter::zip(fields.iter(), variant.iter().clone()) {
+   |
+
+error[E0277]: `&std::slice::Iter<'_, {integer}>` is not an iterator
+  --> $DIR/invalid-suggest-deref-issue-127590.rs:13:24
+   |
+LL |     for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone()) {
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&std::slice::Iter<'_, {integer}>` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>`, which is required by `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>: IntoIterator`
+   = help: the trait `Iterator` is implemented for `std::slice::Iter<'a, T>`
+   = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `Iterator`
+   = note: required for `Zip<std::slice::Iter<'_, {integer}>, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.