rustc: Disallow importing through use statements
Resolve is currently erroneously allowing imports through private `use` statements in some circumstances, even across module boundaries. For example, this code compiles successfully today: use std::c_str; mod test { use c_str::CString; } This should not be allowed because it was explicitly decided that private `use` statements are purely bringing local names into scope, they are not participating further in name resolution. As a consequence of this patch, this code, while valid today, is now invalid: mod test { use std::c_str; unsafe fn foo() { ::test::c_str::CString::new(0 as *u8, false); } } While plausibly acceptable, I found it to be more consistent if private imports were only considered candidates to resolve the first component in a path, and no others. Closes #12612
This commit is contained in:
parent
0bf4e900d4
commit
83d2c0b8a6
8 changed files with 101 additions and 18 deletions
|
@ -324,7 +324,7 @@ pub fn mkdir(p: &CString, _mode: io::FilePermission) -> IoResult<()> {
|
|||
}
|
||||
|
||||
pub fn readdir(p: &CString) -> IoResult<Vec<Path>> {
|
||||
use rt::global_heap::malloc_raw;
|
||||
use std::rt::global_heap::malloc_raw;
|
||||
|
||||
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
|
||||
let root = unsafe { CString::new(root.with_ref(|p| p), false) };
|
||||
|
|
|
@ -297,20 +297,22 @@ mod __test {
|
|||
|
||||
fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
||||
let id_test = token::str_to_ident("test");
|
||||
let vi = if cx.is_test_crate {
|
||||
ast::ViewItemUse(
|
||||
let (vi, vis) = if cx.is_test_crate {
|
||||
(ast::ViewItemUse(
|
||||
vec!(@nospan(ast::ViewPathSimple(id_test,
|
||||
path_node(vec!(id_test)),
|
||||
ast::DUMMY_NODE_ID))))
|
||||
ast::DUMMY_NODE_ID)))),
|
||||
ast::Public)
|
||||
} else {
|
||||
ast::ViewItemExternCrate(id_test,
|
||||
(ast::ViewItemExternCrate(id_test,
|
||||
with_version("test"),
|
||||
ast::DUMMY_NODE_ID)
|
||||
ast::DUMMY_NODE_ID),
|
||||
ast::Inherited)
|
||||
};
|
||||
ast::ViewItem {
|
||||
node: vi,
|
||||
attrs: Vec::new(),
|
||||
vis: ast::Inherited,
|
||||
vis: vis,
|
||||
span: DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2286,10 +2286,12 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
Some(child_name_bindings) => {
|
||||
if child_name_bindings.defined_in_namespace(ValueNS) {
|
||||
debug!("(resolving single import) found value binding");
|
||||
value_result = BoundResult(containing_module,
|
||||
*child_name_bindings);
|
||||
}
|
||||
if child_name_bindings.defined_in_namespace(TypeNS) {
|
||||
debug!("(resolving single import) found type binding");
|
||||
type_result = BoundResult(containing_module,
|
||||
*child_name_bindings);
|
||||
}
|
||||
|
@ -2320,6 +2322,7 @@ impl<'a> Resolver<'a> {
|
|||
.borrow();
|
||||
match import_resolutions.find(&source.name) {
|
||||
None => {
|
||||
debug!("(resolving single import) no import");
|
||||
// The containing module definitely doesn't have an
|
||||
// exported import with the name in question. We can
|
||||
// therefore accurately report that the names are
|
||||
|
@ -2353,6 +2356,8 @@ impl<'a> Resolver<'a> {
|
|||
return UnboundResult;
|
||||
}
|
||||
Some(target) => {
|
||||
debug!("(resolving single import) found \
|
||||
import in ns {:?}", namespace);
|
||||
let id = import_resolution.id(namespace);
|
||||
this.used_imports.insert((id, namespace));
|
||||
return BoundResult(target.target_module,
|
||||
|
@ -2396,6 +2401,8 @@ impl<'a> Resolver<'a> {
|
|||
.find_copy(&source.name) {
|
||||
None => {} // Continue.
|
||||
Some(module) => {
|
||||
debug!("(resolving single import) found external \
|
||||
module");
|
||||
let name_bindings =
|
||||
@Resolver::create_name_bindings_from_module(
|
||||
module);
|
||||
|
@ -2669,7 +2676,8 @@ impl<'a> Resolver<'a> {
|
|||
match self.resolve_name_in_module(search_module,
|
||||
name,
|
||||
TypeNS,
|
||||
name_search_type) {
|
||||
name_search_type,
|
||||
false) {
|
||||
Failed => {
|
||||
let segment_name = token::get_ident(name);
|
||||
let module_name = self.module_to_str(search_module);
|
||||
|
@ -2977,7 +2985,8 @@ impl<'a> Resolver<'a> {
|
|||
match self.resolve_name_in_module(search_module,
|
||||
name,
|
||||
namespace,
|
||||
PathSearch) {
|
||||
PathSearch,
|
||||
true) {
|
||||
Failed => {
|
||||
// Continue up the search chain.
|
||||
}
|
||||
|
@ -3141,7 +3150,8 @@ impl<'a> Resolver<'a> {
|
|||
module_: @Module,
|
||||
name: Ident,
|
||||
namespace: Namespace,
|
||||
name_search_type: NameSearchType)
|
||||
name_search_type: NameSearchType,
|
||||
allow_private_imports: bool)
|
||||
-> ResolveResult<(Target, bool)> {
|
||||
debug!("(resolving name in module) resolving `{}` in `{}`",
|
||||
token::get_ident(name),
|
||||
|
@ -3172,7 +3182,9 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
// Check the list of resolved imports.
|
||||
match module_.import_resolutions.borrow().find(&name.name) {
|
||||
Some(import_resolution) => {
|
||||
Some(import_resolution) if allow_private_imports ||
|
||||
import_resolution.is_public.get() => {
|
||||
|
||||
if import_resolution.is_public.get() &&
|
||||
import_resolution.outstanding_references.get() != 0 {
|
||||
debug!("(resolving name in module) import \
|
||||
|
@ -3193,7 +3205,7 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
None => {} // Continue.
|
||||
Some(..) | None => {} // Continue.
|
||||
}
|
||||
|
||||
// Finally, search through external children.
|
||||
|
|
13
src/test/auxiliary/issue-12612-1.rs
Normal file
13
src/test/auxiliary/issue-12612-1.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2014 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub mod bar {
|
||||
pub fn foo() {}
|
||||
}
|
11
src/test/auxiliary/issue-12612-2.rs
Normal file
11
src/test/auxiliary/issue-12612-2.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn baz() {}
|
24
src/test/compile-fail/issue-12612.rs
Normal file
24
src/test/compile-fail/issue-12612.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2014 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:issue-12612-1.rs
|
||||
|
||||
extern crate foo = "issue-12612-1";
|
||||
|
||||
use foo::bar;
|
||||
|
||||
mod test {
|
||||
use bar::foo;
|
||||
//~^ ERROR: unresolved import
|
||||
//~^^ ERROR: failed to resolve import
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -8,13 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate ser = "serialize";
|
||||
extern crate serialize;
|
||||
|
||||
use serialize = self::ser;
|
||||
//necessary for deriving(Encodable)
|
||||
use ser::{Encodable, Encoder};
|
||||
use ser::json;
|
||||
use ser::ebml::writer;
|
||||
use serialize::{Encodable, Encoder};
|
||||
use serialize::json;
|
||||
use serialize::ebml::writer;
|
||||
use std::io::MemWriter;
|
||||
use std::str::from_utf8_owned;
|
||||
|
||||
|
|
23
src/test/run-pass/issue-12612.rs
Normal file
23
src/test/run-pass/issue-12612.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:issue-12612-1.rs
|
||||
// aux-build:issue-12612-2.rs
|
||||
|
||||
extern crate foo = "issue-12612-1";
|
||||
extern crate bar = "issue-12612-2";
|
||||
|
||||
use foo::bar;
|
||||
|
||||
mod test {
|
||||
use bar::baz;
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Reference in a new issue