Skip to content

Commit

Permalink
librustc: Forbid external crates, imports, and/or items from being
Browse files Browse the repository at this point in the history
declared with the same name in the same scope.

This breaks several common patterns. First are unused imports:

    use foo::bar;
    use baz::bar;

Change this code to the following:

    use baz::bar;

Second, this patch breaks globs that import names that are shadowed by
subsequent imports. For example:

    use foo::*; // including `bar`
    use baz::bar;

Change this code to remove the glob:

    use foo::{boo, quux};
    use baz::bar;

Or qualify all uses of `bar`:

    use foo::{boo, quux};
    use baz;

    ... baz::bar ...

Finally, this patch breaks code that, at top level, explicitly imports
`std` and doesn't disable the prelude.

    extern crate std;

Because the prelude imports `std` implicitly, there is no need to
explicitly import it; just remove such directives.

The old behavior can be opted into via the `import_shadowing` feature
gate. Use of this feature gate is discouraged.

This implements RFC #116.

Closes #16464.

[breaking-change]
  • Loading branch information
pcwalton committed Aug 17, 2014
1 parent 85fd37f commit 7f928d1
Show file tree
Hide file tree
Showing 86 changed files with 579 additions and 433 deletions.
3 changes: 2 additions & 1 deletion src/doc/guide-unsafe.md
Expand Up @@ -537,11 +537,12 @@ extern crate core;
use core::prelude::*;
use core::mem;
use core::raw::Slice;
#[no_mangle]
pub extern fn dot_product(a: *const u32, a_len: u32,
b: *const u32, b_len: u32) -> u32 {
use core::raw::Slice;
// Convert the provided arrays into Rust slices.
// The core::raw module guarantees that the Slice
// structure has the same memory layout as a &[T]
Expand Down
3 changes: 1 addition & 2 deletions src/libcollections/bitv.rs
Expand Up @@ -68,12 +68,11 @@ use core::default::Default;
use core::fmt;
use core::iter::Take;
use core::iter;
use core::ops::Index;
use core::slice;
use core::uint;
use std::hash;

use {Collection, Mutable, Set, MutableSet, MutableSeq};
use {Mutable, Set, MutableSet, MutableSeq};
use vec::Vec;


Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/btree.rs
Expand Up @@ -24,7 +24,7 @@ use alloc::boxed::Box;
use core::fmt;
use core::fmt::Show;

use {Collection, MutableSeq};
use MutableSeq;
use vec::Vec;

#[allow(missing_doc)]
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/dlist.rs
Expand Up @@ -31,7 +31,7 @@ use core::mem;
use core::ptr;
use std::hash::{Writer, Hash};

use {Collection, Mutable, Deque, MutableSeq};
use {Mutable, Deque, MutableSeq};

/// A doubly-linked list.
pub struct DList<T> {
Expand Down
9 changes: 6 additions & 3 deletions src/libcollections/lib.rs
Expand Up @@ -22,9 +22,12 @@
html_playground_url = "http://play.rust-lang.org/")]

#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
#![feature(unsafe_destructor)]
#![feature(unsafe_destructor, import_shadowing)]
#![no_std]

// NOTE(stage0, pcwalton): Remove after snapshot.
#![allow(unknown_features)]

#[phase(plugin, link)] extern crate core;
extern crate unicode;
extern crate alloc;
Expand All @@ -36,11 +39,11 @@ extern crate alloc;
#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate log;

use core::prelude::*;
use core::prelude::Option;

pub use core::collections::Collection;
pub use bitv::{Bitv, BitvSet};
pub use btree::BTree;
pub use core::prelude::Collection;
pub use dlist::DList;
pub use enum_set::EnumSet;
pub use priority_queue::PriorityQueue;
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/priority_queue.rs
Expand Up @@ -154,7 +154,7 @@ use core::default::Default;
use core::mem::{zeroed, replace, swap};
use core::ptr;

use {Collection, Mutable, MutableSeq};
use {Mutable, MutableSeq};
use slice;
use vec::Vec;

Expand Down
3 changes: 1 addition & 2 deletions src/libcollections/ringbuf.rs
Expand Up @@ -18,11 +18,10 @@ use core::prelude::*;
use core::cmp;
use core::default::Default;
use core::fmt;
use core::iter::RandomAccessIterator;
use core::iter;
use std::hash::{Writer, Hash};

use {Deque, Collection, Mutable, MutableSeq};
use {Deque, Mutable, MutableSeq};
use vec::Vec;

static INITIAL_CAPACITY: uint = 8u; // 2^3
Expand Down
13 changes: 6 additions & 7 deletions src/libcollections/slice.rs
Expand Up @@ -86,23 +86,22 @@ for &x in numbers.iter() {

#![doc(primitive = "slice")]

use core::prelude::*;

use core::cmp;
use core::mem::size_of;
use core::mem;
use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option};
use core::prelude::{Ord, Ordering, RawPtr, Some, range};
use core::ptr;
use core::iter::{range_step, MultiplicativeIterator};

use {Collection, MutableSeq};
use MutableSeq;
use vec::Vec;

pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
pub use core::slice::{Chunks, Slice, ImmutableSlice, ImmutablePartialEqSlice};
pub use core::slice::{ImmutableOrdSlice, MutableSlice, Items, MutItems};
pub use core::slice::{MutSplits, MutChunks};
pub use core::slice::{bytes, MutableCloneableSlice};
pub use core::slice::{BinarySearchResult, Found, NotFound};
pub use core::slice::{MutSplits, MutChunks, Splits};
pub use core::slice::{bytes, ref_slice, MutableCloneableSlice};
pub use core::slice::{Found, NotFound};

// Functional utilities

Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/smallintmap.rs
Expand Up @@ -21,7 +21,7 @@ use core::iter;
use core::iter::{Enumerate, FilterMap};
use core::mem::replace;

use {Collection, Mutable, Map, MutableMap, MutableSeq};
use {Mutable, Map, MutableMap, MutableSeq};
use {vec, slice};
use vec::Vec;
use hash;
Expand Down
8 changes: 5 additions & 3 deletions src/libcollections/str.rs
Expand Up @@ -69,15 +69,17 @@ is the same as `&[u8]`.

#![doc(primitive = "str")]

use core::prelude::*;

use core::default::Default;
use core::fmt;
use core::cmp;
use core::iter::AdditiveIterator;
use core::mem;
use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice};
use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering};
use core::prelude::{PartialEq, PartialOrd, Result, Slice, Some, Tuple2};
use core::prelude::{range};

use {Collection, Deque, MutableSeq};
use {Deque, MutableSeq};
use hash;
use ringbuf::RingBuf;
use string::String;
Expand Down
3 changes: 1 addition & 2 deletions src/libcollections/string.rs
Expand Up @@ -20,9 +20,8 @@ use core::mem;
use core::ptr;
// FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
use RawSlice = core::raw::Slice;
use core::slice::Slice;

use {Collection, Mutable, MutableSeq};
use {Mutable, MutableSeq};
use hash;
use str;
use str::{CharRange, StrAllocating, MaybeOwned, Owned};
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/treemap.rs
Expand Up @@ -40,7 +40,7 @@ use core::mem::{replace, swap};
use core::ptr;
use std::hash::{Writer, Hash};

use {Collection, Mutable, Set, MutableSet, MutableMap, Map, MutableSeq};
use {Mutable, Set, MutableSet, MutableMap, Map, MutableSeq};
use vec::Vec;

/// This is implemented as an AA tree, which is a simplified variation of
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/trie.rs
Expand Up @@ -23,7 +23,7 @@ use core::uint;
use core::iter;
use std::hash::{Writer, Hash};

use {Collection, Mutable, Map, MutableMap, Set, MutableSet};
use {Mutable, Map, MutableMap, Set, MutableSet};
use slice::{Items, MutItems};
use slice;

Expand Down
4 changes: 1 addition & 3 deletions src/libcollections/vec.rs
Expand Up @@ -14,17 +14,15 @@ use core::prelude::*;

use alloc::heap::{allocate, reallocate, deallocate};
use RawSlice = core::raw::Slice;
use core::slice::Slice;
use core::cmp::max;
use core::default::Default;
use core::fmt;
use core::mem;
use core::num::{CheckedMul, CheckedAdd};
use core::num;
use core::ptr;
use core::uint;

use {Collection, Mutable, MutableSeq};
use {Mutable, MutableSeq};
use slice::{MutableOrdSlice, MutableSliceAllocating, CloneableVector};
use slice::{Items, MutItems};

Expand Down
19 changes: 12 additions & 7 deletions src/libcore/fmt/mod.rs
Expand Up @@ -14,12 +14,10 @@

use any;
use cell::{Cell, Ref, RefMut};
use char::Char;
use collections::Collection;
use iter::{Iterator, range};
use kinds::Copy;
use mem;
use num::Float;
use option::{Option, Some, None};
use ops::Deref;
use result::{Ok, Err};
Expand Down Expand Up @@ -342,8 +340,12 @@ impl<'a> Formatter<'a> {
///
/// This function will correctly account for the flags provided as well as
/// the minimum width. It will not take precision into account.
pub fn pad_integral(&mut self, is_positive: bool, prefix: &str,
buf: &[u8]) -> Result {
pub fn pad_integral(&mut self,
is_positive: bool,
prefix: &str,
buf: &[u8])
-> Result {
use char::Char;
use fmt::rt::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};

let mut width = buf.len();
Expand Down Expand Up @@ -456,6 +458,7 @@ impl<'a> Formatter<'a> {
padding: uint,
default: rt::Alignment,
f: |&mut Formatter| -> Result) -> Result {
use char::Char;
let align = match self.align {
rt::AlignUnknown => default,
rt::AlignLeft | rt::AlignRight => self.align
Expand Down Expand Up @@ -539,6 +542,8 @@ impl<'a, T: str::Str> String for T {

impl Char for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::Char;

let mut utf8 = [0u8, ..4];
let amt = self.encode_utf8(utf8);
let s: &str = unsafe { mem::transmute(utf8.slice_to(amt)) };
Expand Down Expand Up @@ -571,7 +576,7 @@ impl<'a, T> Pointer for &'a mut T {
macro_rules! floating(($ty:ident) => {
impl Float for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Signed;
use num::{Float, Signed};

let digits = match fmt.precision {
Some(i) => float::DigExact(i),
Expand All @@ -592,7 +597,7 @@ macro_rules! floating(($ty:ident) => {

impl LowerExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Signed;
use num::{Float, Signed};

let digits = match fmt.precision {
Some(i) => float::DigExact(i),
Expand All @@ -613,7 +618,7 @@ macro_rules! floating(($ty:ident) => {

impl UpperExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Signed;
use num::{Float, Signed};

let digits = match fmt.precision {
Some(i) => float::DigExact(i),
Expand Down
5 changes: 4 additions & 1 deletion src/libfmt_macros/lib.rs
Expand Up @@ -19,7 +19,10 @@
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![feature(macro_rules, globs)]
#![feature(macro_rules, globs, import_shadowing)]

// NOTE(stage0, pcwalton): Remove after snapshot.
#![allow(unknown_features)]

use std::char;
use std::str;
Expand Down
4 changes: 4 additions & 0 deletions src/libgetopts/lib.rs
Expand Up @@ -88,8 +88,12 @@
html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(globs, phase)]
#![feature(import_shadowing)]
#![deny(missing_doc)]

// NOTE(stage0, pcwalton): Remove after snapshot.
#![allow(unknown_features)]

#[cfg(test)] extern crate debug;
#[cfg(test)] #[phase(plugin, link)] extern crate log;

Expand Down
6 changes: 3 additions & 3 deletions src/liblibc/lib.rs
Expand Up @@ -226,7 +226,7 @@ pub use funcs::bsd43::{shutdown};
#[cfg(windows)] pub use consts::os::extra::{FILE_FLAG_BACKUP_SEMANTICS, INVALID_HANDLE_VALUE};
#[cfg(windows)] pub use consts::os::extra::{MOVEFILE_REPLACE_EXISTING};
#[cfg(windows)] pub use consts::os::extra::{GENERIC_READ, GENERIC_WRITE};
#[cfg(windows)] pub use consts::os::extra::{VOLUME_NAME_DOS, FILE_ATTRIBUTE_NORMAL};
#[cfg(windows)] pub use consts::os::extra::{VOLUME_NAME_DOS};
#[cfg(windows)] pub use consts::os::extra::{PIPE_ACCESS_DUPLEX, FILE_FLAG_FIRST_PIPE_INSTANCE};
#[cfg(windows)] pub use consts::os::extra::{FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE};
#[cfg(windows)] pub use consts::os::extra::{PIPE_READMODE_BYTE, PIPE_WAIT};
Expand Down Expand Up @@ -255,10 +255,10 @@ pub use funcs::bsd43::{shutdown};
#[cfg(windows)] pub use funcs::extra::kernel32::{UnmapViewOfFile, CloseHandle};
#[cfg(windows)] pub use funcs::extra::kernel32::{WaitForSingleObject, GetSystemTimeAsFileTime};
#[cfg(windows)] pub use funcs::extra::kernel32::{QueryPerformanceCounter};
#[cfg(windows)] pub use funcs::extra::kernel32::{WaitForSingleObject, QueryPerformanceFrequency};
#[cfg(windows)] pub use funcs::extra::kernel32::{QueryPerformanceFrequency};
#[cfg(windows)] pub use funcs::extra::kernel32::{GetExitCodeProcess, TerminateProcess};
#[cfg(windows)] pub use funcs::extra::kernel32::{ReadFile, WriteFile, SetFilePointerEx};
#[cfg(windows)] pub use funcs::extra::kernel32::{FlushFileBuffers, SetEndOfFile, CreateFileW};
#[cfg(windows)] pub use funcs::extra::kernel32::{SetEndOfFile, CreateFileW};
#[cfg(windows)] pub use funcs::extra::kernel32::{CreateDirectoryW, FindFirstFileW};
#[cfg(windows)] pub use funcs::extra::kernel32::{FindNextFileW, FindClose, DeleteFileW};
#[cfg(windows)] pub use funcs::extra::kernel32::{CreateHardLinkW, CreateEventW};
Expand Down
1 change: 0 additions & 1 deletion src/librand/distributions/mod.rs
Expand Up @@ -24,7 +24,6 @@ that do not need to record state.

use core::prelude::*;
use core::num;
use core::num::CheckedAdd;

use {Rng, Rand};

Expand Down
3 changes: 1 addition & 2 deletions src/librand/distributions/range.rs
Expand Up @@ -35,12 +35,11 @@ use distributions::{Sample, IndependentSample};
/// # Example
///
/// ```rust
/// use std::rand;
/// use std::rand::distributions::{IndependentSample, Range};
///
/// fn main() {
/// let between = Range::new(10u, 10000u);
/// let mut rng = rand::task_rng();
/// let mut rng = std::rand::task_rng();
/// let mut sum = 0;
/// for _ in range(0u, 1000) {
/// sum += between.ind_sample(&mut rng);
Expand Down
5 changes: 4 additions & 1 deletion src/librlibc/lib.rs
Expand Up @@ -28,13 +28,16 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/master/")]

#![feature(intrinsics, phase)]
#![feature(import_shadowing, intrinsics, phase)]
#![no_std]

// This library defines the builtin functions, so it would be a shame for
// LLVM to optimize these function calls to themselves!
#![no_builtins]

// NOTE(stage0, pcwalton): Remove after snapshot.
#![allow(unknown_features)]

#[cfg(test)] extern crate native;
#[cfg(test)] extern crate test;
#[cfg(test)] extern crate debug;
Expand Down
9 changes: 7 additions & 2 deletions src/librustc/front/feature_gate.rs
Expand Up @@ -68,6 +68,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[

("rustc_diagnostic_macros", Active),
("unboxed_closures", Active),
("import_shadowing", Active),

// if you change this list without updating src/doc/rust.md, cmr will be sad

Expand Down Expand Up @@ -98,7 +99,8 @@ pub struct Features {
pub default_type_params: Cell<bool>,
pub issue_5723_bootstrap: Cell<bool>,
pub overloaded_calls: Cell<bool>,
pub rustc_diagnostic_macros: Cell<bool>
pub rustc_diagnostic_macros: Cell<bool>,
pub import_shadowing: Cell<bool>,
}

impl Features {
Expand All @@ -107,7 +109,8 @@ impl Features {
default_type_params: Cell::new(false),
issue_5723_bootstrap: Cell::new(false),
overloaded_calls: Cell::new(false),
rustc_diagnostic_macros: Cell::new(false)
rustc_diagnostic_macros: Cell::new(false),
import_shadowing: Cell::new(false),
}
}
}
Expand Down Expand Up @@ -439,4 +442,6 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros"));
sess.features.import_shadowing.set(cx.has_feature("import_shadowing"));
}

5 comments on commit 7f928d1

@bors
Copy link
Contributor

@bors bors commented on 7f928d1 Aug 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at pcwalton@7f928d1

@bors
Copy link
Contributor

@bors bors commented on 7f928d1 Aug 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/resolve-shadowing = 7f928d1 into auto

@bors
Copy link
Contributor

@bors bors commented on 7f928d1 Aug 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/resolve-shadowing = 7f928d1 merged ok, testing candidate = 4a5654f

@bors
Copy link
Contributor

@bors bors commented on 7f928d1 Aug 17, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 4a5654f

Please sign in to comment.