1
Fork 0

rustc: Remove CrateStore::used_crate*

This commit removes the `use_crates` and `used_crate_source` methods in favor of
a mix of queries and helper methods being used now instead.
This commit is contained in:
Alex Crichton 2017-08-31 12:08:29 -07:00
parent 0b7e0aaba5
commit 490f34ac0c
11 changed files with 120 additions and 92 deletions

View file

@ -567,6 +567,8 @@ define_dep_nodes!( <'tcx>
[] VisibleParentMap,
[] IsDirectExternCrate(CrateNum),
[] MissingExternCrateItem(CrateNum),
[] UsedCrateSource(CrateNum),
[] PostorderCnums,
);
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

View file

@ -23,7 +23,7 @@
//! probably get a better home if someone can find one.
use hir::def;
use hir::def_id::{CrateNum, DefId, DefIndex};
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use hir::map as hir_map;
use hir::map::definitions::{Definitions, DefKey, DefPathTable};
use hir::svh::Svh;
@ -251,14 +251,13 @@ pub trait CrateStore {
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn item_generics_cloned_untracked(&self, def: DefId) -> ty::Generics;
fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem;
fn postorder_cnums_untracked(&self) -> Vec<CrateNum>;
// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<CrateNum>;
// utility functions
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
@ -340,9 +339,6 @@ impl CrateStore for DummyCrateStore {
fn crates(&self) -> Vec<CrateNum> { vec![] }
// utility functions
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{ vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -352,6 +348,7 @@ impl CrateStore for DummyCrateStore {
bug!("encode_metadata")
}
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
fn postorder_cnums_untracked(&self) -> Vec<CrateNum> { bug!("postorder_cnums_untracked") }
// access to the metadata loader
fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") }
@ -361,3 +358,46 @@ pub trait CrateLoader {
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
fn postprocess(&mut self, krate: &ast::Crate);
}
// This method is used when generating the command line to pass through to
// system linker. The linker expects undefined symbols on the left of the
// command line to be defined in libraries on the right, not the other way
// around. For more info, see some comments in the add_used_library function
// below.
//
// In order to get this left-to-right dependency ordering, we perform a
// topological sort of all crates putting the leaves at the right-most
// positions.
pub fn used_crates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
let mut libs = tcx.sess.cstore.crates()
.into_iter()
.filter_map(|cnum| {
if tcx.dep_kind(cnum).macros_only() {
return None
}
let source = tcx.used_crate_source(cnum);
let path = match prefer {
LinkagePreference::RequireDynamic => source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => source.rlib.clone().map(|p| p.0),
};
let path = match path {
Some(p) => LibSource::Some(p),
None => {
if source.rmeta.is_some() {
LibSource::MetadataOnly
} else {
LibSource::None
}
}
};
Some((cnum, path))
})
.collect::<Vec<_>>();
let mut ordering = tcx.postorder_cnums(LOCAL_CRATE);
Rc::make_mut(&mut ordering).reverse();
libs.sort_by_key(|&(a, _)| {
ordering.iter().position(|x| *x == a)
});
libs
}

View file

@ -66,7 +66,7 @@ use hir::def_id::CrateNum;
use session;
use session::config;
use ty::TyCtxt;
use middle::cstore::DepKind;
use middle::cstore::{self, DepKind};
use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
use util::nodemap::FxHashMap;
use rustc_back::PanicStrategy;
@ -134,7 +134,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
for cnum in sess.cstore.crates() {
if tcx.dep_kind(cnum).macros_only() { continue }
let src = sess.cstore.used_crate_source(cnum);
let src = tcx.used_crate_source(cnum);
if src.rlib.is_some() { continue }
sess.err(&format!("dependency `{}` not found in rlib format",
tcx.crate_name(cnum)));
@ -168,7 +168,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
for cnum in sess.cstore.crates() {
if tcx.dep_kind(cnum).macros_only() { continue }
let name = tcx.crate_name(cnum);
let src = sess.cstore.used_crate_source(cnum);
let src = tcx.used_crate_source(cnum);
if src.dylib.is_some() {
info!("adding dylib: {}", name);
add_library(tcx, cnum, RequireDynamic, &mut formats);
@ -196,7 +196,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// 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.
for cnum in sess.cstore.crates() {
let src = sess.cstore.used_crate_source(cnum);
let src = tcx.used_crate_source(cnum);
if src.dylib.is_none() &&
!formats.contains_key(&cnum) &&
tcx.dep_kind(cnum) == DepKind::Explicit {
@ -225,7 +225,7 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// making sure that everything is available in the requested format.
for (cnum, kind) in ret.iter().enumerate() {
let cnum = CrateNum::new(cnum + 1);
let src = sess.cstore.used_crate_source(cnum);
let src = tcx.used_crate_source(cnum);
match *kind {
Linkage::NotLinked |
Linkage::IncludedFromDylib => {}
@ -274,7 +274,7 @@ fn add_library(tcx: TyCtxt,
fn attempt_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<DependencyList> {
let sess = &tcx.sess;
let crates = sess.cstore.used_crates(RequireStatic);
let crates = cstore::used_crates(tcx, RequireStatic);
if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
return None
}

View file

@ -17,7 +17,7 @@ use hir::svh::Svh;
use lint;
use middle::const_val;
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary};
use middle::cstore::{NativeLibraryKind, DepKind};
use middle::cstore::{NativeLibraryKind, DepKind, CrateSource};
use middle::privacy::AccessLevels;
use middle::region;
use middle::region::RegionMaps;
@ -718,6 +718,18 @@ impl<'tcx> QueryDescription for queries::missing_extern_crate_item<'tcx> {
}
}
impl<'tcx> QueryDescription for queries::used_crate_source<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("looking at the source for a crate")
}
}
impl<'tcx> QueryDescription for queries::postorder_cnums<'tcx> {
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
format!("generating a postorder list of CrateNums")
}
}
// If enabled, send a message to the profile-queries thread
macro_rules! profq_msg {
($tcx:expr, $msg:expr) => {
@ -1331,6 +1343,8 @@ define_maps! { <'tcx>
[] visible_parent_map: visible_parent_map_node(CrateNum)
-> Rc<DefIdMap<DefId>>,
[] missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool,
[] used_crate_source: UsedCrateSource(CrateNum) -> Rc<CrateSource>,
[] postorder_cnums: postorder_cnums_node(CrateNum) -> Rc<Vec<CrateNum>>,
}
fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@ -1428,3 +1442,7 @@ fn get_lang_items_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
fn visible_parent_map_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::VisibleParentMap
}
fn postorder_cnums_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::PostorderCnums
}

View file

@ -24,7 +24,7 @@ use rustc::session::config::{Sanitizer, self};
use rustc_back::PanicStrategy;
use rustc::session::search_paths::PathKind;
use rustc::middle;
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
use rustc::middle::cstore::{validate_crate_name, ExternCrate};
use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashSet;
use rustc::hir::map::Definitions;
@ -166,7 +166,7 @@ impl<'a> CrateLoader<'a> {
// We're also sure to compare *paths*, not actual byte slices. The
// `source` stores paths which are normalized which may be different
// from the strings on the command line.
let source = self.cstore.used_crate_source(cnum);
let source = &self.cstore.get_crate_data(cnum).source;
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
let found = locs.iter().any(|l| {
let l = fs::canonicalize(l).ok();

View file

@ -150,52 +150,12 @@ impl CStore {
ordering.push(krate);
}
// This method is used when generating the command line to pass through to
// system linker. The linker expects undefined symbols on the left of the
// command line to be defined in libraries on the right, not the other way
// around. For more info, see some comments in the add_used_library function
// below.
//
// In order to get this left-to-right dependency ordering, we perform a
// topological sort of all crates putting the leaves at the right-most
// positions.
pub fn do_get_used_crates(&self,
prefer: LinkagePreference)
-> Vec<(CrateNum, LibSource)> {
pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
let mut ordering = Vec::new();
for (&num, _) in self.metas.borrow().iter() {
self.push_dependencies_in_postorder(&mut ordering, num);
}
info!("topological ordering: {:?}", ordering);
ordering.reverse();
let mut libs = self.metas
.borrow()
.iter()
.filter_map(|(&cnum, data)| {
if data.dep_kind.get().macros_only() { return None; }
let path = match prefer {
LinkagePreference::RequireDynamic => data.source.dylib.clone().map(|p| p.0),
LinkagePreference::RequireStatic => data.source.rlib.clone().map(|p| p.0),
};
let path = match path {
Some(p) => LibSource::Some(p),
None => {
if data.source.rmeta.is_some() {
LibSource::MetadataOnly
} else {
LibSource::None
}
}
};
Some((cnum, path))
})
.collect::<Vec<_>>();
libs.sort_by(|&(a, _), &(b, _)| {
let a = ordering.iter().position(|x| *x == a);
let b = ordering.iter().position(|x| *x == b);
a.cmp(&b)
});
libs
return ordering
}
pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {

View file

@ -15,9 +15,9 @@ use native_libs;
use schema;
use rustc::ty::maps::QueryConfig;
use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind,
use rustc::middle::cstore::{CrateStore, DepKind,
MetadataLoader, LinkMeta,
LinkagePreference, LoadedMacro, EncodedMetadata,
LoadedMacro, EncodedMetadata,
EncodedMetadataHashes, NativeLibraryKind};
use rustc::hir::def;
use rustc::session::Session;
@ -229,6 +229,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
_ => false,
}
}
used_crate_source => { Rc::new(cdata.source.clone()) }
}
pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
@ -332,6 +334,11 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
Rc::new(visible_parent_map)
},
postorder_cnums: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Rc::new(tcx.sess.cstore.postorder_cnums_untracked())
},
..*providers
};
}
@ -477,21 +484,15 @@ impl CrateStore for cstore::CStore {
result
}
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
{
self.do_get_used_crates(prefer)
}
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource
{
self.get_crate_data(cnum).source.clone()
}
fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>
{
self.do_extern_mod_stmt_cnum(emod_id)
}
fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
self.do_postorder_cnums_untracked()
}
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,

View file

@ -19,8 +19,7 @@ use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, Pri
use rustc::session::filesearch;
use rustc::session::search_paths::PathKind;
use rustc::session::Session;
use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, LinkagePreference,
NativeLibraryKind};
use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, NativeLibraryKind};
use rustc::middle::dependency_format::Linkage;
use {CrateTranslation, CrateInfo};
use rustc::util::common::time;
@ -218,7 +217,7 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
pub fn each_linked_rlib(sess: &Session,
info: &CrateInfo,
f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
let crates = info.used_crates_static.iter();
let fmts = sess.dependency_formats.borrow();
let fmts = fmts.get(&config::CrateTypeExecutable)
.or_else(|| fmts.get(&config::CrateTypeStaticlib))
@ -228,7 +227,7 @@ pub fn each_linked_rlib(sess: &Session,
Some(f) => f,
None => return Err(format!("could not find formats for rlibs"))
};
for (cnum, path) in crates {
for &(cnum, ref path) in crates {
match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked) |
Some(&Linkage::IncludedFromDylib) => continue,
@ -236,8 +235,8 @@ pub fn each_linked_rlib(sess: &Session,
None => return Err(format!("could not find formats for rlibs"))
}
let name = &info.crate_name[&cnum];
let path = match path {
LibSource::Some(p) => p,
let path = match *path {
LibSource::Some(ref p) => p,
LibSource::MetadataOnly => {
return Err(format!("could not find rlib for: `{}`, found rmeta (metadata) file",
name))
@ -1028,7 +1027,7 @@ fn link_args(cmd: &mut Linker,
path
};
let mut rpath_config = RPathConfig {
used_crates: sess.cstore.used_crates(LinkagePreference::RequireDynamic),
used_crates: &trans.crate_info.used_crates_dynamic,
out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
@ -1107,21 +1106,21 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// Invoke get_used_crates to ensure that we get a topological sorting of
// crates.
let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic);
let deps = &trans.crate_info.used_crates_dynamic;
let mut compiler_builtins = None;
for &(cnum, _) in &deps {
for &(cnum, _) in deps.iter() {
// We may not pass all crates through to the linker. Some crates may
// appear statically in an existing dylib, meaning we'll pick up all the
// symbols from the dylib.
let src = sess.cstore.used_crate_source(cnum);
let src = &trans.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
_ if trans.crate_info.profiler_runtime == Some(cnum) => {
add_static_crate(cmd, sess, trans, tmpdir, crate_type, cnum);
}
_ if trans.crate_info.sanitizer_runtime == Some(cnum) => {
link_sanitizer_runtime(cmd, sess, tmpdir, cnum);
link_sanitizer_runtime(cmd, sess, trans, tmpdir, cnum);
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
@ -1135,7 +1134,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
add_static_crate(cmd, sess, trans, tmpdir, crate_type, cnum);
}
Linkage::Dynamic => {
add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0)
}
}
}
@ -1164,10 +1163,11 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// linking it.
fn link_sanitizer_runtime(cmd: &mut Linker,
sess: &Session,
trans: &CrateTranslation,
tmpdir: &Path,
cnum: CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
let src = &trans.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
if sess.target.target.options.is_like_osx {
// On Apple platforms, the sanitizer is always built as a dylib, and
@ -1236,8 +1236,8 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
tmpdir: &Path,
crate_type: config::CrateType,
cnum: CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
let src = &trans.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
// See the comment above in `link_staticlib` and `link_rlib` for why if
// there's a static library that's not relevant we skip all object
@ -1371,8 +1371,8 @@ fn add_upstream_native_libraries(cmd: &mut Linker,
let formats = sess.dependency_formats.borrow();
let data = formats.get(&crate_type).unwrap();
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic);
for (cnum, _) in crates {
let crates = &trans.crate_info.used_crates_static;
for &(cnum, _) in crates {
for lib in trans.crate_info.native_libraries[&cnum].iter() {
if !relevant_lib(sess, &lib) {
continue

View file

@ -17,7 +17,7 @@ use rustc::hir::def_id::CrateNum;
use rustc::middle::cstore::LibSource;
pub struct RPathConfig<'a> {
pub used_crates: Vec<(CrateNum, LibSource)>,
pub used_crates: &'a [(CrateNum, LibSource)],
pub out_filename: PathBuf,
pub is_like_osx: bool,
pub has_rpath: bool,
@ -36,7 +36,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
debug!("preparing the RPATH!");
let libs = config.used_crates.clone();
let libs = libs.into_iter().filter_map(|(_, l)| l.option()).collect::<Vec<_>>();
let libs = libs.iter().filter_map(|&(_, ref l)| l.option()).collect::<Vec<_>>();
let rpaths = get_rpaths(config, &libs);
flags.extend_from_slice(&rpaths_to_flags(&rpaths));

View file

@ -41,7 +41,7 @@ use rustc::middle::lang_items::StartFnLangItem;
use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::dep_graph::AssertDepGraphSafe;
use rustc::middle::cstore::LinkMeta;
use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
use rustc::hir::map as hir_map;
use rustc::util::common::{time, print_time_passes_entry};
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
@ -1508,7 +1508,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
}
impl CrateInfo {
pub fn new(tcx: TyCtxt) -> CrateInfo {
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CrateInfo {
let mut info = CrateInfo {
panic_runtime: None,
compiler_builtins: None,
@ -1519,11 +1519,15 @@ impl CrateInfo {
used_libraries: tcx.native_libraries(LOCAL_CRATE),
link_args: tcx.link_args(LOCAL_CRATE),
crate_name: FxHashMap(),
used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),
used_crate_source: FxHashMap(),
};
for cnum in tcx.sess.cstore.crates() {
info.native_libraries.insert(cnum, tcx.native_libraries(cnum));
info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string());
info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum));
if tcx.is_panic_runtime(cnum) {
info.panic_runtime = Some(cnum);
}

View file

@ -70,7 +70,7 @@ use std::rc::Rc;
use rustc::hir::def_id::CrateNum;
use rustc::util::nodemap::{FxHashSet, FxHashMap};
use rustc::middle::cstore::NativeLibrary;
use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource};
pub mod back {
mod archive;
@ -237,6 +237,9 @@ pub struct CrateInfo {
crate_name: FxHashMap<CrateNum, String>,
used_libraries: Rc<Vec<NativeLibrary>>,
link_args: Rc<Vec<String>>,
used_crate_source: FxHashMap<CrateNum, Rc<CrateSource>>,
used_crates_static: Vec<(CrateNum, LibSource)>,
used_crates_dynamic: Vec<(CrateNum, LibSource)>,
}
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }