about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast/src/ast.rs11
-rw-r--r--compiler/rustc_ast/src/util/parser.rs3
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs27
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs7
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs9
-rw-r--r--compiler/rustc_errors/Cargo.toml1
-rw-r--r--compiler/rustc_errors/src/emitter.rs10
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs11
-rw-r--r--compiler/rustc_hir/src/hir.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs45
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs9
-rw-r--r--compiler/rustc_interface/src/passes.rs15
-rw-r--r--compiler/rustc_lint/src/types.rs22
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp50
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs111
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs12
-rw-r--r--compiler/rustc_middle/src/middle/dependency_format.rs6
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mappings.rs20
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs40
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs9
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/tests.rs81
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs17
-rw-r--r--compiler/rustc_parse/src/parser/path.rs3
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs28
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_session/src/cstore.rs2
-rw-r--r--compiler/rustc_session/src/output.rs15
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs7
37 files changed, 293 insertions, 358 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 69c3e0553d4..cec868e5c8e 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1322,11 +1322,15 @@ impl Expr {
     }
 
     pub fn precedence(&self) -> ExprPrecedence {
-        match self.kind {
-            ExprKind::Closure(..) => ExprPrecedence::Closure,
+        match &self.kind {
+            ExprKind::Closure(closure) => {
+                match closure.fn_decl.output {
+                    FnRetTy::Default(_) => ExprPrecedence::Jump,
+                    FnRetTy::Ty(_) => ExprPrecedence::Unambiguous,
+                }
+            }
 
             ExprKind::Break(..)
-            | ExprKind::Continue(..)
             | ExprKind::Ret(..)
             | ExprKind::Yield(..)
             | ExprKind::Yeet(..)
@@ -1360,6 +1364,7 @@ impl Expr {
             | ExprKind::Block(..)
             | ExprKind::Call(..)
             | ExprKind::ConstBlock(_)
+            | ExprKind::Continue(..)
             | ExprKind::Field(..)
             | ExprKind::ForLoop { .. }
             | ExprKind::FormatArgs(..)
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 0d8042005a8..1d4b01aa94c 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -231,8 +231,7 @@ impl AssocOp {
 
 #[derive(Clone, Copy, PartialEq, PartialOrd)]
 pub enum ExprPrecedence {
-    Closure,
-    // return, break, yield
+    // return, break, yield, closures
     Jump,
     // = += -= *= /= %= &= |= ^= <<= >>=
     Assign,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index d39fbf32921..60f7770d3f7 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -795,7 +795,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         // If the member region lives in a higher universe, we currently choose
         // the most conservative option by leaving it unchanged.
-
         if !self.constraint_sccs().annotation(scc).min_universe().is_root() {
             return;
         }
@@ -823,12 +822,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
         debug!(?choice_regions, "after ub");
 
-        // At this point we can pick any member of `choice_regions`, but to avoid potential
-        // non-determinism we will pick the *unique minimum* choice.
+        // At this point we can pick any member of `choice_regions` and would like to choose
+        // it to be a small as possible. To avoid potential non-determinism we will pick the
+        // smallest such choice.
         //
         // Because universal regions are only partially ordered (i.e, not every two regions are
         // comparable), we will ignore any region that doesn't compare to all others when picking
         // the minimum choice.
+        //
         // For example, consider `choice_regions = ['static, 'a, 'b, 'c, 'd, 'e]`, where
         // `'static: 'a, 'static: 'b, 'a: 'c, 'b: 'c, 'c: 'd, 'c: 'e`.
         // `['d, 'e]` are ignored because they do not compare - the same goes for `['a, 'b]`.
@@ -853,6 +854,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             return;
         };
 
+        // As we require `'scc: 'min_choice`, we have definitely already computed
+        // its `scc_values` at this point.
         let min_choice_scc = self.constraint_sccs.scc(min_choice);
         debug!(?min_choice, ?min_choice_scc);
         if self.scc_values.add_region(scc, min_choice_scc) {
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 4be4291021d..eaab3362c7e 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -294,7 +294,7 @@ fn dep_symbol_lookup_fn(
     // search path.
     for &cnum in crate_info.used_crates.iter().rev() {
         let src = &crate_info.used_crate_source[&cnum];
-        match data[cnum.as_usize() - 1] {
+        match data[cnum] {
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
             Linkage::Static => {
                 let name = crate_info.crate_name[&cnum];
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index d62632d1431..9a2bfd95562 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -56,25 +56,6 @@ pub enum LLVMRustResult {
     Failure,
 }
 
-// Rust version of the C struct with the same name in rustc_llvm/llvm-wrapper/RustWrapper.cpp.
-#[repr(C)]
-pub struct LLVMRustCOFFShortExport {
-    pub name: *const c_char,
-    pub ordinal_present: bool,
-    /// value of `ordinal` only important when `ordinal_present` is true
-    pub ordinal: u16,
-}
-
-impl LLVMRustCOFFShortExport {
-    pub fn new(name: *const c_char, ordinal: Option<u16>) -> LLVMRustCOFFShortExport {
-        LLVMRustCOFFShortExport {
-            name,
-            ordinal_present: ordinal.is_some(),
-            ordinal: ordinal.unwrap_or(0),
-        }
-    }
-}
-
 /// Translation of LLVM's MachineTypes enum, defined in llvm\include\llvm\BinaryFormat\COFF.h.
 ///
 /// We include only architectures supported on Windows.
@@ -2347,15 +2328,6 @@ unsafe extern "C" {
     ) -> &'a mut RustArchiveMember<'a>;
     pub fn LLVMRustArchiveMemberFree<'a>(Member: &'a mut RustArchiveMember<'a>);
 
-    pub fn LLVMRustWriteImportLibrary(
-        ImportName: *const c_char,
-        Path: *const c_char,
-        Exports: *const LLVMRustCOFFShortExport,
-        NumExports: usize,
-        Machine: u16,
-        MinGW: bool,
-    ) -> LLVMRustResult;
-
     pub fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine);
 
     pub fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index f4f6161ebbc..4bc064528f3 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -15,7 +15,7 @@ use rustc_ast::CRATE_NODE_ID;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
-use rustc_errors::{DiagCtxtHandle, FatalError};
+use rustc_errors::DiagCtxtHandle;
 use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file};
@@ -234,8 +234,6 @@ pub fn each_linked_rlib(
     crate_type: Option<CrateType>,
     f: &mut dyn FnMut(CrateNum, &Path),
 ) -> Result<(), errors::LinkRlibError> {
-    let crates = info.used_crates.iter();
-
     let fmts = if let Some(crate_type) = crate_type {
         let Some(fmts) = info.dependency_formats.get(&crate_type) else {
             return Err(errors::LinkRlibError::MissingFormat);
@@ -261,8 +259,9 @@ pub fn each_linked_rlib(
         info.dependency_formats.first().unwrap().1
     };
 
-    for &cnum in crates {
-        match fmts.get(cnum.as_usize() - 1) {
+    let used_dep_crates = info.used_crates.iter();
+    for &cnum in used_dep_crates {
+        match fmts.get(cnum) {
             Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
             Some(_) => {}
             None => return Err(errors::LinkRlibError::MissingFormat),
@@ -624,7 +623,7 @@ fn link_staticlib(
 
     let mut all_rust_dylibs = vec![];
     for &cnum in crates {
-        match fmts.get(cnum.as_usize() - 1) {
+        match fmts.get(cnum) {
             Some(&Linkage::Dynamic) => {}
             _ => continue,
         }
@@ -1039,22 +1038,22 @@ fn link_natively(
         Err(e) => {
             let linker_not_found = e.kind() == io::ErrorKind::NotFound;
 
-            if linker_not_found {
-                sess.dcx().emit_err(errors::LinkerNotFound { linker_path, error: e });
+            let err = if linker_not_found {
+                sess.dcx().emit_err(errors::LinkerNotFound { linker_path, error: e })
             } else {
                 sess.dcx().emit_err(errors::UnableToExeLinker {
                     linker_path,
                     error: e,
                     command_formatted: format!("{cmd:?}"),
-                });
-            }
+                })
+            };
 
             if sess.target.is_like_msvc && linker_not_found {
                 sess.dcx().emit_note(errors::MsvcMissingLinker);
                 sess.dcx().emit_note(errors::CheckInstalledVisualStudio);
                 sess.dcx().emit_note(errors::InsufficientVSCodeProduct);
             }
-            FatalError.raise();
+            err.raise_fatal();
         }
     }
 
@@ -2361,8 +2360,8 @@ fn linker_with_args(
         .crate_info
         .native_libraries
         .iter()
-        .filter_map(|(cnum, libraries)| {
-            (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then_some(libraries)
+        .filter_map(|(&cnum, libraries)| {
+            (dependency_linkage[cnum] != Linkage::Static).then_some(libraries)
         })
         .flatten()
         .collect::<Vec<_>>();
@@ -2754,7 +2753,7 @@ fn add_upstream_rust_crates(
         // (e.g. `libstd` when `-C prefer-dynamic` is used).
         // FIXME: `dependency_formats` can report `profiler_builtins` as `NotLinked` for some
         // reason, it shouldn't do that because `profiler_builtins` should indeed be linked.
-        let linkage = data[cnum.as_usize() - 1];
+        let linkage = data[cnum];
         let link_static_crate = linkage == Linkage::Static
             || (linkage == Linkage::IncludedFromDylib || linkage == Linkage::NotLinked)
                 && (codegen_results.crate_info.compiler_builtins == Some(cnum)
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 8a2f3d73bc1..3c6513ca26b 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1744,15 +1744,10 @@ fn for_each_exported_symbols_include_dep<'tcx>(
     crate_type: CrateType,
     mut callback: impl FnMut(ExportedSymbol<'tcx>, SymbolExportInfo, CrateNum),
 ) {
-    for &(symbol, info) in tcx.exported_symbols(LOCAL_CRATE).iter() {
-        callback(symbol, info, LOCAL_CRATE);
-    }
-
     let formats = tcx.dependency_formats(());
     let deps = &formats[&crate_type];
 
-    for (index, dep_format) in deps.iter().enumerate() {
-        let cnum = CrateNum::new(index + 1);
+    for (cnum, dep_format) in deps.iter_enumerated() {
         // For each dependency that we are linking to statically ...
         if *dep_format == Linkage::Static {
             for &(symbol, info) in tcx.exported_symbols(cnum).iter() {
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 5a1a873d4bd..93f3d2ab911 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -4,7 +4,6 @@ use std::cell::Cell;
 use std::fmt::Write;
 
 use rustc_ast_pretty::pprust as pprust_ast;
-use rustc_errors::FatalError;
 use rustc_middle::bug;
 use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
 use rustc_middle::ty::{self, TyCtxt};
@@ -311,9 +310,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
             let tcx = ex.tcx();
             let mut out = String::new();
             rustc_hir_analysis::check_crate(tcx);
-            if tcx.dcx().has_errors().is_some() {
-                FatalError.raise();
-            }
+            tcx.dcx().abort_if_errors();
             debug!("pretty printing THIR tree");
             for did in tcx.hir().body_owners() {
                 let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did));
@@ -324,9 +321,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
             let tcx = ex.tcx();
             let mut out = String::new();
             rustc_hir_analysis::check_crate(tcx);
-            if tcx.dcx().has_errors().is_some() {
-                FatalError.raise();
-            }
+            tcx.dcx().abort_if_errors();
             debug!("pretty printing THIR flat");
             for did in tcx.hir().body_owners() {
                 let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did));
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 06bae57638f..66b9adbead0 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -16,6 +16,7 @@ rustc_error_messages = { path = "../rustc_error_messages" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_index = { path = "../rustc_index" }
+rustc_lexer = { path = "../rustc_lexer" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index f63188402fe..977721a5b8a 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -19,6 +19,7 @@ use derive_setters::Setters;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::sync::{DynSend, IntoDynSyncSend, Lrc};
 use rustc_error_messages::{FluentArgs, SpanLabel};
+use rustc_lexer;
 use rustc_lint_defs::pluralize;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
@@ -1698,9 +1699,14 @@ impl HumanEmitter {
                     if let Some(source_string) =
                         line.line_index.checked_sub(1).and_then(|l| file.get_line(l))
                     {
+                        // Whitespace can only be removed (aka considered leading)
+                        // if the lexer considers it whitespace.
+                        // non-rustc_lexer::is_whitespace() chars are reported as an
+                        // error (ex. no-break-spaces \u{a0}), and thus can't be considered
+                        // for removal during error reporting.
                         let leading_whitespace = source_string
                             .chars()
-                            .take_while(|c| c.is_whitespace())
+                            .take_while(|c| rustc_lexer::is_whitespace(*c))
                             .map(|c| {
                                 match c {
                                     // Tabs are displayed as 4 spaces
@@ -1709,7 +1715,7 @@ impl HumanEmitter {
                                 }
                             })
                             .sum();
-                        if source_string.chars().any(|c| !c.is_whitespace()) {
+                        if source_string.chars().any(|c| !rustc_lexer::is_whitespace(c)) {
                             whitespace_margin = min(whitespace_margin, leading_whitespace);
                         }
                     }
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 4b9f62fa764..63e5ebb8688 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -912,12 +912,21 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(
         rustc_deny_explicit_impl,
         AttributeType::Normal,
-        template!(List: "implement_via_object = (true|false)"),
+        template!(Word),
         ErrorFollowing,
         EncodeCrossCrate::No,
         "#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls"
     ),
     rustc_attr!(
+        rustc_do_not_implement_via_object,
+        AttributeType::Normal,
+        template!(Word),
+        ErrorFollowing,
+        EncodeCrossCrate::No,
+        "#[rustc_do_not_implement_via_object] opts out of the automatic trait impl for trait objects \
+        (`impl Trait for dyn Trait`)"
+    ),
+    rustc_attr!(
         rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word),
         ErrorFollowing, EncodeCrossCrate::Yes,
         "#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 398b694ae6b..8cea269f298 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1943,11 +1943,15 @@ pub struct Expr<'hir> {
 
 impl Expr<'_> {
     pub fn precedence(&self) -> ExprPrecedence {
-        match self.kind {
-            ExprKind::Closure { .. } => ExprPrecedence::Closure,
+        match &self.kind {
+            ExprKind::Closure(closure) => {
+                match closure.fn_decl.output {
+                    FnRetTy::DefaultReturn(_) => ExprPrecedence::Jump,
+                    FnRetTy::Return(_) => ExprPrecedence::Unambiguous,
+                }
+            }
 
             ExprKind::Break(..)
-            | ExprKind::Continue(..)
             | ExprKind::Ret(..)
             | ExprKind::Yield(..)
             | ExprKind::Become(..) => ExprPrecedence::Jump,
@@ -1973,6 +1977,7 @@ impl Expr<'_> {
             | ExprKind::Block(..)
             | ExprKind::Call(..)
             | ExprKind::ConstBlock(_)
+            | ExprKind::Continue(..)
             | ExprKind::Field(..)
             | ExprKind::If(..)
             | ExprKind::Index(..)
@@ -1990,7 +1995,7 @@ impl Expr<'_> {
             | ExprKind::UnsafeBinderCast(..)
             | ExprKind::Err(_) => ExprPrecedence::Unambiguous,
 
-            ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
+            ExprKind::DropTemps(expr, ..) => expr.precedence(),
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 3aad4bafeb5..1be4aa2f63a 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -206,7 +206,9 @@ fn check_object_overlap<'tcx>(
                 // so this is valid.
             } else {
                 let mut supertrait_def_ids = tcx.supertrait_def_ids(component_def_id);
-                if supertrait_def_ids.any(|d| d == trait_def_id) {
+                if supertrait_def_ids
+                    .any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object)
+                {
                     let span = tcx.def_span(impl_def_id);
                     return Err(struct_span_code_err!(
                         tcx.dcx(),
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 5e662bb96bc..ada70117b62 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1261,49 +1261,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
             no_dups.then_some(list)
         });
 
-    let mut deny_explicit_impl = false;
-    let mut implement_via_object = true;
-    if let Some(attr) = tcx.get_attr(def_id, sym::rustc_deny_explicit_impl) {
-        deny_explicit_impl = true;
-        let mut seen_attr = false;
-        for meta in attr.meta_item_list().iter().flatten() {
-            if let Some(meta) = meta.meta_item()
-                && meta.name_or_empty() == sym::implement_via_object
-                && let Some(lit) = meta.name_value_literal()
-            {
-                if seen_attr {
-                    tcx.dcx().span_err(meta.span, "duplicated `implement_via_object` meta item");
-                }
-                seen_attr = true;
-
-                match lit.symbol {
-                    kw::True => {
-                        implement_via_object = true;
-                    }
-                    kw::False => {
-                        implement_via_object = false;
-                    }
-                    _ => {
-                        tcx.dcx().span_err(
-                            meta.span,
-                            format!(
-                                "unknown literal passed to `implement_via_object` attribute: {}",
-                                lit.symbol
-                            ),
-                        );
-                    }
-                }
-            } else {
-                tcx.dcx().span_err(
-                    meta.span(),
-                    format!("unknown meta item passed to `rustc_deny_explicit_impl` {meta:?}"),
-                );
-            }
-        }
-        if !seen_attr {
-            tcx.dcx().span_err(attr.span, "missing `implement_via_object` meta item");
-        }
-    }
+    let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl);
+    let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
 
     ty::TraitDef {
         def_id: def_id.to_def_id(),
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index fb599558490..ace114f1ffa 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1329,6 +1329,15 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         mutbl: hir::Mutability,
         track_unstable_candidates: bool,
     ) -> Result<(), MethodError<'tcx>> {
+        // The errors emitted by this function are part of
+        // the arbitrary self types work, and should not impact
+        // other users.
+        if !self.tcx.features().arbitrary_self_types()
+            && !self.tcx.features().arbitrary_self_types_pointers()
+        {
+            return Ok(());
+        }
+
         // We don't want to remember any of the diagnostic hints from this
         // shadow search, but we do need to provide Some/None for the
         // unstable_candidates in order to reflect the behavior of the
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 02905e632ab..aff66e48fbb 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -19,7 +19,7 @@ use rustc_incremental::setup_dep_graph;
 use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
-use rustc_middle::ty::{self, GlobalCtxt, RegisteredTools, TyCtxt};
+use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt};
 use rustc_middle::util::Providers;
 use rustc_parse::{
     new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
@@ -770,15 +770,14 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
     // subtyping for GlobalCtxt::enter to be allowed.
     let inner: Box<
         dyn for<'tcx> FnOnce(
-            &'tcx Compiler,
+            &'tcx Session,
+            CurrentGcx,
             &'tcx OnceLock<GlobalCtxt<'tcx>>,
             &'tcx WorkerLocal<Arena<'tcx>>,
             &'tcx WorkerLocal<rustc_hir::Arena<'tcx>>,
             F,
         ) -> T,
-    > = Box::new(move |compiler, gcx_cell, arena, hir_arena, f| {
-        let sess = &compiler.sess;
-
+    > = Box::new(move |sess, current_gcx, gcx_cell, arena, hir_arena, f| {
         TyCtxt::create_global_ctxt(
             gcx_cell,
             sess,
@@ -796,7 +795,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
                 incremental,
             ),
             providers.hooks,
-            compiler.current_gcx.clone(),
+            current_gcx,
             |tcx| {
                 let feed = tcx.create_crate_num(stable_crate_id).unwrap();
                 assert_eq!(feed.key(), LOCAL_CRATE);
@@ -804,7 +803,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
 
                 let feed = tcx.feed_unit_query();
                 feed.features_query(tcx.arena.alloc(rustc_expand::config::features(
-                    sess,
+                    tcx.sess,
                     &pre_configured_attrs,
                     crate_name,
                 )));
@@ -819,7 +818,7 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
         )
     });
 
-    inner(compiler, &gcx_cell, &arena, &hir_arena, f)
+    inner(&compiler.sess, compiler.current_gcx.clone(), &gcx_cell, &arena, &hir_arena, f)
 }
 
 /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 0c58c804353..c0371b1f606 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -4,7 +4,7 @@ use std::ops::ControlFlow;
 use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagMessage;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
 use rustc_middle::ty::{
@@ -444,7 +444,25 @@ fn lint_fn_pointer<'tcx>(
     let (l_ty, l_ty_refs) = peel_refs(l_ty);
     let (r_ty, r_ty_refs) = peel_refs(r_ty);
 
-    if !l_ty.is_fn() || !r_ty.is_fn() {
+    if l_ty.is_fn() && r_ty.is_fn() {
+        // both operands are function pointers, fallthrough
+    } else if let ty::Adt(l_def, l_args) = l_ty.kind()
+        && let ty::Adt(r_def, r_args) = r_ty.kind()
+        && cx.tcx.is_lang_item(l_def.did(), LangItem::Option)
+        && cx.tcx.is_lang_item(r_def.did(), LangItem::Option)
+        && let Some(l_some_arg) = l_args.get(0)
+        && let Some(r_some_arg) = r_args.get(0)
+        && l_some_arg.expect_ty().is_fn()
+        && r_some_arg.expect_ty().is_fn()
+    {
+        // both operands are `Option<{function ptr}>`
+        return cx.emit_span_lint(
+            UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
+            e.span,
+            UnpredictableFunctionPointerComparisons::Warn,
+        );
+    } else {
+        // types are not function pointers, nothing to do
         return;
     }
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index b79205ff946..36441a95adb 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1796,56 +1796,6 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS,
   return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS)));
 }
 
-// This struct contains all necessary info about a symbol exported from a DLL.
-struct LLVMRustCOFFShortExport {
-  const char *name;
-  bool ordinal_present;
-  // The value of `ordinal` is only meaningful if `ordinal_present` is true.
-  uint16_t ordinal;
-};
-
-// Machine must be a COFF machine type, as defined in PE specs.
-extern "C" LLVMRustResult
-LLVMRustWriteImportLibrary(const char *ImportName, const char *Path,
-                           const LLVMRustCOFFShortExport *Exports,
-                           size_t NumExports, uint16_t Machine, bool MinGW) {
-  std::vector<llvm::object::COFFShortExport> ConvertedExports;
-  ConvertedExports.reserve(NumExports);
-
-  for (size_t i = 0; i < NumExports; ++i) {
-    bool ordinal_present = Exports[i].ordinal_present;
-    uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0;
-    ConvertedExports.push_back(llvm::object::COFFShortExport{
-        Exports[i].name, // Name
-        std::string{},   // ExtName
-        std::string{},   // SymbolName
-        std::string{},   // AliasTarget
-#if LLVM_VERSION_GE(19, 0)
-        std::string{}, // ExportAs
-#endif
-        ordinal,         // Ordinal
-        ordinal_present, // Noname
-        false,           // Data
-        false,           // Private
-        false            // Constant
-    });
-  }
-
-  auto Error = llvm::object::writeImportLibrary(
-      ImportName, Path, ConvertedExports,
-      static_cast<llvm::COFF::MachineTypes>(Machine), MinGW);
-  if (Error) {
-    std::string errorString;
-    auto stream = llvm::raw_string_ostream(errorString);
-    stream << Error;
-    stream.flush();
-    LLVMRustSetLastError(errorString.c_str());
-    return LLVMRustResult::Failure;
-  } else {
-    return LLVMRustResult::Success;
-  }
-}
-
 // Transfers ownership of DiagnosticHandler unique_ptr to the caller.
 extern "C" DiagnosticHandler *
 LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) {
diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index e8de0acb7c9..582c2215d92 100644
--- a/compiler/rustc_metadata/src/dependency_format.rs
+++ b/compiler/rustc_metadata/src/dependency_format.rs
@@ -52,7 +52,8 @@
 //! than finding a number of solutions (there are normally quite a few).
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def_id::CrateNum;
+use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_index::IndexVec;
 use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage};
 use rustc_middle::ty::TyCtxt;
@@ -84,7 +85,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     let sess = &tcx.sess;
 
     if !sess.opts.output_types.should_codegen() {
-        return Vec::new();
+        return IndexVec::new();
     }
 
     let preferred_linkage = match ty {
@@ -131,7 +132,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
 
     match preferred_linkage {
         // If the crate is not linked, there are no link-time dependencies.
-        Linkage::NotLinked => return Vec::new(),
+        Linkage::NotLinked => return IndexVec::new(),
         Linkage::Static => {
             // Attempt static linkage first. For dylibs and executables, we may be
             // able to retry below with dynamic linkage.
@@ -156,7 +157,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
                     }
                     sess.dcx().emit_err(RlibRequired { crate_name: tcx.crate_name(cnum) });
                 }
-                return Vec::new();
+                return IndexVec::new();
             }
         }
         Linkage::Dynamic | Linkage::IncludedFromDylib => {}
@@ -210,19 +211,32 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
 
     // Collect what we've got so far in the return vector.
     let last_crate = tcx.crates(()).len();
-    let mut ret = (1..last_crate + 1)
-        .map(|cnum| match formats.get(&CrateNum::new(cnum)) {
-            Some(&RequireDynamic) => Linkage::Dynamic,
-            Some(&RequireStatic) => Linkage::IncludedFromDylib,
-            None => Linkage::NotLinked,
-        })
-        .collect::<Vec<_>>();
+    let mut ret = IndexVec::new();
+
+    // We need to fill in something for LOCAL_CRATE as IndexVec is a dense map.
+    // Linkage::Static semantically the most correct thing to use as the local
+    // crate is always statically linked into the linker output, even when
+    // linking a dylib. Using Linkage::Static also allow avoiding special cases
+    // for LOCAL_CRATE in some places.
+    assert_eq!(ret.push(Linkage::Static), LOCAL_CRATE);
+
+    for cnum in 1..last_crate + 1 {
+        let cnum = CrateNum::new(cnum);
+        assert_eq!(
+            ret.push(match formats.get(&cnum) {
+                Some(&RequireDynamic) => Linkage::Dynamic,
+                Some(&RequireStatic) => Linkage::IncludedFromDylib,
+                None => Linkage::NotLinked,
+            }),
+            cnum
+        );
+    }
 
     // Run through the dependency list again, and add any missing libraries as
     // static libraries.
     //
     // If the crate hasn't been included yet and it's not actually required
-    // (e.g., it's an allocator) then we skip it here as well.
+    // (e.g., it's a panic runtime) then we skip it here as well.
     for &cnum in tcx.crates(()).iter() {
         let src = tcx.used_crate_source(cnum);
         if src.dylib.is_none()
@@ -232,7 +246,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
             assert!(src.rlib.is_some() || src.rmeta.is_some());
             info!("adding staticlib: {}", tcx.crate_name(cnum));
             add_library(tcx, cnum, RequireStatic, &mut formats, &mut unavailable_as_static);
-            ret[cnum.as_usize() - 1] = Linkage::Static;
+            ret[cnum] = Linkage::Static;
         }
     }
 
@@ -240,8 +254,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     // artifact which means that we may need to inject dependencies of some
     // form.
     //
-    // Things like allocators and panic runtimes may not have been activated
-    // quite yet, so do so here.
+    // Things like panic runtimes may not have been activated quite yet, so do so here.
     activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| {
         tcx.is_panic_runtime(cnum)
     });
@@ -252,8 +265,10 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
     //
     // For situations like this, we perform one last pass over the dependencies,
     // making sure that everything is available in the requested format.
-    for (cnum, kind) in ret.iter().enumerate() {
-        let cnum = CrateNum::new(cnum + 1);
+    for (cnum, kind) in ret.iter_enumerated() {
+        if cnum == LOCAL_CRATE {
+            continue;
+        }
         let src = tcx.used_crate_source(cnum);
         match *kind {
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
@@ -334,18 +349,21 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
 
     // All crates are available in an rlib format, so we're just going to link
     // everything in explicitly so long as it's actually required.
-    let mut ret = tcx
-        .crates(())
-        .iter()
-        .map(|&cnum| match tcx.dep_kind(cnum) {
-            CrateDepKind::Explicit => Linkage::Static,
-            CrateDepKind::MacrosOnly | CrateDepKind::Implicit => Linkage::NotLinked,
-        })
-        .collect::<Vec<_>>();
+    let mut ret = IndexVec::new();
+    assert_eq!(ret.push(Linkage::Static), LOCAL_CRATE);
+    for &cnum in tcx.crates(()) {
+        assert_eq!(
+            ret.push(match tcx.dep_kind(cnum) {
+                CrateDepKind::Explicit => Linkage::Static,
+                CrateDepKind::MacrosOnly | CrateDepKind::Implicit => Linkage::NotLinked,
+            }),
+            cnum
+        );
+    }
 
-    // Our allocator/panic runtime may not have been linked above if it wasn't
-    // explicitly linked, which is the case for any injected dependency. Handle
-    // that here and activate them.
+    // Our panic runtime may not have been linked above if it wasn't explicitly
+    // linked, which is the case for any injected dependency. Handle that here
+    // and activate it.
     activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| {
         tcx.is_panic_runtime(cnum)
     });
@@ -367,8 +385,7 @@ fn activate_injected_dep(
     list: &mut DependencyList,
     replaces_injected: &dyn Fn(CrateNum) -> bool,
 ) {
-    for (i, slot) in list.iter().enumerate() {
-        let cnum = CrateNum::new(i + 1);
+    for (cnum, slot) in list.iter_enumerated() {
         if !replaces_injected(cnum) {
             continue;
         }
@@ -377,25 +394,23 @@ fn activate_injected_dep(
         }
     }
     if let Some(injected) = injected {
-        let idx = injected.as_usize() - 1;
-        assert_eq!(list[idx], Linkage::NotLinked);
-        list[idx] = Linkage::Static;
+        assert_eq!(list[injected], Linkage::NotLinked);
+        list[injected] = Linkage::Static;
     }
 }
 
-// After the linkage for a crate has been determined we need to verify that
-// there's only going to be one allocator in the output.
-fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
+/// After the linkage for a crate has been determined we need to verify that
+/// there's only going to be one panic runtime in the output.
+fn verify_ok(tcx: TyCtxt<'_>, list: &DependencyList) {
     let sess = &tcx.sess;
     if list.is_empty() {
         return;
     }
     let mut panic_runtime = None;
-    for (i, linkage) in list.iter().enumerate() {
+    for (cnum, linkage) in list.iter_enumerated() {
         if let Linkage::NotLinked = *linkage {
             continue;
         }
-        let cnum = CrateNum::new(i + 1);
 
         if tcx.is_panic_runtime(cnum) {
             if let Some((prev, _)) = panic_runtime {
@@ -431,11 +446,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
         // strategy. If the dep isn't linked, we ignore it, and if our strategy
         // is abort then it's compatible with everything. Otherwise all crates'
         // panic strategy must match our own.
-        for (i, linkage) in list.iter().enumerate() {
+        for (cnum, linkage) in list.iter_enumerated() {
             if let Linkage::NotLinked = *linkage {
                 continue;
             }
-            let cnum = CrateNum::new(i + 1);
             if cnum == runtime_cnum || tcx.is_compiler_builtins(cnum) {
                 continue;
             }
@@ -450,13 +464,16 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
                 });
             }
 
-            let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
-            if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
-                sess.dcx().emit_err(IncompatiblePanicInDropStrategy {
-                    crate_name: tcx.crate_name(cnum),
-                    found_strategy: found_drop_strategy,
-                    desired_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
-                });
+            // panic_in_drop_strategy isn't allowed for LOCAL_CRATE
+            if cnum != LOCAL_CRATE {
+                let found_drop_strategy = tcx.panic_in_drop_strategy(cnum);
+                if tcx.sess.opts.unstable_opts.panic_in_drop != found_drop_strategy {
+                    sess.dcx().emit_err(IncompatiblePanicInDropStrategy {
+                        crate_name: tcx.crate_name(cnum),
+                        found_strategy: found_drop_strategy,
+                        desired_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
+                    });
+                }
             }
         }
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 90b1d2952c5..c2b5e318bda 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1474,7 +1474,7 @@ impl<'a> CrateMetadataRef<'a> {
     ) -> &'tcx [(CrateNum, LinkagePreference)] {
         tcx.arena.alloc_from_iter(
             self.root.dylib_dependency_formats.decode(self).enumerate().flat_map(|(i, link)| {
-                let cnum = CrateNum::new(i + 1);
+                let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding
                 link.map(|link| (self.cnum_map[cnum], link))
             }),
         )
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index fff6f3f804f..c538ab99fb5 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2165,12 +2165,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         empty_proc_macro!(self);
         let formats = self.tcx.dependency_formats(());
         if let Some(arr) = formats.get(&CrateType::Dylib) {
-            return self.lazy_array(arr.iter().map(|slot| match *slot {
-                Linkage::NotLinked | Linkage::IncludedFromDylib => None,
+            return self.lazy_array(arr.iter().skip(1 /* skip LOCAL_CRATE */).map(
+                |slot| match *slot {
+                    Linkage::NotLinked | Linkage::IncludedFromDylib => None,
 
-                Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
-                Linkage::Static => Some(LinkagePreference::RequireStatic),
-            }));
+                    Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
+                    Linkage::Static => Some(LinkagePreference::RequireStatic),
+                },
+            ));
         }
         LazyArray::default()
     }
diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs
index e3b40b64157..4f613e97631 100644
--- a/compiler/rustc_middle/src/middle/dependency_format.rs
+++ b/compiler/rustc_middle/src/middle/dependency_format.rs
@@ -8,13 +8,13 @@
 // this will introduce circular dependency between rustc_metadata and rustc_middle
 
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_hir::def_id::CrateNum;
+use rustc_index::IndexVec;
 use rustc_macros::{Decodable, Encodable, HashStable};
 use rustc_session::config::CrateType;
 
 /// A list of dependencies for a certain crate type.
-///
-/// The length of this vector is the same as the number of external crates used.
-pub type DependencyList = Vec<Linkage>;
+pub type DependencyList = IndexVec<CrateNum, Linkage>;
 
 /// A mapping of all required dependencies for a particular flavor of output.
 ///
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 188107e5d54..743ea33b20a 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -70,12 +70,12 @@ pub struct TraitDef {
 
     /// Whether to add a builtin `dyn Trait: Trait` implementation.
     /// This is enabled for all traits except ones marked with
-    /// `#[rustc_deny_explicit_impl(implement_via_object = false)]`.
+    /// `#[rustc_do_not_implement_via_object]`.
     pub implement_via_object: bool,
 
     /// Whether a trait is fully built-in, and any implementation is disallowed.
     /// This only applies to built-in traits, and is marked via
-    /// `#[rustc_deny_explicit_impl(implement_via_object = ...)]`.
+    /// `#[rustc_deny_explicit_impl]`.
     pub deny_explicit_impl: bool,
 }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs
index 2db7c6cf1d6..4185b3f4d4d 100644
--- a/compiler/rustc_mir_transform/src/coverage/mappings.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs
@@ -80,7 +80,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
     tcx: TyCtxt<'tcx>,
     mir_body: &mir::Body<'tcx>,
     hir_info: &ExtractedHirInfo,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
 ) -> ExtractedMappings {
     let mut code_mappings = vec![];
     let mut branch_pairs = vec![];
@@ -102,23 +102,23 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
         }
     } else {
         // Extract coverage spans from MIR statements/terminators as normal.
-        extract_refined_covspans(mir_body, hir_info, basic_coverage_blocks, &mut code_mappings);
+        extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings);
     }
 
-    branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, basic_coverage_blocks));
+    branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph));
 
     extract_mcdc_mappings(
         mir_body,
         tcx,
         hir_info.body_span,
-        basic_coverage_blocks,
+        graph,
         &mut mcdc_bitmap_bits,
         &mut mcdc_degraded_branches,
         &mut mcdc_mappings,
     );
 
     ExtractedMappings {
-        num_bcbs: basic_coverage_blocks.num_nodes(),
+        num_bcbs: graph.num_nodes(),
         code_mappings,
         branch_pairs,
         mcdc_bitmap_bits,
@@ -211,7 +211,7 @@ fn resolve_block_markers(
 pub(super) fn extract_branch_pairs(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
 ) -> Vec<BranchPair> {
     let Some(coverage_info_hi) = mir_body.coverage_info_hi.as_deref() else { return vec![] };
 
@@ -228,8 +228,7 @@ pub(super) fn extract_branch_pairs(
             }
             let span = unexpand_into_body_span(raw_span, hir_info.body_span)?;
 
-            let bcb_from_marker =
-                |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
+            let bcb_from_marker = |marker: BlockMarkerId| graph.bcb_from_bb(block_markers[marker]?);
 
             let true_bcb = bcb_from_marker(true_marker)?;
             let false_bcb = bcb_from_marker(false_marker)?;
@@ -243,7 +242,7 @@ pub(super) fn extract_mcdc_mappings(
     mir_body: &mir::Body<'_>,
     tcx: TyCtxt<'_>,
     body_span: Span,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
     mcdc_bitmap_bits: &mut usize,
     mcdc_degraded_branches: &mut impl Extend<MCDCBranch>,
     mcdc_mappings: &mut impl Extend<(MCDCDecision, Vec<MCDCBranch>)>,
@@ -252,8 +251,7 @@ pub(super) fn extract_mcdc_mappings(
 
     let block_markers = resolve_block_markers(coverage_info_hi, mir_body);
 
-    let bcb_from_marker =
-        |marker: BlockMarkerId| basic_coverage_blocks.bcb_from_bb(block_markers[marker]?);
+    let bcb_from_marker = |marker: BlockMarkerId| graph.bcb_from_bb(block_markers[marker]?);
 
     let check_branch_bcb =
         |raw_span: Span, true_marker: BlockMarkerId, false_marker: BlockMarkerId| {
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 83e7ff99639..57956448414 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -71,16 +71,15 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     let _span = debug_span!("instrument_function_for_coverage", ?def_id).entered();
 
     let hir_info = extract_hir_info(tcx, def_id.expect_local());
-    let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
+
+    // Build the coverage graph, which is a simplified view of the MIR control-flow
+    // graph that ignores some details not relevant to coverage instrumentation.
+    let graph = CoverageGraph::from_mir(mir_body);
 
     ////////////////////////////////////////////////////
     // Extract coverage spans and other mapping info from MIR.
-    let extracted_mappings = mappings::extract_all_mapping_info_from_mir(
-        tcx,
-        mir_body,
-        &hir_info,
-        &basic_coverage_blocks,
-    );
+    let extracted_mappings =
+        mappings::extract_all_mapping_info_from_mir(tcx, mir_body, &hir_info, &graph);
 
     ////////////////////////////////////////////////////
     // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure
@@ -94,7 +93,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
     }
 
     let coverage_counters =
-        CoverageCounters::make_bcb_counters(&basic_coverage_blocks, &bcbs_with_counter_mappings);
+        CoverageCounters::make_bcb_counters(&graph, &bcbs_with_counter_mappings);
 
     let mappings = create_mappings(&extracted_mappings, &coverage_counters);
     if mappings.is_empty() {
@@ -103,14 +102,9 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
         return;
     }
 
-    inject_coverage_statements(
-        mir_body,
-        &basic_coverage_blocks,
-        &extracted_mappings,
-        &coverage_counters,
-    );
+    inject_coverage_statements(mir_body, &graph, &extracted_mappings, &coverage_counters);
 
-    inject_mcdc_statements(mir_body, &basic_coverage_blocks, &extracted_mappings);
+    inject_mcdc_statements(mir_body, &graph, &extracted_mappings);
 
     let mcdc_num_condition_bitmaps = extracted_mappings
         .mcdc_mappings
@@ -243,7 +237,7 @@ fn create_mappings(
 /// inject any necessary coverage statements into MIR.
 fn inject_coverage_statements<'tcx>(
     mir_body: &mut mir::Body<'tcx>,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
     extracted_mappings: &ExtractedMappings,
     coverage_counters: &CoverageCounters,
 ) {
@@ -253,12 +247,12 @@ fn inject_coverage_statements<'tcx>(
         // For BCB nodes this is just their first block, but for edges we need
         // to create a new block between the two BCBs, and inject into that.
         let target_bb = match site {
-            Site::Node { bcb } => basic_coverage_blocks[bcb].leader_bb(),
+            Site::Node { bcb } => graph[bcb].leader_bb(),
             Site::Edge { from_bcb, to_bcb } => {
                 // Create a new block between the last block of `from_bcb` and
                 // the first block of `to_bcb`.
-                let from_bb = basic_coverage_blocks[from_bcb].last_bb();
-                let to_bb = basic_coverage_blocks[to_bcb].leader_bb();
+                let from_bb = graph[from_bcb].last_bb();
+                let to_bb = graph[to_bcb].leader_bb();
 
                 let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb);
                 debug!(
@@ -291,7 +285,7 @@ fn inject_coverage_statements<'tcx>(
         inject_statement(
             mir_body,
             CoverageKind::ExpressionUsed { id: expression_id },
-            basic_coverage_blocks[bcb].leader_bb(),
+            graph[bcb].leader_bb(),
         );
     }
 }
@@ -300,13 +294,13 @@ fn inject_coverage_statements<'tcx>(
 /// For each decision inject statements to update test vector bitmap after it has been evaluated.
 fn inject_mcdc_statements<'tcx>(
     mir_body: &mut mir::Body<'tcx>,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
     extracted_mappings: &ExtractedMappings,
 ) {
     for (decision, conditions) in &extracted_mappings.mcdc_mappings {
         // Inject test vector update first because `inject_statement` always insert new statement at head.
         for &end in &decision.end_bcbs {
-            let end_bb = basic_coverage_blocks[end].leader_bb();
+            let end_bb = graph[end].leader_bb();
             inject_statement(
                 mir_body,
                 CoverageKind::TestVectorBitmapUpdate {
@@ -327,7 +321,7 @@ fn inject_mcdc_statements<'tcx>(
         } in conditions
         {
             for (index, bcb) in [(false_index, false_bcb), (true_index, true_bcb)] {
-                let bb = basic_coverage_blocks[bcb].leader_bb();
+                let bb = graph[bcb].leader_bb();
                 inject_statement(
                     mir_body,
                     CoverageKind::CondBitmapUpdate {
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 085c738f1f9..314a86ea52f 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -17,14 +17,13 @@ mod from_mir;
 pub(super) fn extract_refined_covspans(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
     code_mappings: &mut impl Extend<mappings::CodeMapping>,
 ) {
-    let ExtractedCovspans { mut covspans } =
-        extract_covspans_from_mir(mir_body, hir_info, basic_coverage_blocks);
+    let ExtractedCovspans { mut covspans } = extract_covspans_from_mir(mir_body, hir_info, graph);
 
     // First, perform the passes that need macro information.
-    covspans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb));
+    covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb));
     remove_unwanted_expansion_spans(&mut covspans);
     split_visible_macro_spans(&mut covspans);
 
@@ -34,7 +33,7 @@ pub(super) fn extract_refined_covspans(
     let compare_covspans = |a: &Covspan, b: &Covspan| {
         compare_spans(a.span, b.span)
             // After deduplication, we want to keep only the most-dominated BCB.
-            .then_with(|| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
+            .then_with(|| graph.cmp_in_dominator_order(a.bcb, b.bcb).reverse())
     };
     covspans.sort_by(compare_covspans);
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 824d657e1fc..26ce743be36 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -22,13 +22,13 @@ pub(crate) struct ExtractedCovspans {
 pub(crate) fn extract_covspans_from_mir(
     mir_body: &mir::Body<'_>,
     hir_info: &ExtractedHirInfo,
-    basic_coverage_blocks: &CoverageGraph,
+    graph: &CoverageGraph,
 ) -> ExtractedCovspans {
     let &ExtractedHirInfo { body_span, .. } = hir_info;
 
     let mut covspans = vec![];
 
-    for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() {
+    for (bcb, bcb_data) in graph.iter_enumerated() {
         bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data, &mut covspans);
     }
 
diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs
index 233ca9981c5..b2ee50de50a 100644
--- a/compiler/rustc_mir_transform/src/coverage/tests.rs
+++ b/compiler/rustc_mir_transform/src/coverage/tests.rs
@@ -223,16 +223,12 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
     }
 }
 
-fn print_coverage_graphviz(
-    name: &str,
-    mir_body: &Body<'_>,
-    basic_coverage_blocks: &graph::CoverageGraph,
-) {
+fn print_coverage_graphviz(name: &str, mir_body: &Body<'_>, graph: &graph::CoverageGraph) {
     if PRINT_GRAPHS {
         println!(
             "digraph {} {{\n{}\n}}",
             name,
-            basic_coverage_blocks
+            graph
                 .iter_enumerated()
                 .map(|(bcb, bcb_data)| {
                     format!(
@@ -240,7 +236,7 @@ fn print_coverage_graphviz(
                         bcb,
                         bcb,
                         mir_body[bcb_data.last_bb()].terminator().kind.name(),
-                        basic_coverage_blocks
+                        graph
                             .successors(bcb)
                             .map(|successor| { format!("    {:?} -> {:?};", bcb, successor) })
                             .join("\n")
@@ -300,11 +296,11 @@ fn goto_switchint<'a>() -> Body<'a> {
 
 #[track_caller]
 fn assert_successors(
-    basic_coverage_blocks: &graph::CoverageGraph,
+    graph: &graph::CoverageGraph,
     bcb: BasicCoverageBlock,
     expected_successors: &[BasicCoverageBlock],
 ) {
-    let mut successors = basic_coverage_blocks.successors[bcb].clone();
+    let mut successors = graph.successors[bcb].clone();
     successors.sort_unstable();
     assert_eq!(successors, expected_successors);
 }
@@ -315,8 +311,8 @@ fn test_covgraph_goto_switchint() {
     if false {
         eprintln!("basic_blocks = {}", debug_basic_blocks(&mir_body));
     }
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    print_coverage_graphviz("covgraph_goto_switchint ", &mir_body, &basic_coverage_blocks);
+    let graph = graph::CoverageGraph::from_mir(&mir_body);
+    print_coverage_graphviz("covgraph_goto_switchint ", &mir_body, &graph);
     /*
     ┌──────────────┐     ┌─────────────────┐
     │ bcb2: Return │ ◀── │ bcb0: SwitchInt │
@@ -328,16 +324,11 @@ fn test_covgraph_goto_switchint() {
                          │  bcb1: Return   │
                          └─────────────────┘
     */
-    assert_eq!(
-        basic_coverage_blocks.num_nodes(),
-        3,
-        "basic_coverage_blocks: {:?}",
-        basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
-    );
+    assert_eq!(graph.num_nodes(), 3, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
 
-    assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1), bcb(2)]);
-    assert_successors(&basic_coverage_blocks, bcb(1), &[]);
-    assert_successors(&basic_coverage_blocks, bcb(2), &[]);
+    assert_successors(&graph, bcb(0), &[bcb(1), bcb(2)]);
+    assert_successors(&graph, bcb(1), &[]);
+    assert_successors(&graph, bcb(2), &[]);
 }
 
 /// Create a mock `Body` with a loop.
@@ -383,12 +374,8 @@ fn switchint_then_loop_else_return<'a>() -> Body<'a> {
 #[test]
 fn test_covgraph_switchint_then_loop_else_return() {
     let mir_body = switchint_then_loop_else_return();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
-    print_coverage_graphviz(
-        "covgraph_switchint_then_loop_else_return",
-        &mir_body,
-        &basic_coverage_blocks,
-    );
+    let graph = graph::CoverageGraph::from_mir(&mir_body);
+    print_coverage_graphviz("covgraph_switchint_then_loop_else_return", &mir_body, &graph);
     /*
                        ┌─────────────────┐
                        │   bcb0: Call    │
@@ -408,17 +395,12 @@ fn test_covgraph_switchint_then_loop_else_return() {
       │                                     │
       └─────────────────────────────────────┘
     */
-    assert_eq!(
-        basic_coverage_blocks.num_nodes(),
-        4,
-        "basic_coverage_blocks: {:?}",
-        basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
-    );
+    assert_eq!(graph.num_nodes(), 4, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
 
-    assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1)]);
-    assert_successors(&basic_coverage_blocks, bcb(1), &[bcb(2), bcb(3)]);
-    assert_successors(&basic_coverage_blocks, bcb(2), &[]);
-    assert_successors(&basic_coverage_blocks, bcb(3), &[bcb(1)]);
+    assert_successors(&graph, bcb(0), &[bcb(1)]);
+    assert_successors(&graph, bcb(1), &[bcb(2), bcb(3)]);
+    assert_successors(&graph, bcb(2), &[]);
+    assert_successors(&graph, bcb(3), &[bcb(1)]);
 }
 
 /// Create a mock `Body` with nested loops.
@@ -494,11 +476,11 @@ fn switchint_loop_then_inner_loop_else_break<'a>() -> Body<'a> {
 #[test]
 fn test_covgraph_switchint_loop_then_inner_loop_else_break() {
     let mir_body = switchint_loop_then_inner_loop_else_break();
-    let basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
+    let graph = graph::CoverageGraph::from_mir(&mir_body);
     print_coverage_graphviz(
         "covgraph_switchint_loop_then_inner_loop_else_break",
         &mir_body,
-        &basic_coverage_blocks,
+        &graph,
     );
     /*
                          ┌─────────────────┐
@@ -531,18 +513,13 @@ fn test_covgraph_switchint_loop_then_inner_loop_else_break() {
       │                                            │
       └────────────────────────────────────────────┘
     */
-    assert_eq!(
-        basic_coverage_blocks.num_nodes(),
-        7,
-        "basic_coverage_blocks: {:?}",
-        basic_coverage_blocks.iter_enumerated().collect::<Vec<_>>()
-    );
-
-    assert_successors(&basic_coverage_blocks, bcb(0), &[bcb(1)]);
-    assert_successors(&basic_coverage_blocks, bcb(1), &[bcb(2), bcb(3)]);
-    assert_successors(&basic_coverage_blocks, bcb(2), &[]);
-    assert_successors(&basic_coverage_blocks, bcb(3), &[bcb(4)]);
-    assert_successors(&basic_coverage_blocks, bcb(4), &[bcb(5), bcb(6)]);
-    assert_successors(&basic_coverage_blocks, bcb(5), &[bcb(1)]);
-    assert_successors(&basic_coverage_blocks, bcb(6), &[bcb(4)]);
+    assert_eq!(graph.num_nodes(), 7, "graph: {:?}", graph.iter_enumerated().collect::<Vec<_>>());
+
+    assert_successors(&graph, bcb(0), &[bcb(1)]);
+    assert_successors(&graph, bcb(1), &[bcb(2), bcb(3)]);
+    assert_successors(&graph, bcb(2), &[]);
+    assert_successors(&graph, bcb(3), &[bcb(4)]);
+    assert_successors(&graph, bcb(4), &[bcb(5), bcb(6)]);
+    assert_successors(&graph, bcb(5), &[bcb(1)]);
+    assert_successors(&graph, bcb(6), &[bcb(4)]);
 }
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 7e9b9219e7a..aab4e1b1afc 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -16,8 +16,8 @@ use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{
-    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PResult, Subdiagnostic,
-    Suggestions, pluralize,
+    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, PResult, Subdiagnostic, Suggestions,
+    pluralize,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -3023,17 +3023,10 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn recover_vcs_conflict_marker(&mut self) {
-        if let Err(err) = self.err_vcs_conflict_marker() {
-            err.emit();
-            FatalError.raise();
-        }
-    }
-
-    pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> {
         // <<<<<<<
         let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt)
         else {
-            return Ok(());
+            return;
         };
         let mut spans = Vec::with_capacity(3);
         spans.push(start);
@@ -3063,7 +3056,7 @@ impl<'a> Parser<'a> {
             self.bump();
         }
 
-        let mut err = self.dcx().struct_span_err(spans, "encountered diff marker");
+        let mut err = self.dcx().struct_span_fatal(spans, "encountered diff marker");
         match middlediff3 {
             // We're using diff3
             Some(middlediff3) => {
@@ -3106,7 +3099,7 @@ impl<'a> Parser<'a> {
              visit <https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_checking_out_conflicts>",
         );
 
-        Err(err)
+        err.emit();
     }
 
     /// Parse and throw away a parenthesized comma separated
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 73612d1da29..39737b9e137 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -597,8 +597,7 @@ impl<'a> Parser<'a> {
                 // When encountering severely malformed code where there are several levels of
                 // nested unclosed angle args (`f::<f::<f::<f::<...`), we avoid severe O(n^2)
                 // behavior by bailing out earlier (#117080).
-                e.emit();
-                rustc_errors::FatalError.raise();
+                e.emit().raise_fatal();
             }
             Err(e) if is_first_invocation && self.unmatched_angle_bracket_count > 0 => {
                 self.angle_bracket_nesting -= 1;
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 9cc94b75624..ba3101e9058 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -566,6 +566,10 @@ passes_no_sanitize =
     `#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
     .label = not {$accepted_kind}
 
+passes_non_exaustive_with_default_field_values =
+    `#[non_exhaustive]` can't be used to annotate items with default field values
+    .label = this struct has default field values
+
 passes_non_exported_macro_invalid_attrs =
     attribute should be applied to function or closure
     .label = not a function or closure
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 2310dd9dc72..8cf20a378d4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -124,7 +124,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 [sym::coverage, ..] => self.check_coverage(attr, span, target),
                 [sym::optimize, ..] => self.check_optimize(hir_id, attr, span, target),
                 [sym::no_sanitize, ..] => self.check_no_sanitize(attr, span, target),
-                [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
+                [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item),
                 [sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
                 [sym::target_feature, ..] => {
                     self.check_target_feature(hir_id, attr, span, target, attrs)
@@ -186,6 +186,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 [sym::rustc_coinductive, ..]
                 | [sym::rustc_must_implement_one_of, ..]
                 | [sym::rustc_deny_explicit_impl, ..]
+                | [sym::rustc_do_not_implement_via_object, ..]
                 | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target),
                 [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
                 [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
@@ -684,9 +685,30 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid.
-    fn check_non_exhaustive(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
+    fn check_non_exhaustive(
+        &self,
+        hir_id: HirId,
+        attr: &Attribute,
+        span: Span,
+        target: Target,
+        item: Option<ItemLike<'_>>,
+    ) {
         match target {
-            Target::Struct | Target::Enum | Target::Variant => {}
+            Target::Struct => {
+                if let Some(ItemLike::Item(hir::Item {
+                    kind: hir::ItemKind::Struct(hir::VariantData::Struct { fields, .. }, _),
+                    ..
+                })) = item
+                    && !fields.is_empty()
+                    && fields.iter().any(|f| f.default.is_some())
+                {
+                    self.dcx().emit_err(errors::NonExhaustiveWithDefaultFieldValues {
+                        attr_span: attr.span,
+                        defn_span: span,
+                    });
+                }
+            }
+            Target::Enum | Target::Variant => {}
             // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
             // `#[non_exhaustive]` attribute with just a lint, because we previously
             // erroneously allowed it and some crates used it accidentally, to be compatible
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 5e7bfa5e3bb..163325f2a3c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -120,6 +120,15 @@ pub(crate) struct NonExhaustiveWrongLocation {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_non_exaustive_with_default_field_values)]
+pub(crate) struct NonExhaustiveWithDefaultFieldValues {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub defn_span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_should_be_applied_to_trait)]
 pub(crate) struct AttrShouldBeAppliedToTrait {
     #[primary_span]
diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index beae9dc278c..c8a5c22ad12 100644
--- a/compiler/rustc_session/src/cstore.rs
+++ b/compiler/rustc_session/src/cstore.rs
@@ -42,7 +42,7 @@ pub enum CrateDepKind {
     /// A dependency that is only used for its macros.
     MacrosOnly,
     /// A dependency that is always injected into the dependency list and so
-    /// doesn't need to be linked to an rlib, e.g., the injected allocator.
+    /// doesn't need to be linked to an rlib, e.g., the injected panic runtime.
     Implicit,
     /// A dependency that is required by an rlib version of this crate.
     /// Ordinary `extern crate`s result in `Explicit` dependencies.
diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs
index bd103e86e26..ff0419d06bf 100644
--- a/compiler/rustc_session/src/output.rs
+++ b/compiler/rustc_session/src/output.rs
@@ -3,7 +3,6 @@
 use std::path::Path;
 
 use rustc_ast::{self as ast, attr};
-use rustc_errors::FatalError;
 use rustc_span::{Span, Symbol, sym};
 
 use crate::Session;
@@ -90,11 +89,10 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol {
 }
 
 pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
-    let mut err_count = 0;
+    let mut guar = None;
     {
         if s.is_empty() {
-            err_count += 1;
-            sess.dcx().emit_err(CrateNameEmpty { span: sp });
+            guar = Some(sess.dcx().emit_err(CrateNameEmpty { span: sp }));
         }
         for c in s.as_str().chars() {
             if c.is_alphanumeric() {
@@ -103,8 +101,7 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
             if c == '_' {
                 continue;
             }
-            err_count += 1;
-            sess.dcx().emit_err(InvalidCharacterInCrateName {
+            guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName {
                 span: sp,
                 character: c,
                 crate_name: s,
@@ -113,12 +110,12 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option<Span>) {
                 } else {
                     None
                 },
-            });
+            }));
         }
     }
 
-    if err_count > 0 {
-        FatalError.raise();
+    if let Some(guar) = guar {
+        guar.raise_fatal();
     }
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index a7ff0576f92..123e4b1f01f 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1717,6 +1717,7 @@ symbols! {
         rustc_diagnostic_macros,
         rustc_dirty,
         rustc_do_not_const_check,
+        rustc_do_not_implement_via_object,
         rustc_doc_primitive,
         rustc_driver,
         rustc_dummy,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
index c47c2169691..d82acc4e054 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs
@@ -1,8 +1,6 @@
 use std::fmt;
 
-use rustc_errors::{
-    Diag, E0275, EmissionGuarantee, ErrorGuaranteed, FatalError, struct_span_code_err,
-};
+use rustc_errors::{Diag, E0275, EmissionGuarantee, ErrorGuaranteed, struct_span_code_err};
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_infer::traits::{Obligation, PredicateObligation};
@@ -52,8 +50,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
     ) -> ! {
         let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
         mutate(&mut err);
-        err.emit();
-        FatalError.raise();
+        err.emit().raise_fatal();
     }
 
     pub fn build_overflow_error(