From: Jeffrey Seyfried Date: Thu, 18 Aug 2016 00:11:56 +0000 (+0000) Subject: Improve import failure detection. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=5b969a2a58da5a1c7f6ea0587b9ff97b56e2f21d;p=rust.git Improve import failure detection. --- diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index c2f8e31277c..195333f4acd 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -68,7 +68,7 @@ pub struct ImportDirective<'a> { target_module: Cell>>, // the resolution of `module_path` subclass: ImportDirectiveSubclass<'a>, span: Span, - vis: ty::Visibility, // see note in ImportResolutionPerNamespace about how to use this + vis: Cell, } impl<'a> ImportDirective<'a> { @@ -191,7 +191,7 @@ pub fn resolve_name_in_module(&mut self, // Check if the globs are determined for directive in module.globs.borrow().iter() { - if self.is_accessible(directive.vis) { + if self.is_accessible(directive.vis.get()) { if let Some(target_module) = directive.target_module.get() { let result = self.resolve_name_in_module(target_module, name, ns, true, None); if let Indeterminate = result { @@ -219,7 +219,7 @@ fn try_result(&mut self, resolution: &NameResolution<'a>, ns: Namespace) // Check if a single import can still define the name. match resolution.single_imports { SingleImports::AtLeastOne => return Some(Indeterminate), - SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis) => { + SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis.get()) => { let target_module = match directive.target_module.get() { Some(target_module) => target_module, None => return Some(Indeterminate), @@ -254,7 +254,7 @@ pub fn add_import_directive(&mut self, subclass: subclass, span: span, id: id, - vis: vis, + vis: Cell::new(vis), }); self.indeterminate_imports.push(directive); @@ -282,7 +282,7 @@ fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirectiv directive: directive, }, span: directive.span, - vis: directive.vis, + vis: directive.vis.get(), } } @@ -488,13 +488,22 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul let module = directive.parent; self.set_current_module(module); - let target_module = match directive.target_module.get() { - Some(module) => module, - _ => match self.resolve_module_path(&directive.module_path, DontUseLexicalScope, None) { + let target_module = if let Some(module) = directive.target_module.get() { + module + } else { + let vis = directive.vis.get(); + // For better failure detection, pretend that the import will not define any names + // while resolving its module path. + directive.vis.set(ty::Visibility::PrivateExternal); + let result = + self.resolve_module_path(&directive.module_path, DontUseLexicalScope, None); + directive.vis.set(vis); + + match result { Success(module) => module, Indeterminate => return Indeterminate, Failed(err) => return Failed(err), - }, + } }; directive.target_module.set(Some(target_module)); @@ -614,7 +623,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResu } match (value_result, type_result) { - (Ok(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis, self) => { + (Ok(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis.get(), self) => { let msg = format!("`{}` is private, and cannot be reexported", source); let note_msg = format!("consider marking `{}` as `pub` in the imported module", source); @@ -623,7 +632,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResu .emit(); } - (_, Ok(binding)) if !binding.pseudo_vis().is_at_least(directive.vis, self) => { + (_, Ok(binding)) if !binding.pseudo_vis().is_at_least(directive.vis.get(), self) => { if binding.is_extern_crate() { let msg = format!("extern crate `{}` is private, and cannot be reexported \ (error E0364), consider declaring with `pub`",