From 482b77a1470681da08748f1461c598eb8e48615b Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 7 Apr 2019 18:48:40 -0400 Subject: [PATCH] Refactor structure of ExternEntry --- src/librustc/session/config.rs | 66 ++++++++++++----------------- src/librustc_metadata/creader.rs | 20 +++------ src/librustc_metadata/locator.rs | 6 +-- src/librustc_typeck/lib.rs | 6 +-- src/tools/compiletest/src/header.rs | 1 + 5 files changed, 40 insertions(+), 59 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 474848fbaf345..9bc9c7cbbe3f0 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -283,26 +283,24 @@ impl OutputTypes { // DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That // would break dependency tracking for command-line arguments. #[derive(Clone, Hash)] -pub struct Externs(BTreeMap>); +pub struct Externs(BTreeMap); #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)] pub struct ExternEntry { - pub location: Option, - pub public: bool + pub locations: BTreeSet>, + pub is_private_dep: bool } - - impl Externs { - pub fn new(data: BTreeMap>) -> Externs { + pub fn new(data: BTreeMap) -> Externs { Externs(data) } - pub fn get(&self, key: &str) -> Option<&BTreeSet> { + pub fn get(&self, key: &str) -> Option<&ExternEntry> { self.0.get(key) } - pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet> { + pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, ExternEntry> { self.0.iter() } } @@ -2323,9 +2321,9 @@ pub fn build_session_options_and_crate_config( // and later convert it into a BTreeSet<(Option, bool)> // This allows to modify entries in-place to set their correct // 'public' value - let mut externs: BTreeMap<_, BTreeMap, bool>> = BTreeMap::new(); - for (arg, public) in matches.opt_strs("extern").into_iter().map(|v| (v, true)) - .chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, false))) { + let mut externs: BTreeMap = BTreeMap::new(); + for (arg, private) in matches.opt_strs("extern").into_iter().map(|v| (v, false)) + .chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, true))) { let mut parts = arg.splitn(2, '='); let name = parts.next().unwrap_or_else(|| @@ -2340,36 +2338,26 @@ pub fn build_session_options_and_crate_config( }; - // Extern crates start out public, - // and become private if we later see - // an '--extern-private' key. They never - // go back to being public once we've seen - // '--extern-private', so we logical-AND - // their current and new 'public' value together - externs .entry(name.to_owned()) - .or_default() - .entry(location) - .and_modify(|e| *e &= public) - .or_insert(public); - } + .and_modify(|e| { + e.locations.insert(location.clone()); + + // Crates start out being not private, + // and go to being private if we see an '--extern-private' + // flag + e.is_private_dep |= private; + }) + .or_insert_with(|| { + let mut locations = BTreeSet::new(); + locations.insert(location); - // Now that we've determined the 'public' status of each extern, - // collect them into a set of ExternEntry - let externs: BTreeMap> = externs.into_iter() - .map(|(k, v)| { - let values =v.into_iter().map(|(location, public)| { ExternEntry { - location, - public + locations: locations, + is_private_dep: private } - }).collect::>(); - (k, values) - }) - .collect(); - - + }); + } let crate_name = matches.opt_str("crate-name"); @@ -2699,9 +2687,11 @@ mod tests { impl ExternEntry { fn new_public(location: Option) -> ExternEntry { + let mut locations = BTreeSet::new(); + locations.insert(location); ExternEntry { - location, - public: true + locations, + is_private_dep: false } } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7c5b5dc7113ae..160d4c30c0bad 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -131,9 +131,9 @@ impl<'a> CrateLoader<'a> { // `source` stores paths which are normalized which may be different // from the strings on the command line. let source = &self.cstore.get_crate_data(cnum).source; - if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) { + if let Some(entry) = self.sess.opts.externs.get(&*name.as_str()) { // Only use `--extern crate_name=path` here, not `--extern crate_name`. - let found = locs.iter().filter_map(|l| l.location.as_ref()).any(|l| { + let found = entry.locations.iter().filter_map(|l| l.as_ref()).any(|l| { let l = fs::canonicalize(l).ok(); source.dylib.as_ref().map(|p| &p.0) == l.as_ref() || source.rlib.as_ref().map(|p| &p.0) == l.as_ref() @@ -201,19 +201,9 @@ impl<'a> CrateLoader<'a> { let crate_root = lib.metadata.get_root(); self.verify_no_symbol_conflicts(span, &crate_root); - let mut private_dep = false; - if let Some(s) = self.sess.opts.externs.get(&name.as_str()) { - for entry in s { - let p = entry.location.as_ref().map(|s| s.as_str()); - if p == lib.dylib.as_ref().and_then(|r| r.0.to_str()) || - p == lib.rlib.as_ref().and_then(|r| r.0.to_str()) { - - private_dep = !entry.public; - break; - } - } - } - + let private_dep = self.sess.opts.externs.get(&name.as_str()) + .map(|e| e.is_private_dep) + .unwrap_or(false); info!("register crate `extern crate {} as {}` (private_dep = {})", crate_root.name, ident, private_dep); diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index f56ca5af76e8f..116042c53fb9e 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -442,11 +442,11 @@ impl<'a> Context<'a> { // must be loaded via -L plus some filtering. if self.hash.is_none() { self.should_match_name = false; - if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) { + if let Some(entry) = self.sess.opts.externs.get(&self.crate_name.as_str()) { // Only use `--extern crate_name=path` here, not `--extern crate_name`. - if s.iter().any(|l| l.location.is_some()) { + if entry.locations.iter().any(|l| l.is_some()) { return self.find_commandline_library( - s.iter().filter_map(|l| l.location.as_ref()), + entry.locations.iter().filter_map(|l| l.as_ref()), ); } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 21d1af229ddc2..401d7457517e6 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -176,7 +176,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) } -fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) { +pub fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) { let main_id = tcx.hir().as_local_hir_id(main_def_id).unwrap(); let main_span = tcx.def_span(main_def_id); let main_t = tcx.type_of(main_def_id); @@ -241,7 +241,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, main_def_id: DefId) { } } -fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) { +pub fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) { let start_id = tcx.hir().as_local_hir_id(start_def_id).unwrap(); let start_span = tcx.def_span(start_def_id); let start_t = tcx.type_of(start_def_id); @@ -298,7 +298,7 @@ fn check_start_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, start_def_id: DefId) } } -fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { +pub fn check_for_entry_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, EntryFnType::Main)) => check_main_fn_ty(tcx, def_id), Some((def_id, EntryFnType::Start)) => check_start_fn_ty(tcx, def_id), diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index c548b1efa75cb..64882c603bad3 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -288,6 +288,7 @@ pub struct TestProps { pub aux_builds: Vec, // A list of crates to pass '--extern-private name:PATH' flags for // This should be a subset of 'aux_build' + // FIXME: Replace this with a better solution: https://github.com/rust-lang/rust/pull/54020 pub extern_private: Vec, // Environment settings to use for compiling pub rustc_env: Vec<(String, String)>,