From 62f44957bf74f9127be7cd18c494fd98d9ef6d85 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 18 Mar 2016 00:11:52 +0000 Subject: Add test for #32119 --- src/test/compile-fail/issue-32119.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/compile-fail/issue-32119.rs (limited to 'src/test') diff --git a/src/test/compile-fail/issue-32119.rs b/src/test/compile-fail/issue-32119.rs new file mode 100644 index 00000000000..226a3a24c9b --- /dev/null +++ b/src/test/compile-fail/issue-32119.rs @@ -0,0 +1,21 @@ +// 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. + +#![feature(rustc_attrs)] + +pub type T = (); +mod foo { pub use super::T; } +mod bar { pub use super::T; } + +pub use foo::*; +pub use bar::*; + +#[rustc_error] +fn main() {} //~ ERROR compilation successful -- cgit 1.4.1-3-g733a5 From 26e38d2fffbcf7fc39d733686a1277291b54535d Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 18 Mar 2016 06:06:07 +0000 Subject: Remove the test for #32089; it is subsumed by the test for #32119 --- src/test/compile-fail/issue-32089.rs | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/test/compile-fail/issue-32089.rs (limited to 'src/test') diff --git a/src/test/compile-fail/issue-32089.rs b/src/test/compile-fail/issue-32089.rs deleted file mode 100644 index 5da7b9fff6e..00000000000 --- a/src/test/compile-fail/issue-32089.rs +++ /dev/null @@ -1,23 +0,0 @@ -// 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. - -#![feature(rustc_attrs)] -#![allow(unused_imports)] - -pub type Type = i32; - -mod one { use super::Type; } -pub use self::one::*; - -mod two { use super::Type; } -pub use self::two::*; - -#[rustc_error] -fn main() {} //~ ERROR compilation successful -- cgit 1.4.1-3-g733a5 From 3d9db595661a96c37f4a5f9cf310c20da08efa5f Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 30 Mar 2016 22:21:56 +0000 Subject: Detect cycles that include renamed imports --- src/librustc_resolve/lib.rs | 9 +++++++-- src/librustc_resolve/resolve_imports.rs | 32 ++++++++++++++++++-------------- src/test/compile-fail/issue-32119.rs | 7 +++++++ 3 files changed, 32 insertions(+), 16 deletions(-) (limited to 'src/test') diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cc229f1f161..fc13ee11ae1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -827,7 +827,7 @@ pub struct ModuleS<'a> { // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None). extern_crate_id: Option, - resolutions: RefCell>>, + resolutions: RefCell>>>, unresolved_imports: RefCell>>, // The module children of this node, including normal modules and anonymous modules. @@ -885,7 +885,7 @@ impl<'a> ModuleS<'a> { fn for_each_child)>(&self, mut f: F) { for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() { - name_resolution.binding.map(|binding| f(name, ns, binding)); + name_resolution.borrow().binding.map(|binding| f(name, ns, binding)); } } @@ -1117,6 +1117,7 @@ struct ResolverArenas<'a> { modules: arena::TypedArena>, name_bindings: arena::TypedArena>, import_directives: arena::TypedArena>, + name_resolutions: arena::TypedArena>>, } impl<'a> ResolverArenas<'a> { @@ -1130,6 +1131,9 @@ impl<'a> ResolverArenas<'a> { -> &'a ImportDirective { self.import_directives.alloc(import_directive) } + fn alloc_name_resolution(&'a self) -> &'a RefCell> { + self.name_resolutions.alloc(Default::default()) + } } #[derive(PartialEq)] @@ -1198,6 +1202,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { modules: arena::TypedArena::new(), name_bindings: arena::TypedArena::new(), import_directives: arena::TypedArena::new(), + name_resolutions: arena::TypedArena::new(), } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index ae78f697851..2f7de8c4aa4 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -30,7 +30,7 @@ use syntax::codemap::Span; use syntax::util::lev_distance::find_best_match_for_name; use std::mem::replace; -use std::cell::Cell; +use std::cell::{Cell, RefCell}; /// Contains data for specific types of import directives. #[derive(Clone, Debug)] @@ -194,8 +194,8 @@ impl<'a> NameResolution<'a> { None => return Some(Indeterminate), }; let name = match directive.subclass { - SingleImport { source, target, .. } if source == target => target, - _ => return Some(Indeterminate), + SingleImport { source, .. } => source, + GlobImport => unreachable!(), }; match target_module.resolve_name(name, ns, false) { Failed(_) => {} @@ -227,14 +227,19 @@ impl<'a> NameResolution<'a> { } 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()) + } + pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: bool) -> ResolveResult<&'a NameBinding<'a>> { - let resolutions = match self.resolutions.borrow_state() { - ::std::cell::BorrowState::Unused => self.resolutions.borrow(), - _ => return Failed(None), // This happens when there is a cycle of glob imports + 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 }; - let resolution = resolutions.get(&(name, ns)).cloned().unwrap_or_default(); 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| { @@ -261,7 +266,7 @@ impl<'a> ::ModuleS<'a> { // Invariant: this may not be called until import resolution is complete. pub fn resolve_name_in_lexical_scope(&self, name: Name, ns: Namespace) -> Option<&'a NameBinding<'a>> { - self.resolutions.borrow().get(&(name, ns)).and_then(|resolution| resolution.binding) + self.resolution(name, ns).borrow().binding .or_else(|| self.prelude.borrow().and_then(|prelude| { prelude.resolve_name(name, ns, false).success() })) @@ -296,10 +301,9 @@ impl<'a> ::ModuleS<'a> { self.unresolved_imports.borrow_mut().push(directive); match directive.subclass { SingleImport { target, .. } => { - let mut resolutions = self.resolutions.borrow_mut(); for &ns in &[ValueNS, TypeNS] { - resolutions.entry((target, ns)).or_insert_with(Default::default) - .single_imports.add_directive(directive); + self.resolution(target, ns).borrow_mut().single_imports + .add_directive(directive); } } // We don't add prelude imports to the globs since they only affect lexical scopes, @@ -314,8 +318,7 @@ impl<'a> ::ModuleS<'a> { fn update_resolution(&self, name: Name, ns: Namespace, update: F) -> T where F: FnOnce(&mut NameResolution<'a>) -> T { - let mut resolutions = self.resolutions.borrow_mut(); - let resolution = resolutions.entry((name, ns)).or_insert_with(Default::default); + let mut resolution = &mut *self.resolution(name, ns).borrow_mut(); let was_known = resolution.binding().is_some(); let t = update(resolution); @@ -638,7 +641,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { target_module.glob_importers.borrow_mut().push((module_, directive)); for (&(name, ns), resolution) in target_module.resolutions.borrow().iter() { - if let Some(binding) = resolution.binding() { + if let Some(binding) = resolution.borrow().binding() { if binding.defined_with(DefModifiers::IMPORTABLE | DefModifiers::PUBLIC) { let _ = module_.try_define_child(name, ns, directive.import(binding, None)); } @@ -666,6 +669,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { let mut reexports = Vec::new(); for (&(name, ns), resolution) in module.resolutions.borrow().iter() { + let resolution = resolution.borrow(); resolution.report_conflicts(|b1, b2| { self.resolver.report_conflict(module, name, ns, b1, b2) }); diff --git a/src/test/compile-fail/issue-32119.rs b/src/test/compile-fail/issue-32119.rs index 226a3a24c9b..4743b779ef6 100644 --- a/src/test/compile-fail/issue-32119.rs +++ b/src/test/compile-fail/issue-32119.rs @@ -17,5 +17,12 @@ mod bar { pub use super::T; } pub use foo::*; pub use bar::*; +mod baz { + pub type T = (); + mod foo { pub use super::T as S; } + mod bar { pub use super::foo::S as T; } + pub use self::bar::*; +} + #[rustc_error] fn main() {} //~ ERROR compilation successful -- cgit 1.4.1-3-g733a5