Skip to content

Commit ee959a8

Browse files
authored
Auto merge of #36525 - jseyfried:load_crates_in_resolve, r=nikomatsakis
Load extern crates in `resolve` This PR loads `extern crate`s in `resolve`'s `BuildReducedGraphVistor`. r? @nikomatsakis
2 parents cb1b1ee + 7b5c59e commit ee959a8

File tree

8 files changed

+98
-155
lines changed

8 files changed

+98
-155
lines changed

src/librustc/dep_graph/dep_node.rs

-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ pub enum DepNode<D: Clone + Debug> {
5151
WorkProduct(Arc<WorkProductId>),
5252

5353
// Represents different phases in the compiler.
54-
CrateReader,
5554
CollectLanguageItems,
5655
CheckStaticRecursion,
5756
ResolveLifetimes,
@@ -171,7 +170,6 @@ impl<D: Clone + Debug> DepNode<D> {
171170

172171
match *self {
173172
Krate => Some(Krate),
174-
CrateReader => Some(CrateReader),
175173
CollectLanguageItems => Some(CollectLanguageItems),
176174
CheckStaticRecursion => Some(CheckStaticRecursion),
177175
ResolveLifetimes => Some(ResolveLifetimes),

src/librustc/middle/cstore.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
use hir::def::{self, Def};
2626
use hir::def_id::{CrateNum, DefId, DefIndex};
2727
use hir::map as hir_map;
28-
use hir::map::definitions::DefKey;
28+
use hir::map::definitions::{Definitions, DefKey};
2929
use hir::svh::Svh;
3030
use middle::lang_items;
3131
use ty::{self, Ty, TyCtxt};
@@ -422,6 +422,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
422422
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
423423
}
424424

425-
pub trait MacroLoader {
426-
fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
425+
pub trait CrateLoader {
426+
fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
427+
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
428+
fn postprocess(&mut self, krate: &ast::Crate);
427429
}

src/librustc_driver/driver.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ use rustc_back::sha2::{Sha256, Digest};
2828
use rustc_borrowck as borrowck;
2929
use rustc_incremental::{self, IncrementalHashesMap};
3030
use rustc_resolve::{MakeGlobMap, Resolver};
31-
use rustc_metadata::macro_import;
32-
use rustc_metadata::creader::read_local_crates;
31+
use rustc_metadata::creader::CrateLoader;
3332
use rustc_metadata::cstore::CStore;
3433
use rustc_trans::back::{link, write};
3534
use rustc_trans as trans;
@@ -639,12 +638,10 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
639638
}
640639
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;
641640

642-
let mut macro_loader =
643-
macro_import::MacroLoader::new(sess, &cstore, crate_name, krate.config.clone());
644-
641+
let mut crate_loader = CrateLoader::new(sess, &cstore, &krate, crate_name);
645642
let resolver_arenas = Resolver::arenas();
646643
let mut resolver =
647-
Resolver::new(sess, &krate, make_glob_map, &mut macro_loader, &resolver_arenas);
644+
Resolver::new(sess, &krate, make_glob_map, &mut crate_loader, &resolver_arenas);
648645
syntax_ext::register_builtins(&mut resolver, sess.features.borrow().quote);
649646

650647
krate = time(time_passes, "expansion", || {
@@ -736,11 +733,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
736733
// Collect defintions for def ids.
737734
time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));
738735

739-
time(sess.time_passes(), "external crate/lib resolution", || {
740-
let defs = &resolver.definitions;
741-
read_local_crates(sess, &cstore, defs, &krate, crate_name, &sess.dep_graph)
742-
});
743-
744736
time(sess.time_passes(),
745737
"early lint checks",
746738
|| lint::check_ast_crate(sess, &krate));

src/librustc_metadata/creader.rs

+74-109
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@
1212
1313
use cstore::{self, CStore, CrateSource, MetadataBlob};
1414
use loader::{self, CratePaths};
15+
use macro_import;
1516
use schema::CrateRoot;
1617

1718
use rustc::hir::def_id::{CrateNum, DefIndex};
1819
use rustc::hir::svh::Svh;
19-
use rustc::dep_graph::{DepGraph, DepNode};
2020
use rustc::session::{config, Session};
2121
use rustc::session::config::PanicStrategy;
2222
use rustc::session::search_paths::PathKind;
23+
use rustc::middle;
2324
use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
2425
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
2526
use rustc::hir::map as hir_map;
@@ -31,20 +32,18 @@ use std::rc::Rc;
3132
use std::fs;
3233

3334
use syntax::ast;
35+
use syntax::ext::base::LoadedMacro;
3436
use syntax::abi::Abi;
3537
use syntax::parse;
3638
use syntax::attr;
3739
use syntax::parse::token::InternedString;
38-
use syntax::visit;
3940
use syntax_pos::{self, Span, mk_sp};
4041
use log;
4142

42-
struct LocalCrateReader<'a> {
43-
sess: &'a Session,
43+
pub struct CrateLoader<'a> {
44+
pub sess: &'a Session,
45+
pub creader: CrateReader<'a>,
4446
cstore: &'a CStore,
45-
creader: CrateReader<'a>,
46-
krate: &'a ast::Crate,
47-
definitions: &'a hir_map::Definitions,
4847
}
4948

5049
pub struct CrateReader<'a> {
@@ -56,13 +55,6 @@ pub struct CrateReader<'a> {
5655
local_crate_config: ast::CrateConfig,
5756
}
5857

59-
impl<'a> visit::Visitor for LocalCrateReader<'a> {
60-
fn visit_item(&mut self, a: &ast::Item) {
61-
self.process_item(a);
62-
visit::walk_item(self, a);
63-
}
64-
}
65-
6658
fn dump_crates(cstore: &CStore) {
6759
info!("resolved crates:");
6860
cstore.iter_crate_data_origins(|_, data, opt_source| {
@@ -918,98 +910,22 @@ impl ExtensionCrate {
918910
}
919911
}
920912

921-
impl<'a> LocalCrateReader<'a> {
922-
fn new(sess: &'a Session,
923-
cstore: &'a CStore,
924-
defs: &'a hir_map::Definitions,
925-
krate: &'a ast::Crate,
926-
local_crate_name: &str)
927-
-> LocalCrateReader<'a> {
928-
LocalCrateReader {
913+
impl<'a> CrateLoader<'a> {
914+
pub fn new(sess: &'a Session, cstore: &'a CStore, krate: &ast::Crate, crate_name: &str)
915+
-> Self {
916+
let loader = CrateLoader {
929917
sess: sess,
930918
cstore: cstore,
931-
creader: CrateReader::new(sess, cstore, local_crate_name, krate.config.clone()),
932-
krate: krate,
933-
definitions: defs,
934-
}
935-
}
936-
937-
// Traverses an AST, reading all the information about use'd crates and
938-
// extern libraries necessary for later resolving, typechecking, linking,
939-
// etc.
940-
fn read_crates(&mut self, dep_graph: &DepGraph) {
941-
let _task = dep_graph.in_task(DepNode::CrateReader);
942-
943-
self.process_crate(self.krate);
944-
visit::walk_crate(self, self.krate);
945-
self.creader.inject_allocator_crate();
946-
self.creader.inject_panic_runtime(self.krate);
947-
948-
if log_enabled!(log::INFO) {
949-
dump_crates(&self.cstore);
950-
}
951-
952-
for &(ref name, kind) in &self.sess.opts.libs {
953-
register_native_lib(self.sess, self.cstore, None, name.clone(), kind);
954-
}
955-
self.creader.register_statically_included_foreign_items();
956-
}
919+
creader: CrateReader::new(sess, cstore, crate_name, krate.config.clone()),
920+
};
957921

958-
fn process_crate(&self, c: &ast::Crate) {
959-
for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
960-
if let Some(ref linkarg) = a.value_str() {
961-
self.cstore.add_used_link_args(&linkarg);
922+
for attr in krate.attrs.iter().filter(|m| m.name() == "link_args") {
923+
if let Some(ref linkarg) = attr.value_str() {
924+
loader.cstore.add_used_link_args(&linkarg);
962925
}
963926
}
964-
}
965927

966-
fn process_item(&mut self, i: &ast::Item) {
967-
match i.node {
968-
ast::ItemKind::ExternCrate(_) => {
969-
// If this `extern crate` item has `#[macro_use]` then we can
970-
// safely skip it. These annotations were processed during macro
971-
// expansion and are already loaded (if necessary) into our
972-
// crate store.
973-
//
974-
// Note that it's important we *don't* fall through below as
975-
// some `#[macro_use]` crate are explicitly not linked (e.g.
976-
// macro crates) so we want to ensure we avoid `resolve_crate`
977-
// with those.
978-
if attr::contains_name(&i.attrs, "macro_use") {
979-
if self.cstore.was_used_for_derive_macros(i) {
980-
return
981-
}
982-
}
983-
984-
if let Some(info) = self.creader.extract_crate_info(i) {
985-
if !info.should_link {
986-
return;
987-
}
988-
let (cnum, ..) = self.creader.resolve_crate(&None,
989-
&info.ident,
990-
&info.name,
991-
None,
992-
i.span,
993-
PathKind::Crate,
994-
true);
995-
996-
let def_id = self.definitions.opt_local_def_id(i.id).unwrap();
997-
let len = self.definitions.def_path(def_id.index).data.len();
998-
999-
self.creader.update_extern_crate(cnum,
1000-
ExternCrate {
1001-
def_id: def_id,
1002-
span: i.span,
1003-
direct: true,
1004-
path_len: len,
1005-
},
1006-
&mut FnvHashSet());
1007-
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
1008-
}
1009-
}
1010-
ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm),
1011-
_ => { }
1012-
}
928+
loader
1013929
}
1014930

1015931
fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) {
@@ -1073,13 +989,62 @@ impl<'a> LocalCrateReader<'a> {
1073989
}
1074990
}
1075991

1076-
/// Traverses an AST, reading all the information about use'd crates and extern
1077-
/// libraries necessary for later resolving, typechecking, linking, etc.
1078-
pub fn read_local_crates(sess: & Session,
1079-
cstore: & CStore,
1080-
defs: & hir_map::Definitions,
1081-
krate: & ast::Crate,
1082-
local_crate_name: &str,
1083-
dep_graph: &DepGraph) {
1084-
LocalCrateReader::new(sess, cstore, defs, krate, local_crate_name).read_crates(dep_graph)
992+
impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
993+
fn postprocess(&mut self, krate: &ast::Crate) {
994+
self.creader.inject_allocator_crate();
995+
self.creader.inject_panic_runtime(krate);
996+
997+
if log_enabled!(log::INFO) {
998+
dump_crates(&self.cstore);
999+
}
1000+
1001+
for &(ref name, kind) in &self.sess.opts.libs {
1002+
register_native_lib(self.sess, self.cstore, None, name.clone(), kind);
1003+
}
1004+
self.creader.register_statically_included_foreign_items();
1005+
}
1006+
1007+
fn process_item(&mut self, item: &ast::Item, definitions: &hir_map::Definitions) {
1008+
match item.node {
1009+
ast::ItemKind::ExternCrate(_) => {}
1010+
ast::ItemKind::ForeignMod(ref fm) => return self.process_foreign_mod(item, fm),
1011+
_ => return,
1012+
}
1013+
1014+
// If this `extern crate` item has `#[macro_use]` then we can safely skip it.
1015+
// These annotations were processed during macro expansion and are already loaded
1016+
// (if necessary) into our crate store.
1017+
//
1018+
// Note that it's important we *don't* fall through below as some `#[macro_use]`
1019+
// crates are explicitly not linked (e.g. macro crates) so we want to ensure
1020+
// we avoid `resolve_crate` with those.
1021+
if attr::contains_name(&item.attrs, "macro_use") {
1022+
if self.cstore.was_used_for_derive_macros(item) {
1023+
return
1024+
}
1025+
}
1026+
1027+
if let Some(info) = self.creader.extract_crate_info(item) {
1028+
if !info.should_link {
1029+
return;
1030+
}
1031+
1032+
let (cnum, ..) = self.creader.resolve_crate(
1033+
&None, &info.ident, &info.name, None, item.span, PathKind::Crate, true,
1034+
);
1035+
1036+
let def_id = definitions.opt_local_def_id(item.id).unwrap();
1037+
let len = definitions.def_path(def_id.index).data.len();
1038+
1039+
let extern_crate =
1040+
ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len };
1041+
self.creader.update_extern_crate(cnum, extern_crate, &mut FnvHashSet());
1042+
1043+
self.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
1044+
}
1045+
}
1046+
1047+
fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro> {
1048+
macro_import::load_macros(self, extern_crate, allows_macros)
1049+
}
10851050
}

src/librustc_metadata/macro_import.rs

+8-25
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ use std::collections::HashSet;
1414
use std::env;
1515
use std::mem;
1616

17-
use creader::{CrateReader, Macros};
18-
use cstore::CStore;
17+
use creader::{CrateLoader, Macros};
1918

2019
use rustc::hir::def_id::DefIndex;
21-
use rustc::middle;
2220
use rustc::session::Session;
2321
use rustc::util::nodemap::FnvHashMap;
2422
use rustc_back::dynamic_lib::DynamicLibrary;
@@ -31,31 +29,18 @@ use syntax::parse::token;
3129
use syntax_ext::deriving::custom::CustomDerive;
3230
use syntax_pos::Span;
3331

34-
pub struct MacroLoader<'a> {
35-
sess: &'a Session,
36-
reader: CrateReader<'a>,
37-
}
38-
39-
impl<'a> MacroLoader<'a> {
40-
pub fn new(sess: &'a Session,
41-
cstore: &'a CStore,
42-
crate_name: &str,
43-
crate_config: ast::CrateConfig)
44-
-> MacroLoader<'a> {
45-
MacroLoader {
46-
sess: sess,
47-
reader: CrateReader::new(sess, cstore, crate_name, crate_config),
48-
}
49-
}
50-
}
51-
5232
pub fn call_bad_macro_reexport(a: &Session, b: Span) {
5333
span_err!(a, b, E0467, "bad macro reexport");
5434
}
5535

5636
pub type MacroSelection = FnvHashMap<token::InternedString, Span>;
5737

58-
impl<'a> middle::cstore::MacroLoader for MacroLoader<'a> {
38+
pub fn load_macros(loader: &mut CrateLoader, extern_crate: &ast::Item, allows_macros: bool)
39+
-> Vec<LoadedMacro> {
40+
loader.load_crate(extern_crate, allows_macros)
41+
}
42+
43+
impl<'a> CrateLoader<'a> {
5944
fn load_crate(&mut self,
6045
extern_crate: &ast::Item,
6146
allows_macros: bool) -> Vec<LoadedMacro> {
@@ -108,9 +93,7 @@ impl<'a> middle::cstore::MacroLoader for MacroLoader<'a> {
10893

10994
self.load_macros(extern_crate, allows_macros, import, reexport)
11095
}
111-
}
11296

113-
impl<'a> MacroLoader<'a> {
11497
fn load_macros<'b>(&mut self,
11598
vi: &ast::Item,
11699
allows_macros: bool,
@@ -129,7 +112,7 @@ impl<'a> MacroLoader<'a> {
129112
return Vec::new();
130113
}
131114

132-
let mut macros = self.reader.read_macros(vi);
115+
let mut macros = self.creader.read_macros(vi);
133116
let mut ret = Vec::new();
134117
let mut seen = HashSet::new();
135118

src/librustc_resolve/build_reduced_graph.rs

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ impl<'b> Resolver<'b> {
7979

8080
/// Constructs the reduced graph for one item.
8181
fn build_reduced_graph_for_item(&mut self, item: &Item) {
82+
self.crate_loader.process_item(item, &self.definitions);
83+
8284
let parent = self.current_module;
8385
let name = item.ident.name;
8486
let sp = item.span;

0 commit comments

Comments
 (0)