about summary refs log tree commit diff
path: root/src/librustc_resolve/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_resolve/lib.rs')
-rw-r--r--src/librustc_resolve/lib.rs1621
1 files changed, 178 insertions, 1443 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c168709eec5..10756f21551 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -26,11 +26,9 @@ extern crate rustc;
 
 use self::PatternBindingMode::*;
 use self::Namespace::*;
-use self::NamespaceError::*;
 use self::NamespaceResult::*;
 use self::NameDefinition::*;
 use self::ImportDirectiveSubclass::*;
-use self::ReducedGraphParent::*;
 use self::ResolveResult::*;
 use self::FallbackSuggestion::*;
 use self::TypeParameters::*;
@@ -40,7 +38,6 @@ use self::UseLexicalScopeFlag::*;
 use self::ModulePrefixResult::*;
 use self::NameSearchType::*;
 use self::BareIdentifierPatternResolution::*;
-use self::DuplicateCheckingMode::*;
 use self::ParentLink::*;
 use self::ModuleKind::*;
 use self::TraitReferenceType::*;
@@ -60,46 +57,45 @@ use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
 use rustc::util::lev_distance::lev_distance;
 
 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
-use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
+use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
 use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
 use syntax::ast::{ExprPath, ExprStruct, FnDecl};
-use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
+use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
 use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
 use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
 use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
-use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
+use syntax::ast::{MethodImplItem, Mod, Name, NodeId};
 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
-use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
-use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
-use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
-use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
-use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
+use syntax::ast::{PatRange, PatStruct, Path};
+use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
+use syntax::ast::{RegionTyParamBound, StructField};
+use syntax::ast::{TraitRef, TraitTyParamBound};
+use syntax::ast::{Ty, TyBool, TyChar, TyClosure, TyF32};
 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
-use syntax::ast::{TypeImplItem, UnnamedField};
-use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
-use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
-use syntax::ast::{Visibility};
+use syntax::ast::{TypeImplItem};
 use syntax::ast;
 use syntax::ast_map;
-use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
+use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
 use syntax::attr::AttrMetaMethods;
 use syntax::ext::mtwt;
 use syntax::parse::token::{mod, special_names, special_idents};
-use syntax::codemap::{Span, DUMMY_SP, Pos};
+use syntax::codemap::{Span, Pos};
 use syntax::owned_slice::OwnedSlice;
 use syntax::visit::{mod, Visitor};
 
 use std::collections::{HashMap, HashSet};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::cell::{Cell, RefCell};
+use std::fmt;
 use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::uint;
 
 mod check_unused;
 mod record_exports;
+mod build_reduced_graph;
 
 #[deriving(Copy)]
 struct BindingInfo {
@@ -123,14 +119,6 @@ enum Namespace {
     ValueNS
 }
 
-#[deriving(Copy, PartialEq)]
-enum NamespaceError {
-    NoError,
-    ModuleError,
-    TypeError,
-    ValueError
-}
-
 /// A NamespaceResult represents the result of resolving an import in
 /// a particular namespace. The result is either definitely-resolved,
 /// definitely- unresolved, or unknown.
@@ -191,28 +179,12 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
 }
 
 /// Contains data for specific types of import directives.
-#[deriving(Copy)]
+#[deriving(Copy,Show)]
 enum ImportDirectiveSubclass {
     SingleImport(Name /* target */, Name /* source */),
     GlobImport
 }
 
-/// The context that we thread through while building the reduced graph.
-#[deriving(Clone)]
-enum ReducedGraphParent {
-    ModuleReducedGraphParent(Rc<Module>)
-}
-
-impl ReducedGraphParent {
-    fn module(&self) -> Rc<Module> {
-        match *self {
-            ModuleReducedGraphParent(ref m) => {
-                m.clone()
-            }
-        }
-    }
-}
-
 type ErrorMessage = Option<(Span, String)>;
 
 enum ResolveResult<T> {
@@ -314,17 +286,6 @@ enum BareIdentifierPatternResolution {
     BareIdentifierPatternUnresolved
 }
 
-// Specifies how duplicates should be handled when adding a child item if
-// another item exists with the same name in some namespace.
-#[deriving(Copy, PartialEq)]
-enum DuplicateCheckingMode {
-    ForbidDuplicateModules,
-    ForbidDuplicateTypesAndModules,
-    ForbidDuplicateValues,
-    ForbidDuplicateTypesAndValues,
-    OverwriteDuplicates
-}
-
 /// One local scope.
 #[deriving(Show)]
 struct Rib {
@@ -345,13 +306,11 @@ impl Rib {
 #[deriving(Show,PartialEq,Clone,Copy)]
 enum Shadowable {
     Always,
-    /// Means that the recorded import obeys the glob shadowing rules, i.e., can
-    /// only be shadowed by another glob import.
-    Glob,
     Never
 }
 
 /// One import directive.
+#[deriving(Show)]
 struct ImportDirective {
     module_path: Vec<Name>,
     subclass: ImportDirectiveSubclass,
@@ -381,7 +340,7 @@ impl ImportDirective {
 }
 
 /// The item that an import resolves to.
-#[deriving(Clone)]
+#[deriving(Clone,Show)]
 struct Target {
     target_module: Rc<Module>,
     bindings: Rc<NameBindings>,
@@ -402,6 +361,7 @@ impl Target {
 }
 
 /// An ImportResolution represents a particular `use` directive.
+#[deriving(Show)]
 struct ImportResolution {
     /// Whether this resolution came from a `use` or a `pub use`. Note that this
     /// should *not* be used whenever resolution is being performed, this is
@@ -462,10 +422,26 @@ impl ImportResolution {
 
         target.unwrap().shadowable
     }
+
+    fn set_target_and_id(&mut self,
+                         namespace: Namespace,
+                         target: Option<Target>,
+                         id: NodeId) {
+        match namespace {
+            TypeNS  => {
+                self.type_target = target;
+                self.type_id = id;
+            }
+            ValueNS => {
+                self.value_target = target;
+                self.value_id = id;
+            }
+        }
+    }
 }
 
 /// The link from a module up to its nearest parent node.
-#[deriving(Clone)]
+#[deriving(Clone,Show)]
 enum ParentLink {
     NoParentLink,
     ModuleParentLink(Weak<Module>, Name),
@@ -473,7 +449,7 @@ enum ParentLink {
 }
 
 /// The type of module this is.
-#[deriving(Copy, PartialEq)]
+#[deriving(Copy, PartialEq, Show)]
 enum ModuleKind {
     NormalModuleKind,
     TraitModuleKind,
@@ -555,6 +531,15 @@ impl Module {
     }
 }
 
+impl fmt::Show for Module {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}, kind: {}, {}",
+               self.def_id,
+               self.kind,
+               if self.is_public { "public" } else { "private" } )
+    }
+}
+
 bitflags! {
     #[deriving(Show)]
     flags DefModifiers: u8 {
@@ -564,7 +549,7 @@ bitflags! {
 }
 
 // Records a possibly-private type definition.
-#[deriving(Clone)]
+#[deriving(Clone,Show)]
 struct TypeNsDef {
     modifiers: DefModifiers, // see note in ImportResolution about how to use this
     module_def: Option<Rc<Module>>,
@@ -582,6 +567,7 @@ struct ValueNsDef {
 
 // Records the definitions (at most one for each namespace) that a name is
 // bound to.
+#[deriving(Show)]
 struct NameBindings {
     type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
     value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
@@ -852,15 +838,6 @@ impl PrimitiveTypeTable {
     }
 }
 
-
-fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
-    match ns {
-        NoError                 => "",
-        ModuleError | TypeError => "type or module",
-        ValueError              => "value",
-    }
-}
-
 /// The main resolver class.
 struct Resolver<'a, 'tcx:'a> {
     session: &'a Session,
@@ -926,46 +903,6 @@ struct Resolver<'a, 'tcx:'a> {
     used_crates: HashSet<CrateNum>,
 }
 
-struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
-    resolver: &'a mut Resolver<'b, 'tcx>,
-    parent: ReducedGraphParent
-}
-
-impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
-
-    fn visit_item(&mut self, item: &Item) {
-        let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
-        let old_parent = replace(&mut self.parent, p);
-        visit::walk_item(self, item);
-        self.parent = old_parent;
-    }
-
-    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
-        let parent = self.parent.clone();
-        self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
-                                                           parent.clone(),
-                                                           |r| {
-            let mut v = BuildReducedGraphVisitor {
-                resolver: r,
-                parent: parent.clone()
-            };
-            visit::walk_foreign_item(&mut v, foreign_item);
-        })
-    }
-
-    fn visit_view_item(&mut self, view_item: &ViewItem) {
-        self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
-    }
-
-    fn visit_block(&mut self, block: &Block) {
-        let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
-        let old_parent = replace(&mut self.parent, np);
-        visit::walk_block(self, block);
-        self.parent = old_parent;
-    }
-
-}
-
 #[deriving(PartialEq)]
 enum FallbackChecks {
     Everything,
@@ -1034,1195 +971,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    //
-    // Reduced graph building
-    //
-    // Here we build the "reduced graph": the graph of the module tree without
-    // any imports resolved.
-    //
-
-    /// Constructs the reduced graph for the entire crate.
-    fn build_reduced_graph(&mut self, krate: &ast::Crate) {
-        let parent = ModuleReducedGraphParent(self.graph_root.get_module());
-        let mut visitor = BuildReducedGraphVisitor {
-            resolver: self,
-            parent: parent
-        };
-        visit::walk_crate(&mut visitor, krate);
-    }
-
-    /// Adds a new child item to the module definition of the parent node and
-    /// returns its corresponding name bindings as well as the current parent.
-    /// Or, if we're inside a block, creates (or reuses) an anonymous module
-    /// corresponding to the innermost block ID and returns the name bindings
-    /// as well as the newly-created parent.
-    ///
-    /// # Panics
-    ///
-    /// Panics if this node does not have a module definition and we are not inside
-    /// a block.
-    fn add_child(&self,
-                 name: Name,
-                 reduced_graph_parent: ReducedGraphParent,
-                 duplicate_checking_mode: DuplicateCheckingMode,
-                 // For printing errors
-                 sp: Span)
-                 -> Rc<NameBindings> {
-        // If this is the immediate descendant of a module, then we add the
-        // child name directly. Otherwise, we create or reuse an anonymous
-        // module and add the child to that.
-
-        let module_ = reduced_graph_parent.module();
-
-        self.check_for_conflicts_between_external_crates_and_items(&*module_,
-                                                                   name,
-                                                                   sp);
-
-        // Add or reuse the child.
-        let child = module_.children.borrow().get(&name).cloned();
-        match child {
-            None => {
-                let child = Rc::new(NameBindings::new());
-                module_.children.borrow_mut().insert(name, child.clone());
-                child
-            }
-            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.
-
-                let mut duplicate_type = NoError;
-                let ns = match duplicate_checking_mode {
-                    ForbidDuplicateModules => {
-                        if child.get_module_if_available().is_some() {
-                            duplicate_type = ModuleError;
-                        }
-                        Some(TypeNS)
-                    }
-                    ForbidDuplicateTypesAndModules => {
-                        match child.def_for_namespace(TypeNS) {
-                            None => {}
-                            Some(_) if child.get_module_if_available()
-                                            .map(|m| m.kind.get()) ==
-                                       Some(ImplModuleKind) => {}
-                            Some(_) => duplicate_type = TypeError
-                        }
-                        Some(TypeNS)
-                    }
-                    ForbidDuplicateValues => {
-                        if child.defined_in_namespace(ValueNS) {
-                            duplicate_type = ValueError;
-                        }
-                        Some(ValueNS)
-                    }
-                    ForbidDuplicateTypesAndValues => {
-                        let mut n = None;
-                        match child.def_for_namespace(TypeNS) {
-                            Some(DefMod(_)) | None => {}
-                            Some(_) => {
-                                n = Some(TypeNS);
-                                duplicate_type = TypeError;
-                            }
-                        };
-                        if child.defined_in_namespace(ValueNS) {
-                            duplicate_type = ValueError;
-                            n = Some(ValueNS);
-                        }
-                        n
-                    }
-                    OverwriteDuplicates => None
-                };
-                if duplicate_type != NoError {
-                    // Return an error here by looking up the namespace that
-                    // had the duplicate.
-                    let ns = ns.unwrap();
-                    self.resolve_error(sp,
-                        format!("duplicate definition of {} `{}`",
-                             namespace_error_to_string(duplicate_type),
-                             token::get_name(name))[]);
-                    {
-                        let r = child.span_for_namespace(ns);
-                        for sp in r.iter() {
-                            self.session.span_note(*sp,
-                                 format!("first definition of {} `{}` here",
-                                      namespace_error_to_string(duplicate_type),
-                                      token::get_name(name))[]);
-                        }
-                    }
-                }
-                child
-            }
-        }
-    }
-
-    fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
-        // If the block has view items, we need an anonymous module.
-        if block.view_items.len() > 0 {
-            return true;
-        }
-
-        // Check each statement.
-        for statement in block.stmts.iter() {
-            match statement.node {
-                StmtDecl(ref declaration, _) => {
-                    match declaration.node {
-                        DeclItem(_) => {
-                            return true;
-                        }
-                        _ => {
-                            // Keep searching.
-                        }
-                    }
-                }
-                _ => {
-                    // Keep searching.
-                }
-            }
-        }
-
-        // If we found neither view items nor items, we don't need to create
-        // an anonymous module.
-
-        return false;
-    }
-
-    fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
-                       -> ParentLink {
-        match parent {
-            ModuleReducedGraphParent(module_) => {
-                return ModuleParentLink(module_.downgrade(), name);
-            }
-        }
-    }
-
-    /// Constructs the reduced graph for one item.
-    fn build_reduced_graph_for_item(&mut self,
-                                    item: &Item,
-                                    parent: ReducedGraphParent)
-                                    -> ReducedGraphParent
-    {
-        let name = item.ident.name;
-        let sp = item.span;
-        let is_public = item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-
-        match item.node {
-            ItemMod(..) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
-
-                let parent_link = self.get_parent_link(parent, name);
-                let def_id = DefId { krate: 0, node: item.id };
-                name_bindings.define_module(parent_link,
-                                            Some(def_id),
-                                            NormalModuleKind,
-                                            false,
-                                            item.vis == ast::Public,
-                                            sp);
-
-                ModuleReducedGraphParent(name_bindings.get_module())
-            }
-
-            ItemForeignMod(..) => parent,
-
-            // These items live in the value namespace.
-            ItemStatic(_, m, _) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
-                let mutbl = m == ast::MutMutable;
-
-                name_bindings.define_value
-                    (DefStatic(local_def(item.id), mutbl), sp, modifiers);
-                parent
-            }
-            ItemConst(_, _) => {
-                self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
-                    .define_value(DefConst(local_def(item.id)),
-                                  sp, modifiers);
-                parent
-            }
-            ItemFn(_, _, _, _, _) => {
-                let name_bindings =
-                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
-
-                let def = DefFn(local_def(item.id), false);
-                name_bindings.define_value(def, sp, modifiers);
-                parent
-            }
-
-            // These items live in the type namespace.
-            ItemTy(..) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                name_bindings.define_type
-                    (DefTy(local_def(item.id), false), sp, modifiers);
-                parent
-            }
-
-            ItemEnum(ref enum_definition, _) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                name_bindings.define_type
-                    (DefTy(local_def(item.id), true), sp, modifiers);
-
-                let parent_link = self.get_parent_link(parent.clone(), name);
-                // We want to make sure the module type is EnumModuleKind
-                // even if there's already an ImplModuleKind module defined,
-                // since that's how we prevent duplicate enum definitions
-                name_bindings.set_module_kind(parent_link,
-                                              Some(local_def(item.id)),
-                                              EnumModuleKind,
-                                              false,
-                                              is_public,
-                                              sp);
-
-                for variant in (*enum_definition).variants.iter() {
-                    self.build_reduced_graph_for_variant(
-                        &**variant,
-                        local_def(item.id),
-                        ModuleReducedGraphParent(name_bindings.get_module()));
-                }
-                parent
-            }
-
-            // These items live in both the type and value namespaces.
-            ItemStruct(ref struct_def, _) => {
-                // Adding to both Type and Value namespaces or just Type?
-                let (forbid, ctor_id) = match struct_def.ctor_id {
-                    Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
-                    None            => (ForbidDuplicateTypesAndModules, None)
-                };
-
-                let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
-
-                // Define a name in the type namespace.
-                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
-
-                // If this is a newtype or unit-like struct, define a name
-                // in the value namespace as well
-                match ctor_id {
-                    Some(cid) => {
-                        name_bindings.define_value(DefStruct(local_def(cid)),
-                                                   sp, modifiers);
-                    }
-                    None => {}
-                }
-
-                // Record the def ID and fields of this struct.
-                let named_fields = struct_def.fields.iter().filter_map(|f| {
-                    match f.node.kind {
-                        NamedField(ident, _) => Some(ident.name),
-                        UnnamedField(_) => None
-                    }
-                }).collect();
-                self.structs.insert(local_def(item.id), named_fields);
-
-                parent
-            }
-
-            ItemImpl(_, _, None, ref ty, ref impl_items) => {
-                // If this implements an anonymous trait, then add all the
-                // methods within to a new module, if the type was defined
-                // within this module.
-
-                let mod_name = match ty.node {
-                    TyPath(ref path, _) if path.segments.len() == 1 => {
-                        // FIXME(18446) we should distinguish between the name of
-                        // a trait and the name of an impl of that trait.
-                        Some(path.segments.last().unwrap().identifier.name)
-                    }
-                    TyObjectSum(ref lhs_ty, _) => {
-                        match lhs_ty.node {
-                            TyPath(ref path, _) if path.segments.len() == 1 => {
-                                Some(path.segments.last().unwrap().identifier.name)
-                            }
-                            _ => {
-                                None
-                            }
-                        }
-                    }
-                    _ => {
-                        None
-                    }
-                };
-
-                match mod_name {
-                    None => {
-                        self.resolve_error(ty.span,
-                                           "inherent implementations may \
-                                            only be implemented in the same \
-                                            module as the type they are \
-                                            implemented for")
-                    }
-                    Some(mod_name) => {
-                        // Create the module and add all methods.
-                        let parent_opt = parent.module().children.borrow()
-                            .get(&mod_name).cloned();
-                        let new_parent = match parent_opt {
-                            // It already exists
-                            Some(ref child) if child.get_module_if_available()
-                                .is_some() &&
-                                (child.get_module().kind.get() == ImplModuleKind ||
-                                 child.get_module().kind.get() == TraitModuleKind) => {
-                                    ModuleReducedGraphParent(child.get_module())
-                                }
-                            Some(ref child) if child.get_module_if_available()
-                                .is_some() &&
-                                child.get_module().kind.get() ==
-                                EnumModuleKind => {
-                                    ModuleReducedGraphParent(child.get_module())
-                                }
-                            // Create the module
-                            _ => {
-                                let name_bindings =
-                                    self.add_child(mod_name,
-                                                   parent.clone(),
-                                                   ForbidDuplicateModules,
-                                                   sp);
-
-                                let parent_link =
-                                    self.get_parent_link(parent.clone(), name);
-                                let def_id = local_def(item.id);
-                                let ns = TypeNS;
-                                let is_public =
-                                    !name_bindings.defined_in_namespace(ns) ||
-                                    name_bindings.defined_in_public_namespace(ns);
-
-                                name_bindings.define_module(parent_link,
-                                                            Some(def_id),
-                                                            ImplModuleKind,
-                                                            false,
-                                                            is_public,
-                                                            sp);
-
-                                ModuleReducedGraphParent(
-                                    name_bindings.get_module())
-                            }
-                        };
-
-                        // For each implementation item...
-                        for impl_item in impl_items.iter() {
-                            match *impl_item {
-                                MethodImplItem(ref method) => {
-                                    // Add the method to the module.
-                                    let name = method.pe_ident().name;
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       new_parent.clone(),
-                                                       ForbidDuplicateValues,
-                                                       method.span);
-                                    let def = match method.pe_explicit_self()
-                                        .node {
-                                            SelfStatic => {
-                                                // Static methods become
-                                                // `DefStaticMethod`s.
-                                                DefStaticMethod(local_def(method.id),
-                                                                FromImpl(local_def(item.id)))
-                                            }
-                                            _ => {
-                                                // Non-static methods become
-                                                // `DefMethod`s.
-                                                DefMethod(local_def(method.id),
-                                                          None,
-                                                          FromImpl(local_def(item.id)))
-                                            }
-                                        };
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if method.pe_vis() == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def,
-                                        method.span,
-                                        modifiers);
-                                }
-                                TypeImplItem(ref typedef) => {
-                                    // Add the typedef to the module.
-                                    let name = typedef.ident.name;
-                                    let typedef_name_bindings =
-                                        self.add_child(
-                                            name,
-                                            new_parent.clone(),
-                                            ForbidDuplicateTypesAndModules,
-                                            typedef.span);
-                                    let def = DefAssociatedTy(local_def(
-                                        typedef.id));
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if typedef.vis == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    typedef_name_bindings.define_type(
-                                        def,
-                                        typedef.span,
-                                        modifiers);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                parent
-            }
-
-            ItemImpl(_, _, Some(_), _, _) => parent,
-
-            ItemTrait(_, _, _, _, ref items) => {
-                let name_bindings =
-                    self.add_child(name,
-                                   parent.clone(),
-                                   ForbidDuplicateTypesAndModules,
-                                   sp);
-
-                // Add all the items within to a new module.
-                let parent_link = self.get_parent_link(parent.clone(), name);
-                name_bindings.define_module(parent_link,
-                                            Some(local_def(item.id)),
-                                            TraitModuleKind,
-                                            false,
-                                            item.vis == ast::Public,
-                                            sp);
-                let module_parent = ModuleReducedGraphParent(name_bindings.
-                                                             get_module());
-
-                let def_id = local_def(item.id);
-
-                // Add the names of all the items to the trait info.
-                for trait_item in items.iter() {
-                    let (name, kind) = match *trait_item {
-                        ast::RequiredMethod(_) |
-                        ast::ProvidedMethod(_) => {
-                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
-
-                            let name = ty_m.ident.name;
-
-                            // Add it as a name in the trait module.
-                            let (def, static_flag) = match ty_m.explicit_self
-                                                               .node {
-                                SelfStatic => {
-                                    // Static methods become `DefStaticMethod`s.
-                                    (DefStaticMethod(
-                                            local_def(ty_m.id),
-                                            FromTrait(local_def(item.id))),
-                                     StaticMethodTraitItemKind)
-                                }
-                                _ => {
-                                    // Non-static methods become `DefMethod`s.
-                                    (DefMethod(local_def(ty_m.id),
-                                               Some(local_def(item.id)),
-                                               FromTrait(local_def(item.id))),
-                                     NonstaticMethodTraitItemKind)
-                                }
-                            };
-
-                            let method_name_bindings =
-                                self.add_child(name,
-                                               module_parent.clone(),
-                                               ForbidDuplicateTypesAndValues,
-                                               ty_m.span);
-                            // NB: not IMPORTABLE
-                            method_name_bindings.define_value(def,
-                                                              ty_m.span,
-                                                              PUBLIC);
-
-                            (name, static_flag)
-                        }
-                        ast::TypeTraitItem(ref associated_type) => {
-                            let def = DefAssociatedTy(local_def(
-                                    associated_type.ty_param.id));
-
-                            let name_bindings =
-                                self.add_child(associated_type.ty_param.ident.name,
-                                               module_parent.clone(),
-                                               ForbidDuplicateTypesAndValues,
-                                               associated_type.ty_param.span);
-                            // NB: not IMPORTABLE
-                            name_bindings.define_type(def,
-                                                      associated_type.ty_param.span,
-                                                      PUBLIC);
-
-                            (associated_type.ty_param.ident.name, TypeTraitItemKind)
-                        }
-                    };
-
-                    self.trait_item_map.insert((name, def_id), kind);
-                }
-
-                name_bindings.define_type(DefTrait(def_id), sp, modifiers);
-                parent
-            }
-            ItemMac(..) => parent
-        }
-    }
-
-    // Constructs the reduced graph for one variant. Variants exist in the
-    // type and value namespaces.
-    fn build_reduced_graph_for_variant(&mut self,
-                                       variant: &Variant,
-                                       item_id: DefId,
-                                       parent: ReducedGraphParent) {
-        let name = variant.node.name.name;
-        let is_exported = match variant.node.kind {
-            TupleVariantKind(_) => false,
-            StructVariantKind(_) => {
-                // Not adding fields for variants as they are not accessed with a self receiver
-                self.structs.insert(local_def(variant.node.id), Vec::new());
-                true
-            }
-        };
-
-        let child = self.add_child(name, parent,
-                                   ForbidDuplicateTypesAndValues,
-                                   variant.span);
-        // variants are always treated as importable to allow them to be glob
-        // used
-        child.define_value(DefVariant(item_id,
-                                      local_def(variant.node.id), is_exported),
-                           variant.span, PUBLIC | IMPORTABLE);
-        child.define_type(DefVariant(item_id,
-                                     local_def(variant.node.id), is_exported),
-                          variant.span, PUBLIC | IMPORTABLE);
-    }
-
-    /// Constructs the reduced graph for one 'view item'. View items consist
-    /// of imports and use directives.
-    fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
-                                         parent: ReducedGraphParent) {
-        match view_item.node {
-            ViewItemUse(ref view_path) => {
-                // Extract and intern the module part of the path. For
-                // globs and lists, the path is found directly in the AST;
-                // for simple paths we have to munge the path a little.
-                let module_path = match view_path.node {
-                    ViewPathSimple(_, ref full_path, _) => {
-                        full_path.segments
-                            .init()
-                            .iter().map(|ident| ident.identifier.name)
-                            .collect()
-                    }
-
-                    ViewPathGlob(ref module_ident_path, _) |
-                    ViewPathList(ref module_ident_path, _, _) => {
-                        module_ident_path.segments
-                            .iter().map(|ident| ident.identifier.name).collect()
-                    }
-                };
-
-                // 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_name(
-                                    special_idents::prelude_import.name)
-                             });
-                let shadowable = if shadowable {
-                    Shadowable::Always
-                } else {
-                    Shadowable::Never
-                };
-
-                match view_path.node {
-                    ViewPathSimple(binding, ref full_path, id) => {
-                        let source_name =
-                            full_path.segments.last().unwrap().identifier.name;
-                        if token::get_name(source_name).get() == "mod" {
-                            self.resolve_error(view_path.span,
-                                "`mod` imports are only allowed within a { } list");
-                        }
-
-                        let subclass = SingleImport(binding.name,
-                                                    source_name);
-                        self.build_import_directive(&*module_,
-                                                    module_path,
-                                                    subclass,
-                                                    view_path.span,
-                                                    id,
-                                                    is_public,
-                                                    shadowable);
-                    }
-                    ViewPathList(_, ref source_items, _) => {
-                        // Make sure there's at most one `mod` import in the list.
-                        let mod_spans = source_items.iter().filter_map(|item| match item.node {
-                            PathListMod { .. } => Some(item.span),
-                            _ => None
-                        }).collect::<Vec<Span>>();
-                        if mod_spans.len() > 1 {
-                            self.resolve_error(mod_spans[0],
-                                "`mod` import can only appear once in the list");
-                            for other_span in mod_spans.iter().skip(1) {
-                                self.session.span_note(*other_span,
-                                    "another `mod` import appears here");
-                            }
-                        }
-
-                        for source_item in source_items.iter() {
-                            let (module_path, name) = match source_item.node {
-                                PathListIdent { name, .. } =>
-                                    (module_path.clone(), name.name),
-                                PathListMod { .. } => {
-                                    let name = match module_path.last() {
-                                        Some(name) => *name,
-                                        None => {
-                                            self.resolve_error(source_item.span,
-                                                "`mod` import can only appear in an import list \
-                                                 with a non-empty prefix");
-                                            continue;
-                                        }
-                                    };
-                                    let module_path = module_path.init();
-                                    (module_path.to_vec(), name)
-                                }
-                            };
-                            self.build_import_directive(
-                                &*module_,
-                                module_path,
-                                SingleImport(name, name),
-                                source_item.span,
-                                source_item.node.id(),
-                                is_public,
-                                shadowable);
-                        }
-                    }
-                    ViewPathGlob(_, id) => {
-                        self.build_import_directive(&*module_,
-                                                    module_path,
-                                                    GlobImport,
-                                                    view_path.span,
-                                                    id,
-                                                    is_public,
-                                                    if shadowable == Shadowable::Never {
-                                                        Shadowable::Glob
-                                                    } else {
-                                                        shadowable
-                                                    });
-                    }
-                }
-            }
-
-            ViewItemExternCrate(name, _, node_id) => {
-                // n.b. we don't need to look at the path option here, because cstore already did
-                for &crate_id in self.session.cstore
-                                     .find_extern_mod_stmt_cnum(node_id).iter() {
-                    let def_id = DefId { krate: crate_id, node: 0 };
-                    self.external_exports.insert(def_id);
-                    let parent_link =
-                        ModuleParentLink(parent.module().downgrade(), name.name);
-                    let external_module = Rc::new(Module::new(parent_link,
-                                                              Some(def_id),
-                                                              NormalModuleKind,
-                                                              false,
-                                                              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);
-                }
-            }
-        }
-    }
-
-    /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item<F>(&mut self,
-                                               foreign_item: &ForeignItem,
-                                               parent: ReducedGraphParent,
-                                               f: F) where
-        F: FnOnce(&mut Resolver),
-    {
-        let name = foreign_item.ident.name;
-        let is_public = foreign_item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let name_bindings =
-            self.add_child(name, parent, ForbidDuplicateValues,
-                           foreign_item.span);
-
-        match foreign_item.node {
-            ForeignItemFn(_, ref generics) => {
-                let def = DefFn(local_def(foreign_item.id), false);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                self.with_type_parameter_rib(
-                    HasTypeParameters(generics,
-                                      FnSpace,
-                                      foreign_item.id,
-                                      NormalRibKind),
-                    f);
-            }
-            ForeignItemStatic(_, m) => {
-                let def = DefStatic(local_def(foreign_item.id), m);
-                name_bindings.define_value(def, foreign_item.span, modifiers);
-
-                f(self)
-            }
-        }
-    }
-
-    fn build_reduced_graph_for_block(&mut self,
-                                         block: &Block,
-                                         parent: ReducedGraphParent)
-                                            -> ReducedGraphParent
-    {
-        if self.block_needs_anonymous_module(block) {
-            let block_id = block.id;
-
-            debug!("(building reduced graph for block) creating a new \
-                    anonymous module for block {}",
-                   block_id);
-
-            let parent_module = parent.module();
-            let new_module = Rc::new(Module::new(
-                BlockParentLink(parent_module.downgrade(), block_id),
-                None,
-                AnonymousModuleKind,
-                false,
-                false));
-            parent_module.anonymous_children.borrow_mut()
-                         .insert(block_id, new_module.clone());
-            ModuleReducedGraphParent(new_module)
-        } else {
-            parent
-        }
-    }
-
-    fn handle_external_def(&mut self,
-                           def: Def,
-                           vis: Visibility,
-                           child_name_bindings: &NameBindings,
-                           final_ident: &str,
-                           name: Name,
-                           new_parent: ReducedGraphParent) {
-        debug!("(building reduced graph for \
-                external crate) building external def, priv {}",
-               vis);
-        let is_public = vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
-        let is_exported = is_public && match new_parent {
-            ModuleReducedGraphParent(ref module) => {
-                match module.def_id.get() {
-                    None => true,
-                    Some(did) => self.external_exports.contains(&did)
-                }
-            }
-        };
-        if is_exported {
-            self.external_exports.insert(def.def_id());
-        }
-
-        let kind = match def {
-            DefTy(_, true) => EnumModuleKind,
-            DefStruct(..) | DefTy(..) => ImplModuleKind,
-            _ => NormalModuleKind
-        };
-
-        match def {
-          DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
-          DefTy(def_id, _) => {
-            let type_def = child_name_bindings.type_def.borrow().clone();
-            match type_def {
-              Some(TypeNsDef { module_def: Some(module_def), .. }) => {
-                debug!("(building reduced graph for external crate) \
-                        already created module");
-                module_def.def_id.set(Some(def_id));
-              }
-              Some(_) | None => {
-                debug!("(building reduced graph for \
-                        external crate) building module \
-                        {}", final_ident);
-                let parent_link = self.get_parent_link(new_parent.clone(), name);
-
-                child_name_bindings.define_module(parent_link,
-                                                  Some(def_id),
-                                                  kind,
-                                                  true,
-                                                  is_public,
-                                                  DUMMY_SP);
-              }
-            }
-          }
-          _ => {}
-        }
-
-        match def {
-          DefMod(_) | DefForeignMod(_) => {}
-          DefVariant(_, variant_id, is_struct) => {
-              debug!("(building reduced graph for external crate) building \
-                      variant {}",
-                      final_ident);
-              // variants are always treated as importable to allow them to be
-              // glob used
-              let modifiers = PUBLIC | IMPORTABLE;
-              if is_struct {
-                  child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-                  // Not adding fields for variants as they are not accessed with a self receiver
-                  self.structs.insert(variant_id, Vec::new());
-              } else {
-                  child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-              }
-          }
-          DefFn(ctor_id, true) => {
-            child_name_bindings.define_value(
-                csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
-                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
-          }
-          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
-            debug!("(building reduced graph for external \
-                    crate) building value (fn/static) {}", final_ident);
-            // impl methods have already been defined with the correct importability modifier
-            let mut modifiers = match *child_name_bindings.value_def.borrow() {
-                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
-                None => modifiers
-            };
-            if new_parent.module().kind.get() != NormalModuleKind {
-                modifiers = modifiers & !IMPORTABLE;
-            }
-            child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-          }
-          DefTrait(def_id) => {
-              debug!("(building reduced graph for external \
-                      crate) building type {}", final_ident);
-
-              // If this is a trait, add all the trait item names to the trait
-              // info.
-
-              let trait_item_def_ids =
-                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
-              for trait_item_def_id in trait_item_def_ids.iter() {
-                  let (trait_item_name, trait_item_kind) =
-                      csearch::get_trait_item_name_and_kind(
-                          &self.session.cstore,
-                          trait_item_def_id.def_id());
-
-                  debug!("(building reduced graph for external crate) ... \
-                          adding trait item '{}'",
-                         token::get_name(trait_item_name));
-
-                  self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
-
-                  if is_exported {
-                      self.external_exports
-                          .insert(trait_item_def_id.def_id());
-                  }
-              }
-
-              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-
-              // Define a module if necessary.
-              let parent_link = self.get_parent_link(new_parent, name);
-              child_name_bindings.set_module_kind(parent_link,
-                                                  Some(def_id),
-                                                  TraitModuleKind,
-                                                  true,
-                                                  is_public,
-                                                  DUMMY_SP)
-          }
-          DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
-              debug!("(building reduced graph for external \
-                      crate) building type {}", final_ident);
-
-              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-          }
-          DefStruct(def_id) => {
-            debug!("(building reduced graph for external \
-                    crate) building type and value for {}",
-                   final_ident);
-            child_name_bindings.define_type(def, DUMMY_SP, modifiers);
-            let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
-                f.name
-            }).collect::<Vec<_>>();
-
-            if fields.len() == 0 {
-                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
-            }
-
-            // Record the def ID and fields of this struct.
-            self.structs.insert(def_id, fields);
-          }
-          DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
-          DefUse(..) | DefUpvar(..) | DefRegion(..) |
-          DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
-            panic!("didn't expect `{}`", def);
-          }
-        }
-    }
-
-    /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_def(&mut self,
-                                                  root: Rc<Module>,
-                                                  def_like: DefLike,
-                                                  name: Name,
-                                                  visibility: Visibility) {
-        match def_like {
-            DlDef(def) => {
-                // Add the new child item, if necessary.
-                match def {
-                    DefForeignMod(def_id) => {
-                        // Foreign modules have no names. Recur and populate
-                        // eagerly.
-                        csearch::each_child_of_item(&self.session.cstore,
-                                                    def_id,
-                                                    |def_like,
-                                                     child_name,
-                                                     vis| {
-                            self.build_reduced_graph_for_external_crate_def(
-                                root.clone(),
-                                def_like,
-                                child_name,
-                                vis)
-                        });
-                    }
-                    _ => {
-                        let child_name_bindings =
-                            self.add_child(name,
-                                           ModuleReducedGraphParent(root.clone()),
-                                           OverwriteDuplicates,
-                                           DUMMY_SP);
-
-                        self.handle_external_def(def,
-                                                 visibility,
-                                                 &*child_name_bindings,
-                                                 token::get_name(name).get(),
-                                                 name,
-                                                 ModuleReducedGraphParent(root));
-                    }
-                }
-            }
-            DlImpl(def) => {
-                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
-                    None => {}
-                    Some(final_name) => {
-                        let methods_opt =
-                            csearch::get_methods_if_impl(&self.session.cstore, def);
-                        match methods_opt {
-                            Some(ref methods) if
-                                methods.len() >= 1 => {
-                                debug!("(building reduced graph for \
-                                        external crate) processing \
-                                        static methods for type name {}",
-                                        token::get_name(final_name));
-
-                                let child_name_bindings =
-                                    self.add_child(
-                                        final_name,
-                                        ModuleReducedGraphParent(root.clone()),
-                                        OverwriteDuplicates,
-                                        DUMMY_SP);
-
-                                // Process the static methods. First,
-                                // create the module.
-                                let type_module;
-                                let type_def = child_name_bindings.type_def.borrow().clone();
-                                match type_def {
-                                    Some(TypeNsDef {
-                                        module_def: Some(module_def),
-                                        ..
-                                    }) => {
-                                        // We already have a module. This
-                                        // is OK.
-                                        type_module = module_def;
-
-                                        // Mark it as an impl module if
-                                        // necessary.
-                                        type_module.kind.set(ImplModuleKind);
-                                    }
-                                    Some(_) | None => {
-                                        let parent_link =
-                                            self.get_parent_link(ModuleReducedGraphParent(root),
-                                                                 final_name);
-                                        child_name_bindings.define_module(
-                                            parent_link,
-                                            Some(def),
-                                            ImplModuleKind,
-                                            true,
-                                            true,
-                                            DUMMY_SP);
-                                        type_module =
-                                            child_name_bindings.
-                                                get_module();
-                                    }
-                                }
-
-                                // Add each static method to the module.
-                                let new_parent =
-                                    ModuleReducedGraphParent(type_module);
-                                for method_info in methods.iter() {
-                                    let name = method_info.name;
-                                    debug!("(building reduced graph for \
-                                             external crate) creating \
-                                             static method '{}'",
-                                           token::get_name(name));
-
-                                    let method_name_bindings =
-                                        self.add_child(name,
-                                                       new_parent.clone(),
-                                                       OverwriteDuplicates,
-                                                       DUMMY_SP);
-                                    let def = DefFn(method_info.def_id, false);
-
-                                    // NB: not IMPORTABLE
-                                    let modifiers = if visibility == ast::Public {
-                                        PUBLIC
-                                    } else {
-                                        DefModifiers::empty()
-                                    };
-                                    method_name_bindings.define_value(
-                                        def, DUMMY_SP, modifiers);
-                                }
-                            }
-
-                            // Otherwise, do nothing.
-                            Some(_) | None => {}
-                        }
-                    }
-                }
-            }
-            DlField => {
-                debug!("(building reduced graph for external crate) \
-                        ignoring field");
-            }
-        }
-    }
-
-    /// Builds the reduced graph rooted at the given external module.
-    fn populate_external_module(&mut self, module: Rc<Module>) {
-        debug!("(populating external module) attempting to populate {}",
-               self.module_to_string(&*module));
-
-        let def_id = match module.def_id.get() {
-            None => {
-                debug!("(populating external module) ... no def ID!");
-                return
-            }
-            Some(def_id) => def_id,
-        };
-
-        csearch::each_child_of_item(&self.session.cstore,
-                                    def_id,
-                                    |def_like, child_name, visibility| {
-            debug!("(populating external module) ... found ident: {}",
-                   token::get_name(child_name));
-            self.build_reduced_graph_for_external_crate_def(module.clone(),
-                                                            def_like,
-                                                            child_name,
-                                                            visibility)
-        });
-        module.populated.set(true)
-    }
-
-    /// Ensures that the reduced graph rooted at the given external module
-    /// is built, building it if it is not.
-    fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
-        if !module.populated.get() {
-            self.populate_external_module(module.clone())
-        }
-        assert!(module.populated.get())
-    }
-
-    /// Builds the reduced graph rooted at the 'use' directive for an external
-    /// crate.
-    fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
-        csearch::each_top_level_item_of_crate(&self.session.cstore,
-                                              root.def_id
-                                                  .get()
-                                                  .unwrap()
-                                                  .krate,
-                                              |def_like, name, visibility| {
-            self.build_reduced_graph_for_external_crate_def(root.clone(),
-                                                            def_like,
-                                                            name,
-                                                            visibility)
-        });
-    }
-
-    /// Creates and adds an import directive to the given module.
-    fn build_import_directive(&mut self,
-                              module_: &Module,
-                              module_path: Vec<Name>,
-                              subclass: ImportDirectiveSubclass,
-                              span: Span,
-                              id: NodeId,
-                              is_public: bool,
-                              shadowable: Shadowable) {
-        module_.imports.borrow_mut().push(ImportDirective::new(module_path,
-                                                               subclass,
-                                                               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.
-
-        match subclass {
-            SingleImport(target, _) => {
-                debug!("(building import directive) building import \
-                        directive: {}::{}",
-                       self.names_to_string(module_.imports.borrow().last().unwrap()
-                                                 .module_path[]),
-                       token::get_name(target));
-
-                let mut import_resolutions = module_.import_resolutions
-                                                    .borrow_mut();
-                match import_resolutions.get_mut(&target) {
-                    Some(resolution) => {
-                        debug!("(building import directive) bumping \
-                                reference");
-                        resolution.outstanding_references += 1;
-
-                        // the source of this name is different now
-                        resolution.type_id = id;
-                        resolution.value_id = id;
-                        resolution.is_public = is_public;
-                        return;
-                    }
-                    None => {}
-                }
-                debug!("(building import directive) creating new");
-                let mut resolution = ImportResolution::new(id, is_public);
-                resolution.outstanding_references = 1;
-                import_resolutions.insert(target, resolution);
-            }
-            GlobImport => {
-                // Set the glob flag. This tells us that we don't know the
-                // module's exports ahead of time.
-
-                module_.glob_count.set(module_.glob_count.get() + 1);
-            }
-        }
-    }
-
     // Import resolution
     //
     // This is a fixed-point algorithm. We resolve imports until our efforts
@@ -2267,7 +1015,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         self.resolve_imports_for_module(module_.clone());
         self.current_module = orig_module;
 
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
         for (_, child_node) in module_.children.borrow().iter() {
             match child_node.get_module_if_available() {
                 None => {
@@ -2533,7 +1281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut type_result = UnknownResult;
 
         // Search for direct children of the containing module.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
         match containing_module.children.borrow().get(&source) {
             None => {
@@ -2712,64 +1460,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // We've successfully resolved the import. Write the results in.
         let mut import_resolutions = module_.import_resolutions.borrow_mut();
         let import_resolution = &mut (*import_resolutions)[target];
+        {
+            let mut check_and_write_import = |&mut: namespace, result: &_, used_public: &mut bool| {
+                let namespace_name = match namespace {
+                    TypeNS => "type",
+                    ValueNS => "value",
+                };
 
-        match value_result {
-            BoundResult(ref target_module, ref name_bindings) => {
-                debug!("(resolving single import) found value target: {}",
-                       { name_bindings.value_def.borrow().clone().unwrap().def });
-                self.check_for_conflicting_import(
-                    &import_resolution.value_target,
-                    directive.span,
-                    target,
-                    ValueNS);
-
-                self.check_that_import_is_importable(
-                    &**name_bindings,
-                    directive.span,
-                    target,
-                    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);
-            }
-            UnboundResult => { /* Continue. */ }
-            UnknownResult => {
-                panic!("value result should be known at this point");
-            }
-        }
-        match type_result {
-            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,
-                    TypeNS);
-
-                self.check_that_import_is_importable(
-                    &**name_bindings,
-                    directive.span,
-                    target,
-                    TypeNS);
-
-                import_resolution.type_target =
-                    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);
-            }
-            UnboundResult => { /* Continue. */ }
-            UnknownResult => {
-                panic!("type result should be known at this point");
-            }
+                match *result {
+                    BoundResult(ref target_module, ref name_bindings) => {
+                        debug!("(resolving single import) found {} target: {}",
+                               namespace_name,
+                               name_bindings.def_for_namespace(namespace));
+                        self.check_for_conflicting_import(
+                            &import_resolution.target_for_namespace(namespace),
+                            directive.span,
+                            target,
+                            namespace);
+
+                        self.check_that_import_is_importable(
+                            &**name_bindings,
+                            directive.span,
+                            target,
+                            namespace);
+
+                        let target = Some(Target::new(target_module.clone(),
+                                                      name_bindings.clone(),
+                                                      directive.shadowable));
+                        import_resolution.set_target_and_id(namespace, target, directive.id);
+                        import_resolution.is_public = directive.is_public;
+                        *used_public = name_bindings.defined_in_public_namespace(namespace);
+                    }
+                    UnboundResult => { /* Continue. */ }
+                    UnknownResult => {
+                        panic!("{} result should be known at this point", namespace_name);
+                    }
+                }
+            };
+            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
+            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
         }
 
         self.check_for_conflicts_between_imports_and_items(
@@ -2825,7 +1554,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     // 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).
+    // that exports nothing is valid). containing_module is the module we are
+    // actually importing, i.e., `foo` in `use foo::*`.
     fn resolve_glob_import(&mut self,
                            module_: &Module,
                            containing_module: Rc<Module>,
@@ -2851,12 +1581,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         assert_eq!(containing_module.glob_count.get(), 0);
 
         // Add all resolved imports from the containing module.
-        let import_resolutions = containing_module.import_resolutions
-                                                  .borrow();
+        let import_resolutions = containing_module.import_resolutions.borrow();
         for (ident, target_import_resolution) in import_resolutions.iter() {
             debug!("(resolving glob import) writing module resolution \
                     {} into `{}`",
-                   target_import_resolution.type_target.is_none(),
+                   token::get_name(*ident),
                    self.module_to_string(module_));
 
             if !target_import_resolution.is_public {
@@ -2876,8 +1605,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // Continue.
                         }
                         Some(ref value_target) => {
-                            dest_import_resolution.value_target =
-                                Some(value_target.clone());
+                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              ValueNS);
+                            dest_import_resolution.value_target = Some(value_target.clone());
                         }
                     }
                     match target_import_resolution.type_target {
@@ -2885,8 +1617,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // Continue.
                         }
                         Some(ref type_target) => {
-                            dest_import_resolution.type_target =
-                                Some(type_target.clone());
+                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              TypeNS);
+                            dest_import_resolution.type_target = Some(type_target.clone());
                         }
                     }
                     dest_import_resolution.is_public = is_public;
@@ -2906,10 +1641,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         // Add all children from the containing module.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
-        for (&name, name_bindings) in containing_module.children
-                                                       .borrow().iter() {
+        for (&name, name_bindings) in containing_module.children.borrow().iter() {
             self.merge_import_resolution(module_,
                                          containing_module.clone(),
                                          import_directive,
@@ -2919,8 +1653,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         // Add external module children from the containing module.
-        for (&name, module) in containing_module.external_module_children
-                                                .borrow().iter() {
+        for (&name, module) in containing_module.external_module_children.borrow().iter() {
             let name_bindings =
                 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
             self.merge_import_resolution(module_,
@@ -2965,41 +1698,39 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         debug!("(resolving glob import) writing resolution `{}` in `{}` \
                to `{}`",
-               token::get_name(name).get().to_string(),
+               token::get_name(name).get(),
                self.module_to_string(&*containing_module),
                self.module_to_string(module_));
 
         // Merge the child item into the import resolution.
-        if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
-            debug!("(resolving glob import) ... for value target");
-            if dest_import_resolution.shadowable(ValueNS) == Shadowable::Never {
-                let msg = format!("a value named `{}` has already been imported \
-                                   in this module",
-                                  token::get_name(name).get());
-                self.session.span_err(import_directive.span, msg.as_slice());
-            } else {
-                dest_import_resolution.value_target =
-                    Some(Target::new(containing_module.clone(),
-                                     name_bindings.clone(),
-                                     import_directive.shadowable));
-                dest_import_resolution.value_id = id;
-            }
-        }
-        if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
-            debug!("(resolving glob import) ... for type target");
-            if dest_import_resolution.shadowable(TypeNS) == Shadowable::Never {
-                let msg = format!("a type named `{}` has already been imported \
-                                   in this module",
-                                  token::get_name(name).get());
-                self.session.span_err(import_directive.span, msg.as_slice());
-            } else {
-                dest_import_resolution.type_target =
-                    Some(Target::new(containing_module,
-                                     name_bindings.clone(),
-                                     import_directive.shadowable));
-                dest_import_resolution.type_id = id;
-            }
+        {
+            let mut merge_child_item = |&mut : namespace| {
+                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
+                    let namespace_name = match namespace {
+                        TypeNS => "type",
+                        ValueNS => "value",
+                    };
+                    debug!("(resolving glob import) ... for {} target", namespace_name);
+                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
+                        let msg = format!("a {} named `{}` has already been imported \
+                                           in this module",
+                                          namespace_name,
+                                          token::get_name(name).get());
+                        self.session.span_err(import_directive.span, msg.as_slice());
+                    } else {
+                        let target = Target::new(containing_module.clone(),
+                                                 name_bindings.clone(),
+                                                 import_directive.shadowable);
+                        dest_import_resolution.set_target_and_id(namespace,
+                                                                 Some(target),
+                                                                 id);
+                    }
+                }
+            };
+            merge_child_item(ValueNS);
+            merge_child_item(TypeNS);
         }
+
         dest_import_resolution.is_public = is_public;
 
         self.check_for_conflicts_between_imports_and_items(
@@ -3019,6 +1750,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             return
         }
 
+        debug!("check_for_conflicting_import: {}; target exists: {}",
+               token::get_name(name).get(),
+               target.is_some());
+
         match *target {
             Some(ref target) if target.shadowable != Shadowable::Always => {
                 let msg = format!("a {} named `{}` has already been imported \
@@ -3426,7 +2161,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         // The current module node is handled specially. First, check for
         // its immediate children.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         match module_.children.borrow().get(&name) {
             Some(name_bindings)
@@ -3691,7 +2426,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                self.module_to_string(&*module_));
 
         // First, check the direct children of the module.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         match module_.children.borrow().get(&name) {
             Some(name_bindings)
@@ -3787,7 +2522,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         // Descend into children and anonymous children.
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
 
         for (_, child_node) in module_.children.borrow().iter() {
             match child_node.get_module_if_available() {
@@ -3834,7 +2569,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 // Nothing to do.
             }
             Some(name) => {
-                self.populate_module_if_necessary(&orig_module);
+                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
 
                 match orig_module.children.borrow().get(&name) {
                     None => {
@@ -3910,7 +2645,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // If the def is a ty param, and came from the parent
                             // item, it's ok
                             match def {
-                                DefTyParam(_, did, _) if {
+                                DefTyParam(_, _, did, _) if {
                                     self.def_map.borrow().get(&did.node).cloned()
                                         == Some(DefTyParamBinder(item_id))
                                 } => {} // ok
@@ -3963,7 +2698,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // If the def is a ty param, and came from the parent
                             // item, it's ok
                             match def {
-                                DefTyParam(_, did, _) if {
+                                DefTyParam(_, _, did, _) if {
                                     self.def_map.borrow().get(&did.node).cloned()
                                         == Some(DefTyParamBinder(item_id))
                                 } => {} // ok
@@ -4008,6 +2743,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
+    /// Searches the current set of local scopes and
+    /// applies translations for closures.
     fn search_ribs(&self,
                    ribs: &[Rib],
                    name: Name,
@@ -4029,6 +2766,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         None
     }
 
+    /// Searches the current set of local scopes for labels.
+    /// Stops after meeting a closure.
+    fn search_label(&self, name: Name) -> Option<DefLike> {
+        for rib in self.label_ribs.iter().rev() {
+            match rib.kind {
+                NormalRibKind => {
+                    // Continue
+                }
+                _ => {
+                    // Do not resolve labels across function boundary
+                    return None
+                }
+            }
+            let result = rib.bindings.get(&name).cloned();
+            if result.is_some() {
+                return result
+            }
+        }
+        None
+    }
+
     fn resolve_crate(&mut self, krate: &ast::Crate) {
         debug!("(resolving crate) starting");
 
@@ -4093,7 +2851,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                             impl_items[]);
             }
 
-            ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
+            ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
                 // Create a new rib for the self type.
                 let mut self_type_rib = Rib::new(ItemRibKind);
 
@@ -4114,13 +2872,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     this.resolve_type_parameter_bounds(item.id, bounds,
                                                        TraitDerivation);
 
-                    match *unbound {
-                        Some(ref tpb) => {
-                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
-                        }
-                        None => {}
-                    }
-
                     for trait_item in (*trait_items).iter() {
                         // Create a new rib for the trait_item-specific type
                         // parameters.
@@ -4253,8 +3004,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     seen_bindings.insert(name);
 
                     let def_like = DlDef(DefTyParam(space,
+                                                    index as u32,
                                                     local_def(type_parameter.id),
-                                                    index as u32));
+                                                    name));
                     // Associate this type parameter with
                     // the item that bound it
                     self.record_def(type_parameter.id,
@@ -4368,12 +3120,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             self.resolve_type_parameter_bound(type_parameter.id, bound,
                                               TraitBoundingTypeParameter);
         }
-        match &type_parameter.unbound {
-            &Some(ref unbound) =>
-                self.resolve_trait_reference(
-                    type_parameter.id, unbound, TraitBoundingTypeParameter),
-            &None => {}
-        }
         match type_parameter.default {
             Some(ref ty) => self.resolve_type(&**ty),
             None => {}
@@ -4395,7 +3141,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     type_parameter_bound: &TyParamBound,
                                     reference_type: TraitReferenceType) {
         match *type_parameter_bound {
-            TraitTyParamBound(ref tref) => {
+            TraitTyParamBound(ref tref, _) => {
                 self.resolve_poly_trait_reference(id, tref, reference_type)
             }
             RegionTyParamBound(..) => {}
@@ -4821,9 +3567,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             Some(def) => {
                                 debug!("(resolving type) resolved `{}` to \
                                         type {}",
-                                       token::get_ident(path.segments
-                                                            .last().unwrap()
-                                                            .identifier),
+                                       token::get_ident(path.segments.last().unwrap() .identifier),
                                        def);
                                 result_def = Some(def);
                             }
@@ -5014,19 +3758,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             self.resolve_error(path.span,
                                 format!("`{}` is not an enum variant, struct or const",
                                     token::get_ident(
-                                        path.segments
-                                            .last()
-                                            .unwrap()
-                                            .identifier))[]);
+                                        path.segments.last().unwrap().identifier))[]);
                         }
                         None => {
                             self.resolve_error(path.span,
                                 format!("unresolved enum variant, struct or const `{}`",
                                     token::get_ident(
-                                        path.segments
-                                            .last()
-                                            .unwrap()
-                                            .identifier))[]);
+                                        path.segments.last().unwrap().identifier))[]);
                         }
                     }
 
@@ -5155,7 +3893,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                           path.span) {
                 Some((def, last_private)) => {
                     match def {
-                        DefTyParam(_, did, _) => {
+                        DefTyParam(_, _, did, _) => {
                             let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
                                                         path.segments.last()
                                                             .unwrap().identifier);
@@ -5180,9 +3918,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         // Try to find a path to an item in a module.
         let unqualified_def =
-                self.resolve_identifier(path.segments
-                                            .last().unwrap()
-                                            .identifier,
+                self.resolve_identifier(path.segments.last().unwrap().identifier,
                                         namespace,
                                         check_ribs,
                                         path.span);
@@ -5236,7 +3972,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                             namespace: Namespace)
                                             -> NameDefinition {
         // First, search children.
-        self.populate_module_if_necessary(&containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
 
         match containing_module.children.borrow().get(&name) {
             Some(child_name_bindings) => {
@@ -5848,8 +4584,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
                 let renamed = mtwt::resolve(label);
-                match self.search_ribs(self.label_ribs[],
-                                       renamed, expr.span) {
+                match self.search_label(renamed) {
                     None => {
                         self.resolve_error(
                             expr.span,
@@ -5925,7 +4660,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
 
             // Look for trait children.
-            self.populate_module_if_necessary(&search_module);
+            build_reduced_graph::populate_module_if_necessary(self, &search_module);
 
             {
                 for (_, child_names) in search_module.children.borrow().iter() {
@@ -6053,7 +4788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         debug!("Dump of module `{}`:", self.module_to_string(&*module_));
 
         debug!("Children:");
-        self.populate_module_if_necessary(&module_);
+        build_reduced_graph::populate_module_if_necessary(self, &module_);
         for (&name, _) in module_.children.borrow().iter() {
             debug!("* {}", token::get_name(name));
         }
@@ -6110,7 +4845,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                                -> CrateMap {
     let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
 
-    resolver.build_reduced_graph(krate);
+    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
     session.abort_if_errors();
 
     resolver.resolve_imports();