Skip to content

Commit 5b12832

Browse files
committed
Make import resolution and error resolution reporting deterministic.
These tasks used to depend on the iteration order of `module_children`.
1 parent 5f47915 commit 5b12832

File tree

2 files changed

+22
-26
lines changed

2 files changed

+22
-26
lines changed

src/librustc_resolve/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,14 +1103,22 @@ pub struct Resolver<'a, 'tcx: 'a> {
11031103

11041104
struct ResolverArenas<'a> {
11051105
modules: arena::TypedArena<ModuleS<'a>>,
1106+
local_modules: RefCell<Vec<Module<'a>>>,
11061107
name_bindings: arena::TypedArena<NameBinding<'a>>,
11071108
import_directives: arena::TypedArena<ImportDirective<'a>>,
11081109
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
11091110
}
11101111

11111112
impl<'a> ResolverArenas<'a> {
11121113
fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
1113-
self.modules.alloc(module)
1114+
let module = self.modules.alloc(module);
1115+
if module.def_id().map(|def_id| def_id.is_local()).unwrap_or(true) {
1116+
self.local_modules.borrow_mut().push(module);
1117+
}
1118+
module
1119+
}
1120+
fn local_modules(&'a self) -> ::std::cell::Ref<'a, Vec<Module<'a>>> {
1121+
self.local_modules.borrow()
11141122
}
11151123
fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
11161124
self.name_bindings.alloc(name_binding)
@@ -1189,6 +1197,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11891197
fn arenas() -> ResolverArenas<'a> {
11901198
ResolverArenas {
11911199
modules: arena::TypedArena::new(),
1200+
local_modules: RefCell::new(Vec::new()),
11921201
name_bindings: arena::TypedArena::new(),
11931202
import_directives: arena::TypedArena::new(),
11941203
name_resolutions: arena::TypedArena::new(),

src/librustc_resolve/resolve_imports.rs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ use syntax::attr::AttrMetaMethods;
2929
use syntax::codemap::Span;
3030
use syntax::util::lev_distance::find_best_match_for_name;
3131

32-
use std::mem::replace;
3332
use std::cell::{Cell, RefCell};
3433

3534
/// Contains data for specific types of import directives.
@@ -371,11 +370,17 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
371370
i,
372371
self.resolver.unresolved_imports);
373372

374-
self.resolve_imports_for_module_subtree(self.resolver.graph_root, &mut errors);
373+
// Attempt to resolve imports in all local modules.
374+
for module in self.resolver.arenas.local_modules().iter() {
375+
self.resolver.current_module = module;
376+
self.resolve_imports_in_current_module(&mut errors);
377+
}
375378

376379
if self.resolver.unresolved_imports == 0 {
377380
debug!("(resolving imports) success");
378-
self.finalize_resolutions(self.resolver.graph_root, false);
381+
for module in self.resolver.arenas.local_modules().iter() {
382+
self.finalize_resolutions_in(module, false);
383+
}
379384
break;
380385
}
381386

@@ -385,7 +390,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
385390
// to avoid generating multiple errors on the same import.
386391
// Imports that are still indeterminate at this point are actually blocked
387392
// by errored imports, so there is no point reporting them.
388-
self.finalize_resolutions(self.resolver.graph_root, errors.len() == 0);
393+
for module in self.resolver.arenas.local_modules().iter() {
394+
self.finalize_resolutions_in(module, errors.len() == 0);
395+
}
389396
for e in errors {
390397
self.import_resolving_error(e)
391398
}
@@ -422,22 +429,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
422429
ResolutionError::UnresolvedImport(Some((&path, &e.help))));
423430
}
424431

425-
/// Attempts to resolve imports for the given module and all of its
426-
/// submodules.
427-
fn resolve_imports_for_module_subtree(&mut self,
428-
module_: Module<'b>,
429-
errors: &mut Vec<ImportResolvingError<'b>>) {
430-
debug!("(resolving imports for module subtree) resolving {}",
431-
module_to_string(&module_));
432-
let orig_module = replace(&mut self.resolver.current_module, module_);
433-
self.resolve_imports_in_current_module(errors);
434-
self.resolver.current_module = orig_module;
435-
436-
for (_, child_module) in module_.module_children.borrow().iter() {
437-
self.resolve_imports_for_module_subtree(child_module, errors);
438-
}
439-
}
440-
441432
/// Attempts to resolve imports for the given module only.
442433
fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolvingError<'b>>) {
443434
let mut imports = Vec::new();
@@ -675,7 +666,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
675666

676667
// Miscellaneous post-processing, including recording reexports, recording shadowed traits,
677668
// reporting conflicts, reporting the PRIVATE_IN_PUBLIC lint, and reporting unresolved imports.
678-
fn finalize_resolutions(&mut self, module: Module<'b>, report_unresolved_imports: bool) {
669+
fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_imports: bool) {
679670
// Since import resolution is finished, globs will not define any more names.
680671
*module.globs.borrow_mut() = Vec::new();
681672

@@ -723,10 +714,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
723714
break;
724715
}
725716
}
726-
727-
for (_, child) in module.module_children.borrow().iter() {
728-
self.finalize_resolutions(child, report_unresolved_imports);
729-
}
730717
}
731718
}
732719

0 commit comments

Comments
 (0)