about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-08-12 20:31:30 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-08-16 19:32:25 -0700
commit7f928d150e53b5873b4238f9e60d1aa4be9b602f (patch)
tree02452858125464ce20b886a2b61d77b0c3b3d65a /src/librustc
parent85fd37f876dad1d4db02208f8a56f02228d975b0 (diff)
downloadrust-7f928d150e53b5873b4238f9e60d1aa4be9b602f.tar.gz
rust-7f928d150e53b5873b4238f9e60d1aa4be9b602f.zip
librustc: Forbid external crates, imports, and/or items from being
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]
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/front/feature_gate.rs9
-rw-r--r--src/librustc/front/std_inject.rs15
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/lint/builtin.rs3
-rw-r--r--src/librustc/metadata/encoder.rs1
-rw-r--r--src/librustc/middle/astencode.rs16
-rw-r--r--src/librustc/middle/resolve.rs317
-rw-r--r--src/librustc/middle/trans/_match.rs3
-rw-r--r--src/librustc/middle/trans/base.rs12
-rw-r--r--src/librustc/middle/trans/cabi_mips.rs2
-rw-r--r--src/librustc/middle/trans/cabi_x86.rs7
-rw-r--r--src/librustc/middle/trans/cabi_x86_64.rs2
-rw-r--r--src/librustc/middle/trans/cabi_x86_win64.rs2
-rw-r--r--src/librustc/middle/trans/callee.rs1
-rw-r--r--src/librustc/middle/trans/controlflow.rs13
-rw-r--r--src/librustc/middle/ty.rs5
16 files changed, 350 insertions, 59 deletions
diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs
index fdfbdea245b..7c19b25e01c 100644
--- a/src/librustc/front/feature_gate.rs
+++ b/src/librustc/front/feature_gate.rs
@@ -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
 
@@ -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 {
@@ -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),
         }
     }
 }
@@ -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"));
 }
+
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 5dca09faf34..ff8711c5df0 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -19,6 +19,7 @@ use syntax::fold::Folder;
 use syntax::fold;
 use syntax::owned_slice::OwnedSlice;
 use syntax::parse::token::InternedString;
+use syntax::parse::token::special_idents;
 use syntax::parse::token;
 use syntax::util::small_vector::SmallVector;
 
@@ -197,7 +198,19 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
                                                                   ast::DUMMY_NODE_ID));
         let vi2 = ast::ViewItem {
             node: ast::ViewItemUse(vp),
-            attrs: Vec::new(),
+            attrs: vec!(ast::Attribute {
+                span: DUMMY_SP,
+                node: ast::Attribute_ {
+                    id: attr::mk_attr_id(),
+                    style: ast::AttrOuter,
+                    value: box(GC) ast::MetaItem {
+                        span: DUMMY_SP,
+                        node: ast::MetaWord(token::get_name(
+                                special_idents::prelude_import.name)),
+                    },
+                    is_sugared_doc: false,
+                },
+            }),
             vis: ast::Inherited,
             span: DUMMY_SP,
         };
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index f9774e83e8a..239e858eeeb 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -34,6 +34,7 @@ This API is completely unstable and subject to change.
 
 #![allow(unknown_features)] // NOTE: Remove after next snapshot
 #![feature(rustc_diagnostic_macros)]
+#![feature(import_shadowing)]
 
 extern crate arena;
 extern crate debug;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 738c5d9be79..7e0ba613e3d 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -581,6 +581,9 @@ impl LintPass for UnusedAttribute {
             "thread_local",
             "no_debug",
 
+            // used in resolve
+            "prelude_import",
+
             // not used anywhere (!?) but apparently we want to keep them around
             "comment",
             "desc",
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 1d426aaaf5c..29b5db51cc4 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -42,7 +42,6 @@ use syntax::ast_map::{PathElem, PathElems};
 use syntax::ast_map;
 use syntax::ast_util::*;
 use syntax::ast_util;
-use syntax::ast_util::PostExpansionMethod;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::diagnostic::SpanHandler;
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 26cb2f25129..ff2830421e0 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -47,8 +47,8 @@ use rbml::io::SeekableMemWriter;
 use rbml::{reader, writer};
 use rbml;
 use serialize;
-use serialize::{Encoder, Encodable, EncoderHelpers, DecoderHelpers};
-use serialize::{Decoder, Decodable};
+use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
+use serialize::{EncoderHelpers};
 
 #[cfg(test)] use syntax::parse;
 #[cfg(test)] use syntax::print::pprust;
@@ -620,6 +620,8 @@ fn encode_method_callee(ecx: &e::EncodeContext,
                         rbml_w: &mut Encoder,
                         adjustment: typeck::ExprAdjustment,
                         method: &MethodCallee) {
+    use serialize::Encoder;
+
     rbml_w.emit_struct("MethodCallee", 4, |rbml_w| {
         rbml_w.emit_struct_field("adjustment", 0u, |rbml_w| {
             adjustment.encode(rbml_w)
@@ -695,6 +697,8 @@ fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
                               rbml_w: &mut Encoder,
                               adjustment: typeck::ExprAdjustment,
                               dr: &typeck::vtable_res) {
+    use serialize::Encoder;
+
     rbml_w.emit_struct("VtableWithKey", 2, |rbml_w| {
         rbml_w.emit_struct_field("adjustment", 0u, |rbml_w| {
             adjustment.encode(rbml_w)
@@ -728,6 +732,8 @@ pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
 
 pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
                                    kind: ty::UnboxedClosureKind) {
+    use serialize::Encoder;
+
     ebml_w.emit_enum("UnboxedClosureKind", |ebml_w| {
         match kind {
             ty::FnUnboxedClosureKind => {
@@ -755,6 +761,8 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
 pub fn encode_vtable_origin(ecx: &e::EncodeContext,
                             rbml_w: &mut Encoder,
                             vtable_origin: &typeck::vtable_origin) {
+    use serialize::Encoder;
+
     rbml_w.emit_enum("vtable_origin", |rbml_w| {
         match *vtable_origin {
           typeck::vtable_static(def_id, ref substs, ref vtable_res) => {
@@ -985,6 +993,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
     fn emit_polytype(&mut self,
                  ecx: &e::EncodeContext,
                  pty: ty::Polytype) {
+        use serialize::Encoder;
+
         self.emit_struct("Polytype", 2, |this| {
             this.emit_struct_field("generics", 0, |this| {
                 this.emit_struct("Generics", 2, |this| {
@@ -1013,6 +1023,8 @@ impl<'a> rbml_writer_helpers for Encoder<'a> {
     }
 
     fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustment) {
+        use serialize::Encoder;
+
         self.emit_enum("AutoAdjustment", |this| {
             match *adj {
                 ty::AutoAddEnv(store) => {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 3ce6f726100..bd779b865d6 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -21,10 +21,31 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace};
 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
 use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
 
-use syntax::ast::*;
+use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate};
+use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
+use syntax::ast::{ExprFnBlock, ExprForLoop, ExprLoop, ExprMethodCall};
+use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
+use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
+use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
+use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
+use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, Method};
+use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
+use syntax::ast::{OtherRegionTyParamBound, P, Pat, PatEnum, PatIdent, PatLit};
+use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
+use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
+use syntax::ast::{StaticRegionTyParamBound, StmtDecl, StructField};
+use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
+use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
+use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
+use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyRptr};
+use syntax::ast::{TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
+use syntax::ast::{UnboxedFnTyParamBound, UnnamedField, UnsafeFn, Variant};
+use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse, ViewPathGlob};
+use syntax::ast::{ViewPathList, ViewPathSimple, Visibility};
 use syntax::ast;
-use syntax::ast_util::{local_def, PostExpansionMethod};
-use syntax::ast_util::{walk_pat, trait_item_to_ty_method};
+use syntax::ast_util::{PostExpansionMethod, local_def};
+use syntax::ast_util::{trait_item_to_ty_method, walk_pat};
+use syntax::attr::AttrMetaMethods;
 use syntax::ext::mtwt;
 use syntax::parse::token::special_names;
 use syntax::parse::token::special_idents;
@@ -355,6 +376,7 @@ struct ImportDirective {
     span: Span,
     id: NodeId,
     is_public: bool, // see note in ImportResolution about how to use this
+    shadowable: bool,
 }
 
 impl ImportDirective {
@@ -362,7 +384,8 @@ impl ImportDirective {
            subclass: ImportDirectiveSubclass,
            span: Span,
            id: NodeId,
-           is_public: bool)
+           is_public: bool,
+           shadowable: bool)
            -> ImportDirective {
         ImportDirective {
             module_path: module_path,
@@ -370,6 +393,7 @@ impl ImportDirective {
             span: span,
             id: id,
             is_public: is_public,
+            shadowable: shadowable,
         }
     }
 }
@@ -379,13 +403,18 @@ impl ImportDirective {
 struct Target {
     target_module: Rc<Module>,
     bindings: Rc<NameBindings>,
+    shadowable: bool,
 }
 
 impl Target {
-    fn new(target_module: Rc<Module>, bindings: Rc<NameBindings>) -> Target {
+    fn new(target_module: Rc<Module>,
+           bindings: Rc<NameBindings>,
+           shadowable: bool)
+           -> Target {
         Target {
             target_module: target_module,
-            bindings: bindings
+            bindings: bindings,
+            shadowable: shadowable,
         }
     }
 }
@@ -1018,6 +1047,10 @@ impl<'a> Resolver<'a> {
 
         let module_ = reduced_graph_parent.module();
 
+        self.check_for_conflicts_between_external_crates_and_items(&*module_,
+                                                                   name.name,
+                                                                   sp);
+
         // Add or reuse the child.
         let child = module_.children.borrow().find_copy(&name.name);
         match child {
@@ -1481,6 +1514,14 @@ impl<'a> Resolver<'a> {
                 // Build up the import directives.
                 let module_ = parent.module();
                 let is_public = view_item.vis == ast::Public;
+                let shadowable =
+                    view_item.attrs
+                             .iter()
+                             .any(|attr| {
+                                 attr.name() == token::get_ident(
+                                    special_idents::prelude_import)
+                             });
+
                 match view_path.node {
                     ViewPathSimple(binding, ref full_path, id) => {
                         let source_ident =
@@ -1497,7 +1538,8 @@ impl<'a> Resolver<'a> {
                                                     subclass,
                                                     view_path.span,
                                                     id,
-                                                    is_public);
+                                                    is_public,
+                                                    shadowable);
                     }
                     ViewPathList(_, ref source_items, _) => {
                         // Make sure there's at most one `mod` import in the list.
@@ -1542,7 +1584,9 @@ impl<'a> Resolver<'a> {
                                 module_path,
                                 SingleImport(name, name),
                                 source_item.span,
-                                source_item.node.id(), is_public);
+                                source_item.node.id(),
+                                is_public,
+                                shadowable);
                         }
                     }
                     ViewPathGlob(_, id) => {
@@ -1551,7 +1595,8 @@ impl<'a> Resolver<'a> {
                                                     GlobImport,
                                                     view_path.span,
                                                     id,
-                                                    is_public);
+                                                    is_public,
+                                                    shadowable);
                     }
                 }
             }
@@ -1571,6 +1616,10 @@ impl<'a> Resolver<'a> {
                                                               true));
                     debug!("(build reduced graph for item) found extern `{}`",
                             self.module_to_string(&*external_module));
+                    self.check_for_conflicts_between_external_crates(
+                        &*parent.module(),
+                        name.name,
+                        view_item.span);
                     parent.module().external_module_children.borrow_mut()
                                    .insert(name.name, external_module.clone());
                     self.build_reduced_graph_for_external_crate(external_module);
@@ -1989,11 +2038,14 @@ impl<'a> Resolver<'a> {
                               subclass: ImportDirectiveSubclass,
                               span: Span,
                               id: NodeId,
-                              is_public: bool) {
+                              is_public: bool,
+                              shadowable: bool) {
         module_.imports.borrow_mut().push(ImportDirective::new(module_path,
                                                                subclass,
-                                                               span, id,
-                                                               is_public));
+                                                               span,
+                                                               id,
+                                                               is_public,
+                                                               shadowable));
         self.unresolved_imports += 1;
         // Bump the reference count on the name. Or, if this is a glob, set
         // the appropriate flag.
@@ -2241,8 +2293,7 @@ impl<'a> Resolver<'a> {
                         resolution_result =
                             self.resolve_glob_import(&*module_,
                                                      containing_module,
-                                                     import_directive.id,
-                                                     import_directive.is_public,
+                                                     import_directive,
                                                      lp);
                     }
                 }
@@ -2397,7 +2448,11 @@ impl<'a> Resolver<'a> {
                                 None => {
                                     return UnboundResult;
                                 }
-                                Some(Target {target_module, bindings}) => {
+                                Some(Target {
+                                    target_module,
+                                    bindings,
+                                    shadowable: _
+                                }) => {
                                     debug!("(resolving single import) found \
                                             import in ns {:?}", namespace);
                                     let id = import_resolution.id(namespace);
@@ -2462,8 +2517,16 @@ impl<'a> Resolver<'a> {
         match value_result {
             BoundResult(ref target_module, ref name_bindings) => {
                 debug!("(resolving single import) found value target");
-                import_resolution.value_target = Some(Target::new(target_module.clone(),
-                                                                  name_bindings.clone()));
+                self.check_for_conflicting_import(
+                    &import_resolution.value_target,
+                    directive.span,
+                    target.name,
+                    ValueNS);
+
+                import_resolution.value_target =
+                    Some(Target::new(target_module.clone(),
+                                     name_bindings.clone(),
+                                     directive.shadowable));
                 import_resolution.value_id = directive.id;
                 import_resolution.is_public = directive.is_public;
                 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
@@ -2477,8 +2540,16 @@ impl<'a> Resolver<'a> {
             BoundResult(ref target_module, ref name_bindings) => {
                 debug!("(resolving single import) found type target: {:?}",
                        { name_bindings.type_def.borrow().clone().unwrap().type_def });
+                self.check_for_conflicting_import(
+                    &import_resolution.type_target,
+                    directive.span,
+                    target.name,
+                    TypeNS);
+
                 import_resolution.type_target =
-                    Some(Target::new(target_module.clone(), name_bindings.clone()));
+                    Some(Target::new(target_module.clone(),
+                                     name_bindings.clone(),
+                                     directive.shadowable));
                 import_resolution.type_id = directive.id;
                 import_resolution.is_public = directive.is_public;
                 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
@@ -2489,6 +2560,12 @@ impl<'a> Resolver<'a> {
             }
         }
 
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            import_resolution,
+            directive.span,
+            target.name);
+
         if value_result.is_unbound() && type_result.is_unbound() {
             let msg = format!("There is no `{}` in `{}`",
                               token::get_ident(source),
@@ -2540,10 +2617,12 @@ impl<'a> Resolver<'a> {
     fn resolve_glob_import(&mut self,
                            module_: &Module,
                            containing_module: Rc<Module>,
-                           id: NodeId,
-                           is_public: bool,
+                           import_directive: &ImportDirective,
                            lp: LastPrivate)
                            -> ResolveResult<()> {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
         // This function works in a highly imperative manner; it eagerly adds
         // everything it can to the list of import resolutions of the module
         // node.
@@ -2619,9 +2698,12 @@ impl<'a> Resolver<'a> {
 
         for (&name, name_bindings) in containing_module.children
                                                        .borrow().iter() {
-            self.merge_import_resolution(module_, containing_module.clone(),
-                                         id, is_public,
-                                         name, name_bindings.clone());
+            self.merge_import_resolution(module_,
+                                         containing_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings.clone());
+
         }
 
         // Add external module children from the containing module.
@@ -2629,9 +2711,11 @@ impl<'a> Resolver<'a> {
                                                 .borrow().iter() {
             let name_bindings =
                 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
-            self.merge_import_resolution(module_, containing_module.clone(),
-                                         id, is_public,
-                                         name, name_bindings);
+            self.merge_import_resolution(module_,
+                                         containing_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings);
         }
 
         // Record the destination of this import
@@ -2650,10 +2734,12 @@ impl<'a> Resolver<'a> {
     fn merge_import_resolution(&mut self,
                                module_: &Module,
                                containing_module: Rc<Module>,
-                               id: NodeId,
-                               is_public: bool,
+                               import_directive: &ImportDirective,
                                name: Name,
                                name_bindings: Rc<NameBindings>) {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
         let mut import_resolutions = module_.import_resolutions.borrow_mut();
         let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
             // Create a new import resolution from this child.
@@ -2670,16 +2756,169 @@ impl<'a> Resolver<'a> {
         if name_bindings.defined_in_public_namespace(ValueNS) {
             debug!("(resolving glob import) ... for value target");
             dest_import_resolution.value_target =
-                Some(Target::new(containing_module.clone(), name_bindings.clone()));
+                Some(Target::new(containing_module.clone(),
+                                 name_bindings.clone(),
+                                 import_directive.shadowable));
             dest_import_resolution.value_id = id;
         }
         if name_bindings.defined_in_public_namespace(TypeNS) {
             debug!("(resolving glob import) ... for type target");
             dest_import_resolution.type_target =
-                Some(Target::new(containing_module, name_bindings.clone()));
+                Some(Target::new(containing_module,
+                                 name_bindings.clone(),
+                                 import_directive.shadowable));
             dest_import_resolution.type_id = id;
         }
         dest_import_resolution.is_public = is_public;
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            dest_import_resolution,
+            import_directive.span,
+            name);
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicting_import(&mut self,
+                                    target: &Option<Target>,
+                                    import_span: Span,
+                                    name: Name,
+                                    namespace: Namespace) {
+        if self.session.features.import_shadowing.get() {
+            return
+        }
+
+        match *target {
+            Some(ref target) if !target.shadowable => {
+                let msg = format!("a {} named `{}` has already been imported \
+                                   in this module",
+                                  match namespace {
+                                    TypeNS => "type",
+                                    ValueNS => "value",
+                                  },
+                                  token::get_name(name).get());
+                self.session.span_err(import_span, msg.as_slice());
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicts_between_imports_and_items(&mut self,
+                                                     module: &Module,
+                                                     import_resolution:
+                                                     &mut ImportResolution,
+                                                     import_span: Span,
+                                                     name: Name) {
+        if self.session.features.import_shadowing.get() {
+            return
+        }
+
+        // First, check for conflicts between imports and `extern crate`s.
+        if module.external_module_children
+                 .borrow()
+                 .contains_key(&name) {
+            match import_resolution.type_target {
+                Some(ref target) if !target.shadowable => {
+                    self.session.span_err(import_span,
+                                          "import conflicts with imported \
+                                           crate in this module");
+                }
+                Some(_) | None => {}
+            }
+        }
+
+        // Check for item conflicts.
+        let children = module.children.borrow();
+        let name_bindings = match children.find(&name) {
+            None => {
+                // There can't be any conflicts.
+                return
+            }
+            Some(ref name_bindings) => (*name_bindings).clone(),
+        };
+
+        match import_resolution.value_target {
+            Some(ref target) if !target.shadowable => {
+                match *name_bindings.value_def.borrow() {
+                    None => {}
+                    Some(ref value) => {
+                        self.session.span_err(import_span,
+                                              "import conflicts with value \
+                                               in this module");
+                        match value.value_span {
+                            None => {}
+                            Some(span) => {
+                                self.session
+                                    .span_note(span,
+                                               "note conflicting value here");
+                            }
+                        }
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+
+        match import_resolution.type_target {
+            Some(ref target) if !target.shadowable => {
+                match *name_bindings.type_def.borrow() {
+                    None => {}
+                    Some(ref ty) => {
+                        self.session.span_err(import_span,
+                                              "import conflicts with type in \
+                                               this module");
+                        match ty.type_span {
+                            None => {}
+                            Some(span) => {
+                                self.session
+                                    .span_note(span,
+                                               "note conflicting type here")
+                            }
+                        }
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that the names of external crates don't collide with other
+    /// external crates.
+    fn check_for_conflicts_between_external_crates(&self,
+                                                   module: &Module,
+                                                   name: Name,
+                                                   span: Span) {
+        if self.session.features.import_shadowing.get() {
+            return
+        }
+
+        if module.external_module_children.borrow().contains_key(&name) {
+            self.session
+                .span_err(span,
+                          format!("an external crate named `{}` has already \
+                                   been imported into this module",
+                                  token::get_name(name).get()).as_slice());
+        }
+    }
+
+    /// Checks that the names of items don't collide with external crates.
+    fn check_for_conflicts_between_external_crates_and_items(&self,
+                                                             module: &Module,
+                                                             name: Name,
+                                                             span: Span) {
+        if self.session.features.import_shadowing.get() {
+            return
+        }
+
+        if module.external_module_children.borrow().contains_key(&name) {
+            self.session
+                .span_err(span,
+                          format!("the name `{}` conflicts with an external \
+                                   crate that has been imported into this \
+                                   module",
+                                  token::get_name(name).get()).as_slice());
+        }
     }
 
     /// Resolves the given module path from the given root `module_`.
@@ -2947,7 +3186,9 @@ impl<'a> Resolver<'a> {
             Some(name_bindings)
                     if name_bindings.defined_in_namespace(namespace) => {
                 debug!("top name bindings succeeded");
-                return Success((Target::new(module_.clone(), name_bindings.clone()),
+                return Success((Target::new(module_.clone(),
+                                            name_bindings.clone(),
+                                            false),
                                false));
             }
             Some(_) | None => { /* Not found; continue. */ }
@@ -2987,7 +3228,10 @@ impl<'a> Resolver<'a> {
                     let name_bindings =
                         Rc::new(Resolver::create_name_bindings_from_module(module));
                     debug!("lower name bindings succeeded");
-                    return Success((Target::new(module_, name_bindings), false));
+                    return Success((Target::new(module_,
+                                                name_bindings,
+                                                false),
+                                    false));
                 }
             }
         }
@@ -3210,7 +3454,9 @@ impl<'a> Resolver<'a> {
             Some(name_bindings)
                     if name_bindings.defined_in_namespace(namespace) => {
                 debug!("(resolving name in module) found node as child");
-                return Success((Target::new(module_.clone(), name_bindings.clone()),
+                return Success((Target::new(module_.clone(),
+                                            name_bindings.clone(),
+                                            false),
                                false));
             }
             Some(_) | None => {
@@ -3261,7 +3507,10 @@ impl<'a> Resolver<'a> {
                 Some(module) => {
                     let name_bindings =
                         Rc::new(Resolver::create_name_bindings_from_module(module));
-                    return Success((Target::new(module_, name_bindings), false));
+                    return Success((Target::new(module_,
+                                                name_bindings,
+                                                false),
+                                    false));
                 }
             }
         }
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 85b6294ae34..5f54fbef74e 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -203,7 +203,8 @@ use middle::pat_util::*;
 use middle::resolve::DefMap;
 use middle::trans::adt;
 use middle::trans::base::*;
-use middle::trans::build::*;
+use middle::trans::build::{And, BitCast, Br, CondBr, GEPi, InBoundsGEP, Load};
+use middle::trans::build::{Mul, Not, Store, Sub, Switch, add_comment};
 use middle::trans::build;
 use middle::trans::callee;
 use middle::trans::cleanup;
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 8ea99a5cad3..2098f923dbe 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -47,11 +47,17 @@ use middle::trans::builder::{Builder, noname};
 use middle::trans::callee;
 use middle::trans::cleanup::{CleanupMethods, ScopeId};
 use middle::trans::cleanup;
-use middle::trans::common::*;
+use middle::trans::common::{Block, C_bool, C_bytes, C_i32, C_integral, C_nil};
+use middle::trans::common::{C_null, C_struct, C_u64, C_u8, C_uint, C_undef};
+use middle::trans::common::{CrateContext, ExternMap, FunctionContext};
+use middle::trans::common::{NodeInfo, Result, SubstP, monomorphize_type};
+use middle::trans::common::{node_id_type, param_substs, return_type_is_void};
+use middle::trans::common::{tydesc_info, type_is_immediate};
+use middle::trans::common::{type_is_zero_size, val_ty};
+use middle::trans::common;
 use middle::trans::consts;
 use middle::trans::controlflow;
 use middle::trans::datum;
-// use middle::trans::datum::{Datum, Lvalue, Rvalue, ByRef, ByValue};
 use middle::trans::debuginfo;
 use middle::trans::expr;
 use middle::trans::foreign;
@@ -1074,7 +1080,7 @@ pub fn raw_block<'a>(
                  is_lpad: bool,
                  llbb: BasicBlockRef)
                  -> &'a Block<'a> {
-    Block::new(llbb, is_lpad, None, fcx)
+    common::Block::new(llbb, is_lpad, None, fcx)
 }
 
 pub fn with_cond<'a>(
diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs
index d0709068687..ac4c56a1d1f 100644
--- a/src/librustc/middle/trans/cabi_mips.rs
+++ b/src/librustc/middle/trans/cabi_mips.rs
@@ -15,8 +15,8 @@ use std::cmp;
 use llvm;
 use llvm::{Integer, Pointer, Float, Double, Struct, Array};
 use llvm::{StructRetAttribute, ZExtAttribute};
+use middle::trans::cabi::{ArgType, FnType};
 use middle::trans::context::CrateContext;
-use middle::trans::cabi::*;
 use middle::trans::type_::Type;
 
 fn align_up_to(off: uint, a: uint) -> uint {
diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs
index d9812677d64..b5de0ae29d4 100644
--- a/src/librustc/middle/trans/cabi_x86.rs
+++ b/src/librustc/middle/trans/cabi_x86.rs
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-use syntax::abi::{OsWindows, OsMacos, OsiOS};
 use llvm::*;
-use super::cabi::*;
+use middle::trans::cabi::{ArgType, FnType};
+use middle::trans::type_::Type;
 use super::common::*;
 use super::machine::*;
-use middle::trans::type_::Type;
+use syntax::abi::{OsWindows, OsMacos, OsiOS};
 
 pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs
index 493aca0ddf0..32e481dd2d4 100644
--- a/src/librustc/middle/trans/cabi_x86_64.rs
+++ b/src/librustc/middle/trans/cabi_x86_64.rs
@@ -17,7 +17,7 @@ use llvm;
 use llvm::{Integer, Pointer, Float, Double};
 use llvm::{Struct, Array, Attribute};
 use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
-use middle::trans::cabi::*;
+use middle::trans::cabi::{ArgType, FnType};
 use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
 
diff --git a/src/librustc/middle/trans/cabi_x86_win64.rs b/src/librustc/middle/trans/cabi_x86_win64.rs
index e036ab6675d..6bcd9aefcc6 100644
--- a/src/librustc/middle/trans/cabi_x86_win64.rs
+++ b/src/librustc/middle/trans/cabi_x86_win64.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 use llvm::*;
-use super::cabi::*;
 use super::common::*;
 use super::machine::*;
+use middle::trans::cabi::{ArgType, FnType};
 use middle::trans::type_::Type;
 
 // Win64 ABI: http://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 56c1c665331..59148c5d4c3 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -37,7 +37,6 @@ use middle::trans::closure;
 use middle::trans::common;
 use middle::trans::common::*;
 use middle::trans::datum::*;
-use middle::trans::datum::{Datum, KindOps};
 use middle::trans::expr;
 use middle::trans::glue;
 use middle::trans::inline;
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index 193303f4d1c..7a1864448e2 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -22,10 +22,10 @@ use middle::trans::cleanup;
 use middle::trans::common::*;
 use middle::trans::consts;
 use middle::trans::datum;
-use middle::trans::debuginfo;
 use middle::trans::expr;
 use middle::trans::meth;
 use middle::trans::type_::Type;
+use middle::trans;
 use middle::ty;
 use middle::typeck::MethodCall;
 use util::ppaux::Repr;
@@ -66,7 +66,8 @@ pub fn trans_stmt<'a>(cx: &'a Block<'a>,
                 ast::DeclLocal(ref local) => {
                     bcx = init_local(bcx, &**local);
                     if cx.sess().opts.debuginfo == FullDebugInfo {
-                        debuginfo::create_local_var_metadata(bcx, &**local);
+                        trans::debuginfo::create_local_var_metadata(bcx,
+                                                                    &**local);
                     }
                 }
                 // Inner items are visited by `trans_item`/`trans_meth`.
@@ -154,7 +155,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
             }
             // if true { .. } [else { .. }]
             bcx = trans_block(bcx, &*thn, dest);
-            debuginfo::clear_source_location(bcx.fcx);
+            trans::debuginfo::clear_source_location(bcx.fcx);
         } else {
             let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
             trans.visit_block(&*thn, ());
@@ -163,7 +164,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
                 // if false { .. } else { .. }
                 Some(elexpr) => {
                     bcx = expr::trans_into(bcx, &*elexpr, dest);
-                    debuginfo::clear_source_location(bcx.fcx);
+                    trans::debuginfo::clear_source_location(bcx.fcx);
                 }
 
                 // if false { .. }
@@ -177,7 +178,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
     let name = format!("then-block-{}-", thn.id);
     let then_bcx_in = bcx.fcx.new_id_block(name.as_slice(), thn.id);
     let then_bcx_out = trans_block(then_bcx_in, &*thn, dest);
-    debuginfo::clear_source_location(bcx.fcx);
+    trans::debuginfo::clear_source_location(bcx.fcx);
 
     let next_bcx;
     match els {
@@ -198,7 +199,7 @@ pub fn trans_if<'a>(bcx: &'a Block<'a>,
 
     // Clear the source location because it is still set to whatever has been translated
     // right before.
-    debuginfo::clear_source_location(next_bcx.fcx);
+    trans::debuginfo::clear_source_location(next_bcx.fcx);
 
     next_bcx
 }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 40c4d9682c4..3a2c4857aad 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -51,7 +51,10 @@ use std::ops;
 use std::rc::Rc;
 use std::collections::{HashMap, HashSet};
 use syntax::abi;
-use syntax::ast::*;
+use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};
+use syntax::ast::{MutImmutable, MutMutable, Name, NamedField, NodeId};
+use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
+use syntax::ast::{Visibility};
 use syntax::ast_util::{is_local, lit_is_str};
 use syntax::ast_util;
 use syntax::attr;