about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-10 10:11:25 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-11-17 08:07:44 +0000
commit641274f9072a3c2b5400d99d671d64ef2d696624 (patch)
treed0628d7f438ec9fc2b96e0c2db946406236d2fb6
parent907120637ec1c28f116e612266cdb83cb5a854a9 (diff)
downloadrust-641274f9072a3c2b5400d99d671d64ef2d696624.tar.gz
rust-641274f9072a3c2b5400d99d671d64ef2d696624.zip
Resolve imports during expansion.
-rw-r--r--src/librustc_driver/driver.rs2
-rw-r--r--src/librustc_resolve/lib.rs3
-rw-r--r--src/librustc_resolve/macros.rs5
-rw-r--r--src/librustc_resolve/resolve_imports.rs25
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/expand.rs13
6 files changed, 26 insertions, 24 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 2dd83f70823..5466c8871d4 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -755,8 +755,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
          || ast_validation::check_crate(sess, &krate));
 
     time(sess.time_passes(), "name resolution", || -> CompileResult {
-        resolver.resolve_imports();
-
         // Since import resolution will eventually happen in expansion,
         // don't perform `after_expand` until after import resolution.
         after_expand(&krate)?;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8f743cb6d06..d2f2b078861 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -76,7 +76,7 @@ use std::fmt;
 use std::mem::replace;
 use std::rc::Rc;
 
-use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution};
+use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
 use macros::{InvocationData, LegacyBinding, LegacyScope};
 
 // NB: This module needs to be declared first so diagnostics are
@@ -1335,6 +1335,7 @@ impl<'a> Resolver<'a> {
 
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
+        ImportResolver { resolver: self }.finalize_imports();
         self.current_module = self.graph_root;
         visit::walk_crate(self, krate);
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index afbe6f0d518..82f271e10b9 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -10,6 +10,7 @@
 
 use {Module, ModuleKind, Resolver};
 use build_reduced_graph::BuildReducedGraphVisitor;
+use resolve_imports::ImportResolver;
 use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex};
 use rustc::hir::def::{Def, Export};
 use rustc::hir::map::{self, DefCollector};
@@ -185,6 +186,10 @@ impl<'a> base::Resolver for Resolver<'a> {
         self.macros_at_scope.insert(id, macros);
     }
 
+    fn resolve_imports(&mut self) {
+        ImportResolver { resolver: self }.resolve_imports()
+    }
+
     fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
         for i in 0..attrs.len() {
             let name = intern(&attrs[i].name());
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 44ce48fe615..159b5706ec1 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -32,12 +32,6 @@ use syntax_pos::Span;
 use std::cell::{Cell, RefCell};
 use std::mem;
 
-impl<'a> Resolver<'a> {
-    pub fn resolve_imports(&mut self) {
-        ImportResolver { resolver: self }.resolve_imports();
-    }
-}
-
 /// Contains data for specific types of import directives.
 #[derive(Clone, Debug)]
 pub enum ImportDirectiveSubclass<'a> {
@@ -399,8 +393,8 @@ impl<'a> Resolver<'a> {
     }
 }
 
-struct ImportResolver<'a, 'b: 'a> {
-    resolver: &'a mut Resolver<'b>,
+pub struct ImportResolver<'a, 'b: 'a> {
+    pub resolver: &'a mut Resolver<'b>,
 }
 
 impl<'a, 'b: 'a> ::std::ops::Deref for ImportResolver<'a, 'b> {
@@ -433,28 +427,21 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
 
     /// Resolves all imports for the crate. This method performs the fixed-
     /// point iteration.
-    fn resolve_imports(&mut self) {
-        let mut i = 0;
+    pub fn resolve_imports(&mut self) {
         let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
-
         while self.indeterminate_imports.len() < prev_num_indeterminates {
             prev_num_indeterminates = self.indeterminate_imports.len();
-            debug!("(resolving imports) iteration {}, {} imports left", i, prev_num_indeterminates);
-
-            let mut imports = Vec::new();
-            ::std::mem::swap(&mut imports, &mut self.indeterminate_imports);
-
-            for import in imports {
+            for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) {
                 match self.resolve_import(&import) {
                     Failed(_) => self.determined_imports.push(import),
                     Indeterminate => self.indeterminate_imports.push(import),
                     Success(()) => self.determined_imports.push(import),
                 }
             }
-
-            i += 1;
         }
+    }
 
+    pub fn finalize_imports(&mut self) {
         for module in self.arenas.local_modules().iter() {
             self.finalize_resolutions_in(module);
         }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b4ac576f57a..7f66b060052 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -524,6 +524,7 @@ pub trait Resolver {
     fn add_ext(&mut self, ident: ast::Ident, ext: Rc<SyntaxExtension>);
     fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>);
 
+    fn resolve_imports(&mut self);
     fn find_attr_invoc(&mut self, attrs: &mut Vec<Attribute>) -> Option<Attribute>;
     fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
                      -> Result<Rc<SyntaxExtension>, Determinacy>;
@@ -547,6 +548,7 @@ impl Resolver for DummyResolver {
     fn add_ext(&mut self, _ident: ast::Ident, _ext: Rc<SyntaxExtension>) {}
     fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec<Mark>) {}
 
+    fn resolve_imports(&mut self) {}
     fn find_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>) -> Option<Attribute> { None }
     fn resolve_macro(&mut self, _scope: Mark, _path: &ast::Path, _force: bool)
                      -> Result<Rc<SyntaxExtension>, Determinacy> {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 877b312539f..8e0c3ce8448 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -222,6 +222,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         self.cx.current_expansion.depth = 0;
 
         let (expansion, mut invocations) = self.collect_invocations(expansion);
+        self.resolve_imports();
         invocations.reverse();
 
         let mut expansions = Vec::new();
@@ -230,9 +231,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         loop {
             let invoc = if let Some(invoc) = invocations.pop() {
                 invoc
-            } else if undetermined_invocations.is_empty() {
-                break
             } else {
+                self.resolve_imports();
+                if undetermined_invocations.is_empty() { break }
                 invocations = mem::replace(&mut undetermined_invocations, Vec::new());
                 force = !mem::replace(&mut progress, false);
                 continue
@@ -292,6 +293,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         expansion.fold_with(&mut placeholder_expander)
     }
 
+    fn resolve_imports(&mut self) {
+        if self.monotonic {
+            let err_count = self.cx.parse_sess.span_diagnostic.err_count();
+            self.cx.resolver.resolve_imports();
+            self.cx.resolve_err_count += self.cx.parse_sess.span_diagnostic.err_count() - err_count;
+        }
+    }
+
     fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
         let result = {
             let mut collector = InvocationCollector {