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;
}
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", || {
// 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));
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> {
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| {
}
}
-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) {
}
}
-/// 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)
+ }
}
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> {
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,
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();
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::*;
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.
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));
}),
new_import_semantics: session.features.borrow().item_like_imports,
- macro_loader: macro_loader,
+ crate_loader: crate_loader,
macro_names: FnvHashSet(),
expansion_data: expansion_data,
}
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> {