diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 11c51522b676..aa529de085ea 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -731,8 +731,8 @@ enum RibKind<'a> { // We're in a constant item. Can't refer to dynamic stuff. ConstantItemRibKind, - // We passed through an anonymous module. - AnonymousModuleRibKind(Module<'a>), + // We passed through a module. + ModuleRibKind(Module<'a>), } #[derive(Copy, Clone)] @@ -1653,16 +1653,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn with_scope(&mut self, id: NodeId, f: F) where F: FnOnce(&mut Resolver) { - let orig_module = self.current_module; + if let Some(module) = self.current_module.module_children.borrow().get(&id) { + // Move down in the graph. + let orig_module = ::std::mem::replace(&mut self.current_module, module); + self.value_ribs.push(Rib::new(ModuleRibKind(module))); + self.type_ribs.push(Rib::new(ModuleRibKind(module))); - // Move down in the graph. - if let Some(module) = orig_module.module_children.borrow().get(&id) { - self.current_module = module; + f(self); + + self.current_module = orig_module; + self.value_ribs.pop(); + self.type_ribs.pop(); + } else { + f(self); } - - f(self); - - self.current_module = orig_module; } /// Searches the current set of local scopes for labels. @@ -2239,8 +2243,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(anonymous_module) = anonymous_module { debug!("(resolving block) found anonymous module, moving down"); - self.value_ribs.push(Rib::new(AnonymousModuleRibKind(anonymous_module))); - self.type_ribs.push(Rib::new(AnonymousModuleRibKind(anonymous_module))); + self.value_ribs.push(Rib::new(ModuleRibKind(anonymous_module))); + self.type_ribs.push(Rib::new(ModuleRibKind(anonymous_module))); self.current_module = anonymous_module; } else { self.value_ribs.push(Rib::new(NormalRibKind)); @@ -2817,7 +2821,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Def::Local(_, node_id) => { for rib in ribs { match rib.kind { - NormalRibKind | AnonymousModuleRibKind(..) => { + NormalRibKind | ModuleRibKind(..) => { // Nothing to do. Continue. } ClosureRibKind(function_id) => { @@ -2866,7 +2870,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for rib in ribs { match rib.kind { NormalRibKind | MethodRibKind | ClosureRibKind(..) | - AnonymousModuleRibKind(..) => { + ModuleRibKind(..) => { // Nothing to do. Continue. } ItemRibKind => { @@ -3024,7 +3028,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - if let AnonymousModuleRibKind(module) = self.get_ribs(namespace)[i].kind { + if let ModuleRibKind(module) = self.get_ribs(namespace)[i].kind { if let Success(binding) = self.resolve_name_in_module(module, ident.unhygienic_name, namespace, @@ -3034,6 +3038,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return Some(LocalDef::from_def(def)); } } + // We can only see through anonymous modules + if module.def.is_some() { return None; } } } diff --git a/src/test/compile-fail/issue-31845.rs b/src/test/compile-fail/issue-31845.rs new file mode 100644 index 000000000000..344a11172546 --- /dev/null +++ b/src/test/compile-fail/issue-31845.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Checks lexical scopes cannot see through normal module boundries + +fn f() { + fn g() {} + mod foo { + fn h() { + g(); //~ ERROR unresolved name + } + } +} + +fn main() {}