about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2024-12-12 14:55:36 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2024-12-19 15:30:32 +0000
commit7e6be136472a49c511a6861b9cbd9b6522c11762 (patch)
treea237f3c44cb4298b4d44f463702ca7b2a5415b63
parent38bc902b1596f47b7e8c80760fb7250e0a4ea697 (diff)
downloadrust-7e6be136472a49c511a6861b9cbd9b6522c11762.tar.gz
rust-7e6be136472a49c511a6861b9cbd9b6522c11762.zip
Make DependencyList an IndexVec
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs7
-rw-r--r--compiler/rustc_metadata/src/dependency_format.rs89
-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--src/tools/miri/src/helpers.rs14
8 files changed, 76 insertions, 66 deletions
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_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index f4f6161ebbc..66258790c1e 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -262,7 +262,7 @@ pub fn each_linked_rlib(
     };
 
     for &cnum in crates {
-        match fmts.get(cnum.as_usize() - 1) {
+        match fmts.get(cnum) {
             Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
             Some(_) => {}
             None => return Err(errors::LinkRlibError::MissingFormat),
@@ -624,7 +624,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 +2361,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 +2754,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_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs
index e8de0acb7c9..1d4083a07d3 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,13 +211,19 @@ 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();
+    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.
@@ -232,7 +239,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;
         }
     }
 
@@ -252,8 +259,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,14 +343,17 @@ 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
@@ -367,8 +379,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 +388,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]) {
+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 +440,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 +458,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/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index ef4543dcee8..cb0040fcaf1 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -151,12 +151,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) {