Skip to content

Commit 7fd331e

Browse files
committed
Auto merge of #32328 - jseyfried:coherence, r=nikomatsakis
resolve: Improve import failure detection and lay groundwork for RFC 1422 This PR improves import failure detection and lays some groundwork for RFC 1422. More specifically, it - Avoids recomputing the resolution of an import directive's module path. - Refactors code in `resolve_imports` that does not scale to the arbitrarily many levels of visibility that will be required by RFC 1422. - Replaces `ModuleS`'s fields `public_glob_count`, `private_glob_count`, and `resolved_globs` with a list of glob import directives `globs`. - Replaces `NameResolution`'s fields `pub_outstanding_references` and `outstanding_references` with a field `single_imports` of a newly defined type `SingleImports`. - Improves import failure detection by detecting cycles that include single imports (currently, only cycles of globs are detected). This fixes #32119. r? @nikomatsakis
2 parents 600dc35 + 6f09dea commit 7fd331e

File tree

4 files changed

+207
-207
lines changed

4 files changed

+207
-207
lines changed

src/librustc_resolve/build_reduced_graph.rs

+8-42
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
//! any imports resolved.
1515
1616
use DefModifiers;
17-
use resolve_imports::ImportDirective;
18-
use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
17+
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
1918
use Module;
2019
use Namespace::{self, TypeNS, ValueNS};
2120
use {NameBinding, NameBindingKind};
@@ -28,7 +27,7 @@ use rustc::middle::def::*;
2827
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
2928
use rustc::ty::VariantKind;
3029

31-
use syntax::ast::{Name, NodeId};
30+
use syntax::ast::Name;
3231
use syntax::attr::AttrMetaMethods;
3332
use syntax::parse::token::special_idents;
3433
use syntax::codemap::{Span, DUMMY_SP};
@@ -152,8 +151,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
152151
}
153152

154153
let subclass = ImportDirectiveSubclass::single(binding, source_name);
155-
self.build_import_directive(parent,
156-
module_path,
154+
self.unresolved_imports += 1;
155+
parent.add_import_directive(module_path,
157156
subclass,
158157
view_path.span,
159158
item.id,
@@ -203,8 +202,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
203202
}
204203
};
205204
let subclass = ImportDirectiveSubclass::single(rename, name);
206-
self.build_import_directive(parent,
207-
module_path,
205+
self.unresolved_imports += 1;
206+
parent.add_import_directive(module_path,
208207
subclass,
209208
source_item.span,
210209
source_item.node.id(),
@@ -213,8 +212,8 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
213212
}
214213
}
215214
ViewPathGlob(_) => {
216-
self.build_import_directive(parent,
217-
module_path,
215+
self.unresolved_imports += 1;
216+
parent.add_import_directive(module_path,
218217
GlobImport,
219218
view_path.span,
220219
item.id,
@@ -521,39 +520,6 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> {
521520
}
522521
}
523522

524-
/// Creates and adds an import directive to the given module.
525-
fn build_import_directive(&mut self,
526-
module_: Module<'b>,
527-
module_path: Vec<Name>,
528-
subclass: ImportDirectiveSubclass,
529-
span: Span,
530-
id: NodeId,
531-
is_public: bool,
532-
is_prelude: bool) {
533-
// Bump the reference count on the name. Or, if this is a glob, set
534-
// the appropriate flag.
535-
536-
match subclass {
537-
SingleImport { target, .. } => {
538-
module_.increment_outstanding_references_for(target, ValueNS, is_public);
539-
module_.increment_outstanding_references_for(target, TypeNS, is_public);
540-
}
541-
GlobImport if !is_prelude => {
542-
// Set the glob flag. This tells us that we don't know the
543-
// module's exports ahead of time.
544-
module_.inc_glob_count(is_public)
545-
}
546-
// Prelude imports are not included in the glob counts since they do not get added to
547-
// `resolved_globs` -- they are handled separately in `resolve_imports`.
548-
GlobImport => {}
549-
}
550-
551-
let directive =
552-
ImportDirective::new(module_path, subclass, span, id, is_public, is_prelude);
553-
module_.add_import_directive(directive);
554-
self.unresolved_imports += 1;
555-
}
556-
557523
/// Ensures that the reduced graph rooted at the given external module
558524
/// is built, building it if it is not.
559525
pub fn populate_module_if_necessary(&mut self, module: Module<'b>) {

src/librustc_resolve/lib.rs

+14-26
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,8 @@ pub struct ModuleS<'a> {
828828
// is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
829829
extern_crate_id: Option<NodeId>,
830830

831-
resolutions: RefCell<HashMap<(Name, Namespace), NameResolution<'a>>>,
832-
unresolved_imports: RefCell<Vec<&'a ImportDirective>>,
831+
resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
832+
unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
833833

834834
// The module children of this node, including normal modules and anonymous modules.
835835
// Anonymous children are pseudo-modules that are implicitly created around items
@@ -849,14 +849,8 @@ pub struct ModuleS<'a> {
849849

850850
prelude: RefCell<Option<Module<'a>>>,
851851

852-
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective)>>,
853-
resolved_globs: RefCell<(Vec<Module<'a>> /* public */, Vec<Module<'a>> /* private */)>,
854-
855-
// The number of public glob imports in this module.
856-
public_glob_count: Cell<usize>,
857-
858-
// The number of private glob imports in this module.
859-
private_glob_count: Cell<usize>,
852+
glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
853+
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
860854

861855
// Whether this module is populated. If not populated, any attempt to
862856
// access the children must be preceded with a
@@ -884,22 +878,15 @@ impl<'a> ModuleS<'a> {
884878
module_children: RefCell::new(NodeMap()),
885879
prelude: RefCell::new(None),
886880
glob_importers: RefCell::new(Vec::new()),
887-
resolved_globs: RefCell::new((Vec::new(), Vec::new())),
888-
public_glob_count: Cell::new(0),
889-
private_glob_count: Cell::new(0),
881+
globs: RefCell::new((Vec::new())),
890882
populated: Cell::new(!external),
891883
arenas: arenas
892884
}
893885
}
894886

895-
fn add_import_directive(&self, import_directive: ImportDirective) {
896-
let import_directive = self.arenas.alloc_import_directive(import_directive);
897-
self.unresolved_imports.borrow_mut().push(import_directive);
898-
}
899-
900887
fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
901888
for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
902-
name_resolution.binding.map(|binding| f(name, ns, binding));
889+
name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
903890
}
904891
}
905892

@@ -929,11 +916,6 @@ impl<'a> ModuleS<'a> {
929916
_ => false,
930917
}
931918
}
932-
933-
fn inc_glob_count(&self, is_public: bool) {
934-
let glob_count = if is_public { &self.public_glob_count } else { &self.private_glob_count };
935-
glob_count.set(glob_count.get() + 1);
936-
}
937919
}
938920

939921
impl<'a> fmt::Debug for ModuleS<'a> {
@@ -1135,7 +1117,8 @@ pub struct Resolver<'a, 'tcx: 'a> {
11351117
struct ResolverArenas<'a> {
11361118
modules: arena::TypedArena<ModuleS<'a>>,
11371119
name_bindings: arena::TypedArena<NameBinding<'a>>,
1138-
import_directives: arena::TypedArena<ImportDirective>,
1120+
import_directives: arena::TypedArena<ImportDirective<'a>>,
1121+
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
11391122
}
11401123

11411124
impl<'a> ResolverArenas<'a> {
@@ -1145,9 +1128,13 @@ impl<'a> ResolverArenas<'a> {
11451128
fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
11461129
self.name_bindings.alloc(name_binding)
11471130
}
1148-
fn alloc_import_directive(&'a self, import_directive: ImportDirective) -> &'a ImportDirective {
1131+
fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
1132+
-> &'a ImportDirective {
11491133
self.import_directives.alloc(import_directive)
11501134
}
1135+
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
1136+
self.name_resolutions.alloc(Default::default())
1137+
}
11511138
}
11521139

11531140
#[derive(PartialEq)]
@@ -1216,6 +1203,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12161203
modules: arena::TypedArena::new(),
12171204
name_bindings: arena::TypedArena::new(),
12181205
import_directives: arena::TypedArena::new(),
1206+
name_resolutions: arena::TypedArena::new(),
12191207
}
12201208
}
12211209

0 commit comments

Comments
 (0)