Load extern crates in resolve
.
This commit is contained in:
parent
533c04dbb3
commit
7b5c59ea65
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -12,14 +12,15 @@
|
||||
|
||||
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;
|
||||
@ -31,20 +32,18 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
creader: CrateReader::new(sess, cstore, crate_name, krate.config.clone()),
|
||||
};
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,9 @@
|
||||
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;
|
||||
@ -31,31 +29,18 @@
|
||||
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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user