]> git.lizzy.rs Git - rust.git/commitdiff
Load extern crates in `resolve`.
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Fri, 16 Sep 2016 02:52:09 +0000 (02:52 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Fri, 23 Sep 2016 06:35:33 +0000 (06:35 +0000)
src/librustc/dep_graph/dep_node.rs
src/librustc/middle/cstore.rs
src/librustc_driver/driver.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/macro_import.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs

index 269f0ebb813ca091f6028b60395552790492ab8c..e99ffa95ed63ca3314bb81989ec3a2de3a0f49e4 100644 (file)
@@ -51,7 +51,6 @@ pub enum DepNode<D: Clone + Debug> {
     WorkProduct(Arc<WorkProductId>),
 
     // Represents different phases in the compiler.
-    CrateReader,
     CollectLanguageItems,
     CheckStaticRecursion,
     ResolveLifetimes,
@@ -171,7 +170,6 @@ pub fn map_def<E, OP>(&self, mut op: OP) -> Option<DepNode<E>>
 
         match *self {
             Krate => Some(Krate),
-            CrateReader => Some(CrateReader),
             CollectLanguageItems => Some(CollectLanguageItems),
             CheckStaticRecursion => Some(CheckStaticRecursion),
             ResolveLifetimes => Some(ResolveLifetimes),
index e57e116cea7407e2a48b9fe87cf334e6ed226a7d..62e0de1ba6774bef5851d11f8f5f1a569f09d888 100644 (file)
@@ -25,7 +25,7 @@
 use hir::def::{self, Def};
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::map as hir_map;
-use hir::map::definitions::DefKey;
+use hir::map::definitions::{Definitions, DefKey};
 use hir::svh::Svh;
 use middle::lang_items;
 use ty::{self, Ty, TyCtxt};
@@ -422,6 +422,8 @@ fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
 }
 
-pub trait MacroLoader {
-     fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
+pub trait CrateLoader {
+    fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
+    fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
+    fn postprocess(&mut self, krate: &ast::Crate);
 }
index 18ce35237afcb8d3dcbf4c5fa04e6a1c2256174e..ae80bc53c4c36fd2712d04b2f2654eefa0efe0e8 100644 (file)
@@ -28,8 +28,7 @@
 use rustc_borrowck as borrowck;
 use rustc_incremental::{self, IncrementalHashesMap};
 use rustc_resolve::{MakeGlobMap, Resolver};
-use rustc_metadata::macro_import;
-use rustc_metadata::creader::read_local_crates;
+use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::CStore;
 use rustc_trans::back::{link, write};
 use rustc_trans as trans;
@@ -639,12 +638,10 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
     }
     sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
 
-    let mut macro_loader =
-        macro_import::MacroLoader::new(sess, &cstore, crate_name, krate.config.clone());
-
+    let mut crate_loader = CrateLoader::new(sess, &cstore, &krate, crate_name);
     let resolver_arenas = Resolver::arenas();
     let mut resolver =
-        Resolver::new(sess, &krate, make_glob_map, &mut macro_loader, &resolver_arenas);
+        Resolver::new(sess, &krate, make_glob_map, &mut crate_loader, &resolver_arenas);
     syntax_ext::register_builtins(&mut resolver, sess.features.borrow().quote);
 
     krate = time(time_passes, "expansion", || {
@@ -736,11 +733,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
     // Collect defintions for def ids.
     time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
 
-    time(sess.time_passes(), "external crate/lib resolution", || {
-        let defs = &resolver.definitions;
-        read_local_crates(sess, &cstore, defs, &krate, crate_name, &sess.dep_graph)
-    });
-
     time(sess.time_passes(),
          "early lint checks",
          || lint::check_ast_crate(sess, &krate));
index 95be77c24f46eb952e4c6732fd99dda696f554e0..71cc13aebb37044862863f22eec53071b8a48a31 100644 (file)
 
 use cstore::{self, CStore, CrateSource, MetadataBlob};
 use loader::{self, CratePaths};
+use macro_import;
 use schema::CrateRoot;
 
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::svh::Svh;
-use rustc::dep_graph::{DepGraph, DepNode};
 use rustc::session::{config, Session};
 use rustc::session::config::PanicStrategy;
 use rustc::session::search_paths::PathKind;
+use rustc::middle;
 use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
 use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
 use rustc::hir::map as hir_map;
 use std::fs;
 
 use syntax::ast;
+use syntax::ext::base::LoadedMacro;
 use syntax::abi::Abi;
 use syntax::parse;
 use syntax::attr;
 use syntax::parse::token::InternedString;
-use syntax::visit;
 use syntax_pos::{self, Span, mk_sp};
 use log;
 
-struct LocalCrateReader<'a> {
-    sess: &'a Session,
+pub struct CrateLoader<'a> {
+    pub sess: &'a Session,
+    pub creader: CrateReader<'a>,
     cstore: &'a CStore,
-    creader: CrateReader<'a>,
-    krate: &'a ast::Crate,
-    definitions: &'a hir_map::Definitions,
 }
 
 pub struct CrateReader<'a> {
@@ -56,13 +55,6 @@ pub struct CrateReader<'a> {
     local_crate_config: ast::CrateConfig,
 }
 
-impl<'a> visit::Visitor for LocalCrateReader<'a> {
-    fn visit_item(&mut self, a: &ast::Item) {
-        self.process_item(a);
-        visit::walk_item(self, a);
-    }
-}
-
 fn dump_crates(cstore: &CStore) {
     info!("resolved crates:");
     cstore.iter_crate_data_origins(|_, data, opt_source| {
@@ -918,98 +910,22 @@ fn register(self, creader: &mut CrateReader) {
     }
 }
 
-impl<'a> LocalCrateReader<'a> {
-    fn new(sess: &'a Session,
-           cstore: &'a CStore,
-           defs: &'a hir_map::Definitions,
-           krate: &'a ast::Crate,
-           local_crate_name: &str)
-           -> LocalCrateReader<'a> {
-        LocalCrateReader {
+impl<'a> CrateLoader<'a> {
+    pub fn new(sess: &'a Session, cstore: &'a CStore, krate: &ast::Crate, crate_name: &str)
+               -> Self {
+        let loader = CrateLoader {
             sess: sess,
             cstore: cstore,
-            creader: CrateReader::new(sess, cstore, local_crate_name, krate.config.clone()),
-            krate: krate,
-            definitions: defs,
-        }
-    }
-
-    // Traverses an AST, reading all the information about use'd crates and
-    // extern libraries necessary for later resolving, typechecking, linking,
-    // etc.
-    fn read_crates(&mut self, dep_graph: &DepGraph) {
-        let _task = dep_graph.in_task(DepNode::CrateReader);
-
-        self.process_crate(self.krate);
-        visit::walk_crate(self, self.krate);
-        self.creader.inject_allocator_crate();
-        self.creader.inject_panic_runtime(self.krate);
-
-        if log_enabled!(log::INFO) {
-            dump_crates(&self.cstore);
-        }
-
-        for &(ref name, kind) in &self.sess.opts.libs {
-            register_native_lib(self.sess, self.cstore, None, name.clone(), kind);
-        }
-        self.creader.register_statically_included_foreign_items();
-    }
+            creader: CrateReader::new(sess, cstore, crate_name, krate.config.clone()),
+        };
 
-    fn process_crate(&self, c: &ast::Crate) {
-        for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
-            if let Some(ref linkarg) = a.value_str() {
-                self.cstore.add_used_link_args(&linkarg);
+        for attr in krate.attrs.iter().filter(|m| m.name() == "link_args") {
+            if let Some(ref linkarg) = attr.value_str() {
+                loader.cstore.add_used_link_args(&linkarg);
             }
         }
-    }
 
-    fn process_item(&mut self, i: &ast::Item) {
-        match i.node {
-            ast::ItemKind::ExternCrate(_) => {
-                // If this `extern crate` item has `#[macro_use]` then we can
-                // safely skip it. These annotations were processed during macro
-                // expansion and are already loaded (if necessary) into our
-                // crate store.
-                //
-                // Note that it's important we *don't* fall through below as
-                // some `#[macro_use]` crate are explicitly not linked (e.g.
-                // macro crates) so we want to ensure we avoid `resolve_crate`
-                // with those.
-                if attr::contains_name(&i.attrs, "macro_use") {
-                    if self.cstore.was_used_for_derive_macros(i) {
-                        return
-                    }
-                }
-
-                if let Some(info) = self.creader.extract_crate_info(i) {
-                    if !info.should_link {
-                        return;
-                    }
-                    let (cnum, ..) = self.creader.resolve_crate(&None,
-                                                                &info.ident,
-                                                                &info.name,
-                                                                None,
-                                                                i.span,
-                                                                PathKind::Crate,
-                                                                true);
-
-                    let def_id = self.definitions.opt_local_def_id(i.id).unwrap();
-                    let len = self.definitions.def_path(def_id.index).data.len();
-
-                    self.creader.update_extern_crate(cnum,
-                                                     ExternCrate {
-                                                         def_id: def_id,
-                                                         span: i.span,
-                                                         direct: true,
-                                                         path_len: len,
-                                                     },
-                                                     &mut FnvHashSet());
-                    self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
-                }
-            }
-            ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm),
-            _ => { }
-        }
+        loader
     }
 
     fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
@@ -1073,13 +989,62 @@ fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
     }
 }
 
-/// Traverses an AST, reading all the information about use'd crates and extern
-/// libraries necessary for later resolving, typechecking, linking, etc.
-pub fn read_local_crates(sess: & Session,
-                         cstore: & CStore,
-                         defs: & hir_map::Definitions,
-                         krate: & ast::Crate,
-                         local_crate_name: &str,
-                         dep_graph: &DepGraph) {
-    LocalCrateReader::new(sess, cstore, defs, krate, local_crate_name).read_crates(dep_graph)
+impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
+    fn postprocess(&mut self, krate: &ast::Crate) {
+        self.creader.inject_allocator_crate();
+        self.creader.inject_panic_runtime(krate);
+
+        if log_enabled!(log::INFO) {
+            dump_crates(&self.cstore);
+        }
+
+        for &(ref name, kind) in &self.sess.opts.libs {
+            register_native_lib(self.sess, self.cstore, None, name.clone(), kind);
+        }
+        self.creader.register_statically_included_foreign_items();
+    }
+
+    fn process_item(&mut self, item: &ast::Item, definitions: &hir_map::Definitions) {
+        match item.node {
+            ast::ItemKind::ExternCrate(_) => {}
+            ast::ItemKind::ForeignMod(ref fm) => return self.process_foreign_mod(item, fm),
+            _ => return,
+        }
+
+        // If this `extern crate` item has `#[macro_use]` then we can safely skip it.
+        // These annotations were processed during macro expansion and are already loaded
+        // (if necessary) into our crate store.
+        //
+        // Note that it's important we *don't* fall through below as some `#[macro_use]`
+        // crates are explicitly not linked (e.g. macro crates) so we want to ensure
+        // we avoid `resolve_crate` with those.
+        if attr::contains_name(&item.attrs, "macro_use") {
+            if self.cstore.was_used_for_derive_macros(item) {
+                return
+            }
+        }
+
+        if let Some(info) = self.creader.extract_crate_info(item) {
+            if !info.should_link {
+                return;
+            }
+
+            let (cnum, ..) = self.creader.resolve_crate(
+                &None, &info.ident, &info.name, None, item.span, PathKind::Crate, true,
+            );
+
+            let def_id = definitions.opt_local_def_id(item.id).unwrap();
+            let len = definitions.def_path(def_id.index).data.len();
+
+            let extern_crate =
+                ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len };
+            self.creader.update_extern_crate(cnum, extern_crate, &mut FnvHashSet());
+
+            self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
+        }
+    }
+
+    fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro> {
+        macro_import::load_macros(self, extern_crate, allows_macros)
+    }
 }
index e41f076d64a80bea5abc8e227509d937d3fe05b1..3fe4404525650481ce383d9ffbffd1e5c57dc817 100644 (file)
 use std::env;
 use std::mem;
 
-use creader::{CrateReader, Macros};
-use cstore::CStore;
+use creader::{CrateLoader, Macros};
 
 use rustc::hir::def_id::DefIndex;
-use rustc::middle;
 use rustc::session::Session;
 use rustc::util::nodemap::FnvHashMap;
 use rustc_back::dynamic_lib::DynamicLibrary;
 use syntax_ext::deriving::custom::CustomDerive;
 use syntax_pos::Span;
 
-pub struct MacroLoader<'a> {
-    sess: &'a Session,
-    reader: CrateReader<'a>,
-}
-
-impl<'a> MacroLoader<'a> {
-    pub fn new(sess: &'a Session,
-               cstore: &'a CStore,
-               crate_name: &str,
-               crate_config: ast::CrateConfig)
-               -> MacroLoader<'a> {
-        MacroLoader {
-            sess: sess,
-            reader: CrateReader::new(sess, cstore, crate_name, crate_config),
-        }
-    }
-}
-
 pub fn call_bad_macro_reexport(a: &Session, b: Span) {
     span_err!(a, b, E0467, "bad macro reexport");
 }
 
 pub type MacroSelection = FnvHashMap<token::InternedString, Span>;
 
-impl<'a> middle::cstore::MacroLoader for MacroLoader<'a> {
+pub fn load_macros(loader: &mut CrateLoader, extern_crate: &ast::Item, allows_macros: bool)
+                   -> Vec<LoadedMacro> {
+    loader.load_crate(extern_crate, allows_macros)
+}
+
+impl<'a> CrateLoader<'a> {
     fn load_crate(&mut self,
                   extern_crate: &ast::Item,
                   allows_macros: bool) -> Vec<LoadedMacro> {
@@ -108,9 +93,7 @@ fn load_crate(&mut self,
 
         self.load_macros(extern_crate, allows_macros, import, reexport)
     }
-}
 
-impl<'a> MacroLoader<'a> {
     fn load_macros<'b>(&mut self,
                        vi: &ast::Item,
                        allows_macros: bool,
@@ -129,7 +112,7 @@ fn load_macros<'b>(&mut self,
             return Vec::new();
         }
 
-        let mut macros = self.reader.read_macros(vi);
+        let mut macros = self.creader.read_macros(vi);
         let mut ret = Vec::new();
         let mut seen = HashSet::new();
 
index 3075e394869a5a35322555563ea5b7171314c12b..9202f8c0946f47e3ebb2a5c4c1ed6769e1f00e7a 100644 (file)
@@ -79,6 +79,8 @@ fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
 
     /// Constructs the reduced graph for one item.
     fn build_reduced_graph_for_item(&mut self, item: &Item) {
+        self.crate_loader.process_item(item, &self.definitions);
+
         let parent = self.current_module;
         let name = item.ident.name;
         let sp = item.span;
index 0d75685df55d09e456cf7fc0d97b88d01f69aa35..63ff9de2be29a82dda14fb16cf0a676c602847b9 100644 (file)
@@ -44,7 +44,7 @@
 
 use rustc::hir::map::Definitions;
 use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
-use rustc::middle::cstore::MacroLoader;
+use rustc::middle::cstore::CrateLoader;
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::*;
@@ -1066,7 +1066,7 @@ pub struct Resolver<'a> {
     dummy_binding: &'a NameBinding<'a>,
     new_import_semantics: bool, // true if `#![feature(item_like_imports)]`
 
-    macro_loader: &'a mut MacroLoader,
+    crate_loader: &'a mut CrateLoader,
     macro_names: FnvHashSet<Name>,
 
     // Maps the `Mark` of an expansion to its containing module or block.
@@ -1172,7 +1172,7 @@ impl<'a> Resolver<'a> {
     pub fn new(session: &'a Session,
                krate: &Crate,
                make_glob_map: MakeGlobMap,
-               macro_loader: &'a mut MacroLoader,
+               crate_loader: &'a mut CrateLoader,
                arenas: &'a ResolverArenas<'a>)
                -> Resolver<'a> {
         let root_def = Def::Mod(DefId::local(CRATE_DEF_INDEX));
@@ -1240,7 +1240,7 @@ pub fn new(session: &'a Session,
             }),
             new_import_semantics: session.features.borrow().item_like_imports,
 
-            macro_loader: macro_loader,
+            crate_loader: crate_loader,
             macro_names: FnvHashSet(),
             expansion_data: expansion_data,
         }
@@ -1263,6 +1263,7 @@ pub fn resolve_crate(&mut self, krate: &Crate) {
 
         check_unused::check_crate(self, krate);
         self.report_errors();
+        self.crate_loader.postprocess(krate);
     }
 
     fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Module<'a> {
index c9aa7d6a330184577c1342de8aafd24bc4220724..0b2a70bf4a68db492de26a7409b2c282a56e1291 100644 (file)
@@ -38,7 +38,7 @@ struct ModuleData {
 
 impl<'a> base::Resolver for Resolver<'a> {
     fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro> {
-        self.macro_loader.load_crate(extern_crate, allows_macros)
+        self.crate_loader.load_macros(extern_crate, allows_macros)
     }
 
     fn next_node_id(&mut self) -> ast::NodeId {