about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-03-26 19:53:33 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-03-26 21:30:17 -0700
commit0a4d0f37ca97bb0b69f5f9e768269dde4acedae8 (patch)
tree75872ca3bdd242b58a2cd1d939f87604f32fc818
parent8b56a8380b6cca384f4ade7aa1a07b0c5eb77d60 (diff)
downloadrust-0a4d0f37ca97bb0b69f5f9e768269dde4acedae8.tar.gz
rust-0a4d0f37ca97bb0b69f5f9e768269dde4acedae8.zip
librustc: Enforce that `extern mod` directives come first, then `use` directives, then items.
Resolve them in this order as well.
-rw-r--r--src/compiletest/compiletest.rc13
-rw-r--r--src/libcore/core.rc80
-rw-r--r--src/libcore/managed.rs3
-rw-r--r--src/libcore/os.rs40
-rw-r--r--src/librustc/middle/resolve.rs344
-rw-r--r--src/librustc/rustc.rc38
-rw-r--r--src/librustdoc/rustdoc.rc8
-rw-r--r--src/librustpkg/rustpkg.rc6
-rw-r--r--src/libstd/std.rc2
-rw-r--r--src/libstd/test.rs2
-rw-r--r--src/libsyntax/parse/parser.rs106
-rw-r--r--src/libsyntax/syntax.rc4
-rw-r--r--src/test/auxiliary/extern_mod_ordering_lib.rs6
-rw-r--r--src/test/run-pass/extern-mod-ordering-exe.rs11
14 files changed, 330 insertions, 333 deletions
diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc
index 738045705a2..e213f4fc6da 100644
--- a/src/compiletest/compiletest.rc
+++ b/src/compiletest/compiletest.rc
@@ -22,12 +22,6 @@ extern mod std(vers = "0.6");
 
 use core::*;
 
-pub mod procsrv;
-pub mod util;
-pub mod header;
-pub mod runtest;
-pub mod common;
-pub mod errors;
 
 use std::getopts;
 use std::test;
@@ -43,6 +37,13 @@ use common::mode_debug_info;
 use common::mode;
 use util::logv;
 
+pub mod procsrv;
+pub mod util;
+pub mod header;
+pub mod runtest;
+pub mod common;
+pub mod errors;
+
 pub fn main() {
     let args = os::args();
     let config = parse_config(args);
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 35a016c3cb0..4d91e8f2993 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -65,6 +65,45 @@ they contained the following prologue:
 #[allow(deprecated_mutable_fields)];
 #[allow(deprecated_drop)];
 
+// Make core testable by not duplicating lang items. See #2912
+#[cfg(test)] extern mod realcore(name = "core", vers = "0.6");
+#[cfg(test)] pub use kinds = realcore::kinds;
+#[cfg(test)] pub use ops = realcore::ops;
+#[cfg(test)] pub use cmp = realcore::cmp;
+
+/* Reexported core operators */
+
+pub use kinds::{Const, Copy, Owned, Durable};
+pub use ops::{Drop};
+pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
+pub use ops::{BitAnd, BitOr, BitXor};
+pub use ops::{Shl, Shr, Index};
+
+
+/* Reexported types and traits */
+
+pub use option::{Option, Some, None};
+pub use result::{Result, Ok, Err};
+
+pub use path::Path;
+pub use path::GenericPath;
+pub use path::WindowsPath;
+pub use path::PosixPath;
+
+pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
+pub use str::{StrSlice};
+pub use container::{Container, Mutable};
+pub use vec::{CopyableVector, ImmutableVector};
+pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
+pub use vec::{OwnedVector, OwnedCopyableVector};
+pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
+pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
+
+pub use num::NumCast;
+pub use ptr::Ptr;
+pub use to_str::ToStr;
+pub use clone::Clone;
+
 // On Linux, link to the runtime with -lrt.
 #[cfg(target_os = "linux")]
 #[doc(hidden)]
@@ -130,12 +169,6 @@ pub mod managed;
 #[cfg(notest)] pub mod ops;
 #[cfg(notest)] pub mod cmp;
 
-// Make core testable by not duplicating lang items. See #2912
-#[cfg(test)] extern mod realcore(name = "core", vers = "0.6");
-#[cfg(test)] pub use kinds = realcore::kinds;
-#[cfg(test)] pub use ops = realcore::ops;
-#[cfg(test)] pub use cmp = realcore::cmp;
-
 
 /* Common traits */
 
@@ -189,39 +222,6 @@ pub mod condition;
 pub mod logging;
 pub mod util;
 
-/* Reexported core operators */
-
-pub use kinds::{Const, Copy, Owned, Durable};
-pub use ops::{Drop};
-pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
-pub use ops::{BitAnd, BitOr, BitXor};
-pub use ops::{Shl, Shr, Index};
-
-
-/* Reexported types and traits */
-
-pub use option::{Option, Some, None};
-pub use result::{Result, Ok, Err};
-
-pub use path::Path;
-pub use path::GenericPath;
-pub use path::WindowsPath;
-pub use path::PosixPath;
-
-pub use tuple::{CopyableTuple, ImmutableTuple, ExtendedTupleOps};
-pub use str::{StrSlice};
-pub use container::{Container, Mutable};
-pub use vec::{CopyableVector, ImmutableVector};
-pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
-pub use vec::{OwnedVector, OwnedCopyableVector};
-pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
-pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
-
-pub use num::NumCast;
-pub use ptr::Ptr;
-pub use to_str::ToStr;
-pub use clone::Clone;
-
 
 /* Unsupported interfaces */
 
@@ -241,7 +241,7 @@ pub mod rt;
 // 'core' so that macro-expanded references to core::error and such
 // can be resolved within libcore.
 #[doc(hidden)]
-pub mod core {
+mod core {
     pub use clone;
     pub use cmp;
     pub use condition;
diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs
index 4eda5e7b5e8..4de9f32e732 100644
--- a/src/libcore/managed.rs
+++ b/src/libcore/managed.rs
@@ -15,13 +15,12 @@ use ptr;
 #[cfg(notest)] use cmp::{Eq, Ord};
 
 pub mod raw {
+    use intrinsic::TyDesc;
 
     pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint;
     pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
     pub static RC_IMMORTAL : uint = 0x77777777;
 
-    use intrinsic::TyDesc;
-
     pub struct BoxHeaderRepr {
         ref_count: uint,
         type_desc: *TyDesc,
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index e93888f3eaf..b2e3606eff9 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -1167,14 +1167,6 @@ pub mod consts {
     #[cfg(windows)]
     pub use os::consts::windows::*;
 
-    pub mod unix {
-        pub static FAMILY: &'static str = "unix";
-    }
-
-    pub mod windows {
-        pub static FAMILY: &'static str = "windows";
-    }
-
     #[cfg(target_os = "macos")]
     pub use os::consts::macos::*;
 
@@ -1190,6 +1182,26 @@ pub mod consts {
     #[cfg(target_os = "win32")]
     pub use os::consts::win32::*;
 
+    #[cfg(target_arch = "x86")]
+    pub use os::consts::x86::*;
+
+    #[cfg(target_arch = "x86_64")]
+    pub use os::consts::x86_64::*;
+
+    #[cfg(target_arch = "arm")]
+    pub use os::consts::arm::*;
+
+    #[cfg(target_arch = "mips")]
+    use os::consts::mips::*;
+
+    pub mod unix {
+        pub static FAMILY: &'static str = "unix";
+    }
+
+    pub mod windows {
+        pub static FAMILY: &'static str = "windows";
+    }
+
     pub mod macos {
         pub static SYSNAME: &'static str = "macos";
         pub static DLL_PREFIX: &'static str = "lib";
@@ -1226,18 +1238,6 @@ pub mod consts {
     }
 
 
-    #[cfg(target_arch = "x86")]
-    pub use os::consts::x86::*;
-
-    #[cfg(target_arch = "x86_64")]
-    pub use os::consts::x86_64::*;
-
-    #[cfg(target_arch = "arm")]
-    pub use os::consts::arm::*;
-
-    #[cfg(target_arch = "mips")]
-    use os::consts::mips::*;
-
     pub mod x86 {
         pub static ARCH: &'static str = "x86";
     }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index bd507f4cf22..afc2c9f3352 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -127,6 +127,7 @@ pub enum PatternBindingMode {
     ArgumentIrrefutableMode(mode)
 }
 
+#[deriving(Eq)]
 pub enum Namespace {
     TypeNS,
     ValueNS
@@ -161,7 +162,6 @@ pub enum NameDefinition {
     NoNameDefinition,           //< The name was unbound.
     ChildNameDefinition(def),   //< The name identifies an immediate child.
     ImportNameDefinition(def)   //< The name identifies an import.
-
 }
 
 #[deriving(Eq)]
@@ -177,15 +177,9 @@ pub enum SelfBinding {
 
 pub type ResolveVisitor = vt<()>;
 
-#[deriving(Eq)]
-pub enum ImportDirectiveNS {
-    TypeNSOnly,
-    AnyNS
-}
-
 /// Contains data for specific types of import directives.
 pub enum ImportDirectiveSubclass {
-    SingleImport(ident /* target */, ident /* source */, ImportDirectiveNS),
+    SingleImport(ident /* target */, ident /* source */),
     GlobImport
 }
 
@@ -210,9 +204,9 @@ pub impl<T> ResolveResult<T> {
 }
 
 pub enum TypeParameters<'self> {
-    NoTypeParameters,                  //< No type parameters.
+    NoTypeParameters,                   //< No type parameters.
     HasTypeParameters(&'self Generics,  //< Type parameters.
-                      node_id,         //< ID of the enclosing item
+                      node_id,          //< ID of the enclosing item
 
                       // The index to start numbering the type parameters at.
                       // This is zero if this is the outermost set of type
@@ -458,6 +452,10 @@ pub struct Module {
     children: @mut LinearMap<ident, @mut NameBindings>,
     imports: @mut ~[@ImportDirective],
 
+    // The external module children of this node that were declared with
+    // `extern mod`.
+    external_module_children: @mut LinearMap<ident, @mut Module>,
+
     // The anonymous children of this node. Anonymous children are pseudo-
     // modules that are implicitly created around items contained within
     // blocks.
@@ -495,6 +493,7 @@ pub fn Module(parent_link: ParentLink,
         kind: kind,
         children: @mut LinearMap::new(),
         imports: @mut ~[],
+        external_module_children: @mut LinearMap::new(),
         anonymous_children: @mut LinearMap::new(),
         import_resolutions: @mut LinearMap::new(),
         glob_count: 0,
@@ -968,17 +967,23 @@ pub impl Resolver {
                 return (child, new_parent);
             }
             Some(child) => {
-                // Enforce the duplicate checking mode. If we're requesting
-                // duplicate module checking, check that there isn't a module
-                // in the module with the same name. If we're requesting
-                // duplicate type checking, check that there isn't a type in
-                // the module with the same name. If we're requesting
-                // duplicate value checking, check that there isn't a value in
-                // the module with the same name. If we're requesting
-                // duplicate type checking and duplicate value checking, check
-                // that there isn't a duplicate type and a duplicate value
-                // with the same name. If no duplicate checking was requested
-                // at all, do nothing.
+                // Enforce the duplicate checking mode:
+                //
+                // * If we're requesting duplicate module checking, check that
+                //   there isn't a module in the module with the same name.
+                //
+                // * If we're requesting duplicate type checking, check that
+                //   there isn't a type in the module with the same name.
+                //
+                // * If we're requesting duplicate value checking, check that
+                //   there isn't a value in the module with the same name.
+                //
+                // * If we're requesting duplicate type checking and duplicate
+                //   value checking, check that there isn't a duplicate type
+                //   and a duplicate value with the same name.
+                //
+                // * If no duplicate checking was requested at all, do
+                //   nothing.
 
                 let mut is_duplicate = false;
                 match duplicate_checking_mode {
@@ -1432,16 +1437,10 @@ pub impl Resolver {
                     let module_ = self.get_module_from_parent(parent);
                     let state = @mut ImportState();
                     match view_path.node {
-                        view_path_simple(binding, full_path, ns, _) => {
-                            let ns = match ns {
-                                module_ns => TypeNSOnly,
-                                type_value_ns => AnyNS
-                            };
-
+                        view_path_simple(binding, full_path, _, _) => {
                             let source_ident = *full_path.idents.last();
                             let subclass = @SingleImport(binding,
-                                                         source_ident,
-                                                         ns);
+                                                         source_ident);
                             self.build_import_directive(privacy,
                                                         module_,
                                                         module_path,
@@ -1452,9 +1451,7 @@ pub impl Resolver {
                         view_path_list(_, ref source_idents, _) => {
                             for (*source_idents).each |source_ident| {
                                 let name = source_ident.node.name;
-                                let subclass = @SingleImport(name,
-                                                             name,
-                                                             AnyNS);
+                                let subclass = @SingleImport(name, name);
                                 self.build_import_directive(privacy,
                                                             module_,
                                                             copy module_path,
@@ -1479,25 +1476,21 @@ pub impl Resolver {
                 match find_extern_mod_stmt_cnum(self.session.cstore,
                                                 node_id) {
                     Some(crate_id) => {
-                        let (child_name_bindings, new_parent) =
-                            self.add_child(name, parent, ForbidDuplicateTypes,
-                                           view_item.span);
-
                         let def_id = def_id { crate: crate_id, node: 0 };
                         let parent_link = ModuleParentLink
-                            (self.get_module_from_parent(new_parent), name);
-
-                        child_name_bindings.define_module(Public,
-                                                          parent_link,
+                            (self.get_module_from_parent(parent), name);
+                        let external_module = @mut Module(parent_link,
                                                           Some(def_id),
-                                                          NormalModuleKind,
-                                                          view_item.span);
-                        self.build_reduced_graph_for_external_crate
-                            (child_name_bindings.get_module());
-                    }
-                    None => {
-                        /* Ignore. */
+                                                          NormalModuleKind);
+
+                        parent.external_module_children.insert(
+                            name,
+                            external_module);
+
+                        self.build_reduced_graph_for_external_crate(
+                            external_module);
                     }
+                    None => {}  // Ignore.
                 }
             }
         }
@@ -1869,7 +1862,7 @@ pub impl Resolver {
         // the appropriate flag.
 
         match *subclass {
-            SingleImport(target, _, _) => {
+            SingleImport(target, _) => {
                 debug!("(building import directive) building import \
                         directive: privacy %? %s::%s",
                        privacy,
@@ -2020,7 +2013,7 @@ pub impl Resolver {
                                         subclass: ImportDirectiveSubclass)
                                      -> @~str {
         match subclass {
-            SingleImport(_target, source, _ns) => self.session.str_of(source),
+            SingleImport(_target, source) => self.session.str_of(source),
             GlobImport => @~"*"
         }
     }
@@ -2080,21 +2073,13 @@ pub impl Resolver {
                 // within. Attempt to resolve the import within it.
 
                 match *import_directive.subclass {
-                    SingleImport(target, source, AnyNS) => {
+                    SingleImport(target, source) => {
                         resolution_result =
                             self.resolve_single_import(module_,
                                                        containing_module,
                                                        target,
                                                        source);
                     }
-                    SingleImport(target, source, TypeNSOnly) => {
-                        resolution_result =
-                            self.resolve_single_module_import(
-                                module_,
-                                containing_module,
-                                target,
-                                source);
-                    }
                     GlobImport => {
                         let span = import_directive.span;
                         let privacy = import_directive.privacy;
@@ -2139,6 +2124,19 @@ pub impl Resolver {
         return resolution_result;
     }
 
+    fn create_name_bindings_from_module(module: @mut Module) -> NameBindings {
+        NameBindings {
+            type_def: Some(TypeNsDef {
+                privacy: Public,
+                module_def: Some(module),
+                type_def: None,
+            }),
+            value_def: None,
+            type_span: None,
+            value_span: None,
+        }
+    }
+
     fn resolve_single_import(@mut self,
                              module_: @mut Module,
                              containing_module: @mut Module,
@@ -2261,6 +2259,25 @@ pub impl Resolver {
             }
         }
 
+        // If we didn't find a result in the type namespace, search the
+        // external modules.
+        match type_result {
+            BoundResult(*) => {}
+            _ => {
+                match containing_module.external_module_children
+                                       .find(&source) {
+                    None => {} // Continue.
+                    Some(module) => {
+                        let name_bindings =
+                            @mut Resolver::create_name_bindings_from_module(
+                                *module);
+                        type_result = BoundResult(containing_module,
+                                                  name_bindings);
+                    }
+                }
+            }
+        }
+
         // We've successfully resolved the import. Write the results in.
         fail_unless!(module_.import_resolutions.contains_key(&target));
         let import_resolution = module_.import_resolutions.get(&target);
@@ -2332,135 +2349,9 @@ pub impl Resolver {
         return Success(());
     }
 
-    fn resolve_single_module_import(@mut self,
-                                    module_: @mut Module,
-                                    containing_module: @mut Module,
-                                    target: ident,
-                                    source: ident)
-                                 -> ResolveResult<()> {
-        debug!("(resolving single module import) resolving `%s` = `%s::%s` \
-                from `%s`",
-               *self.session.str_of(target),
-               self.module_to_str(containing_module),
-               *self.session.str_of(source),
-               self.module_to_str(module_));
-
-        // We need to resolve the module namespace for this to succeed.
-        let mut module_result = UnknownResult;
-
-        // Search for direct children of the containing module.
-        match containing_module.children.find(&source) {
-            None => {
-                // Continue.
-            }
-            Some(child_name_bindings) => {
-                if child_name_bindings.defined_in_namespace(TypeNS) {
-                    module_result = BoundResult(containing_module,
-                                                *child_name_bindings);
-                }
-            }
-        }
-
-        // Unless we managed to find a result, search imports as well.
-        match module_result {
-            BoundResult(*) => {
-                // Continue.
-            }
-            _ => {
-                // If there is an unresolved glob at this point in the
-                // containing module, bail out. We don't know enough to be
-                // able to resolve this import.
-
-                if containing_module.glob_count > 0 {
-                    debug!("(resolving single module import) unresolved \
-                            glob; bailing out");
-                    return Indeterminate;
-                }
-
-                // Now search the exported imports within the containing
-                // module.
-                match containing_module.import_resolutions.find(&source) {
-                    None => {
-                        // The containing module definitely doesn't have an
-                        // exported import with the name in question. We can
-                        // therefore accurately report that the names are
-                        // unbound.
-
-                        if module_result.is_unknown() {
-                            module_result = UnboundResult;
-                        }
-                    }
-                    Some(import_resolution)
-                            if import_resolution.outstanding_references
-                                == 0 => {
-                        // The name is an import which has been fully
-                        // resolved. We can, therefore, just follow it.
-
-                        if module_result.is_unknown() {
-                            match (*import_resolution).target_for_namespace(
-                                    TypeNS) {
-                                None => {
-                                    module_result = UnboundResult;
-                                }
-                                Some(target) => {
-                                    import_resolution.state.used = true;
-                                    module_result = BoundResult
-                                        (target.target_module,
-                                         target.bindings);
-                                }
-                            }
-                        }
-                    }
-                    Some(_) => {
-                        // The import is unresolved. Bail out.
-                        debug!("(resolving single module import) unresolved \
-                                import; bailing out");
-                        return Indeterminate;
-                    }
-                }
-            }
-        }
-
-        // We've successfully resolved the import. Write the results in.
-        fail_unless!(module_.import_resolutions.contains_key(&target));
-        let import_resolution = module_.import_resolutions.get(&target);
-
-        match module_result {
-            BoundResult(target_module, name_bindings) => {
-                debug!("(resolving single import) found module binding");
-                import_resolution.type_target =
-                    Some(Target(target_module, name_bindings));
-            }
-            UnboundResult => {
-                debug!("(resolving single import) didn't find module \
-                        binding");
-            }
-            UnknownResult => {
-                fail!(~"module result should be known at this point");
-            }
-        }
-
-        let i = import_resolution;
-        if i.type_target.is_none() {
-          // If this name wasn't found in the type namespace, it's
-          // definitely unresolved.
-          return Failed;
-        }
-
-        fail_unless!(import_resolution.outstanding_references >= 1);
-        import_resolution.outstanding_references -= 1;
-
-        debug!("(resolving single module import) successfully resolved \
-               import");
-        return Success(());
-    }
-
-
-    /**
-     * Resolves a glob import. Note that this function cannot fail; it either
-     * succeeds or bails out (as importing * from an empty module or a module
-     * that exports nothing is valid).
-     */
+    // Resolves a glob import. Note that this function cannot fail; it either
+    // succeeds or bails out (as importing * from an empty module or a module
+    // that exports nothing is valid).
     fn resolve_glob_import(@mut self,
                            privacy: Privacy,
                            module_: @mut Module,
@@ -2535,8 +2426,8 @@ pub impl Resolver {
             }
         }
 
-        // Add all children from the containing module.
-        for containing_module.children.each |&(ident, name_bindings)| {
+        let merge_import_resolution = |ident,
+                                       name_bindings: @mut NameBindings| {
             let mut dest_import_resolution;
             match module_.import_resolutions.find(ident) {
                 None => {
@@ -2563,13 +2454,26 @@ pub impl Resolver {
             if name_bindings.defined_in_public_namespace(ValueNS) {
                 debug!("(resolving glob import) ... for value target");
                 dest_import_resolution.value_target =
-                    Some(Target(containing_module, *name_bindings));
+                    Some(Target(containing_module, name_bindings));
             }
             if name_bindings.defined_in_public_namespace(TypeNS) {
                 debug!("(resolving glob import) ... for type target");
                 dest_import_resolution.type_target =
-                    Some(Target(containing_module, *name_bindings));
+                    Some(Target(containing_module, name_bindings));
             }
+        };
+
+        // Add all children from the containing module.
+        for containing_module.children.each |&(ident, name_bindings)| {
+            merge_import_resolution(ident, *name_bindings);
+        }
+
+        // Add external module children from the containing module.
+        for containing_module.external_module_children.each
+                |&(ident, module)| {
+            let name_bindings =
+                @mut Resolver::create_name_bindings_from_module(*module);
+            merge_import_resolution(ident, name_bindings);
         }
 
         debug!("(resolving glob import) successfully resolved import");
@@ -2759,7 +2663,6 @@ pub impl Resolver {
 
         // The current module node is handled specially. First, check for
         // its immediate children.
-
         match module_.children.find(&name) {
             Some(name_bindings)
                     if name_bindings.defined_in_namespace(namespace) => {
@@ -2772,7 +2675,6 @@ pub impl Resolver {
         // all its imports in the usual way; this is because chains of
         // adjacent import statements are processed as though they mutated the
         // current scope.
-
         match module_.import_resolutions.find(&name) {
             None => {
                 // Not found; continue.
@@ -2795,6 +2697,19 @@ pub impl Resolver {
             }
         }
 
+        // Search for external modules.
+        if namespace == TypeNS {
+            match module_.external_module_children.find(&name) {
+                None => {}
+                Some(module) => {
+                    let name_bindings =
+                        @mut Resolver::create_name_bindings_from_module(
+                            *module);
+                    return Success(Target(module_, name_bindings));
+                }
+            }
+        }
+
         // Finally, proceed up the scope chain looking for parent modules.
         let mut search_module = module_;
         loop {
@@ -3027,7 +2942,8 @@ pub impl Resolver {
         // Check the list of resolved imports.
         match module_.import_resolutions.find(&name) {
             Some(import_resolution) => {
-                if import_resolution.outstanding_references != 0 {
+                if import_resolution.privacy == Public &&
+                        import_resolution.outstanding_references != 0 {
                     debug!("(resolving name in module) import \
                             unresolved; bailing out");
                     return Indeterminate;
@@ -3054,8 +2970,19 @@ pub impl Resolver {
                     }
                 }
             }
-            None => {
-                // Continue.
+            None => {} // Continue.
+        }
+
+        // Finally, search through external children.
+        if namespace == TypeNS {
+            match module_.external_module_children.find(&name) {
+                None => {}
+                Some(module) => {
+                    let name_bindings =
+                        @mut Resolver::create_name_bindings_from_module(
+                            *module);
+                    return Success(Target(module_, name_bindings));
+                }
             }
         }
 
@@ -4541,20 +4468,31 @@ pub impl Resolver {
                             (Some(_), _) | (None, _) => {
                                 // This can happen with external impls, due to
                                 // the imperfect way we read the metadata.
-
-                                return NoNameDefinition;
                             }
                         }
                     }
-                    None => {
-                        return NoNameDefinition;
-                    }
+                    None => {}
                 }
             }
-            Some(_) | None => {
-                return NoNameDefinition;
+            Some(_) | None => {}    // Continue.
+        }
+
+        // Finally, search through external children.
+        if namespace == TypeNS {
+            match containing_module.external_module_children.find(&name) {
+                None => {}
+                Some(module) => {
+                    match module.def_id {
+                        None => {} // Continue.
+                        Some(def_id) => {
+                            return ChildNameDefinition(def_mod(def_id));
+                        }
+                    }
+                }
             }
         }
+
+        return NoNameDefinition;
     }
 
     fn intern_module_part_of_path(@mut self, path: @path) -> ~[ident] {
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index 5b4d3be1264..e3df3b692fb 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -28,11 +28,26 @@
 #[no_core];
 
 extern mod core(vers = "0.6");
-use core::*;
-
 extern mod std(vers = "0.6");
 extern mod syntax(vers = "0.6");
 
+use core::prelude::*;
+
+use driver::driver::{host_triple, optgroups, early_error};
+use driver::driver::{str_input, file_input, build_session_options};
+use driver::driver::{build_session, build_configuration, parse_pretty};
+use driver::driver::{pp_mode, pretty_print_input, list_metadata};
+use driver::driver::{compile_input};
+use driver::session;
+use middle::lint;
+
+use core::io::ReaderUtil;
+use core::result::{Ok, Err};
+use std::getopts::{groups, opt_present};
+use std::getopts;
+use syntax::codemap;
+use syntax::diagnostic;
+
 pub mod middle {
     pub mod trans {
         pub mod macros;
@@ -123,23 +138,6 @@ pub mod lib {
     pub mod llvm;
 }
 
-use core::prelude::*;
-
-use driver::driver::{host_triple, optgroups, early_error};
-use driver::driver::{str_input, file_input, build_session_options};
-use driver::driver::{build_session, build_configuration, parse_pretty};
-use driver::driver::{pp_mode, pretty_print_input, list_metadata};
-use driver::driver::{compile_input};
-use driver::session;
-use middle::lint;
-
-use core::io::ReaderUtil;
-use core::result::{Ok, Err};
-use std::getopts::{groups, opt_present};
-use std::getopts;
-use syntax::codemap;
-use syntax::diagnostic;
-
 pub fn version(argv0: &str) {
     let mut vers = ~"unknown version";
     let env_vers = env!("CFG_VERSION");
@@ -202,7 +200,7 @@ pub fn describe_debug_flags() {
 
 pub fn run_compiler(args: &~[~str], demitter: diagnostic::Emitter) {
     // Don't display log spew by default. Can override with RUST_LOG.
-    logging::console_off();
+    ::core::logging::console_off();
 
     let mut args = /*bad*/copy *args;
     let binary = args.shift();
diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc
index 9eb3e816628..9b19063a908 100644
--- a/src/librustdoc/rustdoc.rc
+++ b/src/librustdoc/rustdoc.rc
@@ -28,6 +28,10 @@ extern mod std(vers = "0.6");
 extern mod rustc(vers = "0.6");
 extern mod syntax(vers = "0.6");
 
+use config::Config;
+use doc::Item;
+use doc::ItemUtils;
+
 use core::*;
 
 pub mod pass;
@@ -59,10 +63,6 @@ pub mod escape_pass;
 pub mod prune_private_pass;
 pub mod util;
 
-use doc::ItemUtils;
-use doc::Item;
-use config::Config;
-
 pub fn main() {
     let args = os::args();
 
diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc
index 35698bb235a..50414bf2d1c 100644
--- a/src/librustpkg/rustpkg.rc
+++ b/src/librustpkg/rustpkg.rc
@@ -27,6 +27,7 @@ extern mod rustc(vers = "0.6");
 extern mod syntax(vers = "0.6");
 
 use core::*;
+use core::container::Map;
 use core::hashmap::linear::LinearMap;
 use core::io::{ReaderUtil, WriterUtil};
 use rustc::driver::{driver, session};
@@ -35,13 +36,12 @@ use std::net::url;
 use std::{json, semver, getopts};
 use syntax::codemap::spanned;
 use syntax::{ast, attr, codemap, diagnostic, parse, visit};
-use core::container::Map;
+
+use util::Package;
 
 mod usage;
 mod util;
 
-use util::Package;
-
 struct PackageScript {
     id: ~str,
     name: ~str,
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 7d46e73a697..a0ab714de05 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -33,7 +33,7 @@ not required in or otherwise suitable for the core library.
 #[no_core];
 
 extern mod core(vers = "0.6");
-use core::*;
+use core::prelude::*;
 
 pub mod uv_ll;
 
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index ded4d6fd1b4..93170668c13 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -563,7 +563,7 @@ pub fn run_test(force_ignore: bool,
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: SharedChan<MonitorMsg>,
                       testfn: ~fn()) {
-        let testfn_cell = ::cell::Cell(testfn);
+        let testfn_cell = ::core::cell::Cell(testfn);
         do task::spawn {
             let mut result_future = None; // task::future_result(builder);
             task::task().unlinked().future_result(|+r| {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index cc0196d18de..53d618e3340 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -120,6 +120,7 @@ pub enum item_or_view_item {
     iovi_view_item(@view_item)
 }
 
+#[deriving(Eq)]
 enum view_item_parse_mode {
     VIEW_ITEMS_AND_ITEMS_ALLOWED,
     FOREIGN_ITEMS_ALLOWED,
@@ -4324,48 +4325,91 @@ pub impl Parser {
             VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED => true,
             FOREIGN_ITEMS_ALLOWED => false
         };
-
-        let restricted_to_imports = match mode {
-            IMPORTS_AND_ITEMS_ALLOWED => true,
-            VIEW_ITEMS_AND_ITEMS_ALLOWED |
-            FOREIGN_ITEMS_ALLOWED => false
-        };
-
         let foreign_items_allowed = match mode {
             FOREIGN_ITEMS_ALLOWED => true,
             VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED => false
         };
 
+        // First, parse view items.
         let mut (view_items, items, foreign_items) = (~[], ~[], ~[]);
-        loop {
-            match self.parse_item_or_view_item(/*bad*/ copy attrs,
-                                               items_allowed,
-                                               foreign_items_allowed,
-                                               macros_allowed) {
-                iovi_none =>
-                    break,
-                iovi_view_item(view_item) => {
-                    if restricted_to_imports {
-                            match view_item.node {
-                                view_item_use(*) => {}
-                                view_item_extern_mod(*) =>
-                                    self.fatal(~"\"extern mod\" \
-                                                 declarations are not \
-                                                 allowed here")
+        let mut done = false;
+        if mode != FOREIGN_ITEMS_ALLOWED {
+            let mut extern_mod_allowed = match mode {
+                VIEW_ITEMS_AND_ITEMS_ALLOWED => true,
+                IMPORTS_AND_ITEMS_ALLOWED => false,
+                FOREIGN_ITEMS_ALLOWED => {
+                    self.bug(~"couldn't get here with FOREIGN_ITEMS_ALLOWED")
+                }
+            };
+
+            loop {
+                match self.parse_item_or_view_item(/*bad*/ copy attrs,
+                                                   items_allowed,
+                                                   foreign_items_allowed,
+                                                   macros_allowed) {
+                    iovi_none => {
+                        done = true;
+                        break;
+                    }
+                    iovi_view_item(view_item) => {
+                        match view_item.node {
+                            view_item_use(*) => {
+                                // `extern mod` must precede `use`.
+                                extern_mod_allowed = false;
+                            }
+                            view_item_extern_mod(*)
+                                    if !extern_mod_allowed => {
+                                self.span_err(view_item.span,
+                                              ~"\"extern mod\" \
+                                                declarations are not \
+                                                allowed here");
                             }
+                            view_item_extern_mod(*) => {}
+                        }
+                        view_items.push(view_item);
+                    }
+                    iovi_item(item) => {
+                        fail_unless!(items_allowed);
+                        items.push(item);
+                        attrs = self.parse_outer_attributes();
+                        break;
+                    }
+                    iovi_foreign_item(foreign_item) => {
+                        fail_unless!(foreign_items_allowed);
+                        foreign_items.push(foreign_item);
+                        attrs = self.parse_outer_attributes();
+                        break;
                     }
-                    view_items.push(view_item);
-                }
-                iovi_item(item) => {
-                    fail_unless!(items_allowed);
-                    items.push(item)
                 }
-                iovi_foreign_item(foreign_item) => {
-                    fail_unless!(foreign_items_allowed);
-                    foreign_items.push(foreign_item);
+                attrs = self.parse_outer_attributes();
+            }
+        }
+
+        // Next, parse items.
+        if !done {
+            loop {
+                match self.parse_item_or_view_item(/*bad*/ copy attrs,
+                                                   items_allowed,
+                                                   foreign_items_allowed,
+                                                   macros_allowed) {
+                    iovi_none => break,
+                    iovi_view_item(view_item) => {
+                        self.span_err(view_item.span,
+                                      ~"`use` and `extern mod` declarations \
+                                        must precede items");
+                        view_items.push(view_item);
+                    }
+                    iovi_item(item) => {
+                        fail_unless!(items_allowed);
+                        items.push(item)
+                    }
+                    iovi_foreign_item(foreign_item) => {
+                        fail_unless!(foreign_items_allowed);
+                        foreign_items.push(foreign_item);
+                    }
                 }
+                attrs = self.parse_outer_attributes();
             }
-            attrs = self.parse_outer_attributes();
         }
 
         ParsedItemsAndViewItems {
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
index 19ed6809326..feff4b0616a 100644
--- a/src/libsyntax/syntax.rc
+++ b/src/libsyntax/syntax.rc
@@ -26,10 +26,10 @@
 #[no_core];
 
 extern mod core(vers = "0.6");
-use core::*;
-
 extern mod std(vers = "0.6");
 
+use core::*;
+
 pub mod syntax {
     pub use ext;
     pub use parse;
diff --git a/src/test/auxiliary/extern_mod_ordering_lib.rs b/src/test/auxiliary/extern_mod_ordering_lib.rs
new file mode 100644
index 00000000000..8276cea465f
--- /dev/null
+++ b/src/test/auxiliary/extern_mod_ordering_lib.rs
@@ -0,0 +1,6 @@
+#[crate_type="lib"];
+
+pub mod extern_mod_ordering_lib {
+    pub fn f() {}
+}
+
diff --git a/src/test/run-pass/extern-mod-ordering-exe.rs b/src/test/run-pass/extern-mod-ordering-exe.rs
new file mode 100644
index 00000000000..b60302277b3
--- /dev/null
+++ b/src/test/run-pass/extern-mod-ordering-exe.rs
@@ -0,0 +1,11 @@
+// aux-build:extern_mod_ordering_lib.rs
+// xfail-fast
+
+extern mod extern_mod_ordering_lib;
+
+use extern_mod_ordering_lib::extern_mod_ordering_lib;
+
+fn main() {
+    extern_mod_ordering_lib::f();
+}
+