Resolve imports during expansion.

This commit is contained in:
Jeffrey Seyfried 2016-11-10 10:11:25 +00:00
parent 907120637e
commit 641274f907
6 changed files with 26 additions and 24 deletions

View File

@ -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)?;

View File

@ -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);

View File

@ -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());

View File

@ -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);
}

View File

@ -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> {

View File

@ -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 {