Skip to content

Commit 2d14b39

Browse files
committed
Auto merge of #31747 - jseyfried:stop_resolve_after_fail, r=nrc
Now that #31461 is merged, a failing resolution can never become indeterminate or succeed, so we no longer have to keep trying to resolve failing import directives. r? @nrc
2 parents 6c751e0 + 5ad84f1 commit 2d14b39

File tree

4 files changed

+37
-72
lines changed

4 files changed

+37
-72
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
1919
use Module;
2020
use Namespace::{self, TypeNS, ValueNS};
2121
use {NameBinding, NameBindingKind};
22-
use {names_to_string, module_to_string};
22+
use module_to_string;
2323
use ParentLink::{ModuleParentLink, BlockParentLink};
2424
use Resolver;
2525
use resolve_imports::Shadowable;
@@ -682,7 +682,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
682682
id: NodeId,
683683
is_public: bool,
684684
shadowable: Shadowable) {
685-
module_.imports
685+
module_.unresolved_imports
686686
.borrow_mut()
687687
.push(ImportDirective::new(module_path, subclass, span, id, is_public, shadowable));
688688
self.unresolved_imports += 1;
@@ -696,9 +696,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
696696

697697
match subclass {
698698
SingleImport(target, _) => {
699-
debug!("(building import directive) building import directive: {}::{}",
700-
names_to_string(&module_.imports.borrow().last().unwrap().module_path),
701-
target);
702699
module_.increment_outstanding_references_for(target, ValueNS);
703700
module_.increment_outstanding_references_for(target, TypeNS);
704701
}

src/librustc_resolve/lib.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#![cfg_attr(not(stage0), deny(warnings))]
1919

2020
#![feature(associated_consts)]
21-
#![feature(borrow_state)]
2221
#![feature(rustc_diagnostic_macros)]
2322
#![feature(rustc_private)]
2423
#![feature(staged_api)]
@@ -810,7 +809,7 @@ pub struct ModuleS<'a> {
810809
is_extern_crate: bool,
811810

812811
resolutions: RefCell<HashMap<(Name, Namespace), NameResolution<'a>>>,
813-
imports: RefCell<Vec<ImportDirective>>,
812+
unresolved_imports: RefCell<Vec<ImportDirective>>,
814813

815814
// The module children of this node, including normal modules and anonymous modules.
816815
// Anonymous children are pseudo-modules that are implicitly created around items
@@ -839,9 +838,6 @@ pub struct ModuleS<'a> {
839838
// The number of unresolved pub glob imports in this module
840839
pub_glob_count: Cell<usize>,
841840

842-
// The index of the import we're resolving.
843-
resolved_import_count: Cell<usize>,
844-
845841
// Whether this module is populated. If not populated, any attempt to
846842
// access the children must be preceded with a
847843
// `populate_module_if_necessary` call.
@@ -859,13 +855,12 @@ impl<'a> ModuleS<'a> {
859855
is_public: is_public,
860856
is_extern_crate: false,
861857
resolutions: RefCell::new(HashMap::new()),
862-
imports: RefCell::new(Vec::new()),
858+
unresolved_imports: RefCell::new(Vec::new()),
863859
module_children: RefCell::new(NodeMap()),
864860
shadowed_traits: RefCell::new(Vec::new()),
865861
glob_count: Cell::new(0),
866862
pub_count: Cell::new(0),
867863
pub_glob_count: Cell::new(0),
868-
resolved_import_count: Cell::new(0),
869864
populated: Cell::new(!external),
870865
}
871866
}
@@ -936,15 +931,6 @@ impl<'a> ModuleS<'a> {
936931
}
937932
}
938933

939-
fn all_imports_resolved(&self) -> bool {
940-
if self.imports.borrow_state() == ::std::cell::BorrowState::Writing {
941-
// it is currently being resolved ! so nope
942-
false
943-
} else {
944-
self.imports.borrow().len() == self.resolved_import_count.get()
945-
}
946-
}
947-
948934
pub fn inc_glob_count(&self) {
949935
self.glob_count.set(self.glob_count.get() + 1);
950936
}
@@ -1635,13 +1621,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16351621
}
16361622

16371623
fn report_unresolved_imports(&mut self, module_: Module<'a>) {
1638-
let index = module_.resolved_import_count.get();
1639-
let imports = module_.imports.borrow();
1640-
let import_count = imports.len();
1641-
if index != import_count {
1642-
resolve_error(self,
1643-
(*imports)[index].span,
1644-
ResolutionError::UnresolvedImport(None));
1624+
for import in module_.unresolved_imports.borrow().iter() {
1625+
resolve_error(self, import.span, ResolutionError::UnresolvedImport(None));
1626+
break;
16451627
}
16461628

16471629
// Descend into children and anonymous children.

src/librustc_resolve/resolve_imports.rs

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
173173
fn resolve_imports(&mut self) {
174174
let mut i = 0;
175175
let mut prev_unresolved_imports = 0;
176+
let mut errors = Vec::new();
177+
176178
loop {
177179
debug!("(resolving imports) iteration {}, {} imports left",
178180
i,
179181
self.resolver.unresolved_imports);
180182

181-
let module_root = self.resolver.graph_root;
182-
let errors = self.resolve_imports_for_module_subtree(module_root);
183+
self.resolve_imports_for_module_subtree(self.resolver.graph_root, &mut errors);
183184

184185
if self.resolver.unresolved_imports == 0 {
185186
debug!("(resolving imports) success");
@@ -197,7 +198,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
197198
// to avoid generating multiple errors on the same import.
198199
// Imports that are still indeterminate at this point are actually blocked
199200
// by errored imports, so there is no point reporting them.
200-
self.resolver.report_unresolved_imports(module_root);
201+
self.resolver.report_unresolved_imports(self.resolver.graph_root);
201202
}
202203
break;
203204
}
@@ -236,67 +237,45 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
236237
/// Attempts to resolve imports for the given module and all of its
237238
/// submodules.
238239
fn resolve_imports_for_module_subtree(&mut self,
239-
module_: Module<'b>)
240-
-> Vec<ImportResolvingError<'b>> {
241-
let mut errors = Vec::new();
240+
module_: Module<'b>,
241+
errors: &mut Vec<ImportResolvingError<'b>>) {
242242
debug!("(resolving imports for module subtree) resolving {}",
243243
module_to_string(&module_));
244244
let orig_module = replace(&mut self.resolver.current_module, module_);
245-
errors.extend(self.resolve_imports_for_module(module_));
245+
self.resolve_imports_for_module(module_, errors);
246246
self.resolver.current_module = orig_module;
247247

248248
for (_, child_module) in module_.module_children.borrow().iter() {
249-
errors.extend(self.resolve_imports_for_module_subtree(child_module));
249+
self.resolve_imports_for_module_subtree(child_module, errors);
250250
}
251-
252-
errors
253251
}
254252

255253
/// Attempts to resolve imports for the given module only.
256-
fn resolve_imports_for_module(&mut self, module: Module<'b>) -> Vec<ImportResolvingError<'b>> {
257-
let mut errors = Vec::new();
258-
259-
if module.all_imports_resolved() {
260-
debug!("(resolving imports for module) all imports resolved for {}",
261-
module_to_string(&module));
262-
return errors;
263-
}
264-
265-
let mut imports = module.imports.borrow_mut();
266-
let import_count = imports.len();
267-
let mut indeterminate_imports = Vec::new();
268-
while module.resolved_import_count.get() + indeterminate_imports.len() < import_count {
269-
let import_index = module.resolved_import_count.get();
270-
match self.resolve_import_for_module(module, &imports[import_index]) {
271-
ResolveResult::Failed(err) => {
272-
let import_directive = &imports[import_index];
254+
fn resolve_imports_for_module(&mut self,
255+
module: Module<'b>,
256+
errors: &mut Vec<ImportResolvingError<'b>>) {
257+
let mut imports = Vec::new();
258+
let mut unresolved_imports = module.unresolved_imports.borrow_mut();
259+
::std::mem::swap(&mut imports, &mut unresolved_imports);
260+
261+
for import_directive in imports {
262+
match self.resolve_import_for_module(module, &import_directive) {
263+
Failed(err) => {
273264
let (span, help) = match err {
274265
Some((span, msg)) => (span, format!(". {}", msg)),
275266
None => (import_directive.span, String::new()),
276267
};
277268
errors.push(ImportResolvingError {
278269
source_module: module,
279-
import_directive: import_directive.clone(),
270+
import_directive: import_directive,
280271
span: span,
281272
help: help,
282273
});
283274
}
284-
ResolveResult::Indeterminate => {}
285-
ResolveResult::Success(()) => {
286-
// count success
287-
module.resolved_import_count
288-
.set(module.resolved_import_count.get() + 1);
289-
continue;
290-
}
275+
Indeterminate => unresolved_imports.push(import_directive),
276+
Success(()) => {}
291277
}
292-
// This resolution was not successful, keep it for later
293-
indeterminate_imports.push(imports.swap_remove(import_index));
294-
295278
}
296-
297-
imports.extend(indeterminate_imports);
298-
299-
errors
300279
}
301280

302281
/// Attempts to resolve the given import. The return value indicates
@@ -564,6 +543,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
564543
ns: Namespace,
565544
binding: &'b NameBinding<'b>,
566545
old_binding: &'b NameBinding<'b>) {
546+
// Error on the second of two conflicting imports
547+
if old_binding.is_import() && binding.is_import() &&
548+
old_binding.span.unwrap().lo > binding.span.unwrap().lo {
549+
self.report_conflict(name, ns, old_binding, binding);
550+
return;
551+
}
552+
567553
if old_binding.is_extern_crate() {
568554
let msg = format!("import `{0}` conflicts with imported crate \
569555
in this module (maybe you meant `use {0}::*`?)",

src/test/compile-fail/import-shadow-6.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
#![no_implicit_prelude]
1414

15-
use qux::*; //~ERROR a type named `Baz` has already been imported in this module
16-
use foo::*;
15+
use qux::*;
16+
use foo::*; //~ERROR a type named `Baz` has already been imported in this module
1717

1818
mod foo {
1919
pub type Baz = isize;

0 commit comments

Comments
 (0)