From b69bf1153d6d59ce449d47a15eeccfcc37917113 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Wed, 5 Aug 2015 21:47:01 +0200 Subject: [PATCH] Block import resolution only on 'pub' imports. When resolving 'use' statements, only consider pub imports of the target module as blocking. Closes #4865 --- src/librustc_resolve/build_reduced_graph.rs | 8 +++++++ src/librustc_resolve/lib.rs | 8 +++++++ src/librustc_resolve/resolve_imports.rs | 26 ++++++++++++++++----- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 656d6a366147..355578ddccf2 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -926,6 +926,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { is_public, shadowable)); self.unresolved_imports += 1; + + if is_public { + module_.pub_count.set(module_.pub_count.get() + 1); + } + // Bump the reference count on the name. Or, if this is a glob, set // the appropriate flag. @@ -959,6 +964,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { // module's exports ahead of time. module_.glob_count.set(module_.glob_count.get() + 1); + if is_public { + module_.pub_glob_count.set(module_.pub_glob_count.get() + 1); + } } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8c2bb9a88025..1dd26fe7c58a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -699,6 +699,12 @@ pub struct Module { // The number of unresolved globs that this module exports. glob_count: Cell, + // The number of unresolved pub imports (both regular and globs) in this module + pub_count: Cell, + + // The number of unresolved pub glob imports in this module + pub_glob_count: Cell, + // The index of the import we're resolving. resolved_import_count: Cell, @@ -726,6 +732,8 @@ impl Module { anonymous_children: RefCell::new(NodeMap()), import_resolutions: RefCell::new(HashMap::new()), glob_count: Cell::new(0), + pub_count: Cell::new(0), + pub_glob_count: Cell::new(0), resolved_import_count: Cell::new(0), populated: Cell::new(!external), } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 412643ba9454..18fefa967ea3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -409,11 +409,19 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { GlobImport => { assert!(module_.glob_count.get() >= 1); module_.glob_count.set(module_.glob_count.get() - 1); + if import_directive.is_public { + assert!(module_.pub_glob_count.get() >= 1); + module_.pub_glob_count.set(module_.pub_glob_count.get() - 1); + } } SingleImport(..) => { // Ignore. } } + if import_directive.is_public { + assert!(module_.pub_count.get() >= 1); + module_.pub_count.set(module_.pub_count.get() - 1); + } } return resolution_result; @@ -503,8 +511,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // containing module, bail out. We don't know enough to be // able to resolve this import. - if target_module.glob_count.get() > 0 { - debug!("(resolving single import) unresolved glob; \ + if target_module.pub_glob_count.get() > 0 { + debug!("(resolving single import) unresolved pub glob; \ bailing out"); return ResolveResult::Indeterminate; } @@ -767,16 +775,22 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // We must bail out if the node has unresolved imports of any kind // (including globs). - if !(*target_module).all_imports_resolved() { + if (*target_module).pub_count.get() > 0 { debug!("(resolving glob import) target module has unresolved \ - imports; bailing out"); + pub imports; bailing out"); return ResolveResult::Indeterminate; } - assert_eq!(target_module.glob_count.get(), 0); - // Add all resolved imports from the containing module. let import_resolutions = target_module.import_resolutions.borrow(); + + if module_.import_resolutions.borrow_state() != ::std::cell::BorrowState::Unused { + // In this case, target_module == module_ + // This means we are trying to glob import a module into itself, + // and it is a no-go + return ResolveResult::Indeterminate; + } + for (ident, target_import_resolution) in import_resolutions.iter() { debug!("(resolving glob import) writing module resolution \ {} into `{}`",