diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 553ef676154bc..f0e151d25778c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -46,7 +46,7 @@ jobs:
   # If you want to modify CI jobs, take a look at src/ci/github-actions/jobs.yml.
   calculate_matrix:
     name: Calculate job matrix
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     outputs:
       jobs: ${{ steps.jobs.outputs.jobs }}
       run_type: ${{ steps.jobs.outputs.run_type }}
@@ -243,7 +243,7 @@ jobs:
   # when a workflow is successful listening to webhooks only in our current bors implementation (homu).
   outcome:
     name: bors build finished
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     needs: [ calculate_matrix, job ]
     # !cancelled() executes the job regardless of whether the previous jobs passed or failed
     if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index b7b5a03bd41f3..98d8c14f7d185 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -27,7 +27,7 @@ jobs:
   not-waiting-on-bors:
     if: github.repository_owner == 'rust-lang'
     name: skip if S-waiting-on-bors
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -47,7 +47,7 @@ jobs:
     if: github.repository_owner == 'rust-lang'
     name: update dependencies
     needs: not-waiting-on-bors
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     steps:
       - name: checkout the source code
         uses: actions/checkout@v4
@@ -94,7 +94,7 @@ jobs:
     if: github.repository_owner == 'rust-lang'
     name: amend PR
     needs: update
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-24.04
     permissions:
       contents: write
       pull-requests: write
diff --git a/Cargo.lock b/Cargo.lock
index 3f05b44ccfa7f..1fd288af3a133 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3722,6 +3722,7 @@ dependencies = [
  "rustc_fluent_macro",
  "rustc_hir",
  "rustc_index",
+ "rustc_lexer",
  "rustc_lint_defs",
  "rustc_macros",
  "rustc_serialize",
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 4be4291021dfa..eaab3362c7e83 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 d62632d143168..9a2bfd95562f2 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 f4f6161ebbccd..562af0777f52f 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -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,
         }
@@ -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 8a2f3d73bc15c..3c6513ca26bb1 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_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 06bae57638f3c..66b9adbead0b6 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 f63188402fe78..977721a5b8a2d 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_index/Cargo.toml b/compiler/rustc_index/Cargo.toml
index 33e8e2824c7a9..f27db7a5400ad 100644
--- a/compiler/rustc_index/Cargo.toml
+++ b/compiler/rustc_index/Cargo.toml
@@ -5,7 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-rustc_index_macros = { path = "../rustc_index_macros", default-features = false }
+rustc_index_macros = { path = "../rustc_index_macros" }
 rustc_macros = { path = "../rustc_macros", optional = true }
 rustc_serialize = { path = "../rustc_serialize", optional = true }
 smallvec = "1.8.1"
diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml
index a7c2a1804ddb8..98bc1b6a29bba 100644
--- a/compiler/rustc_index_macros/Cargo.toml
+++ b/compiler/rustc_index_macros/Cargo.toml
@@ -12,5 +12,4 @@ proc-macro2 = "1"
 quote = "1"
 
 [features]
-default = ["nightly"]
 nightly = []
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 02905e632ab87..aff66e48fbbee 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_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index b79205ff946d3..36441a95adbf9 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 e8de0acb7c9fe..582c2215d92e1 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 90b1d2952c599..c2b5e318bda72 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 fff6f3f804fc3..c538ab99fb54b 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 e3b40b6415784..4f613e97631d0 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_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs
index beae9dc278c15..c8a5c22ad1230 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/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 2b27400e9e362..e817e0f90dccd 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -152,12 +152,14 @@ pub fn iter_exported_symbols<'tcx>(
     let dependency_format = dependency_formats
         .get(&CrateType::Executable)
         .expect("interpreting a non-executable crate");
-    for cnum in dependency_format.iter().enumerate().filter_map(|(num, &linkage)| {
-        // We add 1 to the number because that's what rustc also does everywhere it
-        // calls `CrateNum::new`...
-        #[expect(clippy::arithmetic_side_effects)]
-        (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1))
-    }) {
+    for cnum in dependency_format
+        .iter_enumerated()
+        .filter_map(|(num, &linkage)| (linkage != Linkage::NotLinked).then_some(num))
+    {
+        if cnum == LOCAL_CRATE {
+            continue; // Already handled above
+        }
+
         // We can ignore `_export_info` here: we are a Rust crate, and everything is exported
         // from a Rust crate.
         for &(symbol, _export_info) in tcx.exported_symbols(cnum) {
diff --git a/tests/ui/errors/emitter-overflow-bad-whitespace.rs b/tests/ui/errors/emitter-overflow-bad-whitespace.rs
new file mode 100644
index 0000000000000..d024d1f3921b2
--- /dev/null
+++ b/tests/ui/errors/emitter-overflow-bad-whitespace.rs
@@ -0,0 +1,11 @@
+// Invalid whitespace (not listed here: https://doc.rust-lang.org/reference/whitespace.html
+// e.g. \u{a0}) before any other syntax on the line should not cause any integer overflow
+// in the emitter, even when the terminal width causes the line to be truncated.
+//
+// issue #132918
+
+//@ check-fail
+//@ needs-rustc-debug-assertions
+//@ compile-flags: --diagnostic-width=1
+                                         fn main() {              return;              }
+//~^ ERROR unknown start of token: \u{a0}
diff --git a/tests/ui/errors/emitter-overflow-bad-whitespace.stderr b/tests/ui/errors/emitter-overflow-bad-whitespace.stderr
new file mode 100644
index 0000000000000..8c0c097bcb9c4
--- /dev/null
+++ b/tests/ui/errors/emitter-overflow-bad-whitespace.stderr
@@ -0,0 +1,13 @@
+error: unknown start of token: \u{a0}
+  --> $DIR/emitter-overflow-bad-whitespace.rs:10:1
+   |
+LL |     ...
+   | ^
+   |
+help: Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not
+   |
+LL |                                          fn main() {              return;              }
+   | +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs b/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs
new file mode 100644
index 0000000000000..9326eca1f5353
--- /dev/null
+++ b/tests/ui/self/arbitrary_self_types_niche_deshadowing.rs
@@ -0,0 +1,63 @@
+//@ run-pass
+
+#![allow(dead_code)]
+#![allow(incomplete_features)]
+
+#![feature(arbitrary_self_types)]
+#![feature(arbitrary_self_types_pointers)]
+#![feature(pin_ergonomics)]
+
+use std::pin::Pin;
+use std::pin::pin;
+use std::marker::PhantomData;
+
+struct A;
+
+impl A {
+    fn m(self: *const SmartPtr<Self>) -> usize { 2 }
+    fn n(self: *const SmartPtr<Self>) -> usize { 2 }
+
+    fn o(self: Pin<&SmartPtr2<Self>>) -> usize { 2 }
+    fn p(self: Pin<&SmartPtr2<Self>>) -> usize { 2 }
+}
+
+struct SmartPtr<T>(T);
+
+impl<T> core::ops::Receiver for SmartPtr<T> {
+    type Target = *mut T;
+}
+
+impl<T> SmartPtr<T> {
+    // In general we try to detect cases where a method in a smart pointer
+    // "shadows" a method in the referent (in this test, A).
+    // This method "shadows" the 'n' method in the inner type A
+    // We do not attempt to produce an error in these shadowing cases
+    // since the type signature of this method and the corresponding
+    // method in A are pretty unlikely to occur in practice,
+    // and because it shows up conflicts between *const::cast and *mut::cast.
+    fn n(self: *mut Self) -> usize { 1 }
+}
+
+struct SmartPtr2<'a, T>(T, PhantomData<&'a T>);
+
+impl<'a, T> core::ops::Receiver for SmartPtr2<'a, T> {
+    type Target = Pin<&'a mut T>;
+}
+
+impl<T> SmartPtr2<'_, T> {
+    // Similarly, this method shadows the method in A
+    // Can only happen with the unstable feature pin_ergonomics
+    fn p(self: Pin<&mut Self>) -> usize { 1 }
+}
+
+fn main() {
+    let mut sm = SmartPtr(A);
+    let smp: *mut SmartPtr<A> = &mut sm as *mut SmartPtr<A>;
+    assert_eq!(smp.m(), 2);
+    assert_eq!(smp.n(), 1);
+
+    let smp: Pin<&mut SmartPtr2<A>> = pin!(SmartPtr2(A, PhantomData));
+    assert_eq!(smp.o(), 2);
+    let smp: Pin<&mut SmartPtr2<A>> = pin!(SmartPtr2(A, PhantomData));
+    assert_eq!(smp.p(), 1);
+}