diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 1253d4f9ceff..459a7392f6cf 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -173,13 +173,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { fn resolve_imports(&mut self) { let mut i = 0; let mut prev_unresolved_imports = 0; + let mut errors = Vec::new(); + loop { debug!("(resolving imports) iteration {}, {} imports left", i, self.resolver.unresolved_imports); - let module_root = self.resolver.graph_root; - let errors = self.resolve_imports_for_module_subtree(module_root); + self.resolve_imports_for_module_subtree(self.resolver.graph_root, &mut errors); if self.resolver.unresolved_imports == 0 { debug!("(resolving imports) success"); @@ -197,7 +198,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // to avoid generating multiple errors on the same import. // Imports that are still indeterminate at this point are actually blocked // by errored imports, so there is no point reporting them. - self.resolver.report_unresolved_imports(module_root); + self.resolver.report_unresolved_imports(self.resolver.graph_root); } break; } @@ -234,30 +235,27 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { /// Attempts to resolve imports for the given module and all of its /// submodules. fn resolve_imports_for_module_subtree(&mut self, - module_: Module<'b>) - -> Vec> { - let mut errors = Vec::new(); + module_: Module<'b>, + errors: &mut Vec>) { debug!("(resolving imports for module subtree) resolving {}", module_to_string(&module_)); let orig_module = replace(&mut self.resolver.current_module, module_); - errors.extend(self.resolve_imports_for_module(module_)); + self.resolve_imports_for_module(module_, errors); self.resolver.current_module = orig_module; for (_, child_module) in module_.module_children.borrow().iter() { - errors.extend(self.resolve_imports_for_module_subtree(child_module)); + self.resolve_imports_for_module_subtree(child_module, errors); } - - errors } /// Attempts to resolve imports for the given module only. - fn resolve_imports_for_module(&mut self, module: Module<'b>) -> Vec> { - let mut errors = Vec::new(); - + fn resolve_imports_for_module(&mut self, + module: Module<'b>, + errors: &mut Vec>) { if module.all_imports_resolved() { debug!("(resolving imports for module) all imports resolved for {}", module_to_string(&module)); - return errors; + return; } let mut imports = module.imports.borrow_mut(); @@ -278,6 +276,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { span: span, help: help, }); + module.resolved_import_count.set(module.resolved_import_count.get() + 1); + continue; } ResolveResult::Indeterminate => {} ResolveResult::Success(()) => { @@ -293,8 +293,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { } imports.extend(indeterminate_imports); - - errors } /// Attempts to resolve the given import. The return value indicates @@ -562,6 +560,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { ns: Namespace, binding: &'b NameBinding<'b>, old_binding: &'b NameBinding<'b>) { + // Error on the second of two conflicting imports + if old_binding.is_import() && binding.is_import() && + old_binding.span.unwrap().lo > binding.span.unwrap().lo { + self.report_conflict(name, ns, old_binding, binding); + return; + } + if old_binding.is_extern_crate() { let msg = format!("import `{0}` conflicts with imported crate \ in this module (maybe you meant `use {0}::*`?)", diff --git a/src/test/compile-fail/import-shadow-6.rs b/src/test/compile-fail/import-shadow-6.rs index 0f3d54d5fe3d..fa3b75c70f0b 100644 --- a/src/test/compile-fail/import-shadow-6.rs +++ b/src/test/compile-fail/import-shadow-6.rs @@ -12,8 +12,8 @@ #![no_implicit_prelude] -use qux::*; //~ERROR a type named `Baz` has already been imported in this module -use foo::*; +use qux::*; +use foo::*; //~ERROR a type named `Baz` has already been imported in this module mod foo { pub type Baz = isize;