use crate::creader::CStore;
-use rustc::hir::def_id::CrateNum;
-use rustc::middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
+use rustc::middle::cstore::LinkagePreference::{self, RequireDynamic, RequireStatic};
use rustc::middle::cstore::{self, DepKind};
-use rustc::middle::dependency_format::{DependencyList, Dependencies, Linkage};
+use rustc::middle::dependency_format::{Dependencies, DependencyList, Linkage};
use rustc::session::config;
use rustc::ty::TyCtxt;
-use rustc::util::nodemap::FxHashMap;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def_id::CrateNum;
use rustc_target::spec::PanicStrategy;
crate fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
- tcx.sess.crate_types.borrow().iter().map(|&ty| {
- let linkage = calculate_type(tcx, ty);
- verify_ok(tcx, &linkage);
- (ty, linkage)
- }).collect::<Vec<_>>()
+ tcx.sess
+ .crate_types
+ .borrow()
+ .iter()
+ .map(|&ty| {
+ let linkage = calculate_type(tcx, ty);
+ verify_ok(tcx, &linkage);
+ (ty, linkage)
+ })
+ .collect::<Vec<_>>()
}
fn calculate_type(tcx: TyCtxt<'_>, ty: config::CrateType) -> DependencyList {
// If the global prefer_dynamic switch is turned off, or the final
// executable will be statically linked, prefer static crate linkage.
- config::CrateType::Executable if !sess.opts.cg.prefer_dynamic ||
- sess.crt_static() => Linkage::Static,
+ config::CrateType::Executable if !sess.opts.cg.prefer_dynamic || sess.crt_static() => {
+ Linkage::Static
+ }
config::CrateType::Executable => Linkage::Dynamic,
// proc-macro crates are mostly cdylibs, but we also need metadata.
// Staticlibs, cdylibs, and static executables must have all static
// dependencies. If any are not found, generate some nice pretty errors.
- if ty == config::CrateType::Cdylib || ty == config::CrateType::Staticlib ||
- (ty == config::CrateType::Executable && sess.crt_static() &&
- !sess.target.target.options.crt_static_allows_dylibs) {
+ if ty == config::CrateType::Cdylib
+ || ty == config::CrateType::Staticlib
+ || (ty == config::CrateType::Executable
+ && sess.crt_static()
+ && !sess.target.target.options.crt_static_allows_dylibs)
+ {
for &cnum in tcx.crates().iter() {
- if tcx.dep_kind(cnum).macros_only() { continue }
+ if tcx.dep_kind(cnum).macros_only() {
+ continue;
+ }
let src = tcx.used_crate_source(cnum);
- if src.rlib.is_some() { continue }
- sess.err(&format!("crate `{}` required to be available in rlib format, \
+ if src.rlib.is_some() {
+ continue;
+ }
+ sess.err(&format!(
+ "crate `{}` required to be available in rlib format, \
but was not found in this form",
- tcx.crate_name(cnum)));
+ tcx.crate_name(cnum)
+ ));
}
return Vec::new();
}
// dependencies, ensuring there are no conflicts. The only valid case for a
// dependency to be relied upon twice is for both cases to rely on a dylib.
for &cnum in tcx.crates().iter() {
- if tcx.dep_kind(cnum).macros_only() { continue }
+ if tcx.dep_kind(cnum).macros_only() {
+ continue;
+ }
let name = tcx.crate_name(cnum);
let src = tcx.used_crate_source(cnum);
if src.dylib.is_some() {
// 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)) {
+ 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<_>>();
+ })
+ .collect::<Vec<_>>();
// Run through the dependency list again, and add any missing libraries as
// static libraries.
// (e.g., it's an allocator) 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() &&
- !formats.contains_key(&cnum) &&
- tcx.dep_kind(cnum) == DepKind::Explicit {
+ if src.dylib.is_none()
+ && !formats.contains_key(&cnum)
+ && tcx.dep_kind(cnum) == DepKind::Explicit
+ {
assert!(src.rlib.is_some() || src.rmeta.is_some());
log::info!("adding staticlib: {}", tcx.crate_name(cnum));
add_library(tcx, cnum, RequireStatic, &mut formats);
//
// Things like allocators and 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));
+ activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| {
+ tcx.is_panic_runtime(cnum)
+ });
// When dylib B links to dylib A, then when using B we must also link to A.
// It could be the case, however, that the rlib for A is present (hence we
let cnum = CrateNum::new(cnum + 1);
let src = tcx.used_crate_source(cnum);
match *kind {
- Linkage::NotLinked |
- Linkage::IncludedFromDylib => {}
+ Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static if src.rlib.is_some() => continue,
Linkage::Dynamic if src.dylib.is_some() => continue,
kind => {
Linkage::Static => "rlib",
_ => "dylib",
};
- sess.err(&format!("crate `{}` required to be available in {} format, \
+ sess.err(&format!(
+ "crate `{}` required to be available in {} format, \
but was not found in this form",
- tcx.crate_name(cnum), kind));
+ tcx.crate_name(cnum),
+ kind
+ ));
}
}
}
// This error is probably a little obscure, but I imagine that it
// can be refined over time.
if link2 != link || link == RequireStatic {
- tcx.sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \
- shows up once", tcx.crate_name(cnum)))
- .help("having upstream crates all available in one format \
- will likely make this go away")
+ tcx.sess
+ .struct_err(&format!(
+ "cannot satisfy dependencies so `{}` only \
+ shows up once",
+ tcx.crate_name(cnum)
+ ))
+ .help(
+ "having upstream crates all available in one format \
+ will likely make this go away",
+ )
.emit();
}
}
- None => { m.insert(cnum, link); }
+ None => {
+ m.insert(cnum, link);
+ }
}
}
fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
let crates = cstore::used_crates(tcx, RequireStatic);
if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
- return None
+ return None;
}
// 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 last_crate = tcx.crates().len();
- let mut ret = (1..last_crate+1).map(|cnum| {
- if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
- Linkage::Static
- } else {
- Linkage::NotLinked
- }
- }).collect::<Vec<_>>();
+ let mut ret = (1..last_crate + 1)
+ .map(|cnum| {
+ if tcx.dep_kind(CrateNum::new(cnum)) == DepKind::Explicit {
+ Linkage::Static
+ } else {
+ Linkage::NotLinked
+ }
+ })
+ .collect::<Vec<_>>();
// 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.
- activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret,
- &|cnum| tcx.is_panic_runtime(cnum));
+ activate_injected_dep(CStore::from_tcx(tcx).injected_panic_runtime(), &mut ret, &|cnum| {
+ tcx.is_panic_runtime(cnum)
+ });
Some(ret)
}
// a required dependency) in one of the session's field. If this field is not
// set then this compilation doesn't actually need the dependency and we can
// also skip this step entirely.
-fn activate_injected_dep(injected: Option<CrateNum>,
- list: &mut DependencyList,
- replaces_injected: &dyn Fn(CrateNum) -> bool) {
+fn activate_injected_dep(
+ injected: Option<CrateNum>,
+ list: &mut DependencyList,
+ replaces_injected: &dyn Fn(CrateNum) -> bool,
+) {
for (i, slot) in list.iter().enumerate() {
let cnum = CrateNum::new(i + 1);
if !replaces_injected(cnum) {
- continue
+ continue;
}
if *slot != Linkage::NotLinked {
- return
+ return;
}
}
if let Some(injected) = injected {
fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
let sess = &tcx.sess;
if list.len() == 0 {
- return
+ return;
}
let mut panic_runtime = None;
for (i, linkage) in list.iter().enumerate() {
if let Linkage::NotLinked = *linkage {
- continue
+ continue;
}
let cnum = CrateNum::new(i + 1);
if let Some((prev, _)) = panic_runtime {
let prev_name = tcx.crate_name(prev);
let cur_name = tcx.crate_name(cnum);
- sess.err(&format!("cannot link together two \
+ sess.err(&format!(
+ "cannot link together two \
panic runtimes: {} and {}",
- prev_name, cur_name));
+ prev_name, cur_name
+ ));
}
panic_runtime = Some((cnum, tcx.panic_strategy(cnum)));
}
// First up, validate that our selected panic runtime is indeed exactly
// our same strategy.
if found_strategy != desired_strategy {
- sess.err(&format!("the linked panic runtime `{}` is \
+ sess.err(&format!(
+ "the linked panic runtime `{}` is \
not compiled with this crate's \
panic strategy `{}`",
- tcx.crate_name(cnum),
- desired_strategy.desc()));
+ tcx.crate_name(cnum),
+ desired_strategy.desc()
+ ));
}
// Next up, verify that all other crates are compatible with this panic
// panic strategy must match our own.
for (i, linkage) in list.iter().enumerate() {
if let Linkage::NotLinked = *linkage {
- continue
+ continue;
}
if desired_strategy == PanicStrategy::Abort {
- continue
+ continue;
}
let cnum = CrateNum::new(i + 1);
let found_strategy = tcx.panic_strategy(cnum);
let is_compiler_builtins = tcx.is_compiler_builtins(cnum);
if is_compiler_builtins || desired_strategy == found_strategy {
- continue
+ continue;
}
- sess.err(&format!("the crate `{}` is compiled with the \
+ sess.err(&format!(
+ "the crate `{}` is compiled with the \
panic strategy `{}` which is \
incompatible with this crate's \
strategy of `{}`",
- tcx.crate_name(cnum),
- found_strategy.desc(),
- desired_strategy.desc()));
+ tcx.crate_name(cnum),
+ found_strategy.desc(),
+ desired_strategy.desc()
+ ));
}
}
}