about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs8
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs20
-rw-r--r--compiler/rustc_borrowck/src/lib.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs76
-rw-r--r--compiler/rustc_borrowck/src/root_cx.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs72
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs71
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs53
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/opaque_types.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs28
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs4
-rw-r--r--compiler/rustc_interface/src/util.rs74
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp52
-rw-r--r--compiler/rustc_middle/src/arena.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs7
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs4
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs4
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs17
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs45
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs2
34 files changed, 446 insertions, 231 deletions
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index c9be5575da5..7c9011505d6 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -426,7 +426,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     }
 
     pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> {
-        struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,)
+        struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path)
     }
 
     pub(crate) fn cannot_return_reference_to_local(
@@ -480,7 +480,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
     }
 
     pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> {
-        struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",)
+        struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed")
     }
 }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 7e20a5133e0..efb622e2155 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2992,6 +2992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         self.buffer_error(err);
     }
 
+    #[tracing::instrument(level = "debug", skip(self, explanation))]
     fn report_local_value_does_not_live_long_enough(
         &self,
         location: Location,
@@ -3001,13 +3002,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         borrow_spans: UseSpans<'tcx>,
         explanation: BorrowExplanation<'tcx>,
     ) -> Diag<'infcx> {
-        debug!(
-            "report_local_value_does_not_live_long_enough(\
-             {:?}, {:?}, {:?}, {:?}, {:?}\
-             )",
-            location, name, borrow, drop_span, borrow_spans
-        );
-
         let borrow_span = borrow_spans.var_or_use_path_span();
         if let BorrowExplanation::MustBeValidFor {
             category,
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 7ca07bb9b43..638d89f5bcb 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -416,6 +416,26 @@ impl<'tcx> BorrowExplanation<'tcx> {
                 {
                     self.add_object_lifetime_default_note(tcx, err, unsize_ty);
                 }
+
+                let mut preds = path
+                    .iter()
+                    .filter_map(|constraint| match constraint.category {
+                        ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred),
+                        _ => None,
+                    })
+                    .collect::<Vec<Span>>();
+                preds.sort();
+                preds.dedup();
+                if !preds.is_empty() {
+                    let s = if preds.len() == 1 { "" } else { "s" };
+                    err.span_note(
+                        preds,
+                        format!(
+                            "requirement{s} that the value outlives `{region_name}` introduced here"
+                        ),
+                    );
+                }
+
                 self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
             }
             _ => {}
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 4c380ddcf70..268cb47fd12 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) {
 fn mir_borrowck(
     tcx: TyCtxt<'_>,
     def: LocalDefId,
-) -> Result<&ConcreteOpaqueTypes<'_>, ErrorGuaranteed> {
+) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> {
     assert!(!tcx.is_typeck_child(def.to_def_id()));
     let (input_body, _) = tcx.mir_promoted(def);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
@@ -130,7 +130,7 @@ fn mir_borrowck(
         Err(guar)
     } else if input_body.should_skip() {
         debug!("Skipping borrowck because of injected body");
-        let opaque_types = ConcreteOpaqueTypes(Default::default());
+        let opaque_types = DefinitionSiteHiddenTypes(Default::default());
         Ok(tcx.arena.alloc(opaque_types))
     } else {
         let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None);
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 0910e8ef4b3..e98c60e6338 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1382,10 +1382,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     }
 
     /// The constraints we get from equating the hidden type of each use of an opaque
-    /// with its final concrete type may end up getting preferred over other, potentially
+    /// with its final hidden type may end up getting preferred over other, potentially
     /// longer constraint paths.
     ///
-    /// Given that we compute the final concrete type by relying on this existing constraint
+    /// Given that we compute the final hidden type by relying on this existing constraint
     /// path, this can easily end up hiding the actual reason for why we require these regions
     /// to be equal.
     ///
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
index 0af636aa734..8d89f3e0d87 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs
@@ -8,7 +8,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries};
 use rustc_infer::traits::ObligationCause;
 use rustc_macros::extension;
-use rustc_middle::mir::{Body, ConcreteOpaqueTypes, ConstraintCategory};
+use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes};
 use rustc_middle::ty::{
     self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef,
     OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable,
@@ -129,9 +129,9 @@ fn nll_var_to_universal_region<'tcx>(
 /// Collect all defining uses of opaque types inside of this typeck root. This
 /// expects the hidden type to be mapped to the definition parameters of the opaque
 /// and errors if we end up with distinct hidden types.
-fn add_concrete_opaque_type<'tcx>(
+fn add_hidden_type<'tcx>(
     tcx: TyCtxt<'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     def_id: LocalDefId,
     hidden_ty: OpaqueHiddenType<'tcx>,
 ) {
@@ -139,7 +139,7 @@ fn add_concrete_opaque_type<'tcx>(
     // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
     // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
     // only know that once we convert the generic parameters to those of the opaque type.
-    if let Some(prev) = concrete_opaque_types.0.get_mut(&def_id) {
+    if let Some(prev) = hidden_types.0.get_mut(&def_id) {
         if prev.ty != hidden_ty.ty {
             let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| {
                 let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
@@ -151,15 +151,15 @@ fn add_concrete_opaque_type<'tcx>(
         // FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
         prev.span = prev.span.substitute_dummy(hidden_ty.span);
     } else {
-        concrete_opaque_types.0.insert(def_id, hidden_ty);
+        hidden_types.0.insert(def_id, hidden_ty);
     }
 }
 
-fn get_concrete_opaque_type<'tcx>(
-    concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
+fn get_hidden_type<'tcx>(
+    hidden_types: &DefinitionSiteHiddenTypes<'tcx>,
     def_id: LocalDefId,
 ) -> Option<EarlyBinder<'tcx, OpaqueHiddenType<'tcx>>> {
-    concrete_opaque_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
+    hidden_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty))
 }
 
 #[derive(Debug)]
@@ -173,22 +173,22 @@ struct DefiningUse<'tcx> {
 }
 
 /// This computes the actual hidden types of the opaque types and maps them to their
-/// definition sites. Outside of registering the computed concrete types this function
+/// definition sites. Outside of registering the computed hidden types this function
 /// does not mutate the current borrowck state.
 ///
 /// While it may fail to infer the hidden type and return errors, we always apply
-/// the computed concrete hidden type to all opaque type uses to check whether they
+/// the computed hidden type to all opaque type uses to check whether they
 /// are correct. This is necessary to support non-defining uses of opaques in their
 /// defining scope.
 ///
 /// It also means that this whole function is not really soundness critical as we
 /// recheck all uses of the opaques regardless.
-pub(crate) fn compute_concrete_opaque_types<'tcx>(
+pub(crate) fn compute_definition_site_hidden_types<'tcx>(
     infcx: &BorrowckInferCtxt<'tcx>,
     universal_region_relations: &Frozen<UniversalRegionRelations<'tcx>>,
     constraints: &MirTypeckRegionConstraints<'tcx>,
     location_map: Rc<DenseLocationMap>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
 ) -> Vec<DeferredOpaqueTypeError<'tcx>> {
     let mut errors = Vec::new();
@@ -201,8 +201,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
     // We start by checking each use of an opaque type during type check and
     // check whether the generic arguments of the opaque type are fully
     // universal, if so, it's a defining use.
-    let defining_uses =
-        collect_defining_uses(&mut rcx, concrete_opaque_types, opaque_types, &mut errors);
+    let defining_uses = collect_defining_uses(&mut rcx, hidden_types, opaque_types, &mut errors);
 
     // We now compute and apply member constraints for all regions in the hidden
     // types of each defining use. This mutates the region values of the `rcx` which
@@ -210,11 +209,11 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
     apply_member_constraints(&mut rcx, &defining_uses);
 
     // After applying member constraints, we now check whether all member regions ended
-    // up equal to one of their choice regions and compute the actual concrete type of
+    // up equal to one of their choice regions and compute the actual hidden type of
     // the opaque type definition. This is stored in the `root_cx`.
-    compute_concrete_types_from_defining_uses(
+    compute_definition_site_hidden_types_from_defining_uses(
         &rcx,
-        concrete_opaque_types,
+        hidden_types,
         &defining_uses,
         &mut errors,
     );
@@ -224,7 +223,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>(
 #[instrument(level = "debug", skip_all, ret)]
 fn collect_defining_uses<'tcx>(
     rcx: &mut RegionCtxt<'_, 'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
 ) -> Vec<DefiningUse<'tcx>> {
@@ -244,9 +243,9 @@ fn collect_defining_uses<'tcx>(
             // with `TypingMode::Borrowck`.
             if infcx.tcx.use_typing_mode_borrowck() {
                 match err {
-                    NonDefiningUseReason::Tainted(guar) => add_concrete_opaque_type(
+                    NonDefiningUseReason::Tainted(guar) => add_hidden_type(
                         infcx.tcx,
-                        concrete_opaque_types,
+                        hidden_types,
                         opaque_type_key.def_id,
                         OpaqueHiddenType::new_error(infcx.tcx, guar),
                     ),
@@ -277,9 +276,9 @@ fn collect_defining_uses<'tcx>(
     defining_uses
 }
 
-fn compute_concrete_types_from_defining_uses<'tcx>(
+fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
     rcx: &RegionCtxt<'_, 'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     defining_uses: &[DefiningUse<'tcx>],
     errors: &mut Vec<DeferredOpaqueTypeError<'tcx>>,
 ) {
@@ -358,9 +357,9 @@ fn compute_concrete_types_from_defining_uses<'tcx>(
                 },
             ));
         }
-        add_concrete_opaque_type(
+        add_hidden_type(
             tcx,
-            concrete_opaque_types,
+            hidden_types,
             opaque_type_key.def_id,
             OpaqueHiddenType { span: hidden_type.span, ty },
         );
@@ -489,20 +488,20 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
 ///
 /// It does this by equating the hidden type of each use with the instantiated final
 /// hidden type of the opaque.
-pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
+pub(crate) fn apply_definition_site_hidden_types<'tcx>(
     infcx: &BorrowckInferCtxt<'tcx>,
     body: &Body<'tcx>,
     universal_regions: &UniversalRegions<'tcx>,
     region_bound_pairs: &RegionBoundPairs<'tcx>,
     known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>],
     constraints: &mut MirTypeckRegionConstraints<'tcx>,
-    concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>,
+    hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>,
     opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
 ) -> Vec<DeferredOpaqueTypeError<'tcx>> {
     let tcx = infcx.tcx;
     let mut errors = Vec::new();
     for &(key, hidden_type) in opaque_types {
-        let Some(expected) = get_concrete_opaque_type(concrete_opaque_types, key.def_id) else {
+        let Some(expected) = get_hidden_type(hidden_types, key.def_id) else {
             if !tcx.use_typing_mode_borrowck() {
                 if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind()
                     && alias_ty.def_id == key.def_id.to_def_id()
@@ -521,12 +520,7 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
                 hidden_type.span,
                 "non-defining use in the defining scope with no defining uses",
             );
-            add_concrete_opaque_type(
-                tcx,
-                concrete_opaque_types,
-                key.def_id,
-                OpaqueHiddenType::new_error(tcx, guar),
-            );
+            add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
             continue;
         };
 
@@ -566,18 +560,13 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>(
                 "equating opaque types",
             ),
         ) {
-            add_concrete_opaque_type(
-                tcx,
-                concrete_opaque_types,
-                key.def_id,
-                OpaqueHiddenType::new_error(tcx, guar),
-            );
+            add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar));
         }
     }
     errors
 }
 
-/// In theory `apply_concrete_opaque_types` could introduce new uses of opaque types.
+/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types.
 /// We do not check these new uses so this could be unsound.
 ///
 /// We detect any new uses and simply delay a bug if they occur. If this results in
@@ -682,13 +671,6 @@ impl<'tcx> InferCtxt<'tcx> {
     ///
     /// (*) C1 and C2 were introduced in the comments on
     /// `register_member_constraints`. Read that comment for more context.
-    ///
-    /// # Parameters
-    ///
-    /// - `def_id`, the `impl Trait` type
-    /// - `args`, the args used to instantiate this opaque type
-    /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of
-    ///   `opaque_defn.concrete_ty`
     #[instrument(level = "debug", skip(self))]
     fn infer_opaque_definition_from_instantiation(
         &self,
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index cd4e9683f2d..21c11e12873 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -12,12 +12,12 @@ use smallvec::SmallVec;
 use crate::consumers::BorrowckConsumer;
 use crate::nll::compute_closure_requirements_modulo_opaques;
 use crate::region_infer::opaque_types::{
-    apply_computed_concrete_opaque_types, clone_and_resolve_opaque_types,
-    compute_concrete_opaque_types, detect_opaque_types_added_while_handling_opaque_types,
+    apply_definition_site_hidden_types, clone_and_resolve_opaque_types,
+    compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types,
 };
 use crate::type_check::{Locations, constraint_conversion};
 use crate::{
-    ClosureRegionRequirements, CollectRegionConstraintsResult, ConcreteOpaqueTypes,
+    ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes,
     PropagatedBorrowCheckResults, borrowck_check_region_constraints,
     borrowck_collect_region_constraints,
 };
@@ -27,7 +27,7 @@ use crate::{
 pub(super) struct BorrowCheckRootCtxt<'tcx> {
     pub tcx: TyCtxt<'tcx>,
     root_def_id: LocalDefId,
-    concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
+    hidden_types: DefinitionSiteHiddenTypes<'tcx>,
     /// The region constraints computed by [borrowck_collect_region_constraints]. This uses
     /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before
     /// their parents.
@@ -49,7 +49,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
         BorrowCheckRootCtxt {
             tcx,
             root_def_id,
-            concrete_opaque_types: Default::default(),
+            hidden_types: Default::default(),
             collect_region_constraints_results: Default::default(),
             propagated_borrowck_results: Default::default(),
             tainted_by_errors: None,
@@ -72,11 +72,11 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
         &self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars
     }
 
-    pub(super) fn finalize(self) -> Result<&'tcx ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
+    pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
         if let Some(guar) = self.tainted_by_errors {
             Err(guar)
         } else {
-            Ok(self.tcx.arena.alloc(self.concrete_opaque_types))
+            Ok(self.tcx.arena.alloc(self.hidden_types))
         }
     }
 
@@ -88,12 +88,12 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
                 &input.universal_region_relations,
                 &mut input.constraints,
             );
-            input.deferred_opaque_type_errors = compute_concrete_opaque_types(
+            input.deferred_opaque_type_errors = compute_definition_site_hidden_types(
                 &input.infcx,
                 &input.universal_region_relations,
                 &input.constraints,
                 Rc::clone(&input.location_map),
-                &mut self.concrete_opaque_types,
+                &mut self.hidden_types,
                 &opaque_types,
             );
             per_body_info.push((num_entries, opaque_types));
@@ -103,14 +103,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
             self.collect_region_constraints_results.values_mut().zip(per_body_info)
         {
             if input.deferred_opaque_type_errors.is_empty() {
-                input.deferred_opaque_type_errors = apply_computed_concrete_opaque_types(
+                input.deferred_opaque_type_errors = apply_definition_site_hidden_types(
                     &input.infcx,
                     &input.body_owned,
                     &input.universal_region_relations.universal_regions,
                     &input.region_bound_pairs,
                     &input.known_type_outlives_obligations,
                     &mut input.constraints,
-                    &mut self.concrete_opaque_types,
+                    &mut self.hidden_types,
                     &opaque_types,
                 );
             }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index aa5c17269fb..b1da6f7c740 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -34,7 +34,7 @@ use smallvec::SmallVec;
 use crate::back::write::to_llvm_code_model;
 use crate::callee::get_fn;
 use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
-use crate::llvm::Metadata;
+use crate::llvm::{Metadata, MetadataKindId};
 use crate::type_::Type;
 use crate::value::Value;
 use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util};
@@ -1006,11 +1006,11 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
     pub(crate) fn set_metadata<'a>(
         &self,
         val: &'a Value,
-        kind_id: impl Into<llvm::MetadataKindId>,
+        kind_id: MetadataKindId,
         md: &'ll Metadata,
     ) {
         let node = self.get_metadata_value(md);
-        llvm::LLVMSetMetadata(val, kind_id.into(), node);
+        llvm::LLVMSetMetadata(val, kind_id, node);
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
index bc4f6bb6a82..d50eb533ffd 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
@@ -2,26 +2,25 @@
 
 use std::ffi::CString;
 
-use crate::common::AsCCharPtr;
 use crate::coverageinfo::ffi;
 use crate::llvm;
 
 pub(crate) fn covmap_var_name() -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovmapVarNameToString(s);
     }))
     .expect("covmap variable name should not contain NUL")
 }
 
 pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s);
     }))
     .expect("covmap section name should not contain NUL")
 }
 
 pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString {
-    CString::new(llvm::build_byte_buffer(|s| unsafe {
+    CString::new(llvm::build_byte_buffer(|s| {
         llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s);
     }))
     .expect("covfun section name should not contain NUL")
@@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>(
     unsafe {
         llvm::LLVMRustCoverageCreatePGOFuncNameVar(
             llfn,
-            mangled_fn_name.as_c_char_ptr(),
+            mangled_fn_name.as_ptr(),
             mangled_fn_name.len(),
         )
     }
@@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8
     let (pointers, lengths) = filenames
         .into_iter()
         .map(AsRef::as_ref)
-        .map(|s: &str| (s.as_c_char_ptr(), s.len()))
+        .map(|s: &str| (s.as_ptr(), s.len()))
         .unzip::<_, _, Vec<_>, Vec<_>>();
 
     llvm::build_byte_buffer(|buffer| unsafe {
@@ -89,12 +88,12 @@ pub(crate) fn write_function_mappings_to_buffer(
 /// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`,
 /// as required for parts of the LLVM coverage mapping format.
 pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
-    unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) }
+    unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) }
 }
 
 /// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h)
 /// as a raw numeric value. For historical reasons, the numeric value is 1 less
 /// than the number in the version's name, so `Version7` is actually `6u32`.
 pub(crate) fn mapping_version() -> u32 {
-    unsafe { llvm::LLVMRustCoverageMappingVersion() }
+    llvm::LLVMRustCoverageMappingVersion()
 }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 1e4ace4ca92..bc20c759413 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1611,16 +1611,12 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
         let v = [llvm::LLVMValueAsMetadata(cx.const_usize(0)), typeid];
         llvm::LLVMRustGlobalAddMetadata(
             vtable,
-            llvm::MD_type as c_uint,
+            llvm::MD_type,
             llvm::LLVMMDNodeInContext2(cx.llcx, v.as_ptr(), v.len()),
         );
         let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64));
         let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1);
-        llvm::LLVMGlobalSetMetadata(
-            vtable,
-            llvm::MetadataType::MD_vcall_visibility as c_uint,
-            vcall_visibility_metadata,
-        );
+        llvm::LLVMGlobalSetMetadata(vtable, llvm::MD_vcall_visibility, vcall_visibility_metadata);
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index afd2991a09c..e9f92267a7d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -29,6 +29,7 @@ use super::debuginfo::{
     DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind,
 };
 use crate::llvm;
+use crate::llvm::MetadataKindId;
 
 /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
 /// which has a different ABI from Rust or C++ `bool`.
@@ -513,31 +514,6 @@ pub(crate) enum FileType {
     ObjectFile,
 }
 
-/// LLVMMetadataType
-#[derive(Copy, Clone)]
-#[repr(C)]
-#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")]
-pub(crate) enum MetadataType {
-    MD_dbg = 0,
-    MD_tbaa = 1,
-    MD_prof = 2,
-    MD_fpmath = 3,
-    MD_range = 4,
-    MD_tbaa_struct = 5,
-    MD_invariant_load = 6,
-    MD_alias_scope = 7,
-    MD_noalias = 8,
-    MD_nontemporal = 9,
-    MD_mem_parallel_loop_access = 10,
-    MD_nonnull = 11,
-    MD_unpredictable = 15,
-    MD_align = 17,
-    MD_type = 19,
-    MD_vcall_visibility = 28,
-    MD_noundef = 29,
-    MD_kcfi_type = 36,
-}
-
 /// Must match the layout of `LLVMInlineAsmDialect`.
 #[derive(Copy, Clone, PartialEq)]
 #[repr(C)]
@@ -1035,16 +1011,6 @@ pub(crate) type GetSymbolsCallback =
     unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
 pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void;
 
-#[derive(Copy, Clone)]
-#[repr(transparent)]
-pub(crate) struct MetadataKindId(c_uint);
-
-impl From<MetadataType> for MetadataKindId {
-    fn from(value: MetadataType) -> Self {
-        Self(value as c_uint)
-    }
-}
-
 unsafe extern "C" {
     // Create and destroy contexts.
     pub(crate) fn LLVMContextDispose(C: &'static mut Context);
@@ -1139,7 +1105,11 @@ unsafe extern "C" {
     pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t);
     pub(crate) fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value);
     pub(crate) safe fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: MetadataKindId, Node: &'a Value);
-    pub(crate) fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata);
+    pub(crate) fn LLVMGlobalSetMetadata<'a>(
+        Val: &'a Value,
+        KindID: MetadataKindId,
+        Metadata: &'a Metadata,
+    );
     pub(crate) safe fn LLVMValueAsMetadata(Node: &Value) -> &Metadata;
 
     // Operations on constants of any type
@@ -2059,7 +2029,7 @@ unsafe extern "C" {
     // Operations on all values
     pub(crate) fn LLVMRustGlobalAddMetadata<'a>(
         Val: &'a Value,
-        KindID: c_uint,
+        KindID: MetadataKindId,
         Metadata: &'a Metadata,
     );
     pub(crate) fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool;
@@ -2256,8 +2226,11 @@ unsafe extern "C" {
         ConstraintsLen: size_t,
     ) -> bool;
 
+    /// A list of pointer-length strings is passed as two pointer-length slices,
+    /// one slice containing pointers and one slice containing their corresponding
+    /// lengths. The implementation will check that both slices have the same length.
     pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer(
-        Filenames: *const *const c_char,
+        Filenames: *const *const c_uchar, // See "PTR_LEN_STR".
         FilenamesLen: size_t,
         Lengths: *const size_t,
         LengthsLen: size_t,
@@ -2280,18 +2253,25 @@ unsafe extern "C" {
 
     pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar(
         F: &Value,
-        FuncName: *const c_char,
+        FuncName: *const c_uchar, // See "PTR_LEN_STR".
         FuncNameLen: size_t,
     ) -> &Value;
-    pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64;
-
-    pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString);
+    pub(crate) fn LLVMRustCoverageHashBytes(
+        Bytes: *const c_uchar, // See "PTR_LEN_STR".
+        NumBytes: size_t,
+    ) -> u64;
 
-    pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString);
-
-    pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
+    pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString(
+        M: &Module,
+        OutStr: &RustString,
+    );
+    pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString(
+        M: &Module,
+        OutStr: &RustString,
+    );
+    pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
 
-    pub(crate) fn LLVMRustCoverageMappingVersion() -> u32;
+    pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32;
     pub(crate) fn LLVMRustDebugMetadataVersion() -> u32;
     pub(crate) fn LLVMRustVersionMajor() -> u32;
     pub(crate) fn LLVMRustVersionMinor() -> u32;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
new file mode 100644
index 00000000000..a8a671b5c85
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs
@@ -0,0 +1,71 @@
+use libc::c_uint;
+
+pub(crate) use self::fixed_kinds::*;
+
+#[derive(Copy, Clone)]
+#[repr(transparent)]
+pub(crate) struct MetadataKindId(c_uint);
+
+macro_rules! declare_fixed_metadata_kinds {
+    (
+        $(
+            FIXED_MD_KIND($variant:ident, $value:literal)
+        )*
+    ) => {
+        // Use a submodule to group all declarations into one `#[expect(..)]`.
+        #[expect(dead_code)]
+        mod fixed_kinds {
+            use super::MetadataKindId;
+            $(
+                #[expect(non_upper_case_globals)]
+                pub(crate) const $variant: MetadataKindId = MetadataKindId($value);
+            )*
+        }
+    };
+}
+
+// Must be kept in sync with the corresponding static assertions in `RustWrapper.cpp`.
+declare_fixed_metadata_kinds! {
+    FIXED_MD_KIND(MD_dbg, 0)
+    FIXED_MD_KIND(MD_tbaa, 1)
+    FIXED_MD_KIND(MD_prof, 2)
+    FIXED_MD_KIND(MD_fpmath, 3)
+    FIXED_MD_KIND(MD_range, 4)
+    FIXED_MD_KIND(MD_tbaa_struct, 5)
+    FIXED_MD_KIND(MD_invariant_load, 6)
+    FIXED_MD_KIND(MD_alias_scope, 7)
+    FIXED_MD_KIND(MD_noalias, 8)
+    FIXED_MD_KIND(MD_nontemporal, 9)
+    FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+    FIXED_MD_KIND(MD_nonnull, 11)
+    FIXED_MD_KIND(MD_dereferenceable, 12)
+    FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+    FIXED_MD_KIND(MD_make_implicit, 14)
+    FIXED_MD_KIND(MD_unpredictable, 15)
+    FIXED_MD_KIND(MD_invariant_group, 16)
+    FIXED_MD_KIND(MD_align, 17)
+    FIXED_MD_KIND(MD_loop, 18)
+    FIXED_MD_KIND(MD_type, 19)
+    FIXED_MD_KIND(MD_section_prefix, 20)
+    FIXED_MD_KIND(MD_absolute_symbol, 21)
+    FIXED_MD_KIND(MD_associated, 22)
+    FIXED_MD_KIND(MD_callees, 23)
+    FIXED_MD_KIND(MD_irr_loop, 24)
+    FIXED_MD_KIND(MD_access_group, 25)
+    FIXED_MD_KIND(MD_callback, 26)
+    FIXED_MD_KIND(MD_preserve_access_index, 27)
+    FIXED_MD_KIND(MD_vcall_visibility, 28)
+    FIXED_MD_KIND(MD_noundef, 29)
+    FIXED_MD_KIND(MD_annotation, 30)
+    FIXED_MD_KIND(MD_nosanitize, 31)
+    FIXED_MD_KIND(MD_func_sanitize, 32)
+    FIXED_MD_KIND(MD_exclude, 33)
+    FIXED_MD_KIND(MD_memprof, 34)
+    FIXED_MD_KIND(MD_callsite, 35)
+    FIXED_MD_KIND(MD_kcfi_type, 36)
+    FIXED_MD_KIND(MD_pcsections, 37)
+    FIXED_MD_KIND(MD_DIAssignID, 38)
+    FIXED_MD_KIND(MD_coro_outside_frame, 39)
+    FIXED_MD_KIND(MD_mmra, 40)
+    FIXED_MD_KIND(MD_noalias_addrspace, 41)
+}
diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
index 1115d82fa85..9a53dacb1df 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs
@@ -11,13 +11,14 @@ use rustc_llvm::RustString;
 
 pub(crate) use self::CallConv::*;
 pub(crate) use self::CodeGenOptSize::*;
-pub(crate) use self::MetadataType::*;
 pub(crate) use self::ffi::*;
+pub(crate) use self::metadata_kind::*;
 use crate::common::AsCCharPtr;
 
 pub(crate) mod diagnostic;
 pub(crate) mod enzyme_ffi;
 mod ffi;
+mod metadata_kind;
 
 pub(crate) use self::enzyme_ffi::*;
 
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 9ecaf5f24fe..5b97898a4b8 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -306,7 +306,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
             llvm::LLVMRustGlobalAddMetadata(
                 function,
-                llvm::MD_type as c_uint,
+                llvm::MD_type,
                 llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
             )
         }
@@ -318,7 +318,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata];
             llvm::LLVMGlobalSetMetadata(
                 function,
-                llvm::MD_type as c_uint,
+                llvm::MD_type,
                 llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()),
             )
         }
@@ -333,7 +333,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe {
             llvm::LLVMRustGlobalAddMetadata(
                 function,
-                llvm::MD_kcfi_type as c_uint,
+                llvm::MD_kcfi_type,
                 llvm::LLVMMDNodeInContext2(
                     self.llcx,
                     &llvm::LLVMValueAsMetadata(kcfi_type_metadata),
@@ -348,7 +348,7 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe {
             llvm::LLVMGlobalSetMetadata(
                 function,
-                llvm::MD_kcfi_type as c_uint,
+                llvm::MD_kcfi_type,
                 llvm::LLVMMDNodeInContext2(
                     self.llcx,
                     &llvm::LLVMValueAsMetadata(kcfi_type_metadata),
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 886ebddc75c..e1e6860e430 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -219,7 +219,7 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
     // `async-std` (and `pub async fn` in general).
-    // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
+    // Since rustdoc doesn't care about the hidden type behind `impl Trait`, just don't look at it!
     // See https://github.com/rust-lang/rust/issues/75100
     if tcx.sess.opts.actually_rustdoc {
         return;
@@ -252,7 +252,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
     Ok(())
 }
 
-/// Check that the concrete type behind `impl Trait` actually implements `Trait`.
+/// Check that the hidden type behind `impl Trait` actually implements `Trait`.
 ///
 /// This is mostly checked at the places that specify the opaque type, but we
 /// check those cases in the `param_env` of that function, which may have
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index b6d898886ac..a02990fe4ab 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -177,7 +177,7 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
                 let tables = tcx.typeck(item_def_id);
                 if let Some(guar) = tables.tainted_by_errors {
                     self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
-                } else if let Some(&hidden_type) = tables.concrete_opaque_types.get(&self.def_id) {
+                } else if let Some(&hidden_type) = tables.hidden_types.get(&self.def_id) {
                     self.insert_found(hidden_type);
                 } else {
                     self.non_defining_use_in_defining_scope(item_def_id);
@@ -185,8 +185,8 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
             }
             DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
                 Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
-                Ok(concrete_opaque_types) => {
-                    if let Some(&hidden_type) = concrete_opaque_types.0.get(&self.def_id) {
+                Ok(hidden_types) => {
+                    if let Some(&hidden_type) = hidden_types.0.get(&self.def_id) {
                         debug!(?hidden_type, "found constraint");
                         self.insert_found(hidden_type);
                     } else if let Err(guar) = tcx
@@ -247,7 +247,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
             let tables = tcx.typeck(owner_def_id);
             if let Some(guar) = tables.tainted_by_errors {
                 Ty::new_error(tcx, guar)
-            } else if let Some(hidden_ty) = tables.concrete_opaque_types.get(&def_id) {
+            } else if let Some(hidden_ty) = tables.hidden_types.get(&def_id) {
                 hidden_ty.ty
             } else {
                 assert!(!tcx.next_trait_solver_globally());
@@ -261,8 +261,8 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
             }
         }
         DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
-            Ok(concrete_opaque_types) => {
-                if let Some(hidden_ty) = concrete_opaque_types.0.get(&def_id) {
+            Ok(hidden_types) => {
+                if let Some(hidden_ty) = hidden_types.0.get(&def_id) {
                     hidden_ty.ty
                 } else {
                     let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 2a633810cd7..f8d0ea3e7bf 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -167,15 +167,20 @@ pub(crate) fn setup_constraining_predicates<'tcx>(
     // which is `O(nt)` where `t` is the depth of type-parameter constraints,
     // remembering that `t` should be less than 7 in practice.
     //
+    // FIXME(hkBst): the big-O bound above would be accurate for the number
+    // of calls to `parameters_for`, which itself is some O(complexity of type).
+    // That would make this potentially cubic instead of merely quadratic...
+    // ...unless we cache those `parameters_for` calls.
+    //
     // Basically, I iterate over all projections and swap every
     // "ready" projection to the start of the list, such that
     // all of the projections before `i` are topologically sorted
     // and constrain all the parameters in `input_parameters`.
     //
-    // In the example, `input_parameters` starts by containing `U` - which
-    // is constrained by the trait-ref - and so on the first pass we
+    // In the first example, `input_parameters` starts by containing `U`,
+    // which is constrained by the self type `U`. Then, on the first pass we
     // observe that `<U as Iterator>::Item = T` is a "ready" projection that
-    // constrains `T` and swap it to front. As it is the sole projection,
+    // constrains `T` and swap it to the front. As it is the sole projection,
     // no more swaps can take place afterwards, with the result being
     //   * <U as Iterator>::Item = T
     //   * T: Debug
@@ -193,33 +198,25 @@ pub(crate) fn setup_constraining_predicates<'tcx>(
         for j in i..predicates.len() {
             // Note that we don't have to care about binders here,
             // as the impl trait ref never contains any late-bound regions.
-            if let ty::ClauseKind::Projection(projection) = predicates[j].0.kind().skip_binder() {
-                // Special case: watch out for some kind of sneaky attempt
-                // to project out an associated type defined by this very
-                // trait.
-                let unbound_trait_ref = projection.projection_term.trait_ref(tcx);
-                if Some(unbound_trait_ref) == impl_trait_ref {
-                    continue;
-                }
-
-                // A projection depends on its input types and determines its output
-                // type. For example, if we have
-                //     `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
-                // Then the projection only applies if `T` is known, but it still
-                // does not determine `U`.
-                let inputs = parameters_for(tcx, projection.projection_term, true);
-                let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(p));
-                if !relies_only_on_inputs {
-                    continue;
-                }
+            if let ty::ClauseKind::Projection(projection) = predicates[j].0.kind().skip_binder() &&
+
+            // Special case: watch out for some kind of sneaky attempt to
+            // project out an associated type defined by this very trait.
+            !impl_trait_ref.is_some_and(|t| t == projection.projection_term.trait_ref(tcx)) &&
+
+            // A projection depends on its input types and determines its output
+            // type. For example, if we have
+            //     `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
+            // then the projection only applies if `T` is known, but it still
+            // does not determine `U`.
+                parameters_for(tcx, projection.projection_term, true).iter().all(|p| input_parameters.contains(p))
+            {
                 input_parameters.extend(parameters_for(tcx, projection.term, false));
-            } else {
-                continue;
+
+                predicates.swap(i, j);
+                i += 1;
+                changed = true;
             }
-            // fancy control flow to bypass borrow checker
-            predicates.swap(i, j);
-            i += 1;
-            changed = true;
         }
         debug!(
             "setup_constraining_predicates: predicates={:?} \
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
index 0458fa1204e..0a41659ec66 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs
@@ -134,6 +134,7 @@ fn is_valid_cmse_inputs<'tcx>(
 
     // this type is only used for layout computation, which does not rely on regions
     let fn_sig = tcx.instantiate_bound_regions_with_erased(fn_sig);
+    let fn_sig = tcx.erase_and_anonymize_regions(fn_sig);
 
     for (index, ty) in fn_sig.inputs().iter().enumerate() {
         let layout = tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(*ty))?;
diff --git a/compiler/rustc_hir_typeck/src/opaque_types.rs b/compiler/rustc_hir_typeck/src/opaque_types.rs
index 5cefa506b5a..4c1fe69405e 100644
--- a/compiler/rustc_hir_typeck/src/opaque_types.rs
+++ b/compiler/rustc_hir_typeck/src/opaque_types.rs
@@ -15,7 +15,7 @@ use crate::FnCtxt;
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
     /// This takes all the opaque type uses during HIR typeck. It first computes
-    /// the concrete hidden type by iterating over all defining uses.
+    /// the hidden type by iterating over all defining uses.
     ///
     /// A use during HIR typeck is defining if all non-lifetime arguments are
     /// unique generic parameters and the hidden type does not reference any
@@ -35,8 +35,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         }
         debug!(?opaque_types);
 
-        self.compute_concrete_opaque_types(&opaque_types);
-        self.apply_computed_concrete_opaque_types(&opaque_types);
+        self.compute_definition_site_hidden_types(&opaque_types);
+        self.apply_definition_site_hidden_types(&opaque_types);
     }
 }
 
@@ -71,7 +71,7 @@ impl<'tcx> UsageKind<'tcx> {
 }
 
 impl<'tcx> FnCtxt<'_, 'tcx> {
-    fn compute_concrete_opaque_types(
+    fn compute_definition_site_hidden_types(
         &mut self,
         opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     ) {
@@ -142,7 +142,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
 
             self.typeck_results
                 .borrow_mut()
-                .concrete_opaque_types
+                .hidden_types
                 .insert(def_id, OpaqueHiddenType::new_error(tcx, guar));
             self.set_tainted_by_errors(guar);
         }
@@ -161,7 +161,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         ) {
             match err {
                 NonDefiningUseReason::Tainted(guar) => {
-                    self.typeck_results.borrow_mut().concrete_opaque_types.insert(
+                    self.typeck_results.borrow_mut().hidden_types.insert(
                         opaque_type_key.def_id,
                         OpaqueHiddenType::new_error(self.tcx, guar),
                     );
@@ -197,20 +197,19 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         let prev = self
             .typeck_results
             .borrow_mut()
-            .concrete_opaque_types
+            .hidden_types
             .insert(opaque_type_key.def_id, hidden_type);
         assert!(prev.is_none());
         UsageKind::HasDefiningUse
     }
 
-    fn apply_computed_concrete_opaque_types(
+    fn apply_definition_site_hidden_types(
         &mut self,
         opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)],
     ) {
         let tcx = self.tcx;
         for &(key, hidden_type) in opaque_types {
-            let expected =
-                *self.typeck_results.borrow_mut().concrete_opaque_types.get(&key.def_id).unwrap();
+            let expected = *self.typeck_results.borrow_mut().hidden_types.get(&key.def_id).unwrap();
 
             let expected = EarlyBinder::bind(expected.ty).instantiate(tcx, key.args);
             self.demand_eqtype(hidden_type.span, expected, hidden_type.ty);
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index d01eeb9a4b6..697029e55f7 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -550,13 +550,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     fn visit_opaque_types_next(&mut self) {
         let mut fcx_typeck_results = self.fcx.typeck_results.borrow_mut();
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
-        for hidden_ty in fcx_typeck_results.concrete_opaque_types.values() {
+        for hidden_ty in fcx_typeck_results.hidden_types.values() {
             assert!(!hidden_ty.has_infer());
         }
 
-        assert_eq!(self.typeck_results.concrete_opaque_types.len(), 0);
-        self.typeck_results.concrete_opaque_types =
-            mem::take(&mut fcx_typeck_results.concrete_opaque_types);
+        assert_eq!(self.typeck_results.hidden_types.len(), 0);
+        self.typeck_results.hidden_types = mem::take(&mut fcx_typeck_results.hidden_types);
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -588,7 +587,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 hidden_type.span,
                 DefiningScopeKind::HirTypeck,
             ) {
-                self.typeck_results.concrete_opaque_types.insert(
+                self.typeck_results.hidden_types.insert(
                     opaque_type_key.def_id,
                     ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
                 );
@@ -600,16 +599,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 DefiningScopeKind::HirTypeck,
             );
 
-            if let Some(prev) = self
-                .typeck_results
-                .concrete_opaque_types
-                .insert(opaque_type_key.def_id, hidden_type)
+            if let Some(prev) =
+                self.typeck_results.hidden_types.insert(opaque_type_key.def_id, hidden_type)
             {
-                let entry = &mut self
-                    .typeck_results
-                    .concrete_opaque_types
-                    .get_mut(&opaque_type_key.def_id)
-                    .unwrap();
+                let entry =
+                    &mut self.typeck_results.hidden_types.get_mut(&opaque_type_key.def_id).unwrap();
                 if prev.ty != hidden_type.ty {
                     if let Some(guar) = self.typeck_results.tainted_by_errors {
                         entry.ty = Ty::new_error(tcx, guar);
@@ -628,7 +622,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
 
         let recursive_opaques: Vec<_> = self
             .typeck_results
-            .concrete_opaque_types
+            .hidden_types
             .iter()
             .filter(|&(&def_id, hidden_ty)| {
                 hidden_ty
@@ -636,7 +630,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                     .visit_with(&mut HasRecursiveOpaque {
                         def_id,
                         seen: Default::default(),
-                        opaques: &self.typeck_results.concrete_opaque_types,
+                        opaques: &self.typeck_results.hidden_types,
                         tcx,
                     })
                     .is_break()
@@ -651,7 +645,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 .with_code(E0720)
                 .emit();
             self.typeck_results
-                .concrete_opaque_types
+                .hidden_types
                 .insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
         }
     }
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index b989d419057..a640dcb1b4e 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -170,6 +170,10 @@ impl<'tcx> InferCtxt<'tcx> {
         std::mem::take(&mut self.inner.borrow_mut().region_obligations)
     }
 
+    pub fn clone_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
+        self.inner.borrow().region_obligations.clone()
+    }
+
     pub fn register_region_assumption(&self, assumption: ty::ArgOutlivesPredicate<'tcx>) {
         let mut inner = self.inner.borrow_mut();
         inner.undo_log.push(UndoLog::PushRegionAssumption);
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 58ec72b5b45..be2fd0787b9 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -1,3 +1,4 @@
+use std::any::Any;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
 use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -6,13 +7,20 @@ use std::{env, thread};
 
 use rustc_ast as ast;
 use rustc_attr_parsing::{ShouldEmit, validate_attr};
+use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder;
+use rustc_codegen_ssa::back::link::link_binary;
 use rustc_codegen_ssa::traits::CodegenBackend;
+use rustc_codegen_ssa::{CodegenResults, CrateInfo};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::jobserver::Proxy;
 use rustc_data_structures::sync;
 use rustc_errors::LintBuffer;
-use rustc_metadata::{DylibError, load_symbol_from_dylib};
-use rustc_middle::ty::CurrentGcx;
-use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
+use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib};
+use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
+use rustc_middle::ty::{CurrentGcx, TyCtxt};
+use rustc_session::config::{
+    Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple,
+};
 use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
 use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint};
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -316,12 +324,13 @@ pub fn get_codegen_backend(
         let backend = backend_name
             .or(target.default_codegen_backend.as_deref())
             .or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND"))
-            .unwrap_or("llvm");
+            .unwrap_or("dummy");
 
         match backend {
             filename if filename.contains('.') => {
                 load_backend_from_dylib(early_dcx, filename.as_ref())
             }
+            "dummy" => || Box::new(DummyCodegenBackend),
             #[cfg(feature = "llvm")]
             "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
             backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
@@ -334,6 +343,63 @@ pub fn get_codegen_backend(
     unsafe { load() }
 }
 
+struct DummyCodegenBackend;
+
+impl CodegenBackend for DummyCodegenBackend {
+    fn locale_resource(&self) -> &'static str {
+        ""
+    }
+
+    fn name(&self) -> &'static str {
+        "dummy"
+    }
+
+    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
+        Box::new(CodegenResults {
+            modules: vec![],
+            allocator_module: None,
+            crate_info: CrateInfo::new(tcx, String::new()),
+        })
+    }
+
+    fn join_codegen(
+        &self,
+        ongoing_codegen: Box<dyn Any>,
+        _sess: &Session,
+        _outputs: &OutputFilenames,
+    ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
+        (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default())
+    }
+
+    fn link(
+        &self,
+        sess: &Session,
+        codegen_results: CodegenResults,
+        metadata: EncodedMetadata,
+        outputs: &OutputFilenames,
+    ) {
+        // JUSTIFICATION: TyCtxt no longer available here
+        #[allow(rustc::bad_opt_access)]
+        if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) {
+            #[allow(rustc::untranslatable_diagnostic)]
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            sess.dcx().fatal(format!(
+                "crate type {} not supported by the dummy codegen backend",
+                sess.opts.crate_types[0],
+            ));
+        }
+
+        link_binary(
+            sess,
+            &ArArchiveBuilderBuilder,
+            codegen_results,
+            metadata,
+            outputs,
+            self.name(),
+        );
+    }
+}
+
 // This is used for rustdoc, but it uses similar machinery to codegen backend
 // loading, so we leave the code here. It is potentially useful for other tools
 // that want to invoke the rustc binary while linking to rustc as well.
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 4a778125918..2b83ea24ac6 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1824,3 +1824,55 @@ extern "C" size_t LLVMRustEnzymeGetMaxTypeDepth() {
   return 6; // Default fallback depth
 }
 #endif
+
+// Statically assert that the fixed metadata kind IDs declared in
+// `metadata_kind.rs` match the ones actually used by LLVM.
+#define FIXED_MD_KIND(VARIANT, VALUE)                                          \
+  static_assert(::llvm::LLVMContext::VARIANT == VALUE);
+// Must be kept in sync with the corresponding list in `metadata_kind.rs`.
+FIXED_MD_KIND(MD_dbg, 0)
+FIXED_MD_KIND(MD_tbaa, 1)
+FIXED_MD_KIND(MD_prof, 2)
+FIXED_MD_KIND(MD_fpmath, 3)
+FIXED_MD_KIND(MD_range, 4)
+FIXED_MD_KIND(MD_tbaa_struct, 5)
+FIXED_MD_KIND(MD_invariant_load, 6)
+FIXED_MD_KIND(MD_alias_scope, 7)
+FIXED_MD_KIND(MD_noalias, 8)
+FIXED_MD_KIND(MD_nontemporal, 9)
+FIXED_MD_KIND(MD_mem_parallel_loop_access, 10)
+FIXED_MD_KIND(MD_nonnull, 11)
+FIXED_MD_KIND(MD_dereferenceable, 12)
+FIXED_MD_KIND(MD_dereferenceable_or_null, 13)
+FIXED_MD_KIND(MD_make_implicit, 14)
+FIXED_MD_KIND(MD_unpredictable, 15)
+FIXED_MD_KIND(MD_invariant_group, 16)
+FIXED_MD_KIND(MD_align, 17)
+FIXED_MD_KIND(MD_loop, 18)
+FIXED_MD_KIND(MD_type, 19)
+FIXED_MD_KIND(MD_section_prefix, 20)
+FIXED_MD_KIND(MD_absolute_symbol, 21)
+FIXED_MD_KIND(MD_associated, 22)
+FIXED_MD_KIND(MD_callees, 23)
+FIXED_MD_KIND(MD_irr_loop, 24)
+FIXED_MD_KIND(MD_access_group, 25)
+FIXED_MD_KIND(MD_callback, 26)
+FIXED_MD_KIND(MD_preserve_access_index, 27)
+FIXED_MD_KIND(MD_vcall_visibility, 28)
+FIXED_MD_KIND(MD_noundef, 29)
+FIXED_MD_KIND(MD_annotation, 30)
+FIXED_MD_KIND(MD_nosanitize, 31)
+FIXED_MD_KIND(MD_func_sanitize, 32)
+FIXED_MD_KIND(MD_exclude, 33)
+FIXED_MD_KIND(MD_memprof, 34)
+FIXED_MD_KIND(MD_callsite, 35)
+FIXED_MD_KIND(MD_kcfi_type, 36)
+FIXED_MD_KIND(MD_pcsections, 37)
+FIXED_MD_KIND(MD_DIAssignID, 38)
+FIXED_MD_KIND(MD_coro_outside_frame, 39)
+FIXED_MD_KIND(MD_mmra, 40)
+FIXED_MD_KIND(MD_noalias_addrspace, 41)
+// If some fixed metadata kinds are not present and consistent in all supported
+// LLVM versions, it's fine to omit them from this list; in that case Rust-side
+// code cannot declare them as fixed IDs and must look them up by name instead.
+#undef FIXED_MD_KIND
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index fa6a2db38ef..feaad5bb96e 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -27,7 +27,7 @@ macro_rules! arena_types {
                     rustc_middle::mir::Body<'tcx>
                 >,
             [decode] typeck_results: rustc_middle::ty::TypeckResults<'tcx>,
-            [decode] borrowck_result: rustc_middle::mir::ConcreteOpaqueTypes<'tcx>,
+            [decode] borrowck_result: rustc_middle::mir::DefinitionSiteHiddenTypes<'tcx>,
             [] resolver: rustc_data_structures::steal::Steal<(
                 rustc_middle::ty::ResolverAstLowering,
                 std::sync::Arc<rustc_ast::Crate>,
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index a509c40c89c..2e6c9f207e2 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -84,11 +84,10 @@ impl Debug for CoroutineLayout<'_> {
     }
 }
 
-/// All the opaque types that are restricted to concrete types
-/// by this function. Unlike the value in `TypeckResults`, this has
-/// unerased regions.
+/// All the opaque types that have had their hidden type fully computed.
+/// Unlike the value in `TypeckResults`, this has unerased regions.
 #[derive(Default, Debug, TyEncodable, TyDecodable, HashStable)]
-pub struct ConcreteOpaqueTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
+pub struct DefinitionSiteHiddenTypes<'tcx>(pub FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>);
 
 /// The result of the `mir_const_qualif` query.
 ///
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 326df9239aa..895c8c0295a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1244,7 +1244,7 @@ rustc_queries! {
 
     /// Borrow-checks the given typeck root, e.g. functions, const/static items,
     /// and its children, e.g. closures, inline consts.
-    query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> {
+    query mir_borrowck(key: LocalDefId) -> Result<&'tcx mir::DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> {
         desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) }
     }
 
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 8dd80aab946..944bd9756a9 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -167,7 +167,7 @@ pub struct TypeckResults<'tcx> {
     /// We also store the type here, so that the compiler can use it as a hint
     /// for figuring out hidden types, even if they are only set in dead code
     /// (which doesn't show up in MIR).
-    pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+    pub hidden_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
 
     /// Tracks the minimum captures required for a closure;
     /// see `MinCaptureInformationMap` for more details.
@@ -250,7 +250,7 @@ impl<'tcx> TypeckResults<'tcx> {
             coercion_casts: Default::default(),
             used_trait_imports: Default::default(),
             tainted_by_errors: None,
-            concrete_opaque_types: Default::default(),
+            hidden_types: Default::default(),
             closure_min_captures: Default::default(),
             closure_fake_reads: Default::default(),
             rvalue_scopes: Default::default(),
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index d9f8085083e..0652461e975 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -120,7 +120,7 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
 impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Type inference occasionally gives us opaque types in places where corresponding patterns
     /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
-    /// types, we use the corresponding concrete type if possible.
+    /// types, we use the corresponding hidden type if possible.
     // FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing
     // opaque types defined in a body.
     #[inline]
@@ -146,7 +146,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// know it.
     fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
         self.typeck_results
-            .concrete_opaque_types
+            .hidden_types
             .get(&key.def_id)
             .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
     }
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index ecc74264160..39e604bcce7 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -158,12 +158,22 @@ pub(crate) fn base(
             SplitDebuginfo::Off,
         ]),
 
+        // Tell the linker that we would like it to avoid irreproducible binaries.
+        //
         // This environment variable is pretty magical but is intended for
         // producing deterministic builds. This was first discovered to be used
         // by the `ar` tool as a way to control whether or not mtime entries in
-        // the archive headers were set to zero or not. It appears that
-        // eventually the linker got updated to do the same thing and now reads
-        // this environment variable too in recent versions.
+        // the archive headers were set to zero or not.
+        //
+        // In `ld64-351.8`, shipped with Xcode 9.3, the linker was updated to
+        // read this flag too. Linker versions that don't support this flag
+        // may embed modification timestamps in binaries (especially in debug
+        // information).
+        //
+        // A cleaner alternative would be to pass the `-reproducible` flag,
+        // though that is only supported since `ld64-819.6` shipped with Xcode
+        // 14, which is too new for our minimum supported version:
+        // https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#host-tooling
         //
         // For some more info see the commentary on #47086
         link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index d485eb7266b..bec12750728 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1897,6 +1897,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         other: bool,
         param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
+        let parent_map = self.tcx.visible_parent_map(());
         let alternative_candidates = |def_id: DefId| {
             let mut impl_candidates: Vec<_> = self
                 .tcx
@@ -1921,7 +1922,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         // FIXME(compiler-errors): This could be generalized, both to
                         // be more granular, and probably look past other `#[fundamental]`
                         // types, too.
-                        self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx)
+                        let mut did = def.did();
+                        if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
+                            // don't suggest foreign `#[doc(hidden)]` types
+                            if !did.is_local() {
+                                while let Some(parent) = parent_map.get(&did) {
+                                    if self.tcx.is_doc_hidden(did) {
+                                        return false;
+                                    }
+                                    did = *parent;
+                                }
+                            }
+                            true
+                        } else {
+                            false
+                        }
                     } else {
                         true
                     }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
index b3d1b8e3888..9052031ce4f 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/mod.rs
@@ -21,7 +21,7 @@ use rustc_infer::traits::{
 };
 use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::{ErrorGuaranteed, ExpnKind, Span};
+use rustc_span::{DesugaringKind, ErrorGuaranteed, ExpnKind, Span};
 use tracing::{info, instrument};
 
 pub use self::overflow::*;
@@ -154,9 +154,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             })
             .collect();
 
-        // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last.
+        // Ensure `T: Sized`, `T: MetaSized`, `T: PointeeSized` and `T: WF` obligations come last,
+        // and `Subtype` obligations from `FormatLiteral` desugarings come first.
         // This lets us display diagnostics with more relevant type information and hide redundant
         // E0282 errors.
+        #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
+        enum ErrorSortKey {
+            SubtypeFormat(usize, usize),
+            OtherKind,
+            SizedTrait,
+            MetaSizedTrait,
+            PointeeSizedTrait,
+            Coerce,
+            WellFormed,
+        }
         errors.sort_by_key(|e| {
             let maybe_sizedness_did = match e.obligation.predicate.kind().skip_binder() {
                 ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => Some(pred.def_id()),
@@ -165,12 +176,30 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             };
 
             match e.obligation.predicate.kind().skip_binder() {
-                _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => 1,
-                _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => 2,
-                _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => 3,
-                ty::PredicateKind::Coerce(_) => 4,
-                ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 5,
-                _ => 0,
+                ty::PredicateKind::Subtype(_)
+                    if matches!(
+                        e.obligation.cause.span.desugaring_kind(),
+                        Some(DesugaringKind::FormatLiteral { .. })
+                    ) =>
+                {
+                    let (_, row, col, ..) =
+                        self.tcx.sess.source_map().span_to_location_info(e.obligation.cause.span);
+                    ErrorSortKey::SubtypeFormat(row, col)
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().sized_trait() => {
+                    ErrorSortKey::SizedTrait
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().meta_sized_trait() => {
+                    ErrorSortKey::MetaSizedTrait
+                }
+                _ if maybe_sizedness_did == self.tcx.lang_items().pointee_sized_trait() => {
+                    ErrorSortKey::PointeeSizedTrait
+                }
+                ty::PredicateKind::Coerce(_) => ErrorSortKey::Coerce,
+                ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
+                    ErrorSortKey::WellFormed
+                }
+                _ => ErrorSortKey::OtherKind,
             }
         });
 
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 7540cbe3fd1..e55ffb4d5fd 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -55,6 +55,12 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
     span: Span,
     disable_implied_bounds_hack: bool,
 ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
+    // Inside mir borrowck, each computation starts with an empty list.
+    assert!(
+        ocx.infcx.inner.borrow().region_obligations().is_empty(),
+        "compute_implied_outlives_bounds assumes region obligations are empty before starting"
+    );
+
     let normalize_ty = |ty| -> Result<_, NoSolution> {
         // We must normalize the type so we can compute the right outlives components.
         // for example, if we have some constrained param type like `T: Trait<Out = U>`,
@@ -143,7 +149,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
         && ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
     {
         for TypeOutlivesConstraint { sup_type, sub_region, .. } in
-            ocx.infcx.take_registered_region_obligations()
+            ocx.infcx.clone_registered_region_obligations()
         {
             let mut components = smallvec![];
             push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 1dd31990ab7..fb4f28412d4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2359,7 +2359,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 if self.infcx.can_define_opaque_ty(def_id) {
                     unreachable!()
                 } else {
-                    // We can resolve the `impl Trait` to its concrete type,
+                    // We can resolve the opaque type to its hidden type,
                     // which enforces a DAG between the functions requiring
                     // the auto trait bounds in question.
                     match self.tcx().type_of_opaque(def_id) {
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index f743b84bce6..feafcee7bad 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -80,7 +80,7 @@ pub enum TypingMode<I: Interner> {
     /// the old solver as well.
     PostBorrowckAnalysis { defined_opaque_types: I::LocalDefIds },
     /// After analysis, mostly during codegen and MIR optimizations, we're able to
-    /// reveal all opaque types. As the concrete type should *never* be observable
+    /// reveal all opaque types. As the hidden type should *never* be observable
     /// directly by the user, this should not be used by checks which may expose
     /// such details to the user.
     ///