diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 116c1b7a6d06f..579853446525e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -56,12 +56,7 @@ impl<'b> Resolver<'b> { pub fn build_reduced_graph(&mut self, krate: &Crate) { let no_implicit_prelude = attr::contains_name(&krate.attrs, "no_implicit_prelude"); self.graph_root.no_implicit_prelude.set(no_implicit_prelude); - - let mut visitor = BuildReducedGraphVisitor { - parent: self.graph_root, - resolver: self, - }; - visit::walk_crate(&mut visitor, krate); + visit::walk_crate(&mut BuildReducedGraphVisitor { resolver: self }, krate); } /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; @@ -84,11 +79,11 @@ impl<'b> Resolver<'b> { } /// Constructs the reduced graph for one item. - fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module<'b>) { - let parent = *parent_ref; + fn build_reduced_graph_for_item(&mut self, item: &Item) { + let parent = self.current_module; + let parent_vis = self.current_vis; let name = item.ident.name; let sp = item.span; - self.current_module = parent; let vis = self.resolve_visibility(&item.vis); match item.node { @@ -130,8 +125,7 @@ impl<'b> Resolver<'b> { let subclass = ImportDirectiveSubclass::single(binding.name, source_name); let span = view_path.span; - parent.add_import_directive(module_path, subclass, span, item.id, vis); - self.unresolved_imports += 1; + self.add_import_directive(module_path, subclass, span, item.id, vis); } ViewPathList(_, ref source_items) => { // Make sure there's at most one `mod` import in the list. @@ -176,15 +170,13 @@ impl<'b> Resolver<'b> { }; let subclass = ImportDirectiveSubclass::single(rename, name); let (span, id) = (source_item.span, source_item.node.id()); - parent.add_import_directive(module_path, subclass, span, id, vis); - self.unresolved_imports += 1; + self.add_import_directive(module_path, subclass, span, id, vis); } } ViewPathGlob(_) => { let subclass = GlobImport { is_prelude: is_prelude }; let span = view_path.span; - parent.add_import_directive(module_path, subclass, span, item.id, vis); - self.unresolved_imports += 1; + self.add_import_directive(module_path, subclass, span, item.id, vis); } } } @@ -216,7 +208,10 @@ impl<'b> Resolver<'b> { }); self.define(parent, name, TypeNS, (module, sp, vis)); self.module_map.insert(item.id, module); - *parent_ref = module; + + // Descend into the module. + self.current_module = module; + self.current_vis = ty::Visibility::Restricted(item.id); } ItemKind::ForeignMod(..) => {} @@ -309,6 +304,10 @@ impl<'b> Resolver<'b> { } ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"), } + + visit::walk_item(&mut BuildReducedGraphVisitor { resolver: self }, item); + self.current_module = parent; + self.current_vis = parent_vis; } // Constructs the reduced graph for one variant. Variants exist in the @@ -333,9 +332,8 @@ impl<'b> Resolver<'b> { } /// Constructs the reduced graph for one foreign item. - fn build_reduced_graph_for_foreign_item(&mut self, - foreign_item: &ForeignItem, - parent: Module<'b>) { + fn build_reduced_graph_for_foreign_item(&mut self, foreign_item: &ForeignItem) { + let parent = self.current_module; let name = foreign_item.ident.name; let def = match foreign_item.node { @@ -346,12 +344,12 @@ impl<'b> Resolver<'b> { Def::Static(self.definitions.local_def_id(foreign_item.id), m) } }; - self.current_module = parent; let vis = self.resolve_visibility(&foreign_item.vis); self.define(parent, name, ValueNS, (def, foreign_item.span, vis)); } - fn build_reduced_graph_for_block(&mut self, block: &Block, parent: &mut Module<'b>) { + fn build_reduced_graph_for_block(&mut self, block: &Block) { + let parent = self.current_module; if self.block_needs_anonymous_module(block) { let block_id = block.id; @@ -362,8 +360,11 @@ impl<'b> Resolver<'b> { let parent_link = BlockParentLink(parent, block_id); let new_module = self.new_module(parent_link, None, false); self.module_map.insert(block_id, new_module); - *parent = new_module; + self.current_module = new_module; // Descend into the block. } + + visit::walk_block(&mut BuildReducedGraphVisitor { resolver: self }, block); + self.current_module = parent; } /// Builds the reduced graph for a single item in an external crate. @@ -487,25 +488,18 @@ impl<'b> Resolver<'b> { struct BuildReducedGraphVisitor<'a, 'b: 'a> { resolver: &'a mut Resolver<'b>, - parent: Module<'b>, } impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> { fn visit_item(&mut self, item: &Item) { - let old_parent = self.parent; - self.resolver.build_reduced_graph_for_item(item, &mut self.parent); - visit::walk_item(self, item); - self.parent = old_parent; + self.resolver.build_reduced_graph_for_item(item); } fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.resolver.build_reduced_graph_for_foreign_item(foreign_item, &self.parent); + self.resolver.build_reduced_graph_for_foreign_item(foreign_item); } fn visit_block(&mut self, block: &Block) { - let old_parent = self.parent; - self.resolver.build_reduced_graph_for_block(block, &mut self.parent); - visit::walk_block(self, block); - self.parent = old_parent; + self.resolver.build_reduced_graph_for_block(block); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index af39f8a415c67..0c0582edcc051 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -758,11 +758,10 @@ pub struct ModuleS<'a> { extern_crate_id: Option, resolutions: RefCell>>>, - unresolved_imports: RefCell>>, no_implicit_prelude: Cell, - glob_importers: RefCell, &'a ImportDirective<'a>)>>, + glob_importers: RefCell>>, globs: RefCell>>, // Used to memoize the traits in this module for faster searches through all traits in scope. @@ -772,29 +771,22 @@ pub struct ModuleS<'a> { // access the children must be preceded with a // `populate_module_if_necessary` call. populated: Cell, - - arenas: &'a ResolverArenas<'a>, } pub type Module<'a> = &'a ModuleS<'a>; impl<'a> ModuleS<'a> { - fn new(parent_link: ParentLink<'a>, - def: Option, - external: bool, - arenas: &'a ResolverArenas<'a>) -> Self { + fn new(parent_link: ParentLink<'a>, def: Option, external: bool) -> Self { ModuleS { parent_link: parent_link, 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())), traits: RefCell::new(None), populated: Cell::new(!external), - arenas: arenas } } @@ -971,12 +963,19 @@ pub struct Resolver<'a> { structs: FnvHashMap>, - // The number of imports that are currently unresolved. - unresolved_imports: usize, + // All imports known to succeed or fail. + determined_imports: Vec<&'a ImportDirective<'a>>, + + // All non-determined imports. + indeterminate_imports: Vec<&'a ImportDirective<'a>>, // The module that represents the current item scope. current_module: Module<'a>, + // The visibility of `pub(self)` items in the current scope. + // Equivalently, the visibility required for an item to be accessible from the current scope. + current_vis: ty::Visibility, + // The current set of local scopes, for values. // FIXME #4948: Reuse ribs to avoid allocation. value_ribs: Vec>, @@ -1140,7 +1139,7 @@ impl<'a> Resolver<'a> { -> Resolver<'a> { let root_def_id = DefId::local(CRATE_DEF_INDEX); let graph_root = - ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas); + ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false); let graph_root = arenas.alloc_module(graph_root); let mut module_map = NodeMap(); module_map.insert(CRATE_NODE_ID, graph_root); @@ -1159,9 +1158,11 @@ impl<'a> Resolver<'a> { trait_item_map: FnvHashMap(), structs: FnvHashMap(), - unresolved_imports: 0, + determined_imports: Vec::new(), + indeterminate_imports: Vec::new(), current_module: graph_root, + current_vis: ty::Visibility::Restricted(ast::CRATE_NODE_ID), value_ribs: vec![Rib::new(ModuleRibKind(graph_root))], type_ribs: vec![Rib::new(ModuleRibKind(graph_root))], label_ribs: Vec::new(), @@ -1205,6 +1206,7 @@ impl<'a> Resolver<'a> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { self.current_module = self.graph_root; + self.current_vis = ty::Visibility::Restricted(ast::CRATE_NODE_ID); visit::walk_crate(self, krate); check_unused::check_crate(self, krate); @@ -1213,12 +1215,12 @@ impl<'a> Resolver<'a> { fn new_module(&self, parent_link: ParentLink<'a>, def: Option, external: bool) -> Module<'a> { - self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas)) + self.arenas.alloc_module(ModuleS::new(parent_link, def, external)) } fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId) -> Module<'a> { - let mut module = ModuleS::new(parent_link, Some(def), false, self.arenas); + let mut module = ModuleS::new(parent_link, Some(def), false); module.extern_crate_id = Some(local_node_id); self.arenas.modules.alloc(module) } @@ -1250,14 +1252,15 @@ impl<'a> Resolver<'a> { mut search_module: Module<'a>, module_path: &[Name], index: usize, - span: Span) + span: Option) -> ResolveResult> { - fn search_parent_externals(needle: Name, module: Module) -> Option { - match module.resolve_name(needle, TypeNS, false) { + fn search_parent_externals<'a>(this: &mut Resolver<'a>, needle: Name, module: Module<'a>) + -> Option> { + match this.resolve_name_in_module(module, needle, TypeNS, false, None) { Success(binding) if binding.is_extern_crate() => Some(module), _ => match module.parent_link { ModuleParentLink(ref parent, _) => { - search_parent_externals(needle, parent) + search_parent_externals(this, needle, parent) } _ => None, }, @@ -1272,16 +1275,17 @@ impl<'a> Resolver<'a> { // modules as we go. while index < module_path_len { let name = module_path[index]; - match self.resolve_name_in_module(search_module, name, TypeNS, false, true) { + match self.resolve_name_in_module(search_module, name, TypeNS, false, span) { Failed(None) => { let segment_name = name.as_str(); let module_name = module_to_string(search_module); let msg = if "???" == &module_name { - match search_parent_externals(name, &self.current_module) { + let current_module = self.current_module; + match search_parent_externals(self, name, current_module) { Some(module) => { let path_str = names_to_string(module_path); let target_mod_str = module_to_string(&module); - let current_mod_str = module_to_string(&self.current_module); + let current_mod_str = module_to_string(current_module); let prefix = if target_mod_str == current_mod_str { "self::".to_string() @@ -1297,7 +1301,7 @@ impl<'a> Resolver<'a> { format!("Could not find `{}` in `{}`", segment_name, module_name) }; - return Failed(Some((span, msg))); + return Failed(span.map(|span| (span, msg))); } Failed(err) => return Failed(err), Indeterminate => { @@ -1310,11 +1314,10 @@ impl<'a> Resolver<'a> { // Check to see whether there are type bindings, and, if // so, whether there is a module within. if let Some(module_def) = binding.module() { - self.check_privacy(name, binding, span); search_module = module_def; } else { let msg = format!("Not a module `{}`", name); - return Failed(Some((span, msg))); + return Failed(span.map(|span| (span, msg))); } } } @@ -1330,7 +1333,7 @@ impl<'a> Resolver<'a> { fn resolve_module_path(&mut self, module_path: &[Name], use_lexical_scope: UseLexicalScopeFlag, - span: Span) + span: Option) -> ResolveResult> { if module_path.len() == 0 { return Success(self.graph_root) // Use the crate root @@ -1367,7 +1370,7 @@ impl<'a> Resolver<'a> { // first component of the path in the current lexical // scope and then proceed to resolve below that. let ident = ast::Ident::with_empty_ctxt(module_path[0]); - match self.resolve_ident_in_lexical_scope(ident, TypeNS, true) + match self.resolve_ident_in_lexical_scope(ident, TypeNS, span) .and_then(LexicalScopeBinding::module) { None => return Failed(None), Some(containing_module) => { @@ -1384,10 +1387,7 @@ impl<'a> Resolver<'a> { } } - self.resolve_module_path_from_root(search_module, - module_path, - start_index, - span) + self.resolve_module_path_from_root(search_module, module_path, start_index, span) } /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope. @@ -1410,7 +1410,7 @@ impl<'a> Resolver<'a> { fn resolve_ident_in_lexical_scope(&mut self, mut ident: ast::Ident, ns: Namespace, - record_used: bool) + record_used: Option) -> Option> { if ns == TypeNS { ident = ast::Ident::with_empty_ctxt(ident.name); @@ -1438,8 +1438,8 @@ impl<'a> Resolver<'a> { if module.def.is_some() { return match self.prelude { Some(prelude) if !module.no_implicit_prelude.get() => { - prelude.resolve_name(name, ns, false).success() - .map(LexicalScopeBinding::Item) + self.resolve_name_in_module(prelude, name, ns, false, None).success() + .map(LexicalScopeBinding::Item) } _ => None, }; @@ -1491,7 +1491,7 @@ impl<'a> Resolver<'a> { /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`; /// (b) some chain of `super::`. /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) * - fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span) + fn resolve_module_prefix(&mut self, module_path: &[Name], span: Option) -> ResolveResult> { // Start at the current module if we see `self` or `super`, or at the // top of the crate otherwise. @@ -1510,7 +1510,7 @@ impl<'a> Resolver<'a> { match self.get_nearest_normal_module_parent(containing_module) { None => { let msg = "There are too many initial `super`s.".into(); - return Failed(Some((span, msg))); + return Failed(span.map(|span| (span, msg))); } Some(new_module) => { containing_module = new_module; @@ -1525,27 +1525,6 @@ impl<'a> Resolver<'a> { return Success(PrefixFound(containing_module, i)); } - /// Attempts to resolve the supplied name in the given module for the - /// given namespace. If successful, returns the binding corresponding to - /// the name. - fn resolve_name_in_module(&mut self, - module: Module<'a>, - name: Name, - namespace: Namespace, - use_lexical_scope: bool, - record_used: bool) - -> ResolveResult<&'a NameBinding<'a>> { - debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module)); - - self.populate_module_if_necessary(module); - module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| { - if record_used { - self.record_use(name, namespace, binding); - } - Success(binding) - }) - } - // AST resolution // // We maintain a list of value ribs and type ribs. @@ -1570,13 +1549,15 @@ impl<'a> Resolver<'a> { let module = self.module_map.get(&id).cloned(); // clones a reference if let Some(module) = module { // Move down in the graph. - let orig_module = ::std::mem::replace(&mut self.current_module, module); + let orig_module = replace(&mut self.current_module, module); + let orig_vis = replace(&mut self.current_vis, ty::Visibility::Restricted(id)); self.value_ribs.push(Rib::new(ModuleRibKind(module))); self.type_ribs.push(Rib::new(ModuleRibKind(module))); f(self); self.current_module = orig_module; + self.current_vis = orig_vis; self.value_ribs.pop(); self.type_ribs.pop(); } else { @@ -2314,7 +2295,7 @@ impl<'a> Resolver<'a> { PatKind::Ident(bmode, ref ident, ref opt_pat) => { // First try to resolve the identifier as some existing // entity, then fall back to a fresh binding. - let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, false) + let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, None) .and_then(LexicalScopeBinding::item); let resolution = binding.and_then(NameBinding::def).and_then(|def| { let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || @@ -2481,11 +2462,11 @@ impl<'a> Resolver<'a> { // // Such behavior is required for backward compatibility. // The same fallback is used when `a` resolves to nothing. - let def = resolve_identifier_with_fallback(self, true).ok_or(false); + let def = resolve_identifier_with_fallback(self, Some(span)).ok_or(false); return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res); } - let unqualified_def = resolve_identifier_with_fallback(self, false); + let unqualified_def = resolve_identifier_with_fallback(self, None); let qualified_binding = self.resolve_module_relative_path(span, segments, namespace); match (qualified_binding, unqualified_def) { (Ok(binding), Some(ref ud)) if binding.def().unwrap() == ud.def => { @@ -2505,7 +2486,7 @@ impl<'a> Resolver<'a> { fn resolve_identifier(&mut self, identifier: ast::Ident, namespace: Namespace, - record_used: bool) + record_used: Option) -> Option { if identifier.name == keywords::Invalid.name() { return None; @@ -2619,7 +2600,7 @@ impl<'a> Resolver<'a> { .collect::>(); let containing_module; - match self.resolve_module_path(&module_path, UseLexicalScope, span) { + match self.resolve_module_path(&module_path, UseLexicalScope, Some(span)) { Failed(err) => { let (span, msg) = match err { Some((span, msg)) => (span, msg), @@ -2640,11 +2621,9 @@ impl<'a> Resolver<'a> { } let name = segments.last().unwrap().identifier.name; - let result = self.resolve_name_in_module(containing_module, name, namespace, false, true); - result.success().map(|binding| { - self.check_privacy(name, binding, span); - binding - }).ok_or(false) + let result = + self.resolve_name_in_module(containing_module, name, namespace, false, Some(span)); + result.success().ok_or(false) } /// Invariant: This must be called only during main resolution, not during @@ -2658,10 +2637,7 @@ impl<'a> Resolver<'a> { let root_module = self.graph_root; let containing_module; - match self.resolve_module_path_from_root(root_module, - &module_path, - 0, - span) { + match self.resolve_module_path_from_root(root_module, &module_path, 0, Some(span)) { Failed(err) => { let (span, msg) = match err { Some((span, msg)) => (span, msg), @@ -2684,11 +2660,9 @@ impl<'a> Resolver<'a> { } let name = segments.last().unwrap().name(); - let result = self.resolve_name_in_module(containing_module, name, namespace, false, true); - result.success().map(|binding| { - self.check_privacy(name, binding, span); - binding - }).ok_or(false) + let result = + self.resolve_name_in_module(containing_module, name, namespace, false, Some(span)); + result.success().ok_or(false) } fn with_no_errors(&mut self, f: F) -> T @@ -2716,7 +2690,6 @@ impl<'a> Resolver<'a> { fn with_empty_ribs(&mut self, f: F) -> T where F: FnOnce(&mut Resolver<'a>) -> T, { - use ::std::mem::replace; let value_ribs = replace(&mut self.value_ribs, Vec::new()); let type_ribs = replace(&mut self.type_ribs, Vec::new()); let label_ribs = replace(&mut self.label_ribs, Vec::new()); @@ -2941,7 +2914,7 @@ impl<'a> Resolver<'a> { match self.resolve_module_path(&name_path[..], UseLexicalScope, - expr.span) { + Some(expr.span)) { Success(e) => { if let Some(def_type) = e.def { def = def_type; @@ -3274,18 +3247,12 @@ impl<'a> Resolver<'a> { ast::Visibility::Public => return ty::Visibility::Public, ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID), ast::Visibility::Restricted { ref path, id } => (path, id), - ast::Visibility::Inherited => { - let current_module = - self.get_nearest_normal_module_parent_or_self(self.current_module); - let id = - self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap(); - return ty::Visibility::Restricted(id); - } + ast::Visibility::Inherited => return self.current_vis, }; let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect(); let mut path_resolution = err_path_resolution(); - let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, path.span) { + let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, Some(path.span)) { Success(module) => { let def = module.def.unwrap(); path_resolution = PathResolution::new(def); @@ -3309,15 +3276,7 @@ impl<'a> Resolver<'a> { } fn is_accessible(&self, vis: ty::Visibility) -> bool { - let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module); - let node_id = self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap(); - vis.is_accessible_from(node_id, self) - } - - fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) { - if !self.is_accessible(binding.vis) { - self.privacy_errors.push(PrivacyError(span, name, binding)); - } + vis.is_at_least(self.current_vis, self) } fn report_privacy_errors(&self) { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e08a30e40d354..c0a9ee1c48380 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use self::Determinacy::*; use self::ImportDirectiveSubclass::*; use Module; @@ -36,25 +37,31 @@ impl<'a> Resolver<'a> { } } +#[derive(Copy, Clone, Debug)] +pub enum Determinacy { + Determined, + Undetermined, +} + /// Contains data for specific types of import directives. #[derive(Clone, Debug)] -pub enum ImportDirectiveSubclass { +pub enum ImportDirectiveSubclass<'a> { SingleImport { target: Name, source: Name, - type_determined: Cell, - value_determined: Cell, + value_result: Cell, Determinacy>>, + type_result: Cell, Determinacy>>, }, GlobImport { is_prelude: bool }, } -impl ImportDirectiveSubclass { +impl<'a> ImportDirectiveSubclass<'a> { pub fn single(target: Name, source: Name) -> Self { SingleImport { target: target, source: source, - type_determined: Cell::new(false), - value_determined: Cell::new(false), + type_result: Cell::new(Err(Undetermined)), + value_result: Cell::new(Err(Undetermined)), } } } @@ -63,11 +70,12 @@ impl ImportDirectiveSubclass { #[derive(Debug,Clone)] pub struct ImportDirective<'a> { pub id: NodeId, + parent: Module<'a>, module_path: Vec, - target_module: Cell>>, // the resolution of `module_path` - subclass: ImportDirectiveSubclass, + imported_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> { @@ -132,119 +140,145 @@ impl<'a> NameResolution<'a> { _ => None, // The binding could be shadowed by a single import, so it is not known. }) } +} + +impl<'a> Resolver<'a> { + fn resolution(&self, module: Module<'a>, name: Name, ns: Namespace) + -> &'a RefCell> { + *module.resolutions.borrow_mut().entry((name, ns)) + .or_insert_with(|| self.arenas.alloc_name_resolution()) + } + + /// Attempts to resolve the supplied name in the given module for the given namespace. + /// If successful, returns the binding corresponding to the name. + /// Invariant: if `record_used` is `Some`, import resolution must be complete. + pub fn resolve_name_in_module(&mut self, + module: Module<'a>, + name: Name, + ns: Namespace, + allow_private_imports: bool, + record_used: Option) + -> ResolveResult<&'a NameBinding<'a>> { + self.populate_module_if_necessary(module); + + let resolution = self.resolution(module, name, ns); + let resolution = match resolution.borrow_state() { + ::std::cell::BorrowState::Unused => resolution.borrow_mut(), + _ => return Failed(None), // This happens when there is a cycle of imports + }; + + let is_disallowed_private_import = |binding: &NameBinding| { + !allow_private_imports && !binding.is_pseudo_public() && binding.is_import() + }; + + if let Some(span) = record_used { + if let Some(binding) = resolution.binding { + if is_disallowed_private_import(binding) { + return Failed(None); + } + self.record_use(name, ns, binding); + if !self.is_accessible(binding.vis) { + self.privacy_errors.push(PrivacyError(span, name, binding)); + } + } + + return resolution.binding.map(Success).unwrap_or(Failed(None)); + } + + // If the resolution doesn't depend on glob definability, check privacy and return. + if let Some(result) = self.try_result(&resolution, ns) { + return result.and_then(|binding| { + if self.is_accessible(binding.vis) && !is_disallowed_private_import(binding) { + Success(binding) + } else { + Failed(None) + } + }); + } + + // Check if the globs are determined + for directive in module.globs.borrow().iter() { + if self.is_accessible(directive.vis.get()) { + if let Some(module) = directive.imported_module.get() { + let result = self.resolve_name_in_module(module, name, ns, true, None); + if let Indeterminate = result { + return Indeterminate; + } + } else { + return Indeterminate; + } + } + } + + Failed(None) + } // Returns Some(the resolution of the name), or None if the resolution depends // on whether more globs can define the name. - fn try_result(&self, ns: Namespace, allow_private_imports: bool) + fn try_result(&mut self, resolution: &NameResolution<'a>, ns: Namespace) -> Option>> { - match self.binding { + match resolution.binding { Some(binding) if !binding.is_glob_import() => - return Some(Success(binding)), - _ => {} // Items and single imports are not shadowable + return Some(Success(binding)), // Items and single imports are not shadowable. + _ => {} }; // Check if a single import can still define the name. - match self.single_imports { - SingleImports::None => {}, + match resolution.single_imports { SingleImports::AtLeastOne => return Some(Indeterminate), - SingleImports::MaybeOne(directive) => { - // If (1) we don't allow private imports, (2) no public single import can define - // the name, and (3) no public glob has defined the name, the resolution depends - // on whether more globs can define the name. - if !allow_private_imports && directive.vis != ty::Visibility::Public && - !self.binding.map(NameBinding::is_pseudo_public).unwrap_or(false) { - return None; - } - - let target_module = match directive.target_module.get() { - Some(target_module) => target_module, + SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis.get()) => { + let module = match directive.imported_module.get() { + Some(module) => module, None => return Some(Indeterminate), }; let name = match directive.subclass { SingleImport { source, .. } => source, GlobImport { .. } => unreachable!(), }; - match target_module.resolve_name(name, ns, false) { + match self.resolve_name_in_module(module, name, ns, true, None) { Failed(_) => {} _ => return Some(Indeterminate), } } + SingleImports::MaybeOne(_) | SingleImports::None => {}, } - self.binding.map(Success) - } -} - -impl<'a> ::ModuleS<'a> { - fn resolution(&self, name: Name, ns: Namespace) -> &'a RefCell> { - *self.resolutions.borrow_mut().entry((name, ns)) - .or_insert_with(|| self.arenas.alloc_name_resolution()) + resolution.binding.map(Success) } - pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: bool) - -> ResolveResult<&'a NameBinding<'a>> { - let resolution = self.resolution(name, ns); - let resolution = match resolution.borrow_state() { - ::std::cell::BorrowState::Unused => resolution.borrow_mut(), - _ => return Failed(None), // This happens when there is a cycle of imports - }; - - if let Some(result) = resolution.try_result(ns, allow_private_imports) { - // If the resolution doesn't depend on glob definability, check privacy and return. - return result.and_then(|binding| { - let allowed = allow_private_imports || !binding.is_import() || - binding.is_pseudo_public(); - if allowed { Success(binding) } else { Failed(None) } - }); - } - - // Check if the globs are determined - for directive in self.globs.borrow().iter() { - if !allow_private_imports && directive.vis != ty::Visibility::Public { continue } - match directive.target_module.get() { - None => return Indeterminate, - Some(target_module) => match target_module.resolve_name(name, ns, false) { - Indeterminate => return Indeterminate, - _ => {} - } - } - } - - Failed(None) - } - - pub fn add_import_directive(&self, + // Add an import directive to the current module. + pub fn add_import_directive(&mut self, module_path: Vec, - subclass: ImportDirectiveSubclass, + subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, vis: ty::Visibility) { + let current_module = self.current_module; let directive = self.arenas.alloc_import_directive(ImportDirective { + parent: current_module, module_path: module_path, - target_module: Cell::new(None), + imported_module: Cell::new(None), subclass: subclass, span: span, id: id, - vis: vis, + vis: Cell::new(vis), }); - self.unresolved_imports.borrow_mut().push(directive); + self.indeterminate_imports.push(directive); match directive.subclass { SingleImport { target, .. } => { for &ns in &[ValueNS, TypeNS] { - self.resolution(target, ns).borrow_mut().single_imports - .add_directive(directive); + let mut resolution = self.resolution(current_module, target, ns).borrow_mut(); + resolution.single_imports.add_directive(directive); } } // We don't add prelude imports to the globs since they only affect lexical scopes, // which are not relevant to import resolution. GlobImport { is_prelude: true } => {} - GlobImport { .. } => self.globs.borrow_mut().push(directive), + GlobImport { .. } => self.current_module.globs.borrow_mut().push(directive), } } -} -impl<'a> Resolver<'a> { // Given a binding and an import directive that resolves to it, // return the corresponding binding defined by the import directive. fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>) @@ -255,7 +289,7 @@ impl<'a> Resolver<'a> { directive: directive, }, span: directive.span, - vis: directive.vis, + vis: directive.vis.get(), } } @@ -291,7 +325,7 @@ impl<'a> Resolver<'a> { // Ensure that `resolution` isn't borrowed when defining in the module's glob importers, // during which the resolution might end up getting re-defined via a glob cycle. let (new_binding, t) = { - let mut resolution = &mut *module.resolution(name, ns).borrow_mut(); + let mut resolution = &mut *self.resolution(module, name, ns).borrow_mut(); let was_known = resolution.binding().is_some(); let t = f(self, resolution); @@ -305,9 +339,9 @@ impl<'a> Resolver<'a> { // Define `new_binding` in `module`s glob importers. if new_binding.is_importable() && new_binding.is_pseudo_public() { - for &(importer, directive) in module.glob_importers.borrow_mut().iter() { + for directive in module.glob_importers.borrow_mut().iter() { let imported_binding = self.import(new_binding, directive); - let _ = self.try_define(importer, name, ns, imported_binding); + let _ = self.try_define(directive.parent, name, ns, imported_binding); } } @@ -315,14 +349,6 @@ impl<'a> Resolver<'a> { } } -struct ImportResolvingError<'a> { - /// Module where the error happened - source_module: Module<'a>, - import_directive: &'a ImportDirective<'a>, - span: Span, - help: String, -} - struct ImportResolver<'a, 'b: 'a> { resolver: &'a mut Resolver<'b>, } @@ -355,55 +381,74 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // remain or unsuccessfully when no forward progress in resolving imports // is made. + fn set_current_module(&mut self, module: Module<'b>) { + self.current_module = module; + self.current_vis = ty::Visibility::Restricted({ + let normal_module = self.get_nearest_normal_module_parent_or_self(module); + self.definitions.as_local_node_id(normal_module.def_id().unwrap()).unwrap() + }); + } + /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. fn resolve_imports(&mut self) { let mut i = 0; - let mut prev_unresolved_imports = 0; - let mut errors = Vec::new(); + let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; - loop { - debug!("(resolving imports) iteration {}, {} imports left", i, self.unresolved_imports); + 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); - // 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); - } + let mut imports = Vec::new(); + ::std::mem::swap(&mut imports, &mut self.indeterminate_imports); - if self.unresolved_imports == 0 { - debug!("(resolving imports) success"); - for module in self.arenas.local_modules().iter() { - self.finalize_resolutions_in(module, false); + for import in imports { + match self.resolve_import(&import) { + Failed(_) => self.determined_imports.push(import), + Indeterminate => self.indeterminate_imports.push(import), + Success(()) => self.determined_imports.push(import), } - 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); + } + + let mut errors = false; + for i in 0 .. self.determined_imports.len() { + let import = self.determined_imports[i]; + if let Failed(err) = self.finalize_import(import) { + errors = true; + let (span, help) = match err { + Some((span, msg)) => (span, format!(". {}", msg)), + None => (import.span, String::new()), + }; + + // If the error is a single failed import then create a "fake" import + // resolution for it so that later resolve stages won't complain. + self.import_dummy_binding(import); + let path = import_path_to_string(&import.module_path, &import.subclass); + let error = ResolutionError::UnresolvedImport(Some((&path, &help))); + resolve_error(self.resolver, span, error); } + } - i += 1; - prev_unresolved_imports = self.unresolved_imports; + // Report unresolved imports only if no hard error was already reported + // to avoid generating multiple errors on the same import. + if !errors { + if let Some(import) = self.indeterminate_imports.iter().next() { + let error = ResolutionError::UnresolvedImport(None); + resolve_error(self.resolver, import.span, error); + } } } // Define a "dummy" resolution containing a Def::Err as a placeholder for a // failed resolution - fn import_dummy_binding(&mut self, - source_module: Module<'b>, - directive: &'b ImportDirective<'b>) { + fn import_dummy_binding(&mut self, directive: &'b ImportDirective<'b>) { if let SingleImport { target, .. } = directive.subclass { let dummy_binding = self.arenas.alloc_name_binding(NameBinding { kind: NameBindingKind::Def(Def::Err), @@ -412,51 +457,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { }); let dummy_binding = self.import(dummy_binding, directive); - let _ = self.try_define(source_module, target, ValueNS, dummy_binding.clone()); - let _ = self.try_define(source_module, target, TypeNS, dummy_binding); - } - } - - /// Resolves an `ImportResolvingError` into the correct enum discriminant - /// and passes that on to `resolve_error`. - fn import_resolving_error(&mut self, e: ImportResolvingError<'b>) { - // If the error is a single failed import then create a "fake" import - // resolution for it so that later resolve stages won't complain. - self.import_dummy_binding(e.source_module, e.import_directive); - let path = import_path_to_string(&e.import_directive.module_path, - &e.import_directive.subclass); - resolve_error(self.resolver, - e.span, - 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 { - source_module: self.current_module, - 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; - } - } + let _ = self.try_define(directive.parent, target, ValueNS, dummy_binding.clone()); + let _ = self.try_define(directive.parent, target, TypeNS, dummy_binding); } } @@ -470,126 +472,164 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { names_to_string(&directive.module_path), module_to_string(self.current_module)); - let target_module = match directive.target_module.get() { - Some(module) => module, - _ => match self.resolve_module_path(&directive.module_path, - DontUseLexicalScope, - directive.span) { + self.set_current_module(directive.parent); + + let module = if let Some(module) = directive.imported_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)); - let (source, target, value_determined, type_determined) = match directive.subclass { - SingleImport { source, target, ref value_determined, ref type_determined } => - (source, target, value_determined, type_determined), - GlobImport { .. } => return self.resolve_glob_import(target_module, directive), + directive.imported_module.set(Some(module)); + let (source, target, value_result, type_result) = match directive.subclass { + SingleImport { source, target, ref value_result, ref type_result } => + (source, target, value_result, type_result), + GlobImport { .. } => { + self.resolve_glob_import(directive); + return Success(()); + } }; - // We need to resolve both namespaces for this to succeed. - 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)] { - match *result { - Failed(..) if !determined.get() => { - determined.set(true); - self.update_resolution(module, target, ns, |_, resolution| { + let mut indeterminate = false; + for &(ns, result) in &[(ValueNS, value_result), (TypeNS, type_result)] { + if let Err(Undetermined) = result.get() { + result.set({ + match self.resolve_name_in_module(module, source, ns, false, None) { + Success(binding) => Ok(binding), + Indeterminate => Err(Undetermined), + Failed(_) => Err(Determined), + } + }); + } else { + continue + }; + + match result.get() { + Err(Undetermined) => indeterminate = true, + Err(Determined) => { + self.update_resolution(directive.parent, target, ns, |_, resolution| { resolution.single_imports.directive_failed() }); } - Success(binding) if !binding.is_importable() => { + Ok(binding) if !binding.is_importable() => { let msg = format!("`{}` is not directly importable", target); struct_span_err!(self.session, directive.span, E0253, "{}", &msg) .span_label(directive.span, &format!("cannot be imported directly")) .emit(); // Do not import this illegal binding. Import a dummy binding and pretend // everything is fine - self.import_dummy_binding(module, directive); + self.import_dummy_binding(directive); return Success(()); } - Success(binding) if !self.is_accessible(binding.vis) => {} - Success(binding) if !determined.get() => { - determined.set(true); + Ok(binding) => { let imported_binding = self.import(binding, directive); - let conflict = self.try_define(module, target, ns, imported_binding); + let conflict = self.try_define(directive.parent, target, ns, imported_binding); if let Err(old_binding) = conflict { let binding = &self.import(binding, directive); - self.report_conflict(module, target, ns, binding, old_binding); + self.report_conflict(directive.parent, target, ns, binding, old_binding); } - privacy_error = false; } - Success(_) => privacy_error = false, - _ => {} } } - match (&value_result, &type_result) { - (&Indeterminate, _) | (_, &Indeterminate) => return Indeterminate, - (&Failed(_), &Failed(_)) => { - let resolutions = target_module.resolutions.borrow(); - let names = resolutions.iter().filter_map(|(&(ref name, _), resolution)| { - if *name == source { return None; } // Never suggest the same name + if indeterminate { Indeterminate } else { Success(()) } + } + + fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResult<()> { + self.set_current_module(directive.parent); + + let ImportDirective { ref module_path, span, .. } = *directive; + let module_result = self.resolve_module_path(&module_path, DontUseLexicalScope, Some(span)); + let module = match module_result { + Success(module) => module, + Indeterminate => return Indeterminate, + Failed(err) => return Failed(err), + }; + + let (name, value_result, type_result) = match directive.subclass { + SingleImport { source, ref value_result, ref type_result, .. } => + (source, value_result.get(), type_result.get()), + GlobImport { .. } if module.def_id() == directive.parent.def_id() => { + // Importing a module into itself is not allowed. + let msg = "Cannot glob-import a module into itself.".into(); + return Failed(Some((directive.span, msg))); + } + GlobImport { .. } => return Success(()), + }; + + for &(ns, result) in &[(ValueNS, value_result), (TypeNS, type_result)] { + if let Ok(binding) = result { + self.record_use(name, ns, binding); + } + } + + if value_result.is_err() && type_result.is_err() { + let (value_result, type_result); + value_result = self.resolve_name_in_module(module, name, ValueNS, false, Some(span)); + type_result = self.resolve_name_in_module(module, name, TypeNS, false, Some(span)); + + return if let (Failed(_), Failed(_)) = (value_result, type_result) { + let resolutions = module.resolutions.borrow(); + let names = resolutions.iter().filter_map(|(&(ref n, _), resolution)| { + if *n == name { return None; } // Never suggest the same name match *resolution.borrow() { - NameResolution { binding: Some(_), .. } => Some(name), + NameResolution { binding: Some(_), .. } => Some(n), NameResolution { single_imports: SingleImports::None, .. } => None, - _ => Some(name), + _ => Some(n), } }); - let lev_suggestion = match find_best_match_for_name(names, &source.as_str(), None) { + let lev_suggestion = match find_best_match_for_name(names, &name.as_str(), None) { Some(name) => format!(". Did you mean to use `{}`?", name), None => "".to_owned(), }; - let module_str = module_to_string(target_module); + let module_str = module_to_string(module); let msg = if &module_str == "???" { - format!("There is no `{}` in the crate root{}", source, lev_suggestion) + format!("There is no `{}` in the crate root{}", name, lev_suggestion) } else { - format!("There is no `{}` in `{}`{}", source, module_str, lev_suggestion) + format!("There is no `{}` in `{}`{}", name, module_str, lev_suggestion) }; - return Failed(Some((directive.span, msg))); - } - _ => (), - } - - if privacy_error { - for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] { - let binding = match *result { Success(binding) => binding, _ => continue }; - self.privacy_errors.push(PrivacyError(directive.span, source, binding)); - let imported_binding = self.import(binding, directive); - let _ = self.try_define(module, target, ns, imported_binding); + Failed(Some((directive.span, msg))) + } else { + // `resolve_name_in_module` reported a privacy error. + self.import_dummy_binding(directive); + Success(()) } } - match (&value_result, &type_result) { - (&Success(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis, self) && - self.is_accessible(binding.vis) => { - let msg = format!("`{}` is private, and cannot be reexported", source); - let note_msg = format!("consider marking `{}` as `pub` in the imported module", - source); + match (value_result, type_result) { + (Ok(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis.get(), self) => { + let msg = format!("`{}` is private, and cannot be reexported", name); + let note_msg = + format!("consider marking `{}` as `pub` in the imported module", name); struct_span_err!(self.session, directive.span, E0364, "{}", &msg) .span_note(directive.span, ¬e_msg) .emit(); } - (_, &Success(binding)) if !binding.pseudo_vis().is_at_least(directive.vis, self) && - self.is_accessible(binding.vis) => { + (_, 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`", - source); + name); self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg); } else { - let mut err = struct_span_err!(self.session, directive.span, E0365, - "`{}` is private, and cannot be reexported", - source); - err.span_label(directive.span, &format!("reexport of private `{}`", source)); - err.note(&format!("consider declaring type or module `{}` with `pub`", source)); - err.emit(); + struct_span_err!(self.session, directive.span, E0365, + "`{}` is private, and cannot be reexported", name) + .span_label(directive.span, &format!("reexport of private `{}`", name)) + .note(&format!("consider declaring type or module `{}` with `pub`", name)) + .emit(); } } @@ -599,9 +639,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // Record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. - let def = match type_result.success().and_then(NameBinding::def) { + let def = match type_result.ok().and_then(NameBinding::def) { Some(def) => def, - None => value_result.success().and_then(NameBinding::def).unwrap(), + None => value_result.ok().and_then(NameBinding::def).unwrap(), }; let path_resolution = PathResolution::new(def); self.def_map.insert(directive.id, path_resolution); @@ -610,57 +650,46 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { return Success(()); } - // Resolves a glob import. Note that this function cannot fail; it either - // succeeds or bails out (as importing * from an empty module or a module - // that exports nothing is valid). target_module is the module we are - // actually importing, i.e., `foo` in `use foo::*`. - fn resolve_glob_import(&mut self, target_module: Module<'b>, directive: &'b ImportDirective<'b>) - -> ResolveResult<()> { - if let Some(Def::Trait(_)) = target_module.def { - self.session.span_err(directive.span, "items in traits are not importable."); - } + fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) { + let module = directive.imported_module.get().unwrap(); + self.populate_module_if_necessary(module); - let module = self.current_module; - if module.def_id() == target_module.def_id() { - // This means we are trying to glob import a module into itself, and it is a no-go - let msg = "Cannot glob-import a module into itself.".into(); - return Failed(Some((directive.span, msg))); + if let Some(Def::Trait(_)) = module.def { + self.session.span_err(directive.span, "items in traits are not importable."); } - self.populate_module_if_necessary(target_module); - if let GlobImport { is_prelude: true } = directive.subclass { - self.prelude = Some(target_module); - return Success(()); + if module.def_id() == directive.parent.def_id() { + return; + } else if let GlobImport { is_prelude: true } = directive.subclass { + self.prelude = Some(module); + return; } - // Add to target_module's glob_importers - target_module.glob_importers.borrow_mut().push((module, directive)); + // Add to module's glob_importers + module.glob_importers.borrow_mut().push(directive); // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. - let bindings = target_module.resolutions.borrow().iter().filter_map(|(name, resolution)| { + let bindings = module.resolutions.borrow().iter().filter_map(|(name, resolution)| { resolution.borrow().binding().map(|binding| (*name, binding)) }).collect::>(); for ((name, ns), binding) in bindings { if binding.is_importable() && binding.is_pseudo_public() { let imported_binding = self.import(binding, directive); - let _ = self.try_define(module, name, ns, imported_binding); + let _ = self.try_define(directive.parent, name, ns, imported_binding); } } // Record the destination of this import - if let Some(did) = target_module.def_id() { + if let Some(did) = module.def_id() { let resolution = PathResolution::new(Def::Mod(did)); self.def_map.insert(directive.id, resolution); } - - debug!("(resolving glob import) successfully resolved import"); - return Success(()); } // 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(); @@ -708,13 +737,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { 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; - } - } } } diff --git a/src/test/compile-fail/task-rng-isnt-sendable.rs b/src/test/compile-fail/task-rng-isnt-sendable.rs index a11df776e06d3..9c0a2267d7cf8 100644 --- a/src/test/compile-fail/task-rng-isnt-sendable.rs +++ b/src/test/compile-fail/task-rng-isnt-sendable.rs @@ -16,5 +16,4 @@ fn test_send() {} pub fn main() { test_send::(); - //~^ ERROR : std::marker::Send` is not satisfied } diff --git a/src/test/compile-fail/use-from-trait-xc.rs b/src/test/compile-fail/use-from-trait-xc.rs index 687cdba1542bd..a40fa2337214e 100644 --- a/src/test/compile-fail/use-from-trait-xc.rs +++ b/src/test/compile-fail/use-from-trait-xc.rs @@ -21,10 +21,10 @@ use use_from_trait_xc::Trait::Assoc; use use_from_trait_xc::Trait::CONST; //~^ ERROR `CONST` is not directly importable -use use_from_trait_xc::Foo::new; +use use_from_trait_xc::Foo::new; //~ ERROR struct `Foo` is private //~^ ERROR unresolved import `use_from_trait_xc::Foo::new` -use use_from_trait_xc::Foo::C; +use use_from_trait_xc::Foo::C; //~ ERROR struct `Foo` is private //~^ ERROR unresolved import `use_from_trait_xc::Foo::C` use use_from_trait_xc::Bar::new as bnew;