]> git.lizzy.rs Git - rust.git/commitdiff
Refactor structure of ExternEntry
authorAaron Hill <aa1ronham@gmail.com>
Sun, 7 Apr 2019 22:48:40 +0000 (18:48 -0400)
committerAaron Hill <aa1ronham@gmail.com>
Sun, 14 Apr 2019 19:45:18 +0000 (15:45 -0400)
src/librustc/session/config.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/locator.rs
src/librustc_typeck/lib.rs
src/tools/compiletest/src/header.rs

index 474848fbaf345617984dc619f52a29a117dc4bbb..9bc9c7cbbe3f003adb9c833fbe9ce713487fe80a 100644 (file)
@@ -283,26 +283,24 @@ pub fn should_codegen(&self) -> bool {
 // 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<String, BTreeSet<ExternEntry>>);
+pub struct Externs(BTreeMap<String, ExternEntry>);
 
 #[derive(Clone, Hash, Eq, PartialEq, Ord, PartialOrd, Debug)]
 pub struct ExternEntry {
-    pub location: Option<String>,
-    pub public: bool
+    pub locations: BTreeSet<Option<String>>,
+    pub is_private_dep: bool
 }
 
-
-
 impl Externs {
-    pub fn new(data: BTreeMap<String, BTreeSet<ExternEntry>>) -> Externs {
+    pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
         Externs(data)
     }
 
-    pub fn get(&self, key: &str) -> Option<&BTreeSet<ExternEntry>> {
+    pub fn get(&self, key: &str) -> Option<&ExternEntry> {
         self.0.get(key)
     }
 
-    pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<ExternEntry>> {
+    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<String>, bool)>
     // This allows to modify entries in-place to set their correct
     // 'public' value
-    let mut externs: BTreeMap<_, BTreeMap<Option<String>, 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<String, ExternEntry> = 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<String, BTreeSet<ExternEntry>> = externs.into_iter()
-        .map(|(k, v)| {
-            let values =v.into_iter().map(|(location, public)| {
                 ExternEntry {
-                    location,
-                    public
+                    locations: locations,
+                    is_private_dep: private
                 }
-            }).collect::<BTreeSet<ExternEntry>>();
-            (k, values)
-        })
-        .collect();
-
-
+            });
+    }
 
     let crate_name = matches.opt_str("crate-name");
 
@@ -2699,9 +2687,11 @@ mod tests {
 
     impl ExternEntry {
         fn new_public(location: Option<String>) -> ExternEntry {
+            let mut locations = BTreeSet::new();
+            locations.insert(location);
             ExternEntry {
-                location,
-                public: true
+                locations,
+                is_private_dep: false
             }
         }
     }
index 7c5b5dc7113ae933aefa5c243924eda558bd84f4..160d4c30c0bad24f513cd53b57636e0e17a3c77e 100644 (file)
@@ -131,9 +131,9 @@ fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
             // `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 @@ fn register_crate(
         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);
index f56ca5af76e8f93414531ca00b1bb8f6c811ae14..116042c53fb9e2455e2c00bea4bde81fdc6ea256 100644 (file)
@@ -442,11 +442,11 @@ fn find_library_crate(&mut self,
         // 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()),
                     );
                 }
             }
index 21d1af229ddc2815a4536ed9499cff0adf4378e6..401d7457517e6373fad1351b2cd3e67a9750b452 100644 (file)
@@ -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),
index c548b1efa75cbdc88953c83b6ad5f057d2b3adb1..64882c603bad3c8cbf697100e489f9c09902e339 100644 (file)
@@ -288,6 +288,7 @@ pub struct TestProps {
     pub aux_builds: Vec<String>,
     // 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<String>,
     // Environment settings to use for compiling
     pub rustc_env: Vec<(String, String)>,