From: Jeffrey Seyfried Date: Wed, 17 Aug 2016 00:52:18 +0000 (+0000) Subject: Refactor `unresolved_imports` -> `indeterminate_imports`. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=37154ca95d801c83974e23b913154da402ae5d79;p=rust.git Refactor `unresolved_imports` -> `indeterminate_imports`. --- diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ea946d0117b..2dac64ad2bb 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -131,7 +131,6 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module< let subclass = ImportDirectiveSubclass::single(binding.name, source_name); let span = view_path.span; self.add_import_directive(module_path, subclass, span, item.id, vis); - self.unresolved_imports += 1; } ViewPathList(_, ref source_items) => { // Make sure there's at most one `mod` import in the list. @@ -177,14 +176,12 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module< let subclass = ImportDirectiveSubclass::single(rename, name); let (span, id) = (source_item.span, source_item.node.id()); self.add_import_directive(module_path, subclass, span, id, vis); - self.unresolved_imports += 1; } } ViewPathGlob(_) => { let subclass = GlobImport { is_prelude: is_prelude }; let span = view_path.span; self.add_import_directive(module_path, subclass, span, item.id, vis); - self.unresolved_imports += 1; } } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 742d955e38a..1660a270cbd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -752,7 +752,6 @@ pub struct ModuleS<'a> { extern_crate_id: Option, resolutions: RefCell>>>, - unresolved_imports: RefCell>>, no_implicit_prelude: Cell, @@ -782,7 +781,6 @@ fn new(parent_link: ParentLink<'a>, def: def, extern_crate_id: None, resolutions: RefCell::new(HashMap::new()), - unresolved_imports: RefCell::new(Vec::new()), no_implicit_prelude: Cell::new(false), glob_importers: RefCell::new(Vec::new()), globs: RefCell::new((Vec::new())), @@ -965,8 +963,8 @@ pub struct Resolver<'a> { structs: FnvHashMap>, - // The number of imports that are currently unresolved. - unresolved_imports: usize, + // All indeterminate imports (i.e. imports not known to succeed or fail). + indeterminate_imports: Vec<&'a ImportDirective<'a>>, // The module that represents the current item scope. current_module: Module<'a>, @@ -1153,7 +1151,7 @@ pub fn new(session: &'a Session, make_glob_map: MakeGlobMap, arenas: &'a Resolve trait_item_map: FnvHashMap(), structs: FnvHashMap(), - unresolved_imports: 0, + indeterminate_imports: Vec::new(), current_module: graph_root, value_ribs: vec![Rib::new(ModuleRibKind(graph_root))], diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 83b1f64a33a..23a5b3c4990 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -233,7 +233,7 @@ pub fn add_import_directive(&mut self, vis: vis, }); - self.current_module.unresolved_imports.borrow_mut().push(directive); + self.indeterminate_imports.push(directive); match directive.subclass { SingleImport { target, .. } => { for &ns in &[ValueNS, TypeNS] { @@ -360,43 +360,52 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { /// point iteration. fn resolve_imports(&mut self) { let mut i = 0; - let mut prev_unresolved_imports = 0; + let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; let mut errors = Vec::new(); - loop { - debug!("(resolving imports) iteration {}, {} imports left", i, self.unresolved_imports); - - // Attempt to resolve imports in all local modules. - for module in self.arenas.local_modules().iter() { - self.current_module = module; - self.resolve_imports_in_current_module(&mut errors); - } - - if self.unresolved_imports == 0 { - debug!("(resolving imports) success"); - for module in self.arenas.local_modules().iter() { - self.finalize_resolutions_in(module, false); + while self.indeterminate_imports.len() < prev_num_indeterminates { + prev_num_indeterminates = self.indeterminate_imports.len(); + debug!("(resolving imports) iteration {}, {} imports left", i, prev_num_indeterminates); + + let mut imports = Vec::new(); + ::std::mem::swap(&mut imports, &mut self.indeterminate_imports); + + for import in imports { + match self.resolve_import(&import) { + Failed(err) => { + let (span, help) = match err { + Some((span, msg)) => (span, format!(". {}", msg)), + None => (import.span, String::new()), + }; + errors.push(ImportResolvingError { + import_directive: import, + span: span, + help: help, + }); + } + Indeterminate => self.indeterminate_imports.push(import), + Success(()) => {} } - break; } - if self.unresolved_imports == prev_unresolved_imports { - // resolving failed - // Report unresolved imports only if no hard error was already reported - // 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. - for module in self.arenas.local_modules().iter() { - self.finalize_resolutions_in(module, errors.len() == 0); - } - for e in errors { - self.import_resolving_error(e) - } - break; + i += 1; + } + + for module in self.arenas.local_modules().iter() { + self.finalize_resolutions_in(module); + } + + // Report unresolved imports only if no hard error was already reported + // to avoid generating multiple errors on the same import. + if errors.len() == 0 { + if let Some(import) = self.indeterminate_imports.iter().next() { + let error = ResolutionError::UnresolvedImport(None); + resolve_error(self.resolver, import.span, error); } + } - i += 1; - prev_unresolved_imports = self.unresolved_imports; + for e in errors { + self.import_resolving_error(e) } } @@ -429,35 +438,6 @@ fn import_resolving_error(&mut self, e: ImportResolvingError<'b>) { ResolutionError::UnresolvedImport(Some((&path, &e.help)))); } - /// Attempts to resolve imports for the given module only. - fn resolve_imports_in_current_module(&mut self, errors: &mut Vec>) { - let mut imports = Vec::new(); - let mut unresolved_imports = self.current_module.unresolved_imports.borrow_mut(); - ::std::mem::swap(&mut imports, &mut unresolved_imports); - - for import_directive in imports { - match self.resolve_import(&import_directive) { - Failed(err) => { - let (span, help) = match err { - Some((span, msg)) => (span, format!(". {}", msg)), - None => (import_directive.span, String::new()), - }; - errors.push(ImportResolvingError { - import_directive: import_directive, - span: span, - help: help, - }); - } - Indeterminate => unresolved_imports.push(import_directive), - Success(()) => { - // Decrement the count of unresolved imports. - assert!(self.unresolved_imports >= 1); - self.unresolved_imports -= 1; - } - } - } - } - /// Attempts to resolve the given import. The return value indicates /// failure if we're certain the name does not exist, indeterminate if we /// don't know whether the name exists at the moment due to other @@ -468,6 +448,9 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul names_to_string(&directive.module_path), module_to_string(self.current_module)); + let module = directive.parent; + self.current_module = module; + let target_module = match directive.target_module.get() { Some(module) => module, _ => match self.resolve_module_path(&directive.module_path, @@ -490,7 +473,6 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul let value_result = self.resolve_name_in_module(target_module, source, ValueNS, false, true); let type_result = self.resolve_name_in_module(target_module, source, TypeNS, false, true); - let module = self.current_module; let mut privacy_error = true; for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined), (TypeNS, &type_result, type_determined)] { @@ -658,7 +640,7 @@ fn resolve_glob_import(&mut self, target_module: Module<'b>, directive: &'b Impo // Miscellaneous post-processing, including recording reexports, reporting conflicts, // reporting the PRIVATE_IN_PUBLIC lint, and reporting unresolved imports. - fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_imports: bool) { + fn finalize_resolutions_in(&mut self, module: Module<'b>) { // Since import resolution is finished, globs will not define any more names. *module.globs.borrow_mut() = Vec::new(); @@ -706,13 +688,6 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_impo self.export_map.insert(node_id, reexports); } } - - if report_unresolved_imports { - for import in module.unresolved_imports.borrow().iter() { - resolve_error(self.resolver, import.span, ResolutionError::UnresolvedImport(None)); - break; - } - } } }