Make DependencyList an IndexVec
This commit is contained in:
parent
38bc902b15
commit
7e6be13647
8 changed files with 76 additions and 66 deletions
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}),
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue