Resolve imports during expansion.
This commit is contained in:
parent
907120637e
commit
641274f907
@ -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)?;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user