]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/resolve.rs
rollup merge of #19577: aidancully/master
[rust.git] / src / librustc / middle / resolve.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_camel_case_types)]
12
13 pub use self::PrivateDep::*;
14 pub use self::ImportUse::*;
15 pub use self::TraitItemKind::*;
16 pub use self::LastPrivate::*;
17 use self::PatternBindingMode::*;
18 use self::Namespace::*;
19 use self::NamespaceError::*;
20 use self::NamespaceResult::*;
21 use self::NameDefinition::*;
22 use self::ImportDirectiveSubclass::*;
23 use self::ReducedGraphParent::*;
24 use self::ResolveResult::*;
25 use self::FallbackSuggestion::*;
26 use self::TypeParameters::*;
27 use self::RibKind::*;
28 use self::MethodSort::*;
29 use self::UseLexicalScopeFlag::*;
30 use self::ModulePrefixResult::*;
31 use self::NameSearchType::*;
32 use self::BareIdentifierPatternResolution::*;
33 use self::DuplicateCheckingMode::*;
34 use self::ParentLink::*;
35 use self::ModuleKind::*;
36 use self::TraitReferenceType::*;
37 use self::FallbackChecks::*;
38
39 use session::Session;
40 use lint;
41 use metadata::csearch;
42 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
43 use middle::def::*;
44 use middle::lang_items::LanguageItems;
45 use middle::pat_util::pat_bindings;
46 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
47 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
48 use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
49 use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
50
51 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
52 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
53 use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
54 use syntax::ast::{ExprPath, ExprProc, ExprStruct, FnDecl};
55 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
56 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
57 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
58 use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, ItemConst};
59 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
60 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
61 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
62 use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
63 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
64 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
65 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
66 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
67 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyProc, TyQPath};
68 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
69 use syntax::ast::{TypeImplItem, UnnamedField};
70 use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
71 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
72 use syntax::ast::{Visibility};
73 use syntax::ast;
74 use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
75 use syntax::attr::AttrMetaMethods;
76 use syntax::ext::mtwt;
77 use syntax::parse::token::{mod, special_names, special_idents};
78 use syntax::codemap::{Span, DUMMY_SP, Pos};
79 use syntax::owned_slice::OwnedSlice;
80 use syntax::visit::{mod, Visitor};
81
82 use std::collections::{HashMap, HashSet};
83 use std::collections::hash_map::{Occupied, Vacant};
84 use std::cell::{Cell, RefCell};
85 use std::mem::replace;
86 use std::rc::{Rc, Weak};
87 use std::uint;
88
89 // Definition mapping
90 pub type DefMap = RefCell<NodeMap<Def>>;
91
92 struct binding_info {
93     span: Span,
94     binding_mode: BindingMode,
95 }
96
97 impl Copy for binding_info {}
98
99 // Map from the name in a pattern to its binding mode.
100 type BindingMap = HashMap<Name,binding_info>;
101
102 // Trait method resolution
103 pub type TraitMap = NodeMap<Vec<DefId> >;
104
105 // This is the replacement export map. It maps a module to all of the exports
106 // within.
107 pub type ExportMap2 = NodeMap<Vec<Export2>>;
108
109 pub struct Export2 {
110     pub name: String,        // The name of the target.
111     pub def_id: DefId,     // The definition of the target.
112 }
113
114 // This set contains all exported definitions from external crates. The set does
115 // not contain any entries from local crates.
116 pub type ExternalExports = DefIdSet;
117
118 // FIXME: dox
119 pub type LastPrivateMap = NodeMap<LastPrivate>;
120
121 #[deriving(Show)]
122 pub enum LastPrivate {
123     LastMod(PrivateDep),
124     // `use` directives (imports) can refer to two separate definitions in the
125     // type and value namespaces. We record here the last private node for each
126     // and whether the import is in fact used for each.
127     // If the Option<PrivateDep> fields are None, it means there is no definition
128     // in that namespace.
129     LastImport{value_priv: Option<PrivateDep>,
130                value_used: ImportUse,
131                type_priv: Option<PrivateDep>,
132                type_used: ImportUse},
133 }
134
135 impl Copy for LastPrivate {}
136
137 #[deriving(Show)]
138 pub enum PrivateDep {
139     AllPublic,
140     DependsOn(DefId),
141 }
142
143 impl Copy for PrivateDep {}
144
145 // How an import is used.
146 #[deriving(PartialEq, Show)]
147 pub enum ImportUse {
148     Unused,       // The import is not used.
149     Used,         // The import is used.
150 }
151
152 impl Copy for ImportUse {}
153
154 impl LastPrivate {
155     fn or(self, other: LastPrivate) -> LastPrivate {
156         match (self, other) {
157             (me, LastMod(AllPublic)) => me,
158             (_, other) => other,
159         }
160     }
161 }
162
163 #[deriving(PartialEq)]
164 enum PatternBindingMode {
165     RefutableMode,
166     LocalIrrefutableMode,
167     ArgumentIrrefutableMode,
168 }
169
170 impl Copy for PatternBindingMode {}
171
172 #[deriving(PartialEq, Eq, Hash, Show)]
173 enum Namespace {
174     TypeNS,
175     ValueNS
176 }
177
178 impl Copy for Namespace {}
179
180 #[deriving(PartialEq)]
181 enum NamespaceError {
182     NoError,
183     ModuleError,
184     TypeError,
185     ValueError
186 }
187
188 impl Copy for NamespaceError {}
189
190 /// A NamespaceResult represents the result of resolving an import in
191 /// a particular namespace. The result is either definitely-resolved,
192 /// definitely- unresolved, or unknown.
193 #[deriving(Clone)]
194 enum NamespaceResult {
195     /// Means that resolve hasn't gathered enough information yet to determine
196     /// whether the name is bound in this namespace. (That is, it hasn't
197     /// resolved all `use` directives yet.)
198     UnknownResult,
199     /// Means that resolve has determined that the name is definitely
200     /// not bound in the namespace.
201     UnboundResult,
202     /// Means that resolve has determined that the name is bound in the Module
203     /// argument, and specified by the NameBindings argument.
204     BoundResult(Rc<Module>, Rc<NameBindings>)
205 }
206
207 impl NamespaceResult {
208     fn is_unknown(&self) -> bool {
209         match *self {
210             UnknownResult => true,
211             _ => false
212         }
213     }
214     fn is_unbound(&self) -> bool {
215         match *self {
216             UnboundResult => true,
217             _ => false
218         }
219     }
220 }
221
222 enum NameDefinition {
223     NoNameDefinition,           //< The name was unbound.
224     ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
225     ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
226 }
227
228 impl<'a, 'v> Visitor<'v> for Resolver<'a> {
229     fn visit_item(&mut self, item: &Item) {
230         self.resolve_item(item);
231     }
232     fn visit_arm(&mut self, arm: &Arm) {
233         self.resolve_arm(arm);
234     }
235     fn visit_block(&mut self, block: &Block) {
236         self.resolve_block(block);
237     }
238     fn visit_expr(&mut self, expr: &Expr) {
239         self.resolve_expr(expr);
240     }
241     fn visit_local(&mut self, local: &Local) {
242         self.resolve_local(local);
243     }
244     fn visit_ty(&mut self, ty: &Ty) {
245         self.resolve_type(ty);
246     }
247 }
248
249 /// Contains data for specific types of import directives.
250 enum ImportDirectiveSubclass {
251     SingleImport(Name /* target */, Name /* source */),
252     GlobImport
253 }
254
255 impl Copy for ImportDirectiveSubclass {}
256
257 /// The context that we thread through while building the reduced graph.
258 #[deriving(Clone)]
259 enum ReducedGraphParent {
260     ModuleReducedGraphParent(Rc<Module>)
261 }
262
263 impl ReducedGraphParent {
264     fn module(&self) -> Rc<Module> {
265         match *self {
266             ModuleReducedGraphParent(ref m) => {
267                 m.clone()
268             }
269         }
270     }
271 }
272
273 type ErrorMessage = Option<(Span, String)>;
274
275 enum ResolveResult<T> {
276     Failed(ErrorMessage),   // Failed to resolve the name, optional helpful error message.
277     Indeterminate,          // Couldn't determine due to unresolved globs.
278     Success(T)              // Successfully resolved the import.
279 }
280
281 impl<T> ResolveResult<T> {
282     fn indeterminate(&self) -> bool {
283         match *self { Indeterminate => true, _ => false }
284     }
285 }
286
287 enum FallbackSuggestion {
288     NoSuggestion,
289     Field,
290     Method,
291     TraitItem,
292     StaticMethod(String),
293     TraitMethod(String),
294 }
295
296 enum TypeParameters<'a> {
297     NoTypeParameters,
298     HasTypeParameters(
299         // Type parameters.
300         &'a Generics,
301
302         // Identifies the things that these parameters
303         // were declared on (type, fn, etc)
304         ParamSpace,
305
306         // ID of the enclosing item.
307         NodeId,
308
309         // The kind of the rib used for type parameters.
310         RibKind)
311 }
312
313 impl<'a> Copy for TypeParameters<'a> {}
314
315 // The rib kind controls the translation of local
316 // definitions (`DefLocal`) to upvars (`DefUpvar`).
317
318 enum RibKind {
319     // No translation needs to be applied.
320     NormalRibKind,
321
322     // We passed through a closure scope at the given node ID.
323     // Translate upvars as appropriate.
324     ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
325
326     // We passed through an impl or trait and are now in one of its
327     // methods. Allow references to ty params that impl or trait
328     // binds. Disallow any other upvars (including other ty params that are
329     // upvars).
330               // parent;   method itself
331     MethodRibKind(NodeId, MethodSort),
332
333     // We passed through an item scope. Disallow upvars.
334     ItemRibKind,
335
336     // We're in a constant item. Can't refer to dynamic stuff.
337     ConstantItemRibKind
338 }
339
340 impl Copy for RibKind {}
341
342 // Methods can be required or provided. RequiredMethod methods only occur in traits.
343 enum MethodSort {
344     RequiredMethod,
345     ProvidedMethod(NodeId)
346 }
347
348 impl Copy for MethodSort {}
349
350 enum UseLexicalScopeFlag {
351     DontUseLexicalScope,
352     UseLexicalScope
353 }
354
355 impl Copy for UseLexicalScopeFlag {}
356
357 enum ModulePrefixResult {
358     NoPrefixFound,
359     PrefixFound(Rc<Module>, uint)
360 }
361
362 #[deriving(Clone, Eq, PartialEq)]
363 pub enum TraitItemKind {
364     NonstaticMethodTraitItemKind,
365     StaticMethodTraitItemKind,
366     TypeTraitItemKind,
367 }
368
369 impl Copy for TraitItemKind {}
370
371 impl TraitItemKind {
372     pub fn from_explicit_self_category(explicit_self_category:
373                                        ExplicitSelfCategory)
374                                        -> TraitItemKind {
375         if explicit_self_category == StaticExplicitSelfCategory {
376             StaticMethodTraitItemKind
377         } else {
378             NonstaticMethodTraitItemKind
379         }
380     }
381 }
382
383 #[deriving(PartialEq)]
384 enum NameSearchType {
385     /// We're doing a name search in order to resolve a `use` directive.
386     ImportSearch,
387
388     /// We're doing a name search in order to resolve a path type, a path
389     /// expression, or a path pattern.
390     PathSearch,
391 }
392
393 impl Copy for NameSearchType {}
394
395 enum BareIdentifierPatternResolution {
396     FoundStructOrEnumVariant(Def, LastPrivate),
397     FoundConst(Def, LastPrivate),
398     BareIdentifierPatternUnresolved
399 }
400
401 impl Copy for BareIdentifierPatternResolution {}
402
403 // Specifies how duplicates should be handled when adding a child item if
404 // another item exists with the same name in some namespace.
405 #[deriving(PartialEq)]
406 enum DuplicateCheckingMode {
407     ForbidDuplicateModules,
408     ForbidDuplicateTypesAndModules,
409     ForbidDuplicateValues,
410     ForbidDuplicateTypesAndValues,
411     OverwriteDuplicates
412 }
413
414 impl Copy for DuplicateCheckingMode {}
415
416 /// One local scope.
417 struct Rib {
418     bindings: HashMap<Name, DefLike>,
419     kind: RibKind,
420 }
421
422 impl Rib {
423     fn new(kind: RibKind) -> Rib {
424         Rib {
425             bindings: HashMap::new(),
426             kind: kind
427         }
428     }
429 }
430
431 /// One import directive.
432 struct ImportDirective {
433     module_path: Vec<Name>,
434     subclass: ImportDirectiveSubclass,
435     span: Span,
436     id: NodeId,
437     is_public: bool, // see note in ImportResolution about how to use this
438     shadowable: bool,
439 }
440
441 impl ImportDirective {
442     fn new(module_path: Vec<Name> ,
443            subclass: ImportDirectiveSubclass,
444            span: Span,
445            id: NodeId,
446            is_public: bool,
447            shadowable: bool)
448            -> ImportDirective {
449         ImportDirective {
450             module_path: module_path,
451             subclass: subclass,
452             span: span,
453             id: id,
454             is_public: is_public,
455             shadowable: shadowable,
456         }
457     }
458 }
459
460 /// The item that an import resolves to.
461 #[deriving(Clone)]
462 struct Target {
463     target_module: Rc<Module>,
464     bindings: Rc<NameBindings>,
465     shadowable: bool,
466 }
467
468 impl Target {
469     fn new(target_module: Rc<Module>,
470            bindings: Rc<NameBindings>,
471            shadowable: bool)
472            -> Target {
473         Target {
474             target_module: target_module,
475             bindings: bindings,
476             shadowable: shadowable,
477         }
478     }
479 }
480
481 /// An ImportResolution represents a particular `use` directive.
482 struct ImportResolution {
483     /// Whether this resolution came from a `use` or a `pub use`. Note that this
484     /// should *not* be used whenever resolution is being performed, this is
485     /// only looked at for glob imports statements currently. Privacy testing
486     /// occurs during a later phase of compilation.
487     is_public: bool,
488
489     // The number of outstanding references to this name. When this reaches
490     // zero, outside modules can count on the targets being correct. Before
491     // then, all bets are off; future imports could override this name.
492     outstanding_references: uint,
493
494     /// The value that this `use` directive names, if there is one.
495     value_target: Option<Target>,
496     /// The source node of the `use` directive leading to the value target
497     /// being non-none
498     value_id: NodeId,
499
500     /// The type that this `use` directive names, if there is one.
501     type_target: Option<Target>,
502     /// The source node of the `use` directive leading to the type target
503     /// being non-none
504     type_id: NodeId,
505 }
506
507 impl ImportResolution {
508     fn new(id: NodeId, is_public: bool) -> ImportResolution {
509         ImportResolution {
510             type_id: id,
511             value_id: id,
512             outstanding_references: 0,
513             value_target: None,
514             type_target: None,
515             is_public: is_public,
516         }
517     }
518
519     fn target_for_namespace(&self, namespace: Namespace)
520                                 -> Option<Target> {
521         match namespace {
522             TypeNS  => self.type_target.clone(),
523             ValueNS => self.value_target.clone(),
524         }
525     }
526
527     fn id(&self, namespace: Namespace) -> NodeId {
528         match namespace {
529             TypeNS  => self.type_id,
530             ValueNS => self.value_id,
531         }
532     }
533 }
534
535 /// The link from a module up to its nearest parent node.
536 #[deriving(Clone)]
537 enum ParentLink {
538     NoParentLink,
539     ModuleParentLink(Weak<Module>, Name),
540     BlockParentLink(Weak<Module>, NodeId)
541 }
542
543 /// The type of module this is.
544 #[deriving(PartialEq)]
545 enum ModuleKind {
546     NormalModuleKind,
547     TraitModuleKind,
548     ImplModuleKind,
549     EnumModuleKind,
550     AnonymousModuleKind,
551 }
552
553 impl Copy for ModuleKind {}
554
555 /// One node in the tree of modules.
556 struct Module {
557     parent_link: ParentLink,
558     def_id: Cell<Option<DefId>>,
559     kind: Cell<ModuleKind>,
560     is_public: bool,
561
562     children: RefCell<HashMap<Name, Rc<NameBindings>>>,
563     imports: RefCell<Vec<ImportDirective>>,
564
565     // The external module children of this node that were declared with
566     // `extern crate`.
567     external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
568
569     // The anonymous children of this node. Anonymous children are pseudo-
570     // modules that are implicitly created around items contained within
571     // blocks.
572     //
573     // For example, if we have this:
574     //
575     //  fn f() {
576     //      fn g() {
577     //          ...
578     //      }
579     //  }
580     //
581     // There will be an anonymous module created around `g` with the ID of the
582     // entry block for `f`.
583     anonymous_children: RefCell<NodeMap<Rc<Module>>>,
584
585     // The status of resolving each import in this module.
586     import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
587
588     // The number of unresolved globs that this module exports.
589     glob_count: Cell<uint>,
590
591     // The index of the import we're resolving.
592     resolved_import_count: Cell<uint>,
593
594     // Whether this module is populated. If not populated, any attempt to
595     // access the children must be preceded with a
596     // `populate_module_if_necessary` call.
597     populated: Cell<bool>,
598 }
599
600 impl Module {
601     fn new(parent_link: ParentLink,
602            def_id: Option<DefId>,
603            kind: ModuleKind,
604            external: bool,
605            is_public: bool)
606            -> Module {
607         Module {
608             parent_link: parent_link,
609             def_id: Cell::new(def_id),
610             kind: Cell::new(kind),
611             is_public: is_public,
612             children: RefCell::new(HashMap::new()),
613             imports: RefCell::new(Vec::new()),
614             external_module_children: RefCell::new(HashMap::new()),
615             anonymous_children: RefCell::new(NodeMap::new()),
616             import_resolutions: RefCell::new(HashMap::new()),
617             glob_count: Cell::new(0),
618             resolved_import_count: Cell::new(0),
619             populated: Cell::new(!external),
620         }
621     }
622
623     fn all_imports_resolved(&self) -> bool {
624         self.imports.borrow().len() == self.resolved_import_count.get()
625     }
626 }
627
628 bitflags! {
629     #[deriving(Show)]
630     flags DefModifiers: u8 {
631         const PUBLIC            = 0b0000_0001,
632         const IMPORTABLE        = 0b0000_0010,
633     }
634 }
635
636 impl Copy for DefModifiers {}
637
638 // Records a possibly-private type definition.
639 #[deriving(Clone)]
640 struct TypeNsDef {
641     modifiers: DefModifiers, // see note in ImportResolution about how to use this
642     module_def: Option<Rc<Module>>,
643     type_def: Option<Def>,
644     type_span: Option<Span>
645 }
646
647 // Records a possibly-private value definition.
648 #[deriving(Clone, Show)]
649 struct ValueNsDef {
650     modifiers: DefModifiers, // see note in ImportResolution about how to use this
651     def: Def,
652     value_span: Option<Span>,
653 }
654
655 impl Copy for ValueNsDef {}
656
657 // Records the definitions (at most one for each namespace) that a name is
658 // bound to.
659 struct NameBindings {
660     type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
661     value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
662 }
663
664 /// Ways in which a trait can be referenced
665 enum TraitReferenceType {
666     TraitImplementation,             // impl SomeTrait for T { ... }
667     TraitDerivation,                 // trait T : SomeTrait { ... }
668     TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
669     TraitObject,                     // Box<for<'a> SomeTrait>
670     TraitQPath,                      // <T as SomeTrait>::
671 }
672
673 impl Copy for TraitReferenceType {}
674
675 impl NameBindings {
676     fn new() -> NameBindings {
677         NameBindings {
678             type_def: RefCell::new(None),
679             value_def: RefCell::new(None),
680         }
681     }
682
683     /// Creates a new module in this set of name bindings.
684     fn define_module(&self,
685                      parent_link: ParentLink,
686                      def_id: Option<DefId>,
687                      kind: ModuleKind,
688                      external: bool,
689                      is_public: bool,
690                      sp: Span) {
691         // Merges the module with the existing type def or creates a new one.
692         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
693         let module_ = Rc::new(Module::new(parent_link,
694                                           def_id,
695                                           kind,
696                                           external,
697                                           is_public));
698         let type_def = self.type_def.borrow().clone();
699         match type_def {
700             None => {
701                 *self.type_def.borrow_mut() = Some(TypeNsDef {
702                     modifiers: modifiers,
703                     module_def: Some(module_),
704                     type_def: None,
705                     type_span: Some(sp)
706                 });
707             }
708             Some(type_def) => {
709                 *self.type_def.borrow_mut() = Some(TypeNsDef {
710                     modifiers: modifiers,
711                     module_def: Some(module_),
712                     type_span: Some(sp),
713                     type_def: type_def.type_def
714                 });
715             }
716         }
717     }
718
719     /// Sets the kind of the module, creating a new one if necessary.
720     fn set_module_kind(&self,
721                        parent_link: ParentLink,
722                        def_id: Option<DefId>,
723                        kind: ModuleKind,
724                        external: bool,
725                        is_public: bool,
726                        _sp: Span) {
727         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
728         let type_def = self.type_def.borrow().clone();
729         match type_def {
730             None => {
731                 let module = Module::new(parent_link, def_id, kind,
732                                          external, is_public);
733                 *self.type_def.borrow_mut() = Some(TypeNsDef {
734                     modifiers: modifiers,
735                     module_def: Some(Rc::new(module)),
736                     type_def: None,
737                     type_span: None,
738                 });
739             }
740             Some(type_def) => {
741                 match type_def.module_def {
742                     None => {
743                         let module = Module::new(parent_link,
744                                                  def_id,
745                                                  kind,
746                                                  external,
747                                                  is_public);
748                         *self.type_def.borrow_mut() = Some(TypeNsDef {
749                             modifiers: modifiers,
750                             module_def: Some(Rc::new(module)),
751                             type_def: type_def.type_def,
752                             type_span: None,
753                         });
754                     }
755                     Some(module_def) => module_def.kind.set(kind),
756                 }
757             }
758         }
759     }
760
761     /// Records a type definition.
762     fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
763         debug!("defining type for def {} with modifiers {}", def, modifiers);
764         // Merges the type with the existing type def or creates a new one.
765         let type_def = self.type_def.borrow().clone();
766         match type_def {
767             None => {
768                 *self.type_def.borrow_mut() = Some(TypeNsDef {
769                     module_def: None,
770                     type_def: Some(def),
771                     type_span: Some(sp),
772                     modifiers: modifiers,
773                 });
774             }
775             Some(type_def) => {
776                 *self.type_def.borrow_mut() = Some(TypeNsDef {
777                     type_def: Some(def),
778                     type_span: Some(sp),
779                     module_def: type_def.module_def,
780                     modifiers: modifiers,
781                 });
782             }
783         }
784     }
785
786     /// Records a value definition.
787     fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
788         debug!("defining value for def {} with modifiers {}", def, modifiers);
789         *self.value_def.borrow_mut() = Some(ValueNsDef {
790             def: def,
791             value_span: Some(sp),
792             modifiers: modifiers,
793         });
794     }
795
796     /// Returns the module node if applicable.
797     fn get_module_if_available(&self) -> Option<Rc<Module>> {
798         match *self.type_def.borrow() {
799             Some(ref type_def) => type_def.module_def.clone(),
800             None => None
801         }
802     }
803
804     /// Returns the module node. Panics if this node does not have a module
805     /// definition.
806     fn get_module(&self) -> Rc<Module> {
807         match self.get_module_if_available() {
808             None => {
809                 panic!("get_module called on a node with no module \
810                        definition!")
811             }
812             Some(module_def) => module_def
813         }
814     }
815
816     fn defined_in_namespace(&self, namespace: Namespace) -> bool {
817         match namespace {
818             TypeNS   => return self.type_def.borrow().is_some(),
819             ValueNS  => return self.value_def.borrow().is_some()
820         }
821     }
822
823     fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
824         self.defined_in_namespace_with(namespace, PUBLIC)
825     }
826
827     fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
828         match namespace {
829             TypeNS => match *self.type_def.borrow() {
830                 Some(ref def) => def.modifiers.contains(modifiers), None => false
831             },
832             ValueNS => match *self.value_def.borrow() {
833                 Some(ref def) => def.modifiers.contains(modifiers), None => false
834             }
835         }
836     }
837
838     fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
839         match namespace {
840             TypeNS => {
841                 match *self.type_def.borrow() {
842                     None => None,
843                     Some(ref type_def) => {
844                         match type_def.type_def {
845                             Some(type_def) => Some(type_def),
846                             None => {
847                                 match type_def.module_def {
848                                     Some(ref module) => {
849                                         match module.def_id.get() {
850                                             Some(did) => Some(DefMod(did)),
851                                             None => None,
852                                         }
853                                     }
854                                     None => None,
855                                 }
856                             }
857                         }
858                     }
859                 }
860             }
861             ValueNS => {
862                 match *self.value_def.borrow() {
863                     None => None,
864                     Some(value_def) => Some(value_def.def)
865                 }
866             }
867         }
868     }
869
870     fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
871         if self.defined_in_namespace(namespace) {
872             match namespace {
873                 TypeNS  => {
874                     match *self.type_def.borrow() {
875                         None => None,
876                         Some(ref type_def) => type_def.type_span
877                     }
878                 }
879                 ValueNS => {
880                     match *self.value_def.borrow() {
881                         None => None,
882                         Some(ref value_def) => value_def.value_span
883                     }
884                 }
885             }
886         } else {
887             None
888         }
889     }
890 }
891
892 /// Interns the names of the primitive types.
893 struct PrimitiveTypeTable {
894     primitive_types: HashMap<Name, PrimTy>,
895 }
896
897 impl PrimitiveTypeTable {
898     fn new() -> PrimitiveTypeTable {
899         let mut table = PrimitiveTypeTable {
900             primitive_types: HashMap::new()
901         };
902
903         table.intern("bool",    TyBool);
904         table.intern("char",    TyChar);
905         table.intern("f32",     TyFloat(TyF32));
906         table.intern("f64",     TyFloat(TyF64));
907         table.intern("int",     TyInt(TyI));
908         table.intern("i8",      TyInt(TyI8));
909         table.intern("i16",     TyInt(TyI16));
910         table.intern("i32",     TyInt(TyI32));
911         table.intern("i64",     TyInt(TyI64));
912         table.intern("str",     TyStr);
913         table.intern("uint",    TyUint(TyU));
914         table.intern("u8",      TyUint(TyU8));
915         table.intern("u16",     TyUint(TyU16));
916         table.intern("u32",     TyUint(TyU32));
917         table.intern("u64",     TyUint(TyU64));
918
919         table
920     }
921
922     fn intern(&mut self, string: &str, primitive_type: PrimTy) {
923         self.primitive_types.insert(token::intern(string), primitive_type);
924     }
925 }
926
927
928 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
929     match ns {
930         NoError                 => "",
931         ModuleError | TypeError => "type or module",
932         ValueError              => "value",
933     }
934 }
935
936 /// The main resolver class.
937 struct Resolver<'a> {
938     session: &'a Session,
939
940     graph_root: NameBindings,
941
942     trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
943
944     structs: FnvHashMap<DefId, Vec<Name>>,
945
946     // The number of imports that are currently unresolved.
947     unresolved_imports: uint,
948
949     // The module that represents the current item scope.
950     current_module: Rc<Module>,
951
952     // The current set of local scopes, for values.
953     // FIXME #4948: Reuse ribs to avoid allocation.
954     value_ribs: Vec<Rib>,
955
956     // The current set of local scopes, for types.
957     type_ribs: Vec<Rib>,
958
959     // The current set of local scopes, for labels.
960     label_ribs: Vec<Rib>,
961
962     // The trait that the current context can refer to.
963     current_trait_ref: Option<(DefId, TraitRef)>,
964
965     // The current self type if inside an impl (used for better errors).
966     current_self_type: Option<Ty>,
967
968     // The ident for the keyword "self".
969     self_name: Name,
970     // The ident for the non-keyword "Self".
971     type_self_name: Name,
972
973     // The idents for the primitive types.
974     primitive_type_table: PrimitiveTypeTable,
975
976     def_map: DefMap,
977     freevars: RefCell<FreevarMap>,
978     freevars_seen: RefCell<NodeMap<NodeSet>>,
979     capture_mode_map: CaptureModeMap,
980     export_map2: ExportMap2,
981     trait_map: TraitMap,
982     external_exports: ExternalExports,
983     last_private: LastPrivateMap,
984
985     // Whether or not to print error messages. Can be set to true
986     // when getting additional info for error message suggestions,
987     // so as to avoid printing duplicate errors
988     emit_errors: bool,
989
990     used_imports: HashSet<(NodeId, Namespace)>,
991     used_crates: HashSet<CrateNum>,
992 }
993
994 struct BuildReducedGraphVisitor<'a, 'b:'a> {
995     resolver: &'a mut Resolver<'b>,
996     parent: ReducedGraphParent
997 }
998
999 impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
1000
1001     fn visit_item(&mut self, item: &Item) {
1002         let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
1003         let old_parent = replace(&mut self.parent, p);
1004         visit::walk_item(self, item);
1005         self.parent = old_parent;
1006     }
1007
1008     fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
1009         let parent = self.parent.clone();
1010         self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
1011                                                            parent.clone(),
1012                                                            |r| {
1013             let mut v = BuildReducedGraphVisitor {
1014                 resolver: r,
1015                 parent: parent.clone()
1016             };
1017             visit::walk_foreign_item(&mut v, foreign_item);
1018         })
1019     }
1020
1021     fn visit_view_item(&mut self, view_item: &ViewItem) {
1022         self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
1023     }
1024
1025     fn visit_block(&mut self, block: &Block) {
1026         let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
1027         let old_parent = replace(&mut self.parent, np);
1028         visit::walk_block(self, block);
1029         self.parent = old_parent;
1030     }
1031
1032 }
1033
1034 struct UnusedImportCheckVisitor<'a, 'b:'a> {
1035     resolver: &'a mut Resolver<'b>
1036 }
1037
1038 impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
1039     fn visit_view_item(&mut self, vi: &ViewItem) {
1040         self.resolver.check_for_item_unused_imports(vi);
1041         visit::walk_view_item(self, vi);
1042     }
1043 }
1044
1045 #[deriving(PartialEq)]
1046 enum FallbackChecks {
1047     Everything,
1048     OnlyTraitAndStatics
1049 }
1050
1051
1052 impl<'a> Resolver<'a> {
1053     fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
1054         let graph_root = NameBindings::new();
1055
1056         graph_root.define_module(NoParentLink,
1057                                  Some(DefId { krate: 0, node: 0 }),
1058                                  NormalModuleKind,
1059                                  false,
1060                                  true,
1061                                  crate_span);
1062
1063         let current_module = graph_root.get_module();
1064
1065         Resolver {
1066             session: session,
1067
1068             // The outermost module has def ID 0; this is not reflected in the
1069             // AST.
1070
1071             graph_root: graph_root,
1072
1073             trait_item_map: FnvHashMap::new(),
1074             structs: FnvHashMap::new(),
1075
1076             unresolved_imports: 0,
1077
1078             current_module: current_module,
1079             value_ribs: Vec::new(),
1080             type_ribs: Vec::new(),
1081             label_ribs: Vec::new(),
1082
1083             current_trait_ref: None,
1084             current_self_type: None,
1085
1086             self_name: special_names::self_,
1087             type_self_name: special_names::type_self,
1088
1089             primitive_type_table: PrimitiveTypeTable::new(),
1090
1091             def_map: RefCell::new(NodeMap::new()),
1092             freevars: RefCell::new(NodeMap::new()),
1093             freevars_seen: RefCell::new(NodeMap::new()),
1094             capture_mode_map: NodeMap::new(),
1095             export_map2: NodeMap::new(),
1096             trait_map: NodeMap::new(),
1097             used_imports: HashSet::new(),
1098             used_crates: HashSet::new(),
1099             external_exports: DefIdSet::new(),
1100             last_private: NodeMap::new(),
1101
1102             emit_errors: true,
1103         }
1104     }
1105     /// The main name resolution procedure.
1106     fn resolve(&mut self, krate: &ast::Crate) {
1107         self.build_reduced_graph(krate);
1108         self.session.abort_if_errors();
1109
1110         self.resolve_imports();
1111         self.session.abort_if_errors();
1112
1113         self.record_exports();
1114         self.session.abort_if_errors();
1115
1116         self.resolve_crate(krate);
1117         self.session.abort_if_errors();
1118
1119         self.check_for_unused_imports(krate);
1120     }
1121
1122     //
1123     // Reduced graph building
1124     //
1125     // Here we build the "reduced graph": the graph of the module tree without
1126     // any imports resolved.
1127     //
1128
1129     /// Constructs the reduced graph for the entire crate.
1130     fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1131         let parent = ModuleReducedGraphParent(self.graph_root.get_module());
1132         let mut visitor = BuildReducedGraphVisitor {
1133             resolver: self,
1134             parent: parent
1135         };
1136         visit::walk_crate(&mut visitor, krate);
1137     }
1138
1139     /// Adds a new child item to the module definition of the parent node and
1140     /// returns its corresponding name bindings as well as the current parent.
1141     /// Or, if we're inside a block, creates (or reuses) an anonymous module
1142     /// corresponding to the innermost block ID and returns the name bindings
1143     /// as well as the newly-created parent.
1144     ///
1145     /// # Panics
1146     ///
1147     /// Panics if this node does not have a module definition and we are not inside
1148     /// a block.
1149     fn add_child(&self,
1150                  name: Name,
1151                  reduced_graph_parent: ReducedGraphParent,
1152                  duplicate_checking_mode: DuplicateCheckingMode,
1153                  // For printing errors
1154                  sp: Span)
1155                  -> Rc<NameBindings> {
1156         // If this is the immediate descendant of a module, then we add the
1157         // child name directly. Otherwise, we create or reuse an anonymous
1158         // module and add the child to that.
1159
1160         let module_ = reduced_graph_parent.module();
1161
1162         self.check_for_conflicts_between_external_crates_and_items(&*module_,
1163                                                                    name,
1164                                                                    sp);
1165
1166         // Add or reuse the child.
1167         let child = module_.children.borrow().get(&name).cloned();
1168         match child {
1169             None => {
1170                 let child = Rc::new(NameBindings::new());
1171                 module_.children.borrow_mut().insert(name, child.clone());
1172                 child
1173             }
1174             Some(child) => {
1175                 // Enforce the duplicate checking mode:
1176                 //
1177                 // * If we're requesting duplicate module checking, check that
1178                 //   there isn't a module in the module with the same name.
1179                 //
1180                 // * If we're requesting duplicate type checking, check that
1181                 //   there isn't a type in the module with the same name.
1182                 //
1183                 // * If we're requesting duplicate value checking, check that
1184                 //   there isn't a value in the module with the same name.
1185                 //
1186                 // * If we're requesting duplicate type checking and duplicate
1187                 //   value checking, check that there isn't a duplicate type
1188                 //   and a duplicate value with the same name.
1189                 //
1190                 // * If no duplicate checking was requested at all, do
1191                 //   nothing.
1192
1193                 let mut duplicate_type = NoError;
1194                 let ns = match duplicate_checking_mode {
1195                     ForbidDuplicateModules => {
1196                         if child.get_module_if_available().is_some() {
1197                             duplicate_type = ModuleError;
1198                         }
1199                         Some(TypeNS)
1200                     }
1201                     ForbidDuplicateTypesAndModules => {
1202                         match child.def_for_namespace(TypeNS) {
1203                             None => {}
1204                             Some(_) if child.get_module_if_available()
1205                                             .map(|m| m.kind.get()) ==
1206                                        Some(ImplModuleKind) => {}
1207                             Some(_) => duplicate_type = TypeError
1208                         }
1209                         Some(TypeNS)
1210                     }
1211                     ForbidDuplicateValues => {
1212                         if child.defined_in_namespace(ValueNS) {
1213                             duplicate_type = ValueError;
1214                         }
1215                         Some(ValueNS)
1216                     }
1217                     ForbidDuplicateTypesAndValues => {
1218                         let mut n = None;
1219                         match child.def_for_namespace(TypeNS) {
1220                             Some(DefMod(_)) | None => {}
1221                             Some(_) => {
1222                                 n = Some(TypeNS);
1223                                 duplicate_type = TypeError;
1224                             }
1225                         };
1226                         if child.defined_in_namespace(ValueNS) {
1227                             duplicate_type = ValueError;
1228                             n = Some(ValueNS);
1229                         }
1230                         n
1231                     }
1232                     OverwriteDuplicates => None
1233                 };
1234                 if duplicate_type != NoError {
1235                     // Return an error here by looking up the namespace that
1236                     // had the duplicate.
1237                     let ns = ns.unwrap();
1238                     self.resolve_error(sp,
1239                         format!("duplicate definition of {} `{}`",
1240                              namespace_error_to_string(duplicate_type),
1241                              token::get_name(name)).as_slice());
1242                     {
1243                         let r = child.span_for_namespace(ns);
1244                         for sp in r.iter() {
1245                             self.session.span_note(*sp,
1246                                  format!("first definition of {} `{}` here",
1247                                       namespace_error_to_string(duplicate_type),
1248                                       token::get_name(name)).as_slice());
1249                         }
1250                     }
1251                 }
1252                 child
1253             }
1254         }
1255     }
1256
1257     fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1258         // If the block has view items, we need an anonymous module.
1259         if block.view_items.len() > 0 {
1260             return true;
1261         }
1262
1263         // Check each statement.
1264         for statement in block.stmts.iter() {
1265             match statement.node {
1266                 StmtDecl(ref declaration, _) => {
1267                     match declaration.node {
1268                         DeclItem(_) => {
1269                             return true;
1270                         }
1271                         _ => {
1272                             // Keep searching.
1273                         }
1274                     }
1275                 }
1276                 _ => {
1277                     // Keep searching.
1278                 }
1279             }
1280         }
1281
1282         // If we found neither view items nor items, we don't need to create
1283         // an anonymous module.
1284
1285         return false;
1286     }
1287
1288     fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
1289                            -> ParentLink {
1290         match parent {
1291             ModuleReducedGraphParent(module_) => {
1292                 return ModuleParentLink(module_.downgrade(), name);
1293             }
1294         }
1295     }
1296
1297     /// Constructs the reduced graph for one item.
1298     fn build_reduced_graph_for_item(&mut self,
1299                                     item: &Item,
1300                                     parent: ReducedGraphParent)
1301                                     -> ReducedGraphParent
1302     {
1303         let name = item.ident.name;
1304         let sp = item.span;
1305         let is_public = item.vis == ast::Public;
1306         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1307
1308         match item.node {
1309             ItemMod(..) => {
1310                 let name_bindings =
1311                     self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
1312
1313                 let parent_link = self.get_parent_link(parent, name);
1314                 let def_id = DefId { krate: 0, node: item.id };
1315                 name_bindings.define_module(parent_link,
1316                                             Some(def_id),
1317                                             NormalModuleKind,
1318                                             false,
1319                                             item.vis == ast::Public,
1320                                             sp);
1321
1322                 ModuleReducedGraphParent(name_bindings.get_module())
1323             }
1324
1325             ItemForeignMod(..) => parent,
1326
1327             // These items live in the value namespace.
1328             ItemStatic(_, m, _) => {
1329                 let name_bindings =
1330                     self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1331                 let mutbl = m == ast::MutMutable;
1332
1333                 name_bindings.define_value
1334                     (DefStatic(local_def(item.id), mutbl), sp, modifiers);
1335                 parent
1336             }
1337             ItemConst(_, _) => {
1338                 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
1339                     .define_value(DefConst(local_def(item.id)),
1340                                   sp, modifiers);
1341                 parent
1342             }
1343             ItemFn(_, _, _, _, _) => {
1344                 let name_bindings =
1345                     self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1346
1347                 let def = DefFn(local_def(item.id), false);
1348                 name_bindings.define_value(def, sp, modifiers);
1349                 parent
1350             }
1351
1352             // These items live in the type namespace.
1353             ItemTy(..) => {
1354                 let name_bindings =
1355                     self.add_child(name,
1356                                    parent.clone(),
1357                                    ForbidDuplicateTypesAndModules,
1358                                    sp);
1359
1360                 name_bindings.define_type
1361                     (DefTy(local_def(item.id), false), sp, modifiers);
1362                 parent
1363             }
1364
1365             ItemEnum(ref enum_definition, _) => {
1366                 let name_bindings =
1367                     self.add_child(name,
1368                                    parent.clone(),
1369                                    ForbidDuplicateTypesAndModules,
1370                                    sp);
1371
1372                 name_bindings.define_type
1373                     (DefTy(local_def(item.id), true), sp, modifiers);
1374
1375                 let parent_link = self.get_parent_link(parent.clone(), name);
1376                 // We want to make sure the module type is EnumModuleKind
1377                 // even if there's already an ImplModuleKind module defined,
1378                 // since that's how we prevent duplicate enum definitions
1379                 name_bindings.set_module_kind(parent_link,
1380                                               Some(local_def(item.id)),
1381                                               EnumModuleKind,
1382                                               false,
1383                                               is_public,
1384                                               sp);
1385
1386                 for variant in (*enum_definition).variants.iter() {
1387                     self.build_reduced_graph_for_variant(
1388                         &**variant,
1389                         local_def(item.id),
1390                         ModuleReducedGraphParent(name_bindings.get_module()));
1391                 }
1392                 parent
1393             }
1394
1395             // These items live in both the type and value namespaces.
1396             ItemStruct(ref struct_def, _) => {
1397                 // Adding to both Type and Value namespaces or just Type?
1398                 let (forbid, ctor_id) = match struct_def.ctor_id {
1399                     Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1400                     None            => (ForbidDuplicateTypesAndModules, None)
1401                 };
1402
1403                 let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
1404
1405                 // Define a name in the type namespace.
1406                 name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
1407
1408                 // If this is a newtype or unit-like struct, define a name
1409                 // in the value namespace as well
1410                 match ctor_id {
1411                     Some(cid) => {
1412                         name_bindings.define_value(DefStruct(local_def(cid)),
1413                                                    sp, modifiers);
1414                     }
1415                     None => {}
1416                 }
1417
1418                 // Record the def ID and fields of this struct.
1419                 let named_fields = struct_def.fields.iter().filter_map(|f| {
1420                     match f.node.kind {
1421                         NamedField(ident, _) => Some(ident.name),
1422                         UnnamedField(_) => None
1423                     }
1424                 }).collect();
1425                 self.structs.insert(local_def(item.id), named_fields);
1426
1427                 parent
1428             }
1429
1430             ItemImpl(_, None, ref ty, ref impl_items) => {
1431                 // If this implements an anonymous trait, then add all the
1432                 // methods within to a new module, if the type was defined
1433                 // within this module.
1434
1435                 let mod_name = match ty.node {
1436                     TyPath(ref path, _) if path.segments.len() == 1 => {
1437                         // FIXME(18446) we should distinguish between the name of
1438                         // a trait and the name of an impl of that trait.
1439                         Some(path.segments.last().unwrap().identifier.name)
1440                     }
1441                     TyObjectSum(ref lhs_ty, _) => {
1442                         match lhs_ty.node {
1443                             TyPath(ref path, _) if path.segments.len() == 1 => {
1444                                 Some(path.segments.last().unwrap().identifier.name)
1445                             }
1446                             _ => {
1447                                 None
1448                             }
1449                         }
1450                     }
1451                     _ => {
1452                         None
1453                     }
1454                 };
1455
1456                 match mod_name {
1457                     None => {
1458                         self.resolve_error(ty.span,
1459                                            "inherent implementations may \
1460                                             only be implemented in the same \
1461                                             module as the type they are \
1462                                             implemented for")
1463                     }
1464                     Some(mod_name) => {
1465                         // Create the module and add all methods.
1466                         let parent_opt = parent.module().children.borrow()
1467                             .get(&mod_name).cloned();
1468                         let new_parent = match parent_opt {
1469                             // It already exists
1470                             Some(ref child) if child.get_module_if_available()
1471                                 .is_some() &&
1472                                 (child.get_module().kind.get() == ImplModuleKind ||
1473                                  child.get_module().kind.get() == TraitModuleKind) => {
1474                                     ModuleReducedGraphParent(child.get_module())
1475                                 }
1476                             Some(ref child) if child.get_module_if_available()
1477                                 .is_some() &&
1478                                 child.get_module().kind.get() ==
1479                                 EnumModuleKind => {
1480                                     ModuleReducedGraphParent(child.get_module())
1481                                 }
1482                             // Create the module
1483                             _ => {
1484                                 let name_bindings =
1485                                     self.add_child(mod_name,
1486                                                    parent.clone(),
1487                                                    ForbidDuplicateModules,
1488                                                    sp);
1489
1490                                 let parent_link =
1491                                     self.get_parent_link(parent.clone(), name);
1492                                 let def_id = local_def(item.id);
1493                                 let ns = TypeNS;
1494                                 let is_public =
1495                                     !name_bindings.defined_in_namespace(ns) ||
1496                                     name_bindings.defined_in_public_namespace(ns);
1497
1498                                 name_bindings.define_module(parent_link,
1499                                                             Some(def_id),
1500                                                             ImplModuleKind,
1501                                                             false,
1502                                                             is_public,
1503                                                             sp);
1504
1505                                 ModuleReducedGraphParent(
1506                                     name_bindings.get_module())
1507                             }
1508                         };
1509
1510                         // For each implementation item...
1511                         for impl_item in impl_items.iter() {
1512                             match *impl_item {
1513                                 MethodImplItem(ref method) => {
1514                                     // Add the method to the module.
1515                                     let name = method.pe_ident().name;
1516                                     let method_name_bindings =
1517                                         self.add_child(name,
1518                                                        new_parent.clone(),
1519                                                        ForbidDuplicateValues,
1520                                                        method.span);
1521                                     let def = match method.pe_explicit_self()
1522                                         .node {
1523                                             SelfStatic => {
1524                                                 // Static methods become
1525                                                 // `DefStaticMethod`s.
1526                                                 DefStaticMethod(local_def(method.id),
1527                                                                 FromImpl(local_def(item.id)))
1528                                             }
1529                                             _ => {
1530                                                 // Non-static methods become
1531                                                 // `DefMethod`s.
1532                                                 DefMethod(local_def(method.id),
1533                                                           None,
1534                                                           FromImpl(local_def(item.id)))
1535                                             }
1536                                         };
1537
1538                                     // NB: not IMPORTABLE
1539                                     let modifiers = if method.pe_vis() == ast::Public {
1540                                         PUBLIC
1541                                     } else {
1542                                         DefModifiers::empty()
1543                                     };
1544                                     method_name_bindings.define_value(
1545                                         def,
1546                                         method.span,
1547                                         modifiers);
1548                                 }
1549                                 TypeImplItem(ref typedef) => {
1550                                     // Add the typedef to the module.
1551                                     let name = typedef.ident.name;
1552                                     let typedef_name_bindings =
1553                                         self.add_child(
1554                                             name,
1555                                             new_parent.clone(),
1556                                             ForbidDuplicateTypesAndModules,
1557                                             typedef.span);
1558                                     let def = DefAssociatedTy(local_def(
1559                                         typedef.id));
1560                                     // NB: not IMPORTABLE
1561                                     let modifiers = if typedef.vis == ast::Public {
1562                                         PUBLIC
1563                                     } else {
1564                                         DefModifiers::empty()
1565                                     };
1566                                     typedef_name_bindings.define_type(
1567                                         def,
1568                                         typedef.span,
1569                                         modifiers);
1570                                 }
1571                             }
1572                         }
1573                     }
1574                 }
1575
1576                 parent
1577             }
1578
1579             ItemImpl(_, Some(_), _, _) => parent,
1580
1581             ItemTrait(_, _, _, ref methods) => {
1582                 let name_bindings =
1583                     self.add_child(name,
1584                                    parent.clone(),
1585                                    ForbidDuplicateTypesAndModules,
1586                                    sp);
1587
1588                 // Add all the methods within to a new module.
1589                 let parent_link = self.get_parent_link(parent.clone(), name);
1590                 name_bindings.define_module(parent_link,
1591                                             Some(local_def(item.id)),
1592                                             TraitModuleKind,
1593                                             false,
1594                                             item.vis == ast::Public,
1595                                             sp);
1596                 let module_parent = ModuleReducedGraphParent(name_bindings.
1597                                                              get_module());
1598
1599                 let def_id = local_def(item.id);
1600
1601                 // Add the names of all the methods to the trait info.
1602                 for method in methods.iter() {
1603                     let (name, kind) = match *method {
1604                         ast::RequiredMethod(_) |
1605                         ast::ProvidedMethod(_) => {
1606                             let ty_m =
1607                                 ast_util::trait_item_to_ty_method(method);
1608
1609                             let name = ty_m.ident.name;
1610
1611                             // Add it as a name in the trait module.
1612                             let (def, static_flag) = match ty_m.explicit_self
1613                                                                .node {
1614                                 SelfStatic => {
1615                                     // Static methods become `DefStaticMethod`s.
1616                                     (DefStaticMethod(
1617                                             local_def(ty_m.id),
1618                                             FromTrait(local_def(item.id))),
1619                                      StaticMethodTraitItemKind)
1620                                 }
1621                                 _ => {
1622                                     // Non-static methods become `DefMethod`s.
1623                                     (DefMethod(local_def(ty_m.id),
1624                                                Some(local_def(item.id)),
1625                                                FromTrait(local_def(item.id))),
1626                                      NonstaticMethodTraitItemKind)
1627                                 }
1628                             };
1629
1630                             let method_name_bindings =
1631                                 self.add_child(name,
1632                                                module_parent.clone(),
1633                                                ForbidDuplicateTypesAndValues,
1634                                                ty_m.span);
1635                             // NB: not IMPORTABLE
1636                             method_name_bindings.define_value(def,
1637                                                               ty_m.span,
1638                                                               PUBLIC);
1639
1640                             (name, static_flag)
1641                         }
1642                         ast::TypeTraitItem(ref associated_type) => {
1643                             let def = DefAssociatedTy(local_def(
1644                                     associated_type.ty_param.id));
1645
1646                             let name_bindings =
1647                                 self.add_child(associated_type.ty_param.ident.name,
1648                                                module_parent.clone(),
1649                                                ForbidDuplicateTypesAndValues,
1650                                                associated_type.ty_param.span);
1651                             // NB: not IMPORTABLE
1652                             name_bindings.define_type(def,
1653                                                       associated_type.ty_param.span,
1654                                                       PUBLIC);
1655
1656                             (associated_type.ty_param.ident.name, TypeTraitItemKind)
1657                         }
1658                     };
1659
1660                     self.trait_item_map.insert((name, def_id), kind);
1661                 }
1662
1663                 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
1664                 parent
1665             }
1666             ItemMac(..) => parent
1667         }
1668     }
1669
1670     // Constructs the reduced graph for one variant. Variants exist in the
1671     // type and value namespaces.
1672     fn build_reduced_graph_for_variant(&mut self,
1673                                        variant: &Variant,
1674                                        item_id: DefId,
1675                                        parent: ReducedGraphParent) {
1676         let name = variant.node.name.name;
1677         let is_exported = match variant.node.kind {
1678             TupleVariantKind(_) => false,
1679             StructVariantKind(_) => {
1680                 // Not adding fields for variants as they are not accessed with a self receiver
1681                 self.structs.insert(local_def(variant.node.id), Vec::new());
1682                 true
1683             }
1684         };
1685
1686         let child = self.add_child(name, parent,
1687                                    ForbidDuplicateTypesAndValues,
1688                                    variant.span);
1689         // variants are always treated as importable to allow them to be glob
1690         // used
1691         child.define_value(DefVariant(item_id,
1692                                       local_def(variant.node.id), is_exported),
1693                            variant.span, PUBLIC | IMPORTABLE);
1694         child.define_type(DefVariant(item_id,
1695                                      local_def(variant.node.id), is_exported),
1696                           variant.span, PUBLIC | IMPORTABLE);
1697     }
1698
1699     /// Constructs the reduced graph for one 'view item'. View items consist
1700     /// of imports and use directives.
1701     fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1702                                          parent: ReducedGraphParent) {
1703         match view_item.node {
1704             ViewItemUse(ref view_path) => {
1705                 // Extract and intern the module part of the path. For
1706                 // globs and lists, the path is found directly in the AST;
1707                 // for simple paths we have to munge the path a little.
1708                 let module_path = match view_path.node {
1709                     ViewPathSimple(_, ref full_path, _) => {
1710                         full_path.segments
1711                             .init()
1712                             .iter().map(|ident| ident.identifier.name)
1713                             .collect()
1714                     }
1715
1716                     ViewPathGlob(ref module_ident_path, _) |
1717                     ViewPathList(ref module_ident_path, _, _) => {
1718                         module_ident_path.segments
1719                             .iter().map(|ident| ident.identifier.name).collect()
1720                     }
1721                 };
1722
1723                 // Build up the import directives.
1724                 let module_ = parent.module();
1725                 let is_public = view_item.vis == ast::Public;
1726                 let shadowable =
1727                     view_item.attrs
1728                              .iter()
1729                              .any(|attr| {
1730                                  attr.name() == token::get_name(
1731                                     special_idents::prelude_import.name)
1732                              });
1733
1734                 match view_path.node {
1735                     ViewPathSimple(binding, ref full_path, id) => {
1736                         let source_name =
1737                             full_path.segments.last().unwrap().identifier.name;
1738                         if token::get_name(source_name).get() == "mod" {
1739                             self.resolve_error(view_path.span,
1740                                 "`mod` imports are only allowed within a { } list");
1741                         }
1742
1743                         let subclass = SingleImport(binding.name,
1744                                                     source_name);
1745                         self.build_import_directive(&*module_,
1746                                                     module_path,
1747                                                     subclass,
1748                                                     view_path.span,
1749                                                     id,
1750                                                     is_public,
1751                                                     shadowable);
1752                     }
1753                     ViewPathList(_, ref source_items, _) => {
1754                         // Make sure there's at most one `mod` import in the list.
1755                         let mod_spans = source_items.iter().filter_map(|item| match item.node {
1756                             PathListMod { .. } => Some(item.span),
1757                             _ => None
1758                         }).collect::<Vec<Span>>();
1759                         if mod_spans.len() > 1 {
1760                             self.resolve_error(mod_spans[0],
1761                                 "`mod` import can only appear once in the list");
1762                             for other_span in mod_spans.iter().skip(1) {
1763                                 self.session.span_note(*other_span,
1764                                     "another `mod` import appears here");
1765                             }
1766                         }
1767
1768                         for source_item in source_items.iter() {
1769                             let (module_path, name) = match source_item.node {
1770                                 PathListIdent { name, .. } =>
1771                                     (module_path.clone(), name.name),
1772                                 PathListMod { .. } => {
1773                                     let name = match module_path.last() {
1774                                         Some(name) => *name,
1775                                         None => {
1776                                             self.resolve_error(source_item.span,
1777                                                 "`mod` import can only appear in an import list \
1778                                                  with a non-empty prefix");
1779                                             continue;
1780                                         }
1781                                     };
1782                                     let module_path = module_path.init();
1783                                     (module_path.to_vec(), name)
1784                                 }
1785                             };
1786                             self.build_import_directive(
1787                                 &*module_,
1788                                 module_path,
1789                                 SingleImport(name, name),
1790                                 source_item.span,
1791                                 source_item.node.id(),
1792                                 is_public,
1793                                 shadowable);
1794                         }
1795                     }
1796                     ViewPathGlob(_, id) => {
1797                         self.build_import_directive(&*module_,
1798                                                     module_path,
1799                                                     GlobImport,
1800                                                     view_path.span,
1801                                                     id,
1802                                                     is_public,
1803                                                     shadowable);
1804                     }
1805                 }
1806             }
1807
1808             ViewItemExternCrate(name, _, node_id) => {
1809                 // n.b. we don't need to look at the path option here, because cstore already did
1810                 for &crate_id in self.session.cstore
1811                                      .find_extern_mod_stmt_cnum(node_id).iter() {
1812                     let def_id = DefId { krate: crate_id, node: 0 };
1813                     self.external_exports.insert(def_id);
1814                     let parent_link =
1815                         ModuleParentLink(parent.module().downgrade(), name.name);
1816                     let external_module = Rc::new(Module::new(parent_link,
1817                                                               Some(def_id),
1818                                                               NormalModuleKind,
1819                                                               false,
1820                                                               true));
1821                     debug!("(build reduced graph for item) found extern `{}`",
1822                             self.module_to_string(&*external_module));
1823                     self.check_for_conflicts_between_external_crates(
1824                         &*parent.module(),
1825                         name.name,
1826                         view_item.span);
1827                     parent.module().external_module_children.borrow_mut()
1828                                    .insert(name.name, external_module.clone());
1829                     self.build_reduced_graph_for_external_crate(external_module);
1830                 }
1831             }
1832         }
1833     }
1834
1835     /// Constructs the reduced graph for one foreign item.
1836     fn build_reduced_graph_for_foreign_item(&mut self,
1837                                             foreign_item: &ForeignItem,
1838                                             parent: ReducedGraphParent,
1839                                             f: |&mut Resolver|) {
1840         let name = foreign_item.ident.name;
1841         let is_public = foreign_item.vis == ast::Public;
1842         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1843         let name_bindings =
1844             self.add_child(name, parent, ForbidDuplicateValues,
1845                            foreign_item.span);
1846
1847         match foreign_item.node {
1848             ForeignItemFn(_, ref generics) => {
1849                 let def = DefFn(local_def(foreign_item.id), false);
1850                 name_bindings.define_value(def, foreign_item.span, modifiers);
1851
1852                 self.with_type_parameter_rib(
1853                     HasTypeParameters(generics,
1854                                       FnSpace,
1855                                       foreign_item.id,
1856                                       NormalRibKind),
1857                     f);
1858             }
1859             ForeignItemStatic(_, m) => {
1860                 let def = DefStatic(local_def(foreign_item.id), m);
1861                 name_bindings.define_value(def, foreign_item.span, modifiers);
1862
1863                 f(self)
1864             }
1865         }
1866     }
1867
1868     fn build_reduced_graph_for_block(&mut self,
1869                                          block: &Block,
1870                                          parent: ReducedGraphParent)
1871                                             -> ReducedGraphParent
1872     {
1873         if self.block_needs_anonymous_module(block) {
1874             let block_id = block.id;
1875
1876             debug!("(building reduced graph for block) creating a new \
1877                     anonymous module for block {}",
1878                    block_id);
1879
1880             let parent_module = parent.module();
1881             let new_module = Rc::new(Module::new(
1882                 BlockParentLink(parent_module.downgrade(), block_id),
1883                 None,
1884                 AnonymousModuleKind,
1885                 false,
1886                 false));
1887             parent_module.anonymous_children.borrow_mut()
1888                          .insert(block_id, new_module.clone());
1889             ModuleReducedGraphParent(new_module)
1890         } else {
1891             parent
1892         }
1893     }
1894
1895     fn handle_external_def(&mut self,
1896                            def: Def,
1897                            vis: Visibility,
1898                            child_name_bindings: &NameBindings,
1899                            final_ident: &str,
1900                            name: Name,
1901                            new_parent: ReducedGraphParent) {
1902         debug!("(building reduced graph for \
1903                 external crate) building external def, priv {}",
1904                vis);
1905         let is_public = vis == ast::Public;
1906         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1907         let is_exported = is_public && match new_parent {
1908             ModuleReducedGraphParent(ref module) => {
1909                 match module.def_id.get() {
1910                     None => true,
1911                     Some(did) => self.external_exports.contains(&did)
1912                 }
1913             }
1914         };
1915         if is_exported {
1916             self.external_exports.insert(def.def_id());
1917         }
1918
1919         let kind = match def {
1920             DefTy(_, true) => EnumModuleKind,
1921             DefStruct(..) | DefTy(..) => ImplModuleKind,
1922             _ => NormalModuleKind
1923         };
1924
1925         match def {
1926           DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1927           DefTy(def_id, _) => {
1928             let type_def = child_name_bindings.type_def.borrow().clone();
1929             match type_def {
1930               Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1931                 debug!("(building reduced graph for external crate) \
1932                         already created module");
1933                 module_def.def_id.set(Some(def_id));
1934               }
1935               Some(_) | None => {
1936                 debug!("(building reduced graph for \
1937                         external crate) building module \
1938                         {}", final_ident);
1939                 let parent_link = self.get_parent_link(new_parent.clone(), name);
1940
1941                 child_name_bindings.define_module(parent_link,
1942                                                   Some(def_id),
1943                                                   kind,
1944                                                   true,
1945                                                   is_public,
1946                                                   DUMMY_SP);
1947               }
1948             }
1949           }
1950           _ => {}
1951         }
1952
1953         match def {
1954           DefMod(_) | DefForeignMod(_) => {}
1955           DefVariant(_, variant_id, is_struct) => {
1956               debug!("(building reduced graph for external crate) building \
1957                       variant {}",
1958                       final_ident);
1959               // variants are always treated as importable to allow them to be
1960               // glob used
1961               let modifiers = PUBLIC | IMPORTABLE;
1962               if is_struct {
1963                   child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1964                   // Not adding fields for variants as they are not accessed with a self receiver
1965                   self.structs.insert(variant_id, Vec::new());
1966               } else {
1967                   child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1968               }
1969           }
1970           DefFn(ctor_id, true) => {
1971             child_name_bindings.define_value(
1972                 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
1973                     .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
1974           }
1975           DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
1976             debug!("(building reduced graph for external \
1977                     crate) building value (fn/static) {}", final_ident);
1978             // impl methods have already been defined with the correct importability modifier
1979             let mut modifiers = match *child_name_bindings.value_def.borrow() {
1980                 Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
1981                 None => modifiers
1982             };
1983             if new_parent.module().kind.get() != NormalModuleKind {
1984                 modifiers = modifiers & !IMPORTABLE;
1985             }
1986             child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1987           }
1988           DefTrait(def_id) => {
1989               debug!("(building reduced graph for external \
1990                       crate) building type {}", final_ident);
1991
1992               // If this is a trait, add all the trait item names to the trait
1993               // info.
1994
1995               let trait_item_def_ids =
1996                 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1997               for trait_item_def_id in trait_item_def_ids.iter() {
1998                   let (trait_item_name, trait_item_kind) =
1999                       csearch::get_trait_item_name_and_kind(
2000                           &self.session.cstore,
2001                           trait_item_def_id.def_id());
2002
2003                   debug!("(building reduced graph for external crate) ... \
2004                           adding trait item '{}'",
2005                          token::get_name(trait_item_name));
2006
2007                   self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
2008
2009                   if is_exported {
2010                       self.external_exports
2011                           .insert(trait_item_def_id.def_id());
2012                   }
2013               }
2014
2015               child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2016
2017               // Define a module if necessary.
2018               let parent_link = self.get_parent_link(new_parent, name);
2019               child_name_bindings.set_module_kind(parent_link,
2020                                                   Some(def_id),
2021                                                   TraitModuleKind,
2022                                                   true,
2023                                                   is_public,
2024                                                   DUMMY_SP)
2025           }
2026           DefTy(..) | DefAssociatedTy(..) => {
2027               debug!("(building reduced graph for external \
2028                       crate) building type {}", final_ident);
2029
2030               child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2031           }
2032           DefStruct(def_id) => {
2033             debug!("(building reduced graph for external \
2034                     crate) building type and value for {}",
2035                    final_ident);
2036             child_name_bindings.define_type(def, DUMMY_SP, modifiers);
2037             let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
2038                 f.name
2039             }).collect::<Vec<_>>();
2040
2041             if fields.len() == 0 {
2042                 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
2043             }
2044
2045             // Record the def ID and fields of this struct.
2046             self.structs.insert(def_id, fields);
2047           }
2048           DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
2049           DefUse(..) | DefUpvar(..) | DefRegion(..) |
2050           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
2051             panic!("didn't expect `{}`", def);
2052           }
2053         }
2054     }
2055
2056     /// Builds the reduced graph for a single item in an external crate.
2057     fn build_reduced_graph_for_external_crate_def(&mut self,
2058                                                   root: Rc<Module>,
2059                                                   def_like: DefLike,
2060                                                   name: Name,
2061                                                   visibility: Visibility) {
2062         match def_like {
2063             DlDef(def) => {
2064                 // Add the new child item, if necessary.
2065                 match def {
2066                     DefForeignMod(def_id) => {
2067                         // Foreign modules have no names. Recur and populate
2068                         // eagerly.
2069                         csearch::each_child_of_item(&self.session.cstore,
2070                                                     def_id,
2071                                                     |def_like,
2072                                                      child_name,
2073                                                      vis| {
2074                             self.build_reduced_graph_for_external_crate_def(
2075                                 root.clone(),
2076                                 def_like,
2077                                 child_name,
2078                                 vis)
2079                         });
2080                     }
2081                     _ => {
2082                         let child_name_bindings =
2083                             self.add_child(name,
2084                                            ModuleReducedGraphParent(root.clone()),
2085                                            OverwriteDuplicates,
2086                                            DUMMY_SP);
2087
2088                         self.handle_external_def(def,
2089                                                  visibility,
2090                                                  &*child_name_bindings,
2091                                                  token::get_name(name).get(),
2092                                                  name,
2093                                                  ModuleReducedGraphParent(root));
2094                     }
2095                 }
2096             }
2097             DlImpl(def) => {
2098                 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
2099                     None => {}
2100                     Some(final_name) => {
2101                         let methods_opt =
2102                             csearch::get_methods_if_impl(&self.session.cstore, def);
2103                         match methods_opt {
2104                             Some(ref methods) if
2105                                 methods.len() >= 1 => {
2106                                 debug!("(building reduced graph for \
2107                                         external crate) processing \
2108                                         static methods for type name {}",
2109                                         token::get_name(final_name));
2110
2111                                 let child_name_bindings =
2112                                     self.add_child(
2113                                         final_name,
2114                                         ModuleReducedGraphParent(root.clone()),
2115                                         OverwriteDuplicates,
2116                                         DUMMY_SP);
2117
2118                                 // Process the static methods. First,
2119                                 // create the module.
2120                                 let type_module;
2121                                 let type_def = child_name_bindings.type_def.borrow().clone();
2122                                 match type_def {
2123                                     Some(TypeNsDef {
2124                                         module_def: Some(module_def),
2125                                         ..
2126                                     }) => {
2127                                         // We already have a module. This
2128                                         // is OK.
2129                                         type_module = module_def;
2130
2131                                         // Mark it as an impl module if
2132                                         // necessary.
2133                                         type_module.kind.set(ImplModuleKind);
2134                                     }
2135                                     Some(_) | None => {
2136                                         let parent_link =
2137                                             self.get_parent_link(ModuleReducedGraphParent(root),
2138                                                                  final_name);
2139                                         child_name_bindings.define_module(
2140                                             parent_link,
2141                                             Some(def),
2142                                             ImplModuleKind,
2143                                             true,
2144                                             true,
2145                                             DUMMY_SP);
2146                                         type_module =
2147                                             child_name_bindings.
2148                                                 get_module();
2149                                     }
2150                                 }
2151
2152                                 // Add each static method to the module.
2153                                 let new_parent =
2154                                     ModuleReducedGraphParent(type_module);
2155                                 for method_info in methods.iter() {
2156                                     let name = method_info.name;
2157                                     debug!("(building reduced graph for \
2158                                              external crate) creating \
2159                                              static method '{}'",
2160                                            token::get_name(name));
2161
2162                                     let method_name_bindings =
2163                                         self.add_child(name,
2164                                                        new_parent.clone(),
2165                                                        OverwriteDuplicates,
2166                                                        DUMMY_SP);
2167                                     let def = DefFn(method_info.def_id, false);
2168
2169                                     // NB: not IMPORTABLE
2170                                     let modifiers = if visibility == ast::Public {
2171                                         PUBLIC
2172                                     } else {
2173                                         DefModifiers::empty()
2174                                     };
2175                                     method_name_bindings.define_value(
2176                                         def, DUMMY_SP, modifiers);
2177                                 }
2178                             }
2179
2180                             // Otherwise, do nothing.
2181                             Some(_) | None => {}
2182                         }
2183                     }
2184                 }
2185             }
2186             DlField => {
2187                 debug!("(building reduced graph for external crate) \
2188                         ignoring field");
2189             }
2190         }
2191     }
2192
2193     /// Builds the reduced graph rooted at the given external module.
2194     fn populate_external_module(&mut self, module: Rc<Module>) {
2195         debug!("(populating external module) attempting to populate {}",
2196                self.module_to_string(&*module));
2197
2198         let def_id = match module.def_id.get() {
2199             None => {
2200                 debug!("(populating external module) ... no def ID!");
2201                 return
2202             }
2203             Some(def_id) => def_id,
2204         };
2205
2206         csearch::each_child_of_item(&self.session.cstore,
2207                                     def_id,
2208                                     |def_like, child_name, visibility| {
2209             debug!("(populating external module) ... found ident: {}",
2210                    token::get_name(child_name));
2211             self.build_reduced_graph_for_external_crate_def(module.clone(),
2212                                                             def_like,
2213                                                             child_name,
2214                                                             visibility)
2215         });
2216         module.populated.set(true)
2217     }
2218
2219     /// Ensures that the reduced graph rooted at the given external module
2220     /// is built, building it if it is not.
2221     fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2222         if !module.populated.get() {
2223             self.populate_external_module(module.clone())
2224         }
2225         assert!(module.populated.get())
2226     }
2227
2228     /// Builds the reduced graph rooted at the 'use' directive for an external
2229     /// crate.
2230     fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2231         csearch::each_top_level_item_of_crate(&self.session.cstore,
2232                                               root.def_id
2233                                                   .get()
2234                                                   .unwrap()
2235                                                   .krate,
2236                                               |def_like, name, visibility| {
2237             self.build_reduced_graph_for_external_crate_def(root.clone(),
2238                                                             def_like,
2239                                                             name,
2240                                                             visibility)
2241         });
2242     }
2243
2244     /// Creates and adds an import directive to the given module.
2245     fn build_import_directive(&mut self,
2246                               module_: &Module,
2247                               module_path: Vec<Name>,
2248                               subclass: ImportDirectiveSubclass,
2249                               span: Span,
2250                               id: NodeId,
2251                               is_public: bool,
2252                               shadowable: bool) {
2253         module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2254                                                                subclass,
2255                                                                span,
2256                                                                id,
2257                                                                is_public,
2258                                                                shadowable));
2259         self.unresolved_imports += 1;
2260         // Bump the reference count on the name. Or, if this is a glob, set
2261         // the appropriate flag.
2262
2263         match subclass {
2264             SingleImport(target, _) => {
2265                 debug!("(building import directive) building import \
2266                         directive: {}::{}",
2267                        self.names_to_string(module_.imports.borrow().last().unwrap()
2268                                                  .module_path.as_slice()),
2269                        token::get_name(target));
2270
2271                 let mut import_resolutions = module_.import_resolutions
2272                                                     .borrow_mut();
2273                 match import_resolutions.get_mut(&target) {
2274                     Some(resolution) => {
2275                         debug!("(building import directive) bumping \
2276                                 reference");
2277                         resolution.outstanding_references += 1;
2278
2279                         // the source of this name is different now
2280                         resolution.type_id = id;
2281                         resolution.value_id = id;
2282                         resolution.is_public = is_public;
2283                         return;
2284                     }
2285                     None => {}
2286                 }
2287                 debug!("(building import directive) creating new");
2288                 let mut resolution = ImportResolution::new(id, is_public);
2289                 resolution.outstanding_references = 1;
2290                 import_resolutions.insert(target, resolution);
2291             }
2292             GlobImport => {
2293                 // Set the glob flag. This tells us that we don't know the
2294                 // module's exports ahead of time.
2295
2296                 module_.glob_count.set(module_.glob_count.get() + 1);
2297             }
2298         }
2299     }
2300
2301     // Import resolution
2302     //
2303     // This is a fixed-point algorithm. We resolve imports until our efforts
2304     // are stymied by an unresolved import; then we bail out of the current
2305     // module and continue. We terminate successfully once no more imports
2306     // remain or unsuccessfully when no forward progress in resolving imports
2307     // is made.
2308
2309     /// Resolves all imports for the crate. This method performs the fixed-
2310     /// point iteration.
2311     fn resolve_imports(&mut self) {
2312         let mut i = 0u;
2313         let mut prev_unresolved_imports = 0;
2314         loop {
2315             debug!("(resolving imports) iteration {}, {} imports left",
2316                    i, self.unresolved_imports);
2317
2318             let module_root = self.graph_root.get_module();
2319             self.resolve_imports_for_module_subtree(module_root.clone());
2320
2321             if self.unresolved_imports == 0 {
2322                 debug!("(resolving imports) success");
2323                 break;
2324             }
2325
2326             if self.unresolved_imports == prev_unresolved_imports {
2327                 self.report_unresolved_imports(module_root);
2328                 break;
2329             }
2330
2331             i += 1;
2332             prev_unresolved_imports = self.unresolved_imports;
2333         }
2334     }
2335
2336     /// Attempts to resolve imports for the given module and all of its
2337     /// submodules.
2338     fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2339         debug!("(resolving imports for module subtree) resolving {}",
2340                self.module_to_string(&*module_));
2341         let orig_module = replace(&mut self.current_module, module_.clone());
2342         self.resolve_imports_for_module(module_.clone());
2343         self.current_module = orig_module;
2344
2345         self.populate_module_if_necessary(&module_);
2346         for (_, child_node) in module_.children.borrow().iter() {
2347             match child_node.get_module_if_available() {
2348                 None => {
2349                     // Nothing to do.
2350                 }
2351                 Some(child_module) => {
2352                     self.resolve_imports_for_module_subtree(child_module);
2353                 }
2354             }
2355         }
2356
2357         for (_, child_module) in module_.anonymous_children.borrow().iter() {
2358             self.resolve_imports_for_module_subtree(child_module.clone());
2359         }
2360     }
2361
2362     /// Attempts to resolve imports for the given module only.
2363     fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2364         if module.all_imports_resolved() {
2365             debug!("(resolving imports for module) all imports resolved for \
2366                    {}",
2367                    self.module_to_string(&*module));
2368             return;
2369         }
2370
2371         let imports = module.imports.borrow();
2372         let import_count = imports.len();
2373         while module.resolved_import_count.get() < import_count {
2374             let import_index = module.resolved_import_count.get();
2375             let import_directive = &(*imports)[import_index];
2376             match self.resolve_import_for_module(module.clone(),
2377                                                  import_directive) {
2378                 Failed(err) => {
2379                     let (span, help) = match err {
2380                         Some((span, msg)) => (span, format!(". {}", msg)),
2381                         None => (import_directive.span, String::new())
2382                     };
2383                     let msg = format!("unresolved import `{}`{}",
2384                                       self.import_path_to_string(
2385                                           import_directive.module_path
2386                                                           .as_slice(),
2387                                           import_directive.subclass),
2388                                       help);
2389                     self.resolve_error(span, msg.as_slice());
2390                 }
2391                 Indeterminate => break, // Bail out. We'll come around next time.
2392                 Success(()) => () // Good. Continue.
2393             }
2394
2395             module.resolved_import_count
2396                   .set(module.resolved_import_count.get() + 1);
2397         }
2398     }
2399
2400     fn names_to_string(&self, names: &[Name]) -> String {
2401         let mut first = true;
2402         let mut result = String::new();
2403         for name in names.iter() {
2404             if first {
2405                 first = false
2406             } else {
2407                 result.push_str("::")
2408             }
2409             result.push_str(token::get_name(*name).get());
2410         };
2411         result
2412     }
2413
2414     fn path_names_to_string(&self, path: &Path) -> String {
2415         let names: Vec<ast::Name> = path.segments
2416                                         .iter()
2417                                         .map(|seg| seg.identifier.name)
2418                                         .collect();
2419         self.names_to_string(names.as_slice())
2420     }
2421
2422     fn import_directive_subclass_to_string(&mut self,
2423                                         subclass: ImportDirectiveSubclass)
2424                                         -> String {
2425         match subclass {
2426             SingleImport(_, source) => {
2427                 token::get_name(source).get().to_string()
2428             }
2429             GlobImport => "*".to_string()
2430         }
2431     }
2432
2433     fn import_path_to_string(&mut self,
2434                           names: &[Name],
2435                           subclass: ImportDirectiveSubclass)
2436                           -> String {
2437         if names.is_empty() {
2438             self.import_directive_subclass_to_string(subclass)
2439         } else {
2440             (format!("{}::{}",
2441                      self.names_to_string(names),
2442                      self.import_directive_subclass_to_string(
2443                          subclass))).to_string()
2444         }
2445     }
2446
2447     /// Attempts to resolve the given import. The return value indicates
2448     /// failure if we're certain the name does not exist, indeterminate if we
2449     /// don't know whether the name exists at the moment due to other
2450     /// currently-unresolved imports, or success if we know the name exists.
2451     /// If successful, the resolved bindings are written into the module.
2452     fn resolve_import_for_module(&mut self,
2453                                  module_: Rc<Module>,
2454                                  import_directive: &ImportDirective)
2455                                  -> ResolveResult<()> {
2456         let mut resolution_result = Failed(None);
2457         let module_path = &import_directive.module_path;
2458
2459         debug!("(resolving import for module) resolving import `{}::...` in \
2460                 `{}`",
2461                self.names_to_string(module_path.as_slice()),
2462                self.module_to_string(&*module_));
2463
2464         // First, resolve the module path for the directive, if necessary.
2465         let container = if module_path.len() == 0 {
2466             // Use the crate root.
2467             Some((self.graph_root.get_module(), LastMod(AllPublic)))
2468         } else {
2469             match self.resolve_module_path(module_.clone(),
2470                                            module_path.as_slice(),
2471                                            DontUseLexicalScope,
2472                                            import_directive.span,
2473                                            ImportSearch) {
2474                 Failed(err) => {
2475                     resolution_result = Failed(err);
2476                     None
2477                 },
2478                 Indeterminate => {
2479                     resolution_result = Indeterminate;
2480                     None
2481                 }
2482                 Success(container) => Some(container),
2483             }
2484         };
2485
2486         match container {
2487             None => {}
2488             Some((containing_module, lp)) => {
2489                 // We found the module that the target is contained
2490                 // within. Attempt to resolve the import within it.
2491
2492                 match import_directive.subclass {
2493                     SingleImport(target, source) => {
2494                         resolution_result =
2495                             self.resolve_single_import(&*module_,
2496                                                        containing_module,
2497                                                        target,
2498                                                        source,
2499                                                        import_directive,
2500                                                        lp);
2501                     }
2502                     GlobImport => {
2503                         resolution_result =
2504                             self.resolve_glob_import(&*module_,
2505                                                      containing_module,
2506                                                      import_directive,
2507                                                      lp);
2508                     }
2509                 }
2510             }
2511         }
2512
2513         // Decrement the count of unresolved imports.
2514         match resolution_result {
2515             Success(()) => {
2516                 assert!(self.unresolved_imports >= 1);
2517                 self.unresolved_imports -= 1;
2518             }
2519             _ => {
2520                 // Nothing to do here; just return the error.
2521             }
2522         }
2523
2524         // Decrement the count of unresolved globs if necessary. But only if
2525         // the resolution result is indeterminate -- otherwise we'll stop
2526         // processing imports here. (See the loop in
2527         // resolve_imports_for_module.)
2528
2529         if !resolution_result.indeterminate() {
2530             match import_directive.subclass {
2531                 GlobImport => {
2532                     assert!(module_.glob_count.get() >= 1);
2533                     module_.glob_count.set(module_.glob_count.get() - 1);
2534                 }
2535                 SingleImport(..) => {
2536                     // Ignore.
2537                 }
2538             }
2539         }
2540
2541         return resolution_result;
2542     }
2543
2544     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2545         NameBindings {
2546             type_def: RefCell::new(Some(TypeNsDef {
2547                 modifiers: IMPORTABLE,
2548                 module_def: Some(module),
2549                 type_def: None,
2550                 type_span: None
2551             })),
2552             value_def: RefCell::new(None),
2553         }
2554     }
2555
2556     fn resolve_single_import(&mut self,
2557                              module_: &Module,
2558                              containing_module: Rc<Module>,
2559                              target: Name,
2560                              source: Name,
2561                              directive: &ImportDirective,
2562                              lp: LastPrivate)
2563                                  -> ResolveResult<()> {
2564         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2565                 `{}` id {}, last private {}",
2566                token::get_name(target),
2567                self.module_to_string(&*containing_module),
2568                token::get_name(source),
2569                self.module_to_string(module_),
2570                directive.id,
2571                lp);
2572
2573         let lp = match lp {
2574             LastMod(lp) => lp,
2575             LastImport {..} => {
2576                 self.session
2577                     .span_bug(directive.span,
2578                               "not expecting Import here, must be LastMod")
2579             }
2580         };
2581
2582         // We need to resolve both namespaces for this to succeed.
2583         //
2584
2585         let mut value_result = UnknownResult;
2586         let mut type_result = UnknownResult;
2587
2588         // Search for direct children of the containing module.
2589         self.populate_module_if_necessary(&containing_module);
2590
2591         match containing_module.children.borrow().get(&source) {
2592             None => {
2593                 // Continue.
2594             }
2595             Some(ref child_name_bindings) => {
2596                 if child_name_bindings.defined_in_namespace(ValueNS) {
2597                     debug!("(resolving single import) found value binding");
2598                     value_result = BoundResult(containing_module.clone(),
2599                                                (*child_name_bindings).clone());
2600                 }
2601                 if child_name_bindings.defined_in_namespace(TypeNS) {
2602                     debug!("(resolving single import) found type binding");
2603                     type_result = BoundResult(containing_module.clone(),
2604                                               (*child_name_bindings).clone());
2605                 }
2606             }
2607         }
2608
2609         // Unless we managed to find a result in both namespaces (unlikely),
2610         // search imports as well.
2611         let mut value_used_reexport = false;
2612         let mut type_used_reexport = false;
2613         match (value_result.clone(), type_result.clone()) {
2614             (BoundResult(..), BoundResult(..)) => {} // Continue.
2615             _ => {
2616                 // If there is an unresolved glob at this point in the
2617                 // containing module, bail out. We don't know enough to be
2618                 // able to resolve this import.
2619
2620                 if containing_module.glob_count.get() > 0 {
2621                     debug!("(resolving single import) unresolved glob; \
2622                             bailing out");
2623                     return Indeterminate;
2624                 }
2625
2626                 // Now search the exported imports within the containing module.
2627                 match containing_module.import_resolutions.borrow().get(&source) {
2628                     None => {
2629                         debug!("(resolving single import) no import");
2630                         // The containing module definitely doesn't have an
2631                         // exported import with the name in question. We can
2632                         // therefore accurately report that the names are
2633                         // unbound.
2634
2635                         if value_result.is_unknown() {
2636                             value_result = UnboundResult;
2637                         }
2638                         if type_result.is_unknown() {
2639                             type_result = UnboundResult;
2640                         }
2641                     }
2642                     Some(import_resolution)
2643                             if import_resolution.outstanding_references == 0 => {
2644
2645                         fn get_binding(this: &mut Resolver,
2646                                        import_resolution: &ImportResolution,
2647                                        namespace: Namespace)
2648                                     -> NamespaceResult {
2649
2650                             // Import resolutions must be declared with "pub"
2651                             // in order to be exported.
2652                             if !import_resolution.is_public {
2653                                 return UnboundResult;
2654                             }
2655
2656                             match import_resolution.
2657                                     target_for_namespace(namespace) {
2658                                 None => {
2659                                     return UnboundResult;
2660                                 }
2661                                 Some(Target {
2662                                     target_module,
2663                                     bindings,
2664                                     shadowable: _
2665                                 }) => {
2666                                     debug!("(resolving single import) found \
2667                                             import in ns {}", namespace);
2668                                     let id = import_resolution.id(namespace);
2669                                     // track used imports and extern crates as well
2670                                     this.used_imports.insert((id, namespace));
2671                                     match target_module.def_id.get() {
2672                                         Some(DefId{krate: kid, ..}) => {
2673                                             this.used_crates.insert(kid);
2674                                         },
2675                                         _ => {}
2676                                     }
2677                                     return BoundResult(target_module, bindings);
2678                                 }
2679                             }
2680                         }
2681
2682                         // The name is an import which has been fully
2683                         // resolved. We can, therefore, just follow it.
2684                         if value_result.is_unknown() {
2685                             value_result = get_binding(self, import_resolution,
2686                                                        ValueNS);
2687                             value_used_reexport = import_resolution.is_public;
2688                         }
2689                         if type_result.is_unknown() {
2690                             type_result = get_binding(self, import_resolution,
2691                                                       TypeNS);
2692                             type_used_reexport = import_resolution.is_public;
2693                         }
2694
2695                     }
2696                     Some(_) => {
2697                         // If containing_module is the same module whose import we are resolving
2698                         // and there it has an unresolved import with the same name as `source`,
2699                         // then the user is actually trying to import an item that is declared
2700                         // in the same scope
2701                         //
2702                         // e.g
2703                         // use self::submodule;
2704                         // pub mod submodule;
2705                         //
2706                         // In this case we continue as if we resolved the import and let the
2707                         // check_for_conflicts_between_imports_and_items call below handle
2708                         // the conflict
2709                         match (module_.def_id.get(),  containing_module.def_id.get()) {
2710                             (Some(id1), Some(id2)) if id1 == id2  => {
2711                                 if value_result.is_unknown() {
2712                                     value_result = UnboundResult;
2713                                 }
2714                                 if type_result.is_unknown() {
2715                                     type_result = UnboundResult;
2716                                 }
2717                             }
2718                             _ =>  {
2719                                 // The import is unresolved. Bail out.
2720                                 debug!("(resolving single import) unresolved import; \
2721                                         bailing out");
2722                                 return Indeterminate;
2723                             }
2724                         }
2725                     }
2726                 }
2727             }
2728         }
2729
2730         // If we didn't find a result in the type namespace, search the
2731         // external modules.
2732         let mut value_used_public = false;
2733         let mut type_used_public = false;
2734         match type_result {
2735             BoundResult(..) => {}
2736             _ => {
2737                 match containing_module.external_module_children.borrow_mut()
2738                                        .get(&source).cloned() {
2739                     None => {} // Continue.
2740                     Some(module) => {
2741                         debug!("(resolving single import) found external \
2742                                 module");
2743                         // track the module as used.
2744                         match module.def_id.get() {
2745                             Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
2746                             _ => {}
2747                         }
2748                         let name_bindings =
2749                             Rc::new(Resolver::create_name_bindings_from_module(
2750                                 module));
2751                         type_result = BoundResult(containing_module.clone(),
2752                                                   name_bindings);
2753                         type_used_public = true;
2754                     }
2755                 }
2756             }
2757         }
2758
2759         // We've successfully resolved the import. Write the results in.
2760         let mut import_resolutions = module_.import_resolutions.borrow_mut();
2761         let import_resolution = &mut (*import_resolutions)[target];
2762
2763         match value_result {
2764             BoundResult(ref target_module, ref name_bindings) => {
2765                 debug!("(resolving single import) found value target: {}",
2766                        { name_bindings.value_def.borrow().clone().unwrap().def });
2767                 self.check_for_conflicting_import(
2768                     &import_resolution.value_target,
2769                     directive.span,
2770                     target,
2771                     ValueNS);
2772
2773                 self.check_that_import_is_importable(
2774                     &**name_bindings,
2775                     directive.span,
2776                     target,
2777                     ValueNS);
2778
2779                 import_resolution.value_target =
2780                     Some(Target::new(target_module.clone(),
2781                                      name_bindings.clone(),
2782                                      directive.shadowable));
2783                 import_resolution.value_id = directive.id;
2784                 import_resolution.is_public = directive.is_public;
2785                 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2786             }
2787             UnboundResult => { /* Continue. */ }
2788             UnknownResult => {
2789                 panic!("value result should be known at this point");
2790             }
2791         }
2792         match type_result {
2793             BoundResult(ref target_module, ref name_bindings) => {
2794                 debug!("(resolving single import) found type target: {}",
2795                        { name_bindings.type_def.borrow().clone().unwrap().type_def });
2796                 self.check_for_conflicting_import(
2797                     &import_resolution.type_target,
2798                     directive.span,
2799                     target,
2800                     TypeNS);
2801
2802                 self.check_that_import_is_importable(
2803                     &**name_bindings,
2804                     directive.span,
2805                     target,
2806                     TypeNS);
2807
2808                 import_resolution.type_target =
2809                     Some(Target::new(target_module.clone(),
2810                                      name_bindings.clone(),
2811                                      directive.shadowable));
2812                 import_resolution.type_id = directive.id;
2813                 import_resolution.is_public = directive.is_public;
2814                 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2815             }
2816             UnboundResult => { /* Continue. */ }
2817             UnknownResult => {
2818                 panic!("type result should be known at this point");
2819             }
2820         }
2821
2822         self.check_for_conflicts_between_imports_and_items(
2823             module_,
2824             import_resolution,
2825             directive.span,
2826             target);
2827
2828         if value_result.is_unbound() && type_result.is_unbound() {
2829             let msg = format!("There is no `{}` in `{}`",
2830                               token::get_name(source),
2831                               self.module_to_string(&*containing_module));
2832             return Failed(Some((directive.span, msg)));
2833         }
2834         let value_used_public = value_used_reexport || value_used_public;
2835         let type_used_public = type_used_reexport || type_used_public;
2836
2837         assert!(import_resolution.outstanding_references >= 1);
2838         import_resolution.outstanding_references -= 1;
2839
2840         // record what this import resolves to for later uses in documentation,
2841         // this may resolve to either a value or a type, but for documentation
2842         // purposes it's good enough to just favor one over the other.
2843         let value_private = match import_resolution.value_target {
2844             Some(ref target) => {
2845                 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2846                 self.def_map.borrow_mut().insert(directive.id, def);
2847                 let did = def.def_id();
2848                 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2849             },
2850             // AllPublic here and below is a dummy value, it should never be used because
2851             // _exists is false.
2852             None => None,
2853         };
2854         let type_private = match import_resolution.type_target {
2855             Some(ref target) => {
2856                 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2857                 self.def_map.borrow_mut().insert(directive.id, def);
2858                 let did = def.def_id();
2859                 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2860             },
2861             None => None,
2862         };
2863
2864         self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2865                                                           value_used: Used,
2866                                                           type_priv: type_private,
2867                                                           type_used: Used});
2868
2869         debug!("(resolving single import) successfully resolved import");
2870         return Success(());
2871     }
2872
2873     // Resolves a glob import. Note that this function cannot panic; it either
2874     // succeeds or bails out (as importing * from an empty module or a module
2875     // that exports nothing is valid).
2876     fn resolve_glob_import(&mut self,
2877                            module_: &Module,
2878                            containing_module: Rc<Module>,
2879                            import_directive: &ImportDirective,
2880                            lp: LastPrivate)
2881                            -> ResolveResult<()> {
2882         let id = import_directive.id;
2883         let is_public = import_directive.is_public;
2884
2885         // This function works in a highly imperative manner; it eagerly adds
2886         // everything it can to the list of import resolutions of the module
2887         // node.
2888         debug!("(resolving glob import) resolving glob import {}", id);
2889
2890         // We must bail out if the node has unresolved imports of any kind
2891         // (including globs).
2892         if !(*containing_module).all_imports_resolved() {
2893             debug!("(resolving glob import) target module has unresolved \
2894                     imports; bailing out");
2895             return Indeterminate;
2896         }
2897
2898         assert_eq!(containing_module.glob_count.get(), 0);
2899
2900         // Add all resolved imports from the containing module.
2901         let import_resolutions = containing_module.import_resolutions
2902                                                   .borrow();
2903         for (ident, target_import_resolution) in import_resolutions.iter() {
2904             debug!("(resolving glob import) writing module resolution \
2905                     {} into `{}`",
2906                    target_import_resolution.type_target.is_none(),
2907                    self.module_to_string(module_));
2908
2909             if !target_import_resolution.is_public {
2910                 debug!("(resolving glob import) nevermind, just kidding");
2911                 continue
2912             }
2913
2914             // Here we merge two import resolutions.
2915             let mut import_resolutions = module_.import_resolutions.borrow_mut();
2916             match import_resolutions.get_mut(ident) {
2917                 Some(dest_import_resolution) => {
2918                     // Merge the two import resolutions at a finer-grained
2919                     // level.
2920
2921                     match target_import_resolution.value_target {
2922                         None => {
2923                             // Continue.
2924                         }
2925                         Some(ref value_target) => {
2926                             dest_import_resolution.value_target =
2927                                 Some(value_target.clone());
2928                         }
2929                     }
2930                     match target_import_resolution.type_target {
2931                         None => {
2932                             // Continue.
2933                         }
2934                         Some(ref type_target) => {
2935                             dest_import_resolution.type_target =
2936                                 Some(type_target.clone());
2937                         }
2938                     }
2939                     dest_import_resolution.is_public = is_public;
2940                     continue;
2941                 }
2942                 None => {}
2943             }
2944
2945             // Simple: just copy the old import resolution.
2946             let mut new_import_resolution = ImportResolution::new(id, is_public);
2947             new_import_resolution.value_target =
2948                 target_import_resolution.value_target.clone();
2949             new_import_resolution.type_target =
2950                 target_import_resolution.type_target.clone();
2951
2952             import_resolutions.insert(*ident, new_import_resolution);
2953         }
2954
2955         // Add all children from the containing module.
2956         self.populate_module_if_necessary(&containing_module);
2957
2958         for (&name, name_bindings) in containing_module.children
2959                                                        .borrow().iter() {
2960             self.merge_import_resolution(module_,
2961                                          containing_module.clone(),
2962                                          import_directive,
2963                                          name,
2964                                          name_bindings.clone());
2965
2966         }
2967
2968         // Add external module children from the containing module.
2969         for (&name, module) in containing_module.external_module_children
2970                                                 .borrow().iter() {
2971             let name_bindings =
2972                 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2973             self.merge_import_resolution(module_,
2974                                          containing_module.clone(),
2975                                          import_directive,
2976                                          name,
2977                                          name_bindings);
2978         }
2979
2980         // Record the destination of this import
2981         match containing_module.def_id.get() {
2982             Some(did) => {
2983                 self.def_map.borrow_mut().insert(id, DefMod(did));
2984                 self.last_private.insert(id, lp);
2985             }
2986             None => {}
2987         }
2988
2989         debug!("(resolving glob import) successfully resolved import");
2990         return Success(());
2991     }
2992
2993     fn merge_import_resolution(&mut self,
2994                                module_: &Module,
2995                                containing_module: Rc<Module>,
2996                                import_directive: &ImportDirective,
2997                                name: Name,
2998                                name_bindings: Rc<NameBindings>) {
2999         let id = import_directive.id;
3000         let is_public = import_directive.is_public;
3001
3002         let mut import_resolutions = module_.import_resolutions.borrow_mut();
3003         let dest_import_resolution = match import_resolutions.entry(name) {
3004             Occupied(entry) => entry.into_mut(),
3005             Vacant(entry) => {
3006                 // Create a new import resolution from this child.
3007                 entry.set(ImportResolution::new(id, is_public))
3008             }
3009         };
3010
3011         debug!("(resolving glob import) writing resolution `{}` in `{}` \
3012                to `{}`",
3013                token::get_name(name).get().to_string(),
3014                self.module_to_string(&*containing_module),
3015                self.module_to_string(module_));
3016
3017         // Merge the child item into the import resolution.
3018         if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
3019             debug!("(resolving glob import) ... for value target");
3020             dest_import_resolution.value_target =
3021                 Some(Target::new(containing_module.clone(),
3022                                  name_bindings.clone(),
3023                                  import_directive.shadowable));
3024             dest_import_resolution.value_id = id;
3025         }
3026         if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
3027             debug!("(resolving glob import) ... for type target");
3028             dest_import_resolution.type_target =
3029                 Some(Target::new(containing_module,
3030                                  name_bindings.clone(),
3031                                  import_directive.shadowable));
3032             dest_import_resolution.type_id = id;
3033         }
3034         dest_import_resolution.is_public = is_public;
3035
3036         self.check_for_conflicts_between_imports_and_items(
3037             module_,
3038             dest_import_resolution,
3039             import_directive.span,
3040             name);
3041     }
3042
3043     /// Checks that imported names and items don't have the same name.
3044     fn check_for_conflicting_import(&mut self,
3045                                     target: &Option<Target>,
3046                                     import_span: Span,
3047                                     name: Name,
3048                                     namespace: Namespace) {
3049         if self.session.features.borrow().import_shadowing {
3050             return
3051         }
3052
3053         match *target {
3054             Some(ref target) if !target.shadowable => {
3055                 let msg = format!("a {} named `{}` has already been imported \
3056                                    in this module",
3057                                   match namespace {
3058                                     TypeNS => "type",
3059                                     ValueNS => "value",
3060                                   },
3061                                   token::get_name(name).get());
3062                 self.session.span_err(import_span, msg.as_slice());
3063             }
3064             Some(_) | None => {}
3065         }
3066     }
3067
3068     /// Checks that an import is actually importable
3069     fn check_that_import_is_importable(&mut self,
3070                                        name_bindings: &NameBindings,
3071                                        import_span: Span,
3072                                        name: Name,
3073                                        namespace: Namespace) {
3074         if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
3075             let msg = format!("`{}` is not directly importable",
3076                               token::get_name(name));
3077             self.session.span_err(import_span, msg.as_slice());
3078         }
3079     }
3080
3081     /// Checks that imported names and items don't have the same name.
3082     fn check_for_conflicts_between_imports_and_items(&mut self,
3083                                                      module: &Module,
3084                                                      import_resolution:
3085                                                      &ImportResolution,
3086                                                      import_span: Span,
3087                                                      name: Name) {
3088         if self.session.features.borrow().import_shadowing {
3089             return
3090         }
3091
3092         // First, check for conflicts between imports and `extern crate`s.
3093         if module.external_module_children
3094                  .borrow()
3095                  .contains_key(&name) {
3096             match import_resolution.type_target {
3097                 Some(ref target) if !target.shadowable => {
3098                     let msg = format!("import `{0}` conflicts with imported \
3099                                        crate in this module \
3100                                        (maybe you meant `use {0}::*`?)",
3101                                       token::get_name(name).get());
3102                     self.session.span_err(import_span, msg.as_slice());
3103                 }
3104                 Some(_) | None => {}
3105             }
3106         }
3107
3108         // Check for item conflicts.
3109         let children = module.children.borrow();
3110         let name_bindings = match children.get(&name) {
3111             None => {
3112                 // There can't be any conflicts.
3113                 return
3114             }
3115             Some(ref name_bindings) => (*name_bindings).clone(),
3116         };
3117
3118         match import_resolution.value_target {
3119             Some(ref target) if !target.shadowable => {
3120                 if let Some(ref value) = *name_bindings.value_def.borrow() {
3121                     let msg = format!("import `{}` conflicts with value \
3122                                        in this module",
3123                                       token::get_name(name).get());
3124                     self.session.span_err(import_span, msg.as_slice());
3125                     if let Some(span) = value.value_span {
3126                         self.session.span_note(span,
3127                                                "conflicting value here");
3128                     }
3129                 }
3130             }
3131             Some(_) | None => {}
3132         }
3133
3134         match import_resolution.type_target {
3135             Some(ref target) if !target.shadowable => {
3136                 if let Some(ref ty) = *name_bindings.type_def.borrow() {
3137                     match ty.module_def {
3138                         None => {
3139                             let msg = format!("import `{}` conflicts with type in \
3140                                                this module",
3141                                               token::get_name(name).get());
3142                             self.session.span_err(import_span, msg.as_slice());
3143                             if let Some(span) = ty.type_span {
3144                                 self.session.span_note(span,
3145                                                        "note conflicting type here")
3146                             }
3147                         }
3148                         Some(ref module_def) => {
3149                             match module_def.kind.get() {
3150                                 ImplModuleKind => {
3151                                     if let Some(span) = ty.type_span {
3152                                         let msg = format!("inherent implementations \
3153                                                            are only allowed on types \
3154                                                            defined in the current module");
3155                                         self.session.span_err(span, msg.as_slice());
3156                                         self.session.span_note(import_span,
3157                                                                "import from other module here")
3158                                     }
3159                                 }
3160                                 _ => {
3161                                     let msg = format!("import `{}` conflicts with existing \
3162                                                        submodule",
3163                                                       token::get_name(name).get());
3164                                     self.session.span_err(import_span, msg.as_slice());
3165                                     if let Some(span) = ty.type_span {
3166                                         self.session.span_note(span,
3167                                                                "note conflicting module here")
3168                                     }
3169                                 }
3170                             }
3171                         }
3172                     }
3173                 }
3174             }
3175             Some(_) | None => {}
3176         }
3177     }
3178
3179     /// Checks that the names of external crates don't collide with other
3180     /// external crates.
3181     fn check_for_conflicts_between_external_crates(&self,
3182                                                    module: &Module,
3183                                                    name: Name,
3184                                                    span: Span) {
3185         if self.session.features.borrow().import_shadowing {
3186             return
3187         }
3188
3189         if module.external_module_children.borrow().contains_key(&name) {
3190             self.session
3191                 .span_err(span,
3192                           format!("an external crate named `{}` has already \
3193                                    been imported into this module",
3194                                   token::get_name(name).get()).as_slice());
3195         }
3196     }
3197
3198     /// Checks that the names of items don't collide with external crates.
3199     fn check_for_conflicts_between_external_crates_and_items(&self,
3200                                                              module: &Module,
3201                                                              name: Name,
3202                                                              span: Span) {
3203         if self.session.features.borrow().import_shadowing {
3204             return
3205         }
3206
3207         if module.external_module_children.borrow().contains_key(&name) {
3208             self.session
3209                 .span_err(span,
3210                           format!("the name `{}` conflicts with an external \
3211                                    crate that has been imported into this \
3212                                    module",
3213                                   token::get_name(name).get()).as_slice());
3214         }
3215     }
3216
3217     /// Resolves the given module path from the given root `module_`.
3218     fn resolve_module_path_from_root(&mut self,
3219                                      module_: Rc<Module>,
3220                                      module_path: &[Name],
3221                                      index: uint,
3222                                      span: Span,
3223                                      name_search_type: NameSearchType,
3224                                      lp: LastPrivate)
3225                                 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3226         fn search_parent_externals(needle: Name, module: &Rc<Module>)
3227                                 -> Option<Rc<Module>> {
3228             module.external_module_children.borrow()
3229                                             .get(&needle).cloned()
3230                                             .map(|_| module.clone())
3231                                             .or_else(|| {
3232                 match module.parent_link.clone() {
3233                     ModuleParentLink(parent, _) => {
3234                         search_parent_externals(needle,
3235                                                 &parent.upgrade().unwrap())
3236                     }
3237                    _ => None
3238                 }
3239             })
3240         }
3241
3242         let mut search_module = module_;
3243         let mut index = index;
3244         let module_path_len = module_path.len();
3245         let mut closest_private = lp;
3246
3247         // Resolve the module part of the path. This does not involve looking
3248         // upward though scope chains; we simply resolve names directly in
3249         // modules as we go.
3250         while index < module_path_len {
3251             let name = module_path[index];
3252             match self.resolve_name_in_module(search_module.clone(),
3253                                               name,
3254                                               TypeNS,
3255                                               name_search_type,
3256                                               false) {
3257                 Failed(None) => {
3258                     let segment_name = token::get_name(name);
3259                     let module_name = self.module_to_string(&*search_module);
3260                     let mut span = span;
3261                     let msg = if "???" == module_name.as_slice() {
3262                         span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3263
3264                         match search_parent_externals(name,
3265                                                      &self.current_module) {
3266                             Some(module) => {
3267                                 let path_str = self.names_to_string(module_path);
3268                                 let target_mod_str = self.module_to_string(&*module);
3269                                 let current_mod_str =
3270                                     self.module_to_string(&*self.current_module);
3271
3272                                 let prefix = if target_mod_str == current_mod_str {
3273                                     "self::".to_string()
3274                                 } else {
3275                                     format!("{}::", target_mod_str)
3276                                 };
3277
3278                                 format!("Did you mean `{}{}`?", prefix, path_str)
3279                             },
3280                             None => format!("Maybe a missing `extern crate {}`?",
3281                                             segment_name),
3282                         }
3283                     } else {
3284                         format!("Could not find `{}` in `{}`",
3285                                 segment_name,
3286                                 module_name)
3287                     };
3288
3289                     return Failed(Some((span, msg)));
3290                 }
3291                 Failed(err) => return Failed(err),
3292                 Indeterminate => {
3293                     debug!("(resolving module path for import) module \
3294                             resolution is indeterminate: {}",
3295                             token::get_name(name));
3296                     return Indeterminate;
3297                 }
3298                 Success((target, used_proxy)) => {
3299                     // Check to see whether there are type bindings, and, if
3300                     // so, whether there is a module within.
3301                     match *target.bindings.type_def.borrow() {
3302                         Some(ref type_def) => {
3303                             match type_def.module_def {
3304                                 None => {
3305                                     let msg = format!("Not a module `{}`",
3306                                                         token::get_name(name));
3307
3308                                     return Failed(Some((span, msg)));
3309                                 }
3310                                 Some(ref module_def) => {
3311                                     search_module = module_def.clone();
3312
3313                                     // track extern crates for unused_extern_crate lint
3314                                     if let Some(did) = module_def.def_id.get() {
3315                                         self.used_crates.insert(did.krate);
3316                                     }
3317
3318                                     // Keep track of the closest
3319                                     // private module used when
3320                                     // resolving this import chain.
3321                                     if !used_proxy && !search_module.is_public {
3322                                         if let Some(did) = search_module.def_id.get() {
3323                                             closest_private = LastMod(DependsOn(did));
3324                                         }
3325                                     }
3326                                 }
3327                             }
3328                         }
3329                         None => {
3330                             // There are no type bindings at all.
3331                             let msg = format!("Not a module `{}`",
3332                                               token::get_name(name));
3333                             return Failed(Some((span, msg)));
3334                         }
3335                     }
3336                 }
3337             }
3338
3339             index += 1;
3340         }
3341
3342         return Success((search_module, closest_private));
3343     }
3344
3345     /// Attempts to resolve the module part of an import directive or path
3346     /// rooted at the given module.
3347     ///
3348     /// On success, returns the resolved module, and the closest *private*
3349     /// module found to the destination when resolving this path.
3350     fn resolve_module_path(&mut self,
3351                            module_: Rc<Module>,
3352                            module_path: &[Name],
3353                            use_lexical_scope: UseLexicalScopeFlag,
3354                            span: Span,
3355                            name_search_type: NameSearchType)
3356                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
3357         let module_path_len = module_path.len();
3358         assert!(module_path_len > 0);
3359
3360         debug!("(resolving module path for import) processing `{}` rooted at \
3361                `{}`",
3362                self.names_to_string(module_path),
3363                self.module_to_string(&*module_));
3364
3365         // Resolve the module prefix, if any.
3366         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3367                                                               module_path);
3368
3369         let search_module;
3370         let start_index;
3371         let last_private;
3372         match module_prefix_result {
3373             Failed(None) => {
3374                 let mpath = self.names_to_string(module_path);
3375                 let mpath = mpath.as_slice();
3376                 match mpath.rfind(':') {
3377                     Some(idx) => {
3378                         let msg = format!("Could not find `{}` in `{}`",
3379                                             // idx +- 1 to account for the
3380                                             // colons on either side
3381                                             mpath.slice_from(idx + 1),
3382                                             mpath.slice_to(idx - 1));
3383                         return Failed(Some((span, msg)));
3384                     },
3385                     None => return Failed(None),
3386                 }
3387             }
3388             Failed(err) => return Failed(err),
3389             Indeterminate => {
3390                 debug!("(resolving module path for import) indeterminate; \
3391                         bailing");
3392                 return Indeterminate;
3393             }
3394             Success(NoPrefixFound) => {
3395                 // There was no prefix, so we're considering the first element
3396                 // of the path. How we handle this depends on whether we were
3397                 // instructed to use lexical scope or not.
3398                 match use_lexical_scope {
3399                     DontUseLexicalScope => {
3400                         // This is a crate-relative path. We will start the
3401                         // resolution process at index zero.
3402                         search_module = self.graph_root.get_module();
3403                         start_index = 0;
3404                         last_private = LastMod(AllPublic);
3405                     }
3406                     UseLexicalScope => {
3407                         // This is not a crate-relative path. We resolve the
3408                         // first component of the path in the current lexical
3409                         // scope and then proceed to resolve below that.
3410                         match self.resolve_module_in_lexical_scope(
3411                                                             module_,
3412                                                             module_path[0]) {
3413                             Failed(err) => return Failed(err),
3414                             Indeterminate => {
3415                                 debug!("(resolving module path for import) \
3416                                         indeterminate; bailing");
3417                                 return Indeterminate;
3418                             }
3419                             Success(containing_module) => {
3420                                 search_module = containing_module;
3421                                 start_index = 1;
3422                                 last_private = LastMod(AllPublic);
3423                             }
3424                         }
3425                     }
3426                 }
3427             }
3428             Success(PrefixFound(ref containing_module, index)) => {
3429                 search_module = containing_module.clone();
3430                 start_index = index;
3431                 last_private = LastMod(DependsOn(containing_module.def_id
3432                                                                   .get()
3433                                                                   .unwrap()));
3434             }
3435         }
3436
3437         self.resolve_module_path_from_root(search_module,
3438                                            module_path,
3439                                            start_index,
3440                                            span,
3441                                            name_search_type,
3442                                            last_private)
3443     }
3444
3445     /// Invariant: This must only be called during main resolution, not during
3446     /// import resolution.
3447     fn resolve_item_in_lexical_scope(&mut self,
3448                                      module_: Rc<Module>,
3449                                      name: Name,
3450                                      namespace: Namespace)
3451                                     -> ResolveResult<(Target, bool)> {
3452         debug!("(resolving item in lexical scope) resolving `{}` in \
3453                 namespace {} in `{}`",
3454                token::get_name(name),
3455                namespace,
3456                self.module_to_string(&*module_));
3457
3458         // The current module node is handled specially. First, check for
3459         // its immediate children.
3460         self.populate_module_if_necessary(&module_);
3461
3462         match module_.children.borrow().get(&name) {
3463             Some(name_bindings)
3464                     if name_bindings.defined_in_namespace(namespace) => {
3465                 debug!("top name bindings succeeded");
3466                 return Success((Target::new(module_.clone(),
3467                                             name_bindings.clone(),
3468                                             false),
3469                                false));
3470             }
3471             Some(_) | None => { /* Not found; continue. */ }
3472         }
3473
3474         // Now check for its import directives. We don't have to have resolved
3475         // all its imports in the usual way; this is because chains of
3476         // adjacent import statements are processed as though they mutated the
3477         // current scope.
3478         if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
3479             match (*import_resolution).target_for_namespace(namespace) {
3480                 None => {
3481                     // Not found; continue.
3482                     debug!("(resolving item in lexical scope) found \
3483                             import resolution, but not in namespace {}",
3484                            namespace);
3485                 }
3486                 Some(target) => {
3487                     debug!("(resolving item in lexical scope) using \
3488                             import resolution");
3489                     // track used imports and extern crates as well
3490                     self.used_imports.insert((import_resolution.id(namespace), namespace));
3491                     if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3492                         self.used_crates.insert(kid);
3493                     }
3494                     return Success((target, false));
3495                 }
3496             }
3497         }
3498
3499         // Search for external modules.
3500         if namespace == TypeNS {
3501             if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3502                 let name_bindings =
3503                     Rc::new(Resolver::create_name_bindings_from_module(module));
3504                 debug!("lower name bindings succeeded");
3505                 return Success((Target::new(module_, name_bindings, false),
3506                                 false));
3507             }
3508         }
3509
3510         // Finally, proceed up the scope chain looking for parent modules.
3511         let mut search_module = module_;
3512         loop {
3513             // Go to the next parent.
3514             match search_module.parent_link.clone() {
3515                 NoParentLink => {
3516                     // No more parents. This module was unresolved.
3517                     debug!("(resolving item in lexical scope) unresolved \
3518                             module");
3519                     return Failed(None);
3520                 }
3521                 ModuleParentLink(parent_module_node, _) => {
3522                     match search_module.kind.get() {
3523                         NormalModuleKind => {
3524                             // We stop the search here.
3525                             debug!("(resolving item in lexical \
3526                                     scope) unresolved module: not \
3527                                     searching through module \
3528                                     parents");
3529                             return Failed(None);
3530                         }
3531                         TraitModuleKind |
3532                         ImplModuleKind |
3533                         EnumModuleKind |
3534                         AnonymousModuleKind => {
3535                             search_module = parent_module_node.upgrade().unwrap();
3536                         }
3537                     }
3538                 }
3539                 BlockParentLink(ref parent_module_node, _) => {
3540                     search_module = parent_module_node.upgrade().unwrap();
3541                 }
3542             }
3543
3544             // Resolve the name in the parent module.
3545             match self.resolve_name_in_module(search_module.clone(),
3546                                               name,
3547                                               namespace,
3548                                               PathSearch,
3549                                               true) {
3550                 Failed(Some((span, msg))) =>
3551                     self.resolve_error(span, format!("failed to resolve. {}",
3552                                                      msg)),
3553                 Failed(None) => (), // Continue up the search chain.
3554                 Indeterminate => {
3555                     // We couldn't see through the higher scope because of an
3556                     // unresolved import higher up. Bail.
3557
3558                     debug!("(resolving item in lexical scope) indeterminate \
3559                             higher scope; bailing");
3560                     return Indeterminate;
3561                 }
3562                 Success((target, used_reexport)) => {
3563                     // We found the module.
3564                     debug!("(resolving item in lexical scope) found name \
3565                             in module, done");
3566                     return Success((target, used_reexport));
3567                 }
3568             }
3569         }
3570     }
3571
3572     /// Resolves a module name in the current lexical scope.
3573     fn resolve_module_in_lexical_scope(&mut self,
3574                                        module_: Rc<Module>,
3575                                        name: Name)
3576                                 -> ResolveResult<Rc<Module>> {
3577         // If this module is an anonymous module, resolve the item in the
3578         // lexical scope. Otherwise, resolve the item from the crate root.
3579         let resolve_result = self.resolve_item_in_lexical_scope(
3580             module_, name, TypeNS);
3581         match resolve_result {
3582             Success((target, _)) => {
3583                 let bindings = &*target.bindings;
3584                 match *bindings.type_def.borrow() {
3585                     Some(ref type_def) => {
3586                         match type_def.module_def {
3587                             None => {
3588                                 debug!("!!! (resolving module in lexical \
3589                                         scope) module wasn't actually a \
3590                                         module!");
3591                                 return Failed(None);
3592                             }
3593                             Some(ref module_def) => {
3594                                 return Success(module_def.clone());
3595                             }
3596                         }
3597                     }
3598                     None => {
3599                         debug!("!!! (resolving module in lexical scope) module
3600                                 wasn't actually a module!");
3601                         return Failed(None);
3602                     }
3603                 }
3604             }
3605             Indeterminate => {
3606                 debug!("(resolving module in lexical scope) indeterminate; \
3607                         bailing");
3608                 return Indeterminate;
3609             }
3610             Failed(err) => {
3611                 debug!("(resolving module in lexical scope) failed to resolve");
3612                 return Failed(err);
3613             }
3614         }
3615     }
3616
3617     /// Returns the nearest normal module parent of the given module.
3618     fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3619                                             -> Option<Rc<Module>> {
3620         let mut module_ = module_;
3621         loop {
3622             match module_.parent_link.clone() {
3623                 NoParentLink => return None,
3624                 ModuleParentLink(new_module, _) |
3625                 BlockParentLink(new_module, _) => {
3626                     let new_module = new_module.upgrade().unwrap();
3627                     match new_module.kind.get() {
3628                         NormalModuleKind => return Some(new_module),
3629                         TraitModuleKind |
3630                         ImplModuleKind |
3631                         EnumModuleKind |
3632                         AnonymousModuleKind => module_ = new_module,
3633                     }
3634                 }
3635             }
3636         }
3637     }
3638
3639     /// Returns the nearest normal module parent of the given module, or the
3640     /// module itself if it is a normal module.
3641     fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3642                                                 -> Rc<Module> {
3643         match module_.kind.get() {
3644             NormalModuleKind => return module_,
3645             TraitModuleKind |
3646             ImplModuleKind |
3647             EnumModuleKind |
3648             AnonymousModuleKind => {
3649                 match self.get_nearest_normal_module_parent(module_.clone()) {
3650                     None => module_,
3651                     Some(new_module) => new_module
3652                 }
3653             }
3654         }
3655     }
3656
3657     /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3658     /// (b) some chain of `super::`.
3659     /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3660     fn resolve_module_prefix(&mut self,
3661                              module_: Rc<Module>,
3662                              module_path: &[Name])
3663                                  -> ResolveResult<ModulePrefixResult> {
3664         // Start at the current module if we see `self` or `super`, or at the
3665         // top of the crate otherwise.
3666         let mut containing_module;
3667         let mut i;
3668         let first_module_path_string = token::get_name(module_path[0]);
3669         if "self" == first_module_path_string.get() {
3670             containing_module =
3671                 self.get_nearest_normal_module_parent_or_self(module_);
3672             i = 1;
3673         } else if "super" == first_module_path_string.get() {
3674             containing_module =
3675                 self.get_nearest_normal_module_parent_or_self(module_);
3676             i = 0;  // We'll handle `super` below.
3677         } else {
3678             return Success(NoPrefixFound);
3679         }
3680
3681         // Now loop through all the `super`s we find.
3682         while i < module_path.len() {
3683             let string = token::get_name(module_path[i]);
3684             if "super" != string.get() {
3685                 break
3686             }
3687             debug!("(resolving module prefix) resolving `super` at {}",
3688                    self.module_to_string(&*containing_module));
3689             match self.get_nearest_normal_module_parent(containing_module) {
3690                 None => return Failed(None),
3691                 Some(new_module) => {
3692                     containing_module = new_module;
3693                     i += 1;
3694                 }
3695             }
3696         }
3697
3698         debug!("(resolving module prefix) finished resolving prefix at {}",
3699                self.module_to_string(&*containing_module));
3700
3701         return Success(PrefixFound(containing_module, i));
3702     }
3703
3704     /// Attempts to resolve the supplied name in the given module for the
3705     /// given namespace. If successful, returns the target corresponding to
3706     /// the name.
3707     ///
3708     /// The boolean returned on success is an indicator of whether this lookup
3709     /// passed through a public re-export proxy.
3710     fn resolve_name_in_module(&mut self,
3711                               module_: Rc<Module>,
3712                               name: Name,
3713                               namespace: Namespace,
3714                               name_search_type: NameSearchType,
3715                               allow_private_imports: bool)
3716                               -> ResolveResult<(Target, bool)> {
3717         debug!("(resolving name in module) resolving `{}` in `{}`",
3718                token::get_name(name).get(),
3719                self.module_to_string(&*module_));
3720
3721         // First, check the direct children of the module.
3722         self.populate_module_if_necessary(&module_);
3723
3724         match module_.children.borrow().get(&name) {
3725             Some(name_bindings)
3726                     if name_bindings.defined_in_namespace(namespace) => {
3727                 debug!("(resolving name in module) found node as child");
3728                 return Success((Target::new(module_.clone(),
3729                                             name_bindings.clone(),
3730                                             false),
3731                                false));
3732             }
3733             Some(_) | None => {
3734                 // Continue.
3735             }
3736         }
3737
3738         // Next, check the module's imports if necessary.
3739
3740         // If this is a search of all imports, we should be done with glob
3741         // resolution at this point.
3742         if name_search_type == PathSearch {
3743             assert_eq!(module_.glob_count.get(), 0);
3744         }
3745
3746         // Check the list of resolved imports.
3747         match module_.import_resolutions.borrow().get(&name) {
3748             Some(import_resolution) if allow_private_imports ||
3749                                        import_resolution.is_public => {
3750
3751                 if import_resolution.is_public &&
3752                         import_resolution.outstanding_references != 0 {
3753                     debug!("(resolving name in module) import \
3754                            unresolved; bailing out");
3755                     return Indeterminate;
3756                 }
3757                 match import_resolution.target_for_namespace(namespace) {
3758                     None => {
3759                         debug!("(resolving name in module) name found, \
3760                                 but not in namespace {}",
3761                                namespace);
3762                     }
3763                     Some(target) => {
3764                         debug!("(resolving name in module) resolved to \
3765                                 import");
3766                         // track used imports and extern crates as well
3767                         self.used_imports.insert((import_resolution.id(namespace), namespace));
3768                         if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3769                             self.used_crates.insert(kid);
3770                         }
3771                         return Success((target, true));
3772                     }
3773                 }
3774             }
3775             Some(..) | None => {} // Continue.
3776         }
3777
3778         // Finally, search through external children.
3779         if namespace == TypeNS {
3780             if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3781                 let name_bindings =
3782                     Rc::new(Resolver::create_name_bindings_from_module(module));
3783                 return Success((Target::new(module_, name_bindings, false),
3784                                 false));
3785             }
3786         }
3787
3788         // We're out of luck.
3789         debug!("(resolving name in module) failed to resolve `{}`",
3790                token::get_name(name).get());
3791         return Failed(None);
3792     }
3793
3794     fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3795         let index = module_.resolved_import_count.get();
3796         let imports = module_.imports.borrow();
3797         let import_count = imports.len();
3798         if index != import_count {
3799             let sn = self.session
3800                          .codemap()
3801                          .span_to_snippet((*imports)[index].span)
3802                          .unwrap();
3803             if sn.contains("::") {
3804                 self.resolve_error((*imports)[index].span,
3805                                    "unresolved import");
3806             } else {
3807                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3808                                   sn.slice(0, sn.len()));
3809                 self.resolve_error((*imports)[index].span, err.as_slice());
3810             }
3811         }
3812
3813         // Descend into children and anonymous children.
3814         self.populate_module_if_necessary(&module_);
3815
3816         for (_, child_node) in module_.children.borrow().iter() {
3817             match child_node.get_module_if_available() {
3818                 None => {
3819                     // Continue.
3820                 }
3821                 Some(child_module) => {
3822                     self.report_unresolved_imports(child_module);
3823                 }
3824             }
3825         }
3826
3827         for (_, module_) in module_.anonymous_children.borrow().iter() {
3828             self.report_unresolved_imports(module_.clone());
3829         }
3830     }
3831
3832     // Export recording
3833     //
3834     // This pass simply determines what all "export" keywords refer to and
3835     // writes the results into the export map.
3836     //
3837     // FIXME #4953 This pass will be removed once exports change to per-item.
3838     // Then this operation can simply be performed as part of item (or import)
3839     // processing.
3840
3841     fn record_exports(&mut self) {
3842         let root_module = self.graph_root.get_module();
3843         self.record_exports_for_module_subtree(root_module);
3844     }
3845
3846     fn record_exports_for_module_subtree(&mut self,
3847                                              module_: Rc<Module>) {
3848         // If this isn't a local krate, then bail out. We don't need to record
3849         // exports for nonlocal crates.
3850
3851         match module_.def_id.get() {
3852             Some(def_id) if def_id.krate == LOCAL_CRATE => {
3853                 // OK. Continue.
3854                 debug!("(recording exports for module subtree) recording \
3855                         exports for local module `{}`",
3856                        self.module_to_string(&*module_));
3857             }
3858             None => {
3859                 // Record exports for the root module.
3860                 debug!("(recording exports for module subtree) recording \
3861                         exports for root module `{}`",
3862                        self.module_to_string(&*module_));
3863             }
3864             Some(_) => {
3865                 // Bail out.
3866                 debug!("(recording exports for module subtree) not recording \
3867                         exports for `{}`",
3868                        self.module_to_string(&*module_));
3869                 return;
3870             }
3871         }
3872
3873         self.record_exports_for_module(&*module_);
3874         self.populate_module_if_necessary(&module_);
3875
3876         for (_, child_name_bindings) in module_.children.borrow().iter() {
3877             match child_name_bindings.get_module_if_available() {
3878                 None => {
3879                     // Nothing to do.
3880                 }
3881                 Some(child_module) => {
3882                     self.record_exports_for_module_subtree(child_module);
3883                 }
3884             }
3885         }
3886
3887         for (_, child_module) in module_.anonymous_children.borrow().iter() {
3888             self.record_exports_for_module_subtree(child_module.clone());
3889         }
3890     }
3891
3892     fn record_exports_for_module(&mut self, module_: &Module) {
3893         let mut exports2 = Vec::new();
3894
3895         self.add_exports_for_module(&mut exports2, module_);
3896         match module_.def_id.get() {
3897             Some(def_id) => {
3898                 self.export_map2.insert(def_id.node, exports2);
3899                 debug!("(computing exports) writing exports for {} (some)",
3900                        def_id.node);
3901             }
3902             None => {}
3903         }
3904     }
3905
3906     fn add_exports_of_namebindings(&mut self,
3907                                    exports2: &mut Vec<Export2> ,
3908                                    name: Name,
3909                                    namebindings: &NameBindings,
3910                                    ns: Namespace) {
3911         match namebindings.def_for_namespace(ns) {
3912             Some(d) => {
3913                 let name = token::get_name(name);
3914                 debug!("(computing exports) YES: export '{}' => {}",
3915                        name, d.def_id());
3916                 exports2.push(Export2 {
3917                     name: name.get().to_string(),
3918                     def_id: d.def_id()
3919                 });
3920             }
3921             d_opt => {
3922                 debug!("(computing exports) NO: {}", d_opt);
3923             }
3924         }
3925     }
3926
3927     fn add_exports_for_module(&mut self,
3928                               exports2: &mut Vec<Export2> ,
3929                               module_: &Module) {
3930         for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3931             if !importresolution.is_public {
3932                 continue
3933             }
3934             let xs = [TypeNS, ValueNS];
3935             for &ns in xs.iter() {
3936                 match importresolution.target_for_namespace(ns) {
3937                     Some(target) => {
3938                         debug!("(computing exports) maybe export '{}'",
3939                                token::get_name(*name));
3940                         self.add_exports_of_namebindings(exports2,
3941                                                          *name,
3942                                                          &*target.bindings,
3943                                                          ns)
3944                     }
3945                     _ => ()
3946                 }
3947             }
3948         }
3949     }
3950
3951     // AST resolution
3952     //
3953     // We maintain a list of value ribs and type ribs.
3954     //
3955     // Simultaneously, we keep track of the current position in the module
3956     // graph in the `current_module` pointer. When we go to resolve a name in
3957     // the value or type namespaces, we first look through all the ribs and
3958     // then query the module graph. When we resolve a name in the module
3959     // namespace, we can skip all the ribs (since nested modules are not
3960     // allowed within blocks in Rust) and jump straight to the current module
3961     // graph node.
3962     //
3963     // Named implementations are handled separately. When we find a method
3964     // call, we consult the module node to find all of the implementations in
3965     // scope. This information is lazily cached in the module node. We then
3966     // generate a fake "implementation scope" containing all the
3967     // implementations thus found, for compatibility with old resolve pass.
3968
3969     fn with_scope(&mut self, name: Option<Name>, f: |&mut Resolver|) {
3970         let orig_module = self.current_module.clone();
3971
3972         // Move down in the graph.
3973         match name {
3974             None => {
3975                 // Nothing to do.
3976             }
3977             Some(name) => {
3978                 self.populate_module_if_necessary(&orig_module);
3979
3980                 match orig_module.children.borrow().get(&name) {
3981                     None => {
3982                         debug!("!!! (with scope) didn't find `{}` in `{}`",
3983                                token::get_name(name),
3984                                self.module_to_string(&*orig_module));
3985                     }
3986                     Some(name_bindings) => {
3987                         match (*name_bindings).get_module_if_available() {
3988                             None => {
3989                                 debug!("!!! (with scope) didn't find module \
3990                                         for `{}` in `{}`",
3991                                        token::get_name(name),
3992                                        self.module_to_string(&*orig_module));
3993                             }
3994                             Some(module_) => {
3995                                 self.current_module = module_;
3996                             }
3997                         }
3998                     }
3999                 }
4000             }
4001         }
4002
4003         f(self);
4004
4005         self.current_module = orig_module;
4006     }
4007
4008     /// Wraps the given definition in the appropriate number of `DefUpvar`
4009     /// wrappers.
4010     fn upvarify(&self,
4011                 ribs: &[Rib],
4012                 def_like: DefLike,
4013                 span: Span)
4014                 -> Option<DefLike> {
4015         match def_like {
4016             DlDef(d @ DefUpvar(..)) => {
4017                 self.session.span_bug(span,
4018                     format!("unexpected {} in bindings", d).as_slice())
4019             }
4020             DlDef(d @ DefLocal(_)) => {
4021                 let node_id = d.def_id().node;
4022                 let mut def = d;
4023                 let mut last_proc_body_id = ast::DUMMY_NODE_ID;
4024                 for rib in ribs.iter() {
4025                     match rib.kind {
4026                         NormalRibKind => {
4027                             // Nothing to do. Continue.
4028                         }
4029                         ClosureRibKind(function_id, maybe_proc_body) => {
4030                             let prev_def = def;
4031                             if maybe_proc_body != ast::DUMMY_NODE_ID {
4032                                 last_proc_body_id = maybe_proc_body;
4033                             }
4034                             def = DefUpvar(node_id, function_id, last_proc_body_id);
4035
4036                             let mut seen = self.freevars_seen.borrow_mut();
4037                             let seen = match seen.entry(function_id) {
4038                                 Occupied(v) => v.into_mut(),
4039                                 Vacant(v) => v.set(NodeSet::new()),
4040                             };
4041                             if seen.contains(&node_id) {
4042                                 continue;
4043                             }
4044                             match self.freevars.borrow_mut().entry(function_id) {
4045                                 Occupied(v) => v.into_mut(),
4046                                 Vacant(v) => v.set(vec![]),
4047                             }.push(Freevar { def: prev_def, span: span });
4048                             seen.insert(node_id);
4049                         }
4050                         MethodRibKind(item_id, _) => {
4051                             // If the def is a ty param, and came from the parent
4052                             // item, it's ok
4053                             match def {
4054                                 DefTyParam(_, did, _) if {
4055                                     self.def_map.borrow().get(&did.node).cloned()
4056                                         == Some(DefTyParamBinder(item_id))
4057                                 } => {} // ok
4058                                 DefSelfTy(did) if did == item_id => {} // ok
4059                                 _ => {
4060                                     // This was an attempt to access an upvar inside a
4061                                     // named function item. This is not allowed, so we
4062                                     // report an error.
4063
4064                                     self.resolve_error(
4065                                         span,
4066                                         "can't capture dynamic environment in a fn item; \
4067                                         use the || { ... } closure form instead");
4068
4069                                     return None;
4070                                 }
4071                             }
4072                         }
4073                         ItemRibKind => {
4074                             // This was an attempt to access an upvar inside a
4075                             // named function item. This is not allowed, so we
4076                             // report an error.
4077
4078                             self.resolve_error(
4079                                 span,
4080                                 "can't capture dynamic environment in a fn item; \
4081                                 use the || { ... } closure form instead");
4082
4083                             return None;
4084                         }
4085                         ConstantItemRibKind => {
4086                             // Still doesn't deal with upvars
4087                             self.resolve_error(span,
4088                                                "attempt to use a non-constant \
4089                                                 value in a constant");
4090
4091                         }
4092                     }
4093                 }
4094                 Some(DlDef(def))
4095             }
4096             DlDef(def @ DefTyParam(..)) |
4097             DlDef(def @ DefSelfTy(..)) => {
4098                 for rib in ribs.iter() {
4099                     match rib.kind {
4100                         NormalRibKind | ClosureRibKind(..) => {
4101                             // Nothing to do. Continue.
4102                         }
4103                         MethodRibKind(item_id, _) => {
4104                             // If the def is a ty param, and came from the parent
4105                             // item, it's ok
4106                             match def {
4107                                 DefTyParam(_, did, _) if {
4108                                     self.def_map.borrow().get(&did.node).cloned()
4109                                         == Some(DefTyParamBinder(item_id))
4110                                 } => {} // ok
4111                                 DefSelfTy(did) if did == item_id => {} // ok
4112
4113                                 _ => {
4114                                     // This was an attempt to use a type parameter outside
4115                                     // its scope.
4116
4117                                     self.resolve_error(span,
4118                                                         "can't use type parameters from \
4119                                                         outer function; try using a local \
4120                                                         type parameter instead");
4121
4122                                     return None;
4123                                 }
4124                             }
4125                         }
4126                         ItemRibKind => {
4127                             // This was an attempt to use a type parameter outside
4128                             // its scope.
4129
4130                             self.resolve_error(span,
4131                                                "can't use type parameters from \
4132                                                 outer function; try using a local \
4133                                                 type parameter instead");
4134
4135                             return None;
4136                         }
4137                         ConstantItemRibKind => {
4138                             // see #9186
4139                             self.resolve_error(span,
4140                                                "cannot use an outer type \
4141                                                 parameter in this context");
4142
4143                         }
4144                     }
4145                 }
4146                 Some(DlDef(def))
4147             }
4148             _ => Some(def_like)
4149         }
4150     }
4151
4152     fn search_ribs(&self,
4153                    ribs: &[Rib],
4154                    name: Name,
4155                    span: Span)
4156                    -> Option<DefLike> {
4157         // FIXME #4950: Try caching?
4158
4159         for (i, rib) in ribs.iter().enumerate().rev() {
4160             match rib.bindings.get(&name).cloned() {
4161                 Some(def_like) => {
4162                     return self.upvarify(ribs[i + 1..], def_like, span);
4163                 }
4164                 None => {
4165                     // Continue.
4166                 }
4167             }
4168         }
4169
4170         None
4171     }
4172
4173     fn resolve_crate(&mut self, krate: &ast::Crate) {
4174         debug!("(resolving crate) starting");
4175
4176         visit::walk_crate(self, krate);
4177     }
4178
4179     fn resolve_item(&mut self, item: &Item) {
4180         let name = item.ident.name;
4181
4182         debug!("(resolving item) resolving {}",
4183                token::get_name(name));
4184
4185         match item.node {
4186
4187             // enum item: resolve all the variants' discrs,
4188             // then resolve the ty params
4189             ItemEnum(ref enum_def, ref generics) => {
4190                 for variant in (*enum_def).variants.iter() {
4191                     for dis_expr in variant.node.disr_expr.iter() {
4192                         // resolve the discriminator expr
4193                         // as a constant
4194                         self.with_constant_rib(|this| {
4195                             this.resolve_expr(&**dis_expr);
4196                         });
4197                     }
4198                 }
4199
4200                 // n.b. the discr expr gets visited twice.
4201                 // but maybe it's okay since the first time will signal an
4202                 // error if there is one? -- tjc
4203                 self.with_type_parameter_rib(HasTypeParameters(generics,
4204                                                                TypeSpace,
4205                                                                item.id,
4206                                                                ItemRibKind),
4207                                              |this| {
4208                     this.resolve_type_parameters(&generics.ty_params);
4209                     this.resolve_where_clause(&generics.where_clause);
4210                     visit::walk_item(this, item);
4211                 });
4212             }
4213
4214             ItemTy(_, ref generics) => {
4215                 self.with_type_parameter_rib(HasTypeParameters(generics,
4216                                                                TypeSpace,
4217                                                                item.id,
4218                                                                ItemRibKind),
4219                                              |this| {
4220                     this.resolve_type_parameters(&generics.ty_params);
4221                     visit::walk_item(this, item);
4222                 });
4223             }
4224
4225             ItemImpl(ref generics,
4226                      ref implemented_traits,
4227                      ref self_type,
4228                      ref impl_items) => {
4229                 self.resolve_implementation(item.id,
4230                                             generics,
4231                                             implemented_traits,
4232                                             &**self_type,
4233                                             impl_items.as_slice());
4234             }
4235
4236             ItemTrait(ref generics, ref unbound, ref bounds, ref trait_items) => {
4237                 // Create a new rib for the self type.
4238                 let mut self_type_rib = Rib::new(ItemRibKind);
4239
4240                 // plain insert (no renaming, types are not currently hygienic....)
4241                 let name = self.type_self_name;
4242                 self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
4243                 self.type_ribs.push(self_type_rib);
4244
4245                 // Create a new rib for the trait-wide type parameters.
4246                 self.with_type_parameter_rib(HasTypeParameters(generics,
4247                                                                TypeSpace,
4248                                                                item.id,
4249                                                                NormalRibKind),
4250                                              |this| {
4251                     this.resolve_type_parameters(&generics.ty_params);
4252                     this.resolve_where_clause(&generics.where_clause);
4253
4254                     this.resolve_type_parameter_bounds(item.id, bounds,
4255                                                        TraitDerivation);
4256
4257                     match *unbound {
4258                         Some(ref tpb) => {
4259                             this.resolve_trait_reference(item.id, tpb, TraitDerivation);
4260                         }
4261                         None => {}
4262                     }
4263
4264                     for trait_item in (*trait_items).iter() {
4265                         // Create a new rib for the trait_item-specific type
4266                         // parameters.
4267                         //
4268                         // FIXME #4951: Do we need a node ID here?
4269
4270                         match *trait_item {
4271                           ast::RequiredMethod(ref ty_m) => {
4272                             this.with_type_parameter_rib
4273                                 (HasTypeParameters(&ty_m.generics,
4274                                                    FnSpace,
4275                                                    item.id,
4276                                         MethodRibKind(item.id, RequiredMethod)),
4277                                  |this| {
4278
4279                                 // Resolve the method-specific type
4280                                 // parameters.
4281                                 this.resolve_type_parameters(
4282                                     &ty_m.generics.ty_params);
4283                                 this.resolve_where_clause(&ty_m.generics
4284                                                                .where_clause);
4285
4286                                 for argument in ty_m.decl.inputs.iter() {
4287                                     this.resolve_type(&*argument.ty);
4288                                 }
4289
4290                                 if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
4291                                     this.resolve_type(&**typ)
4292                                 }
4293
4294                                 if let ast::Return(ref ret_ty) = ty_m.decl.output {
4295                                     this.resolve_type(&**ret_ty);
4296                                 }
4297                             });
4298                           }
4299                           ast::ProvidedMethod(ref m) => {
4300                               this.resolve_method(MethodRibKind(item.id,
4301                                                                 ProvidedMethod(m.id)),
4302                                                   &**m)
4303                           }
4304                           ast::TypeTraitItem(ref data) => {
4305                               this.resolve_type_parameter(&data.ty_param);
4306                               visit::walk_trait_item(this, trait_item);
4307                           }
4308                         }
4309                     }
4310                 });
4311
4312                 self.type_ribs.pop();
4313             }
4314
4315             ItemStruct(ref struct_def, ref generics) => {
4316                 self.resolve_struct(item.id,
4317                                     generics,
4318                                     struct_def.fields.as_slice());
4319             }
4320
4321             ItemMod(ref module_) => {
4322                 self.with_scope(Some(name), |this| {
4323                     this.resolve_module(module_, item.span, name,
4324                                         item.id);
4325                 });
4326             }
4327
4328             ItemForeignMod(ref foreign_module) => {
4329                 self.with_scope(Some(name), |this| {
4330                     for foreign_item in foreign_module.items.iter() {
4331                         match foreign_item.node {
4332                             ForeignItemFn(_, ref generics) => {
4333                                 this.with_type_parameter_rib(
4334                                     HasTypeParameters(
4335                                         generics, FnSpace, foreign_item.id,
4336                                         ItemRibKind),
4337                                     |this| visit::walk_foreign_item(this,
4338                                                                     &**foreign_item));
4339                             }
4340                             ForeignItemStatic(..) => {
4341                                 visit::walk_foreign_item(this,
4342                                                          &**foreign_item);
4343                             }
4344                         }
4345                     }
4346                 });
4347             }
4348
4349             ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4350                 self.resolve_function(ItemRibKind,
4351                                       Some(&**fn_decl),
4352                                       HasTypeParameters
4353                                         (generics,
4354                                          FnSpace,
4355                                          item.id,
4356                                          ItemRibKind),
4357                                       &**block);
4358             }
4359
4360             ItemConst(..) | ItemStatic(..) => {
4361                 self.with_constant_rib(|this| {
4362                     visit::walk_item(this, item);
4363                 });
4364             }
4365
4366            ItemMac(..) => {
4367                 // do nothing, these are just around to be encoded
4368            }
4369         }
4370     }
4371
4372     fn with_type_parameter_rib(&mut self,
4373                                type_parameters: TypeParameters,
4374                                f: |&mut Resolver|) {
4375         match type_parameters {
4376             HasTypeParameters(generics, space, node_id, rib_kind) => {
4377                 let mut function_type_rib = Rib::new(rib_kind);
4378                 let mut seen_bindings = HashSet::new();
4379                 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4380                     let name = type_parameter.ident.name;
4381                     debug!("with_type_parameter_rib: {} {}", node_id,
4382                            type_parameter.id);
4383
4384                     if seen_bindings.contains(&name) {
4385                         self.resolve_error(type_parameter.span,
4386                                            format!("the name `{}` is already \
4387                                                     used for a type \
4388                                                     parameter in this type \
4389                                                     parameter list",
4390                                                    token::get_name(
4391                                                        name)).as_slice())
4392                     }
4393                     seen_bindings.insert(name);
4394
4395                     let def_like = DlDef(DefTyParam(space,
4396                                                     local_def(type_parameter.id),
4397                                                     index));
4398                     // Associate this type parameter with
4399                     // the item that bound it
4400                     self.record_def(type_parameter.id,
4401                                     (DefTyParamBinder(node_id), LastMod(AllPublic)));
4402                     // plain insert (no renaming)
4403                     function_type_rib.bindings.insert(name, def_like);
4404                 }
4405                 self.type_ribs.push(function_type_rib);
4406             }
4407
4408             NoTypeParameters => {
4409                 // Nothing to do.
4410             }
4411         }
4412
4413         f(self);
4414
4415         match type_parameters {
4416             HasTypeParameters(..) => { self.type_ribs.pop(); }
4417             NoTypeParameters => { }
4418         }
4419     }
4420
4421     fn with_label_rib(&mut self, f: |&mut Resolver|) {
4422         self.label_ribs.push(Rib::new(NormalRibKind));
4423         f(self);
4424         self.label_ribs.pop();
4425     }
4426
4427     fn with_constant_rib(&mut self, f: |&mut Resolver|) {
4428         self.value_ribs.push(Rib::new(ConstantItemRibKind));
4429         self.type_ribs.push(Rib::new(ConstantItemRibKind));
4430         f(self);
4431         self.type_ribs.pop();
4432         self.value_ribs.pop();
4433     }
4434
4435     fn resolve_function(&mut self,
4436                         rib_kind: RibKind,
4437                         optional_declaration: Option<&FnDecl>,
4438                         type_parameters: TypeParameters,
4439                         block: &Block) {
4440         // Create a value rib for the function.
4441         let function_value_rib = Rib::new(rib_kind);
4442         self.value_ribs.push(function_value_rib);
4443
4444         // Create a label rib for the function.
4445         let function_label_rib = Rib::new(rib_kind);
4446         self.label_ribs.push(function_label_rib);
4447
4448         // If this function has type parameters, add them now.
4449         self.with_type_parameter_rib(type_parameters, |this| {
4450             // Resolve the type parameters.
4451             match type_parameters {
4452                 NoTypeParameters => {
4453                     // Continue.
4454                 }
4455                 HasTypeParameters(ref generics, _, _, _) => {
4456                     this.resolve_type_parameters(&generics.ty_params);
4457                     this.resolve_where_clause(&generics.where_clause);
4458                 }
4459             }
4460
4461             // Add each argument to the rib.
4462             match optional_declaration {
4463                 None => {
4464                     // Nothing to do.
4465                 }
4466                 Some(declaration) => {
4467                     let mut bindings_list = HashMap::new();
4468                     for argument in declaration.inputs.iter() {
4469                         this.resolve_pattern(&*argument.pat,
4470                                              ArgumentIrrefutableMode,
4471                                              &mut bindings_list);
4472
4473                         this.resolve_type(&*argument.ty);
4474
4475                         debug!("(resolving function) recorded argument");
4476                     }
4477
4478                     if let ast::Return(ref ret_ty) = declaration.output {
4479                         this.resolve_type(&**ret_ty);
4480                     }
4481                 }
4482             }
4483
4484             // Resolve the function body.
4485             this.resolve_block(&*block);
4486
4487             debug!("(resolving function) leaving function");
4488         });
4489
4490         self.label_ribs.pop();
4491         self.value_ribs.pop();
4492     }
4493
4494     fn resolve_type_parameters(&mut self,
4495                                type_parameters: &OwnedSlice<TyParam>) {
4496         for type_parameter in type_parameters.iter() {
4497             self.resolve_type_parameter(type_parameter);
4498         }
4499     }
4500
4501     fn resolve_type_parameter(&mut self,
4502                               type_parameter: &TyParam) {
4503         for bound in type_parameter.bounds.iter() {
4504             self.resolve_type_parameter_bound(type_parameter.id, bound,
4505                                               TraitBoundingTypeParameter);
4506         }
4507         match &type_parameter.unbound {
4508             &Some(ref unbound) =>
4509                 self.resolve_trait_reference(
4510                     type_parameter.id, unbound, TraitBoundingTypeParameter),
4511             &None => {}
4512         }
4513         match type_parameter.default {
4514             Some(ref ty) => self.resolve_type(&**ty),
4515             None => {}
4516         }
4517     }
4518
4519     fn resolve_type_parameter_bounds(&mut self,
4520                                      id: NodeId,
4521                                      type_parameter_bounds: &OwnedSlice<TyParamBound>,
4522                                      reference_type: TraitReferenceType) {
4523         for type_parameter_bound in type_parameter_bounds.iter() {
4524             self.resolve_type_parameter_bound(id, type_parameter_bound,
4525                                               reference_type);
4526         }
4527     }
4528
4529     fn resolve_type_parameter_bound(&mut self,
4530                                     id: NodeId,
4531                                     type_parameter_bound: &TyParamBound,
4532                                     reference_type: TraitReferenceType) {
4533         match *type_parameter_bound {
4534             TraitTyParamBound(ref tref) => {
4535                 self.resolve_poly_trait_reference(id, tref, reference_type)
4536             }
4537             RegionTyParamBound(..) => {}
4538         }
4539     }
4540
4541     fn resolve_poly_trait_reference(&mut self,
4542                                     id: NodeId,
4543                                     poly_trait_reference: &PolyTraitRef,
4544                                     reference_type: TraitReferenceType) {
4545         self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
4546     }
4547
4548     fn resolve_trait_reference(&mut self,
4549                                id: NodeId,
4550                                trait_reference: &TraitRef,
4551                                reference_type: TraitReferenceType) {
4552         match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4553             None => {
4554                 let path_str = self.path_names_to_string(&trait_reference.path);
4555                 let usage_str = match reference_type {
4556                     TraitBoundingTypeParameter => "bound type parameter with",
4557                     TraitImplementation        => "implement",
4558                     TraitDerivation            => "derive",
4559                     TraitObject                => "reference",
4560                     TraitQPath                 => "extract an associated type from",
4561                 };
4562
4563                 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4564                 self.resolve_error(trait_reference.path.span, msg.as_slice());
4565             }
4566             Some(def) => {
4567                 match def {
4568                     (DefTrait(_), _) => {
4569                         debug!("(resolving trait) found trait def: {}", def);
4570                         self.record_def(trait_reference.ref_id, def);
4571                     }
4572                     (def, _) => {
4573                         self.resolve_error(trait_reference.path.span,
4574                                            format!("`{}` is not a trait",
4575                                                    self.path_names_to_string(
4576                                                        &trait_reference.path)));
4577
4578                         // If it's a typedef, give a note
4579                         if let DefTy(..) = def {
4580                             self.session.span_note(
4581                                 trait_reference.path.span,
4582                                 format!("`type` aliases cannot be used for traits")
4583                                     .as_slice());
4584                         }
4585                     }
4586                 }
4587             }
4588         }
4589     }
4590
4591     fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4592         for predicate in where_clause.predicates.iter() {
4593             match self.resolve_identifier(predicate.ident,
4594                                           TypeNS,
4595                                           true,
4596                                           predicate.span) {
4597                 Some((def @ DefTyParam(_, _, _), last_private)) => {
4598                     self.record_def(predicate.id, (def, last_private));
4599                 }
4600                 _ => {
4601                     self.resolve_error(
4602                         predicate.span,
4603                         format!("undeclared type parameter `{}`",
4604                                 token::get_ident(
4605                                     predicate.ident)).as_slice());
4606                 }
4607             }
4608
4609             for bound in predicate.bounds.iter() {
4610                 self.resolve_type_parameter_bound(predicate.id, bound,
4611                                                   TraitBoundingTypeParameter);
4612             }
4613         }
4614     }
4615
4616     fn resolve_struct(&mut self,
4617                       id: NodeId,
4618                       generics: &Generics,
4619                       fields: &[StructField]) {
4620         // If applicable, create a rib for the type parameters.
4621         self.with_type_parameter_rib(HasTypeParameters(generics,
4622                                                        TypeSpace,
4623                                                        id,
4624                                                        ItemRibKind),
4625                                      |this| {
4626             // Resolve the type parameters.
4627             this.resolve_type_parameters(&generics.ty_params);
4628             this.resolve_where_clause(&generics.where_clause);
4629
4630             // Resolve fields.
4631             for field in fields.iter() {
4632                 this.resolve_type(&*field.node.ty);
4633             }
4634         });
4635     }
4636
4637     // Does this really need to take a RibKind or is it always going
4638     // to be NormalRibKind?
4639     fn resolve_method(&mut self,
4640                       rib_kind: RibKind,
4641                       method: &ast::Method) {
4642         let method_generics = method.pe_generics();
4643         let type_parameters = HasTypeParameters(method_generics,
4644                                                 FnSpace,
4645                                                 method.id,
4646                                                 rib_kind);
4647
4648         if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
4649             self.resolve_type(&**typ);
4650         }
4651
4652         self.resolve_function(rib_kind,
4653                               Some(method.pe_fn_decl()),
4654                               type_parameters,
4655                               method.pe_body());
4656     }
4657
4658     fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4659         // Handle nested impls (inside fn bodies)
4660         let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4661         let result = f(self);
4662         self.current_self_type = previous_value;
4663         result
4664     }
4665
4666     fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4667                                   opt_trait_ref: &Option<TraitRef>,
4668                                   f: |&mut Resolver| -> T) -> T {
4669         let new_val = match *opt_trait_ref {
4670             Some(ref trait_ref) => {
4671                 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4672
4673                 match self.def_map.borrow().get(&trait_ref.ref_id) {
4674                     Some(def) => {
4675                         let did = def.def_id();
4676                         Some((did, trait_ref.clone()))
4677                     }
4678                     None => None
4679                 }
4680             }
4681             None => None
4682         };
4683         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4684         let result = f(self);
4685         self.current_trait_ref = original_trait_ref;
4686         result
4687     }
4688
4689     fn resolve_implementation(&mut self,
4690                               id: NodeId,
4691                               generics: &Generics,
4692                               opt_trait_reference: &Option<TraitRef>,
4693                               self_type: &Ty,
4694                               impl_items: &[ImplItem]) {
4695         // If applicable, create a rib for the type parameters.
4696         self.with_type_parameter_rib(HasTypeParameters(generics,
4697                                                        TypeSpace,
4698                                                        id,
4699                                                        NormalRibKind),
4700                                      |this| {
4701             // Resolve the type parameters.
4702             this.resolve_type_parameters(&generics.ty_params);
4703             this.resolve_where_clause(&generics.where_clause);
4704
4705             // Resolve the trait reference, if necessary.
4706             this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4707                 // Resolve the self type.
4708                 this.resolve_type(self_type);
4709
4710                 this.with_current_self_type(self_type, |this| {
4711                     for impl_item in impl_items.iter() {
4712                         match *impl_item {
4713                             MethodImplItem(ref method) => {
4714                                 // If this is a trait impl, ensure the method
4715                                 // exists in trait
4716                                 this.check_trait_item(method.pe_ident().name,
4717                                                       method.span);
4718
4719                                 // We also need a new scope for the method-
4720                                 // specific type parameters.
4721                                 this.resolve_method(
4722                                     MethodRibKind(id, ProvidedMethod(method.id)),
4723                                     &**method);
4724                             }
4725                             TypeImplItem(ref typedef) => {
4726                                 // If this is a trait impl, ensure the method
4727                                 // exists in trait
4728                                 this.check_trait_item(typedef.ident.name,
4729                                                       typedef.span);
4730
4731                                 this.resolve_type(&*typedef.typ);
4732                             }
4733                         }
4734                     }
4735                 });
4736             });
4737         });
4738
4739         // Check that the current type is indeed a type, if we have an anonymous impl
4740         if opt_trait_reference.is_none() {
4741             match self_type.node {
4742                 // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
4743                 // where we created a module with the name of the type in order to implement
4744                 // an anonymous trait. In the case that the path does not resolve to an actual
4745                 // type, the result will be that the type name resolves to a module but not
4746                 // a type (shadowing any imported modules or types with this name), leading
4747                 // to weird user-visible bugs. So we ward this off here. See #15060.
4748                 TyPath(ref path, path_id) => {
4749                     match self.def_map.borrow().get(&path_id) {
4750                         // FIXME: should we catch other options and give more precise errors?
4751                         Some(&DefMod(_)) => {
4752                             self.resolve_error(path.span, "inherent implementations are not \
4753                                                            allowed for types not defined in \
4754                                                            the current module");
4755                         }
4756                         _ => {}
4757                     }
4758                 }
4759                 _ => { }
4760             }
4761         }
4762     }
4763
4764     fn check_trait_item(&self, name: Name, span: Span) {
4765         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4766         for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4767             if self.trait_item_map.get(&(name, did)).is_none() {
4768                 let path_str = self.path_names_to_string(&trait_ref.path);
4769                 self.resolve_error(span,
4770                                     format!("method `{}` is not a member of trait `{}`",
4771                                             token::get_name(name),
4772                                             path_str).as_slice());
4773             }
4774         }
4775     }
4776
4777     fn resolve_module(&mut self, module: &Mod, _span: Span,
4778                       _name: Name, id: NodeId) {
4779         // Write the implementations in scope into the module metadata.
4780         debug!("(resolving module) resolving module ID {}", id);
4781         visit::walk_mod(self, module);
4782     }
4783
4784     fn resolve_local(&mut self, local: &Local) {
4785         // Resolve the type.
4786         self.resolve_type(&*local.ty);
4787
4788         // Resolve the initializer, if necessary.
4789         match local.init {
4790             None => {
4791                 // Nothing to do.
4792             }
4793             Some(ref initializer) => {
4794                 self.resolve_expr(&**initializer);
4795             }
4796         }
4797
4798         // Resolve the pattern.
4799         let mut bindings_list = HashMap::new();
4800         self.resolve_pattern(&*local.pat,
4801                              LocalIrrefutableMode,
4802                              &mut bindings_list);
4803     }
4804
4805     // build a map from pattern identifiers to binding-info's.
4806     // this is done hygienically. This could arise for a macro
4807     // that expands into an or-pattern where one 'x' was from the
4808     // user and one 'x' came from the macro.
4809     fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4810         let mut result = HashMap::new();
4811         pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4812             let name = mtwt::resolve(path1.node);
4813             result.insert(name,
4814                           binding_info {span: sp,
4815                                         binding_mode: binding_mode});
4816         });
4817         return result;
4818     }
4819
4820     // check that all of the arms in an or-pattern have exactly the
4821     // same set of bindings, with the same binding modes for each.
4822     fn check_consistent_bindings(&mut self, arm: &Arm) {
4823         if arm.pats.len() == 0 {
4824             return
4825         }
4826         let map_0 = self.binding_mode_map(&*arm.pats[0]);
4827         for (i, p) in arm.pats.iter().enumerate() {
4828             let map_i = self.binding_mode_map(&**p);
4829
4830             for (&key, &binding_0) in map_0.iter() {
4831                 match map_i.get(&key) {
4832                   None => {
4833                     self.resolve_error(
4834                         p.span,
4835                         format!("variable `{}` from pattern #1 is \
4836                                   not bound in pattern #{}",
4837                                 token::get_name(key),
4838                                 i + 1).as_slice());
4839                   }
4840                   Some(binding_i) => {
4841                     if binding_0.binding_mode != binding_i.binding_mode {
4842                         self.resolve_error(
4843                             binding_i.span,
4844                             format!("variable `{}` is bound with different \
4845                                       mode in pattern #{} than in pattern #1",
4846                                     token::get_name(key),
4847                                     i + 1).as_slice());
4848                     }
4849                   }
4850                 }
4851             }
4852
4853             for (&key, &binding) in map_i.iter() {
4854                 if !map_0.contains_key(&key) {
4855                     self.resolve_error(
4856                         binding.span,
4857                         format!("variable `{}` from pattern {}{} is \
4858                                   not bound in pattern {}1",
4859                                 token::get_name(key),
4860                                 "#", i + 1, "#").as_slice());
4861                 }
4862             }
4863         }
4864     }
4865
4866     fn resolve_arm(&mut self, arm: &Arm) {
4867         self.value_ribs.push(Rib::new(NormalRibKind));
4868
4869         let mut bindings_list = HashMap::new();
4870         for pattern in arm.pats.iter() {
4871             self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4872         }
4873
4874         // This has to happen *after* we determine which
4875         // pat_idents are variants
4876         self.check_consistent_bindings(arm);
4877
4878         visit::walk_expr_opt(self, &arm.guard);
4879         self.resolve_expr(&*arm.body);
4880
4881         self.value_ribs.pop();
4882     }
4883
4884     fn resolve_block(&mut self, block: &Block) {
4885         debug!("(resolving block) entering block");
4886         self.value_ribs.push(Rib::new(NormalRibKind));
4887
4888         // Move down in the graph, if there's an anonymous module rooted here.
4889         let orig_module = self.current_module.clone();
4890         match orig_module.anonymous_children.borrow().get(&block.id) {
4891             None => { /* Nothing to do. */ }
4892             Some(anonymous_module) => {
4893                 debug!("(resolving block) found anonymous module, moving \
4894                         down");
4895                 self.current_module = anonymous_module.clone();
4896             }
4897         }
4898
4899         // Descend into the block.
4900         visit::walk_block(self, block);
4901
4902         // Move back up.
4903         self.current_module = orig_module;
4904
4905         self.value_ribs.pop();
4906         debug!("(resolving block) leaving block");
4907     }
4908
4909     fn resolve_type(&mut self, ty: &Ty) {
4910         match ty.node {
4911             // Like path expressions, the interpretation of path types depends
4912             // on whether the path has multiple elements in it or not.
4913
4914             TyPath(ref path, path_id) => {
4915                 // This is a path in the type namespace. Walk through scopes
4916                 // looking for it.
4917                 let mut result_def = None;
4918
4919                 // First, check to see whether the name is a primitive type.
4920                 if path.segments.len() == 1 {
4921                     let id = path.segments.last().unwrap().identifier;
4922
4923                     match self.primitive_type_table
4924                             .primitive_types
4925                             .get(&id.name) {
4926
4927                         Some(&primitive_type) => {
4928                             result_def =
4929                                 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4930
4931                             if path.segments
4932                                    .iter()
4933                                    .any(|s| s.parameters.has_lifetimes()) {
4934                                 span_err!(self.session, path.span, E0157,
4935                                     "lifetime parameters are not allowed on this type");
4936                             } else if path.segments
4937                                           .iter()
4938                                           .any(|s| !s.parameters.is_empty()) {
4939                                 span_err!(self.session, path.span, E0153,
4940                                     "type parameters are not allowed on this type");
4941                             }
4942                         }
4943                         None => {
4944                             // Continue.
4945                         }
4946                     }
4947                 }
4948
4949                 match result_def {
4950                     None => {
4951                         match self.resolve_path(ty.id, path, TypeNS, true) {
4952                             Some(def) => {
4953                                 debug!("(resolving type) resolved `{}` to \
4954                                         type {}",
4955                                        token::get_ident(path.segments
4956                                                             .last().unwrap()
4957                                                             .identifier),
4958                                        def);
4959                                 result_def = Some(def);
4960                             }
4961                             None => {
4962                                 result_def = None;
4963                             }
4964                         }
4965                     }
4966                     Some(_) => {}   // Continue.
4967                 }
4968
4969                 match result_def {
4970                     Some(def) => {
4971                         // Write the result into the def map.
4972                         debug!("(resolving type) writing resolution for `{}` \
4973                                 (id {})",
4974                                self.path_names_to_string(path),
4975                                path_id);
4976                         self.record_def(path_id, def);
4977                     }
4978                     None => {
4979                         let msg = format!("use of undeclared type name `{}`",
4980                                           self.path_names_to_string(path));
4981                         self.resolve_error(ty.span, msg.as_slice());
4982                     }
4983                 }
4984             }
4985
4986             TyObjectSum(ref ty, ref bound_vec) => {
4987                 self.resolve_type(&**ty);
4988                 self.resolve_type_parameter_bounds(ty.id, bound_vec,
4989                                                        TraitBoundingTypeParameter);
4990             }
4991
4992             TyQPath(ref qpath) => {
4993                 self.resolve_type(&*qpath.self_type);
4994                 self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
4995             }
4996
4997             TyClosure(ref c) | TyProc(ref c) => {
4998                 self.resolve_type_parameter_bounds(
4999                     ty.id,
5000                     &c.bounds,
5001                     TraitBoundingTypeParameter);
5002                 visit::walk_ty(self, ty);
5003             }
5004
5005             TyPolyTraitRef(ref bounds) => {
5006                 self.resolve_type_parameter_bounds(
5007                     ty.id,
5008                     bounds,
5009                     TraitObject);
5010                 visit::walk_ty(self, ty);
5011             }
5012             _ => {
5013                 // Just resolve embedded types.
5014                 visit::walk_ty(self, ty);
5015             }
5016         }
5017     }
5018
5019     fn resolve_pattern(&mut self,
5020                        pattern: &Pat,
5021                        mode: PatternBindingMode,
5022                        // Maps idents to the node ID for the (outermost)
5023                        // pattern that binds them
5024                        bindings_list: &mut HashMap<Name, NodeId>) {
5025         let pat_id = pattern.id;
5026         walk_pat(pattern, |pattern| {
5027             match pattern.node {
5028                 PatIdent(binding_mode, ref path1, _) => {
5029
5030                     // The meaning of pat_ident with no type parameters
5031                     // depends on whether an enum variant or unit-like struct
5032                     // with that name is in scope. The probing lookup has to
5033                     // be careful not to emit spurious errors. Only matching
5034                     // patterns (match) can match nullary variants or
5035                     // unit-like structs. For binding patterns (let), matching
5036                     // such a value is simply disallowed (since it's rarely
5037                     // what you want).
5038
5039                     let ident = path1.node;
5040                     let renamed = mtwt::resolve(ident);
5041
5042                     match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
5043                         FoundStructOrEnumVariant(ref def, lp)
5044                                 if mode == RefutableMode => {
5045                             debug!("(resolving pattern) resolving `{}` to \
5046                                     struct or enum variant",
5047                                    token::get_name(renamed));
5048
5049                             self.enforce_default_binding_mode(
5050                                 pattern,
5051                                 binding_mode,
5052                                 "an enum variant");
5053                             self.record_def(pattern.id, (def.clone(), lp));
5054                         }
5055                         FoundStructOrEnumVariant(..) => {
5056                             self.resolve_error(
5057                                 pattern.span,
5058                                 format!("declaration of `{}` shadows an enum \
5059                                          variant or unit-like struct in \
5060                                          scope",
5061                                         token::get_name(renamed)).as_slice());
5062                         }
5063                         FoundConst(ref def, lp) if mode == RefutableMode => {
5064                             debug!("(resolving pattern) resolving `{}` to \
5065                                     constant",
5066                                    token::get_name(renamed));
5067
5068                             self.enforce_default_binding_mode(
5069                                 pattern,
5070                                 binding_mode,
5071                                 "a constant");
5072                             self.record_def(pattern.id, (def.clone(), lp));
5073                         }
5074                         FoundConst(..) => {
5075                             self.resolve_error(pattern.span,
5076                                                   "only irrefutable patterns \
5077                                                    allowed here");
5078                         }
5079                         BareIdentifierPatternUnresolved => {
5080                             debug!("(resolving pattern) binding `{}`",
5081                                    token::get_name(renamed));
5082
5083                             let def = DefLocal(pattern.id);
5084
5085                             // Record the definition so that later passes
5086                             // will be able to distinguish variants from
5087                             // locals in patterns.
5088
5089                             self.record_def(pattern.id, (def, LastMod(AllPublic)));
5090
5091                             // Add the binding to the local ribs, if it
5092                             // doesn't already exist in the bindings list. (We
5093                             // must not add it if it's in the bindings list
5094                             // because that breaks the assumptions later
5095                             // passes make about or-patterns.)
5096                             if !bindings_list.contains_key(&renamed) {
5097                                 let this = &mut *self;
5098                                 let last_rib = this.value_ribs.last_mut().unwrap();
5099                                 last_rib.bindings.insert(renamed, DlDef(def));
5100                                 bindings_list.insert(renamed, pat_id);
5101                             } else if mode == ArgumentIrrefutableMode &&
5102                                     bindings_list.contains_key(&renamed) {
5103                                 // Forbid duplicate bindings in the same
5104                                 // parameter list.
5105                                 self.resolve_error(pattern.span,
5106                                                    format!("identifier `{}` \
5107                                                             is bound more \
5108                                                             than once in \
5109                                                             this parameter \
5110                                                             list",
5111                                                            token::get_ident(
5112                                                                ident))
5113                                                    .as_slice())
5114                             } else if bindings_list.get(&renamed) ==
5115                                     Some(&pat_id) {
5116                                 // Then this is a duplicate variable in the
5117                                 // same disjunction, which is an error.
5118                                 self.resolve_error(pattern.span,
5119                                     format!("identifier `{}` is bound \
5120                                              more than once in the same \
5121                                              pattern",
5122                                             token::get_ident(ident)).as_slice());
5123                             }
5124                             // Else, not bound in the same pattern: do
5125                             // nothing.
5126                         }
5127                     }
5128                 }
5129
5130                 PatEnum(ref path, _) => {
5131                     // This must be an enum variant, struct or const.
5132                     match self.resolve_path(pat_id, path, ValueNS, false) {
5133                         Some(def @ (DefVariant(..), _)) |
5134                         Some(def @ (DefStruct(..), _))  |
5135                         Some(def @ (DefConst(..), _)) => {
5136                             self.record_def(pattern.id, def);
5137                         }
5138                         Some((DefStatic(..), _)) => {
5139                             self.resolve_error(path.span,
5140                                                "static variables cannot be \
5141                                                 referenced in a pattern, \
5142                                                 use a `const` instead");
5143                         }
5144                         Some(_) => {
5145                             self.resolve_error(path.span,
5146                                 format!("`{}` is not an enum variant, struct or const",
5147                                     token::get_ident(
5148                                         path.segments
5149                                             .last()
5150                                             .unwrap()
5151                                             .identifier)).as_slice());
5152                         }
5153                         None => {
5154                             self.resolve_error(path.span,
5155                                 format!("unresolved enum variant, struct or const `{}`",
5156                                     token::get_ident(
5157                                         path.segments
5158                                             .last()
5159                                             .unwrap()
5160                                             .identifier)).as_slice());
5161                         }
5162                     }
5163
5164                     // Check the types in the path pattern.
5165                     for ty in path.segments
5166                                   .iter()
5167                                   .flat_map(|s| s.parameters.types().into_iter()) {
5168                         self.resolve_type(&**ty);
5169                     }
5170                 }
5171
5172                 PatLit(ref expr) => {
5173                     self.resolve_expr(&**expr);
5174                 }
5175
5176                 PatRange(ref first_expr, ref last_expr) => {
5177                     self.resolve_expr(&**first_expr);
5178                     self.resolve_expr(&**last_expr);
5179                 }
5180
5181                 PatStruct(ref path, _, _) => {
5182                     match self.resolve_path(pat_id, path, TypeNS, false) {
5183                         Some(definition) => {
5184                             self.record_def(pattern.id, definition);
5185                         }
5186                         result => {
5187                             debug!("(resolving pattern) didn't find struct \
5188                                     def: {}", result);
5189                             let msg = format!("`{}` does not name a structure",
5190                                               self.path_names_to_string(path));
5191                             self.resolve_error(path.span, msg.as_slice());
5192                         }
5193                     }
5194                 }
5195
5196                 _ => {
5197                     // Nothing to do.
5198                 }
5199             }
5200             true
5201         });
5202     }
5203
5204     fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
5205                                        -> BareIdentifierPatternResolution {
5206         let module = self.current_module.clone();
5207         match self.resolve_item_in_lexical_scope(module,
5208                                                  name,
5209                                                  ValueNS) {
5210             Success((target, _)) => {
5211                 debug!("(resolve bare identifier pattern) succeeded in \
5212                          finding {} at {}",
5213                         token::get_name(name),
5214                         target.bindings.value_def.borrow());
5215                 match *target.bindings.value_def.borrow() {
5216                     None => {
5217                         panic!("resolved name in the value namespace to a \
5218                               set of name bindings with no def?!");
5219                     }
5220                     Some(def) => {
5221                         // For the two success cases, this lookup can be
5222                         // considered as not having a private component because
5223                         // the lookup happened only within the current module.
5224                         match def.def {
5225                             def @ DefVariant(..) | def @ DefStruct(..) => {
5226                                 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5227                             }
5228                             def @ DefConst(..) => {
5229                                 return FoundConst(def, LastMod(AllPublic));
5230                             }
5231                             DefStatic(..) => {
5232                                 self.resolve_error(span,
5233                                                    "static variables cannot be \
5234                                                     referenced in a pattern, \
5235                                                     use a `const` instead");
5236                                 return BareIdentifierPatternUnresolved;
5237                             }
5238                             _ => {
5239                                 return BareIdentifierPatternUnresolved;
5240                             }
5241                         }
5242                     }
5243                 }
5244             }
5245
5246             Indeterminate => {
5247                 panic!("unexpected indeterminate result");
5248             }
5249             Failed(err) => {
5250                 match err {
5251                     Some((span, msg)) => {
5252                         self.resolve_error(span, format!("failed to resolve: {}",
5253                                                          msg));
5254                     }
5255                     None => ()
5256                 }
5257
5258                 debug!("(resolve bare identifier pattern) failed to find {}",
5259                         token::get_name(name));
5260                 return BareIdentifierPatternUnresolved;
5261             }
5262         }
5263     }
5264
5265     /// If `check_ribs` is true, checks the local definitions first; i.e.
5266     /// doesn't skip straight to the containing module.
5267     fn resolve_path(&mut self,
5268                     id: NodeId,
5269                     path: &Path,
5270                     namespace: Namespace,
5271                     check_ribs: bool) -> Option<(Def, LastPrivate)> {
5272         // First, resolve the types.
5273         for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
5274             self.resolve_type(&**ty);
5275         }
5276
5277         if path.global {
5278             return self.resolve_crate_relative_path(path, namespace);
5279         }
5280
5281         let unqualified_def =
5282                 self.resolve_identifier(path.segments
5283                                             .last().unwrap()
5284                                             .identifier,
5285                                         namespace,
5286                                         check_ribs,
5287                                         path.span);
5288
5289         if path.segments.len() > 1 {
5290             let def = self.resolve_module_relative_path(path, namespace);
5291             match (def, unqualified_def) {
5292                 (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5293                     self.session
5294                         .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
5295                                   id,
5296                                   path.span,
5297                                   "unnecessary qualification".to_string());
5298                 }
5299                 _ => ()
5300             }
5301
5302             return def;
5303         }
5304
5305         return unqualified_def;
5306     }
5307
5308     // resolve a single identifier (used as a varref)
5309     fn resolve_identifier(&mut self,
5310                               identifier: Ident,
5311                               namespace: Namespace,
5312                               check_ribs: bool,
5313                               span: Span)
5314                               -> Option<(Def, LastPrivate)> {
5315         if check_ribs {
5316             match self.resolve_identifier_in_local_ribs(identifier,
5317                                                       namespace,
5318                                                       span) {
5319                 Some(def) => {
5320                     return Some((def, LastMod(AllPublic)));
5321                 }
5322                 None => {
5323                     // Continue.
5324                 }
5325             }
5326         }
5327
5328         return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
5329     }
5330
5331     // FIXME #4952: Merge me with resolve_name_in_module?
5332     fn resolve_definition_of_name_in_module(&mut self,
5333                                             containing_module: Rc<Module>,
5334                                             name: Name,
5335                                             namespace: Namespace)
5336                                                 -> NameDefinition {
5337         // First, search children.
5338         self.populate_module_if_necessary(&containing_module);
5339
5340         match containing_module.children.borrow().get(&name) {
5341             Some(child_name_bindings) => {
5342                 match child_name_bindings.def_for_namespace(namespace) {
5343                     Some(def) => {
5344                         // Found it. Stop the search here.
5345                         let p = child_name_bindings.defined_in_public_namespace(
5346                                         namespace);
5347                         let lp = if p {LastMod(AllPublic)} else {
5348                             LastMod(DependsOn(def.def_id()))
5349                         };
5350                         return ChildNameDefinition(def, lp);
5351                     }
5352                     None => {}
5353                 }
5354             }
5355             None => {}
5356         }
5357
5358         // Next, search import resolutions.
5359         match containing_module.import_resolutions.borrow().get(&name) {
5360             Some(import_resolution) if import_resolution.is_public => {
5361                 if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
5362                     match target.bindings.def_for_namespace(namespace) {
5363                         Some(def) => {
5364                             // Found it.
5365                             let id = import_resolution.id(namespace);
5366                             // track imports and extern crates as well
5367                             self.used_imports.insert((id, namespace));
5368                             match target.target_module.def_id.get() {
5369                                 Some(DefId{krate: kid, ..}) => {
5370                                     self.used_crates.insert(kid);
5371                                 },
5372                                 _ => {}
5373                             }
5374                             return ImportNameDefinition(def, LastMod(AllPublic));
5375                         }
5376                         None => {
5377                             // This can happen with external impls, due to
5378                             // the imperfect way we read the metadata.
5379                         }
5380                     }
5381                 }
5382             }
5383             Some(..) | None => {} // Continue.
5384         }
5385
5386         // Finally, search through external children.
5387         if namespace == TypeNS {
5388             if let Some(module) = containing_module.external_module_children.borrow()
5389                                                    .get(&name).cloned() {
5390                 if let Some(def_id) = module.def_id.get() {
5391                     // track used crates
5392                     self.used_crates.insert(def_id.krate);
5393                     let lp = if module.is_public {LastMod(AllPublic)} else {
5394                         LastMod(DependsOn(def_id))
5395                     };
5396                     return ChildNameDefinition(DefMod(def_id), lp);
5397                 }
5398             }
5399         }
5400
5401         return NoNameDefinition;
5402     }
5403
5404     // resolve a "module-relative" path, e.g. a::b::c
5405     fn resolve_module_relative_path(&mut self,
5406                                         path: &Path,
5407                                         namespace: Namespace)
5408                                         -> Option<(Def, LastPrivate)> {
5409         let module_path = path.segments.init().iter()
5410                                               .map(|ps| ps.identifier.name)
5411                                               .collect::<Vec<_>>();
5412
5413         let containing_module;
5414         let last_private;
5415         let module = self.current_module.clone();
5416         match self.resolve_module_path(module,
5417                                        module_path.as_slice(),
5418                                        UseLexicalScope,
5419                                        path.span,
5420                                        PathSearch) {
5421             Failed(err) => {
5422                 let (span, msg) = match err {
5423                     Some((span, msg)) => (span, msg),
5424                     None => {
5425                         let msg = format!("Use of undeclared module `{}`",
5426                                           self.names_to_string(
5427                                                module_path.as_slice()));
5428                         (path.span, msg)
5429                     }
5430                 };
5431
5432                 self.resolve_error(span, format!("failed to resolve. {}",
5433                                                  msg.as_slice()));
5434                 return None;
5435             }
5436             Indeterminate => panic!("indeterminate unexpected"),
5437             Success((resulting_module, resulting_last_private)) => {
5438                 containing_module = resulting_module;
5439                 last_private = resulting_last_private;
5440             }
5441         }
5442
5443         let name = path.segments.last().unwrap().identifier.name;
5444         let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5445                                                                   name,
5446                                                                   namespace) {
5447             NoNameDefinition => {
5448                 // We failed to resolve the name. Report an error.
5449                 return None;
5450             }
5451             ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5452                 (def, last_private.or(lp))
5453             }
5454         };
5455         if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
5456             self.used_crates.insert(kid);
5457         }
5458         return Some(def);
5459     }
5460
5461     /// Invariant: This must be called only during main resolution, not during
5462     /// import resolution.
5463     fn resolve_crate_relative_path(&mut self,
5464                                    path: &Path,
5465                                    namespace: Namespace)
5466                                        -> Option<(Def, LastPrivate)> {
5467         let module_path = path.segments.init().iter()
5468                                               .map(|ps| ps.identifier.name)
5469                                               .collect::<Vec<_>>();
5470
5471         let root_module = self.graph_root.get_module();
5472
5473         let containing_module;
5474         let last_private;
5475         match self.resolve_module_path_from_root(root_module,
5476                                                  module_path.as_slice(),
5477                                                  0,
5478                                                  path.span,
5479                                                  PathSearch,
5480                                                  LastMod(AllPublic)) {
5481             Failed(err) => {
5482                 let (span, msg) = match err {
5483                     Some((span, msg)) => (span, msg),
5484                     None => {
5485                         let msg = format!("Use of undeclared module `::{}`",
5486                                           self.names_to_string(module_path.as_slice()));
5487                         (path.span, msg)
5488                     }
5489                 };
5490
5491                 self.resolve_error(span, format!("failed to resolve. {}",
5492                                                  msg.as_slice()));
5493                 return None;
5494             }
5495
5496             Indeterminate => {
5497                 panic!("indeterminate unexpected");
5498             }
5499
5500             Success((resulting_module, resulting_last_private)) => {
5501                 containing_module = resulting_module;
5502                 last_private = resulting_last_private;
5503             }
5504         }
5505
5506         let name = path.segments.last().unwrap().identifier.name;
5507         match self.resolve_definition_of_name_in_module(containing_module,
5508                                                         name,
5509                                                         namespace) {
5510             NoNameDefinition => {
5511                 // We failed to resolve the name. Report an error.
5512                 return None;
5513             }
5514             ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5515                 return Some((def, last_private.or(lp)));
5516             }
5517         }
5518     }
5519
5520     fn resolve_identifier_in_local_ribs(&mut self,
5521                                             ident: Ident,
5522                                             namespace: Namespace,
5523                                             span: Span)
5524                                             -> Option<Def> {
5525         // Check the local set of ribs.
5526         let search_result = match namespace {
5527             ValueNS => {
5528                 let renamed = mtwt::resolve(ident);
5529                 self.search_ribs(self.value_ribs.as_slice(),
5530                                  renamed, span)
5531             }
5532             TypeNS => {
5533                 let name = ident.name;
5534                 self.search_ribs(self.type_ribs.as_slice(), name, span)
5535             }
5536         };
5537
5538         match search_result {
5539             Some(DlDef(def)) => {
5540                 debug!("(resolving path in local ribs) resolved `{}` to \
5541                         local: {}",
5542                        token::get_ident(ident),
5543                        def);
5544                 return Some(def);
5545             }
5546             Some(DlField) | Some(DlImpl(_)) | None => {
5547                 return None;
5548             }
5549         }
5550     }
5551
5552     fn resolve_item_by_name_in_lexical_scope(&mut self,
5553                                              name: Name,
5554                                              namespace: Namespace)
5555                                             -> Option<(Def, LastPrivate)> {
5556         // Check the items.
5557         let module = self.current_module.clone();
5558         match self.resolve_item_in_lexical_scope(module,
5559                                                  name,
5560                                                  namespace) {
5561             Success((target, _)) => {
5562                 match (*target.bindings).def_for_namespace(namespace) {
5563                     None => {
5564                         // This can happen if we were looking for a type and
5565                         // found a module instead. Modules don't have defs.
5566                         debug!("(resolving item path by identifier in lexical \
5567                                  scope) failed to resolve {} after success...",
5568                                  token::get_name(name));
5569                         return None;
5570                     }
5571                     Some(def) => {
5572                         debug!("(resolving item path in lexical scope) \
5573                                 resolved `{}` to item",
5574                                token::get_name(name));
5575                         // This lookup is "all public" because it only searched
5576                         // for one identifier in the current module (couldn't
5577                         // have passed through reexports or anything like that.
5578                         return Some((def, LastMod(AllPublic)));
5579                     }
5580                 }
5581             }
5582             Indeterminate => {
5583                 panic!("unexpected indeterminate result");
5584             }
5585             Failed(err) => {
5586                 match err {
5587                     Some((span, msg)) =>
5588                         self.resolve_error(span, format!("failed to resolve. {}", msg)),
5589                     None => ()
5590                 }
5591
5592                 debug!("(resolving item path by identifier in lexical scope) \
5593                          failed to resolve {}", token::get_name(name));
5594                 return None;
5595             }
5596         }
5597     }
5598
5599     fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5600         self.emit_errors = false;
5601         let rs = f(self);
5602         self.emit_errors = true;
5603         rs
5604     }
5605
5606     fn resolve_error<T: Str>(&self, span: Span, s: T) {
5607         if self.emit_errors {
5608             self.session.span_err(span, s.as_slice());
5609         }
5610     }
5611
5612     fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5613         fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5614                                                     -> Option<(Path, NodeId, FallbackChecks)> {
5615             match t.node {
5616                 TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
5617                 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5618                 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5619                 // This doesn't handle the remaining `Ty` variants as they are not
5620                 // that commonly the self_type, it might be interesting to provide
5621                 // support for those in future.
5622                 _ => None,
5623             }
5624         }
5625
5626         fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
5627                             -> Option<Rc<Module>> {
5628             let root = this.current_module.clone();
5629             let last_name = name_path.last().unwrap();
5630
5631             if name_path.len() == 1 {
5632                 match this.primitive_type_table.primitive_types.get(last_name) {
5633                     Some(_) => None,
5634                     None => {
5635                         match this.current_module.children.borrow().get(last_name) {
5636                             Some(child) => child.get_module_if_available(),
5637                             None => None
5638                         }
5639                     }
5640                 }
5641             } else {
5642                 match this.resolve_module_path(root,
5643                                                 name_path.as_slice(),
5644                                                 UseLexicalScope,
5645                                                 span,
5646                                                 PathSearch) {
5647                     Success((module, _)) => Some(module),
5648                     _ => None
5649                 }
5650             }
5651         }
5652
5653         let (path, node_id, allowed) = match self.current_self_type {
5654             Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5655                 Some(x) => x,
5656                 None => return NoSuggestion,
5657             },
5658             None => return NoSuggestion,
5659         };
5660
5661         if allowed == Everything {
5662             // Look for a field with the same name in the current self_type.
5663             match self.def_map.borrow().get(&node_id) {
5664                  Some(&DefTy(did, _))
5665                 | Some(&DefStruct(did))
5666                 | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
5667                     None => {}
5668                     Some(fields) => {
5669                         if fields.iter().any(|&field_name| name == field_name) {
5670                             return Field;
5671                         }
5672                     }
5673                 },
5674                 _ => {} // Self type didn't resolve properly
5675             }
5676         }
5677
5678         let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
5679
5680         // Look for a method in the current self type's impl module.
5681         match get_module(self, path.span, name_path.as_slice()) {
5682             Some(module) => match module.children.borrow().get(&name) {
5683                 Some(binding) => {
5684                     let p_str = self.path_names_to_string(&path);
5685                     match binding.def_for_namespace(ValueNS) {
5686                         Some(DefStaticMethod(_, provenance)) => {
5687                             match provenance {
5688                                 FromImpl(_) => return StaticMethod(p_str),
5689                                 FromTrait(_) => unreachable!()
5690                             }
5691                         }
5692                         Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
5693                         Some(DefMethod(_, Some(_), _)) => return TraitItem,
5694                         _ => ()
5695                     }
5696                 }
5697                 None => {}
5698             },
5699             None => {}
5700         }
5701
5702         // Look for a method in the current trait.
5703         match self.current_trait_ref {
5704             Some((did, ref trait_ref)) => {
5705                 let path_str = self.path_names_to_string(&trait_ref.path);
5706
5707                 match self.trait_item_map.get(&(name, did)) {
5708                     Some(&StaticMethodTraitItemKind) => {
5709                         return TraitMethod(path_str)
5710                     }
5711                     Some(_) => return TraitItem,
5712                     None => {}
5713                 }
5714             }
5715             None => {}
5716         }
5717
5718         NoSuggestion
5719     }
5720
5721     fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5722                                 -> Option<String> {
5723         let this = &mut *self;
5724
5725         let mut maybes: Vec<token::InternedString> = Vec::new();
5726         let mut values: Vec<uint> = Vec::new();
5727
5728         for rib in this.value_ribs.iter().rev() {
5729             for (&k, _) in rib.bindings.iter() {
5730                 maybes.push(token::get_name(k));
5731                 values.push(uint::MAX);
5732             }
5733         }
5734
5735         let mut smallest = 0;
5736         for (i, other) in maybes.iter().enumerate() {
5737             values[i] = name.lev_distance(other.get());
5738
5739             if values[i] <= values[smallest] {
5740                 smallest = i;
5741             }
5742         }
5743
5744         if values.len() > 0 &&
5745             values[smallest] != uint::MAX &&
5746             values[smallest] < name.len() + 2 &&
5747             values[smallest] <= max_distance &&
5748             name != maybes[smallest].get() {
5749
5750             Some(maybes[smallest].get().to_string())
5751
5752         } else {
5753             None
5754         }
5755     }
5756
5757     fn resolve_expr(&mut self, expr: &Expr) {
5758         // First, record candidate traits for this expression if it could
5759         // result in the invocation of a method call.
5760
5761         self.record_candidate_traits_for_expr_if_necessary(expr);
5762
5763         // Next, resolve the node.
5764         match expr.node {
5765             // The interpretation of paths depends on whether the path has
5766             // multiple elements in it or not.
5767
5768             ExprPath(ref path) => {
5769                 // This is a local path in the value namespace. Walk through
5770                 // scopes looking for it.
5771
5772                 match self.resolve_path(expr.id, path, ValueNS, true) {
5773                     Some(def) => {
5774                         // Write the result into the def map.
5775                         debug!("(resolving expr) resolved `{}`",
5776                                self.path_names_to_string(path));
5777
5778                         self.record_def(expr.id, def);
5779                     }
5780                     None => {
5781                         let wrong_name = self.path_names_to_string(path);
5782                         // Be helpful if the name refers to a struct
5783                         // (The pattern matching def_tys where the id is in self.structs
5784                         // matches on regular structs while excluding tuple- and enum-like
5785                         // structs, which wouldn't result in this error.)
5786                         match self.with_no_errors(|this|
5787                             this.resolve_path(expr.id, path, TypeNS, false)) {
5788                             Some((DefTy(struct_id, _), _))
5789                               if self.structs.contains_key(&struct_id) => {
5790                                 self.resolve_error(expr.span,
5791                                         format!("`{}` is a structure name, but \
5792                                                  this expression \
5793                                                  uses it like a function name",
5794                                                 wrong_name).as_slice());
5795
5796                                 self.session.span_help(expr.span,
5797                                     format!("Did you mean to write: \
5798                                             `{} {{ /* fields */ }}`?",
5799                                             wrong_name).as_slice());
5800
5801                             }
5802                             _ => {
5803                                 let mut method_scope = false;
5804                                 self.value_ribs.iter().rev().all(|rib| {
5805                                     let res = match *rib {
5806                                         Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5807                                         Rib { bindings: _, kind: ItemRibKind } => false,
5808                                         _ => return true, // Keep advancing
5809                                     };
5810
5811                                     method_scope = res;
5812                                     false // Stop advancing
5813                                 });
5814
5815                                 if method_scope && token::get_name(self.self_name).get()
5816                                                                    == wrong_name {
5817                                         self.resolve_error(
5818                                             expr.span,
5819                                             "`self` is not available \
5820                                              in a static method. Maybe a \
5821                                              `self` argument is missing?");
5822                                 } else {
5823                                     let last_name = path.segments.last().unwrap().identifier.name;
5824                                     let mut msg = match self.find_fallback_in_self_type(last_name) {
5825                                         NoSuggestion => {
5826                                             // limit search to 5 to reduce the number
5827                                             // of stupid suggestions
5828                                             self.find_best_match_for_name(wrong_name.as_slice(), 5)
5829                                                                 .map_or("".to_string(),
5830                                                                         |x| format!("`{}`", x))
5831                                         }
5832                                         Field =>
5833                                             format!("`self.{}`", wrong_name),
5834                                         Method
5835                                         | TraitItem =>
5836                                             format!("to call `self.{}`", wrong_name),
5837                                         TraitMethod(path_str)
5838                                         | StaticMethod(path_str) =>
5839                                             format!("to call `{}::{}`", path_str, wrong_name)
5840                                     };
5841
5842                                     if msg.len() > 0 {
5843                                         msg = format!(". Did you mean {}?", msg)
5844                                     }
5845
5846                                     self.resolve_error(
5847                                         expr.span,
5848                                         format!("unresolved name `{}`{}",
5849                                                 wrong_name,
5850                                                 msg).as_slice());
5851                                 }
5852                             }
5853                         }
5854                     }
5855                 }
5856
5857                 visit::walk_expr(self, expr);
5858             }
5859
5860             ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
5861                 self.capture_mode_map.insert(expr.id, capture_clause);
5862                 self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
5863                                       Some(&**fn_decl), NoTypeParameters,
5864                                       &**block);
5865             }
5866
5867             ExprProc(ref fn_decl, ref block) => {
5868                 self.capture_mode_map.insert(expr.id, ast::CaptureByValue);
5869                 self.resolve_function(ClosureRibKind(expr.id, block.id),
5870                                       Some(&**fn_decl), NoTypeParameters,
5871                                       &**block);
5872             }
5873
5874             ExprStruct(ref path, _, _) => {
5875                 // Resolve the path to the structure it goes to. We don't
5876                 // check to ensure that the path is actually a structure; that
5877                 // is checked later during typeck.
5878                 match self.resolve_path(expr.id, path, TypeNS, false) {
5879                     Some(definition) => self.record_def(expr.id, definition),
5880                     result => {
5881                         debug!("(resolving expression) didn't find struct \
5882                                 def: {}", result);
5883                         let msg = format!("`{}` does not name a structure",
5884                                           self.path_names_to_string(path));
5885                         self.resolve_error(path.span, msg.as_slice());
5886                     }
5887                 }
5888
5889                 visit::walk_expr(self, expr);
5890             }
5891
5892             ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5893                 self.with_label_rib(|this| {
5894                     let def_like = DlDef(DefLabel(expr.id));
5895
5896                     {
5897                         let rib = this.label_ribs.last_mut().unwrap();
5898                         let renamed = mtwt::resolve(label);
5899                         rib.bindings.insert(renamed, def_like);
5900                     }
5901
5902                     visit::walk_expr(this, expr);
5903                 })
5904             }
5905
5906             ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5907                 self.resolve_expr(&**head);
5908
5909                 self.value_ribs.push(Rib::new(NormalRibKind));
5910
5911                 self.resolve_pattern(&**pattern,
5912                                      LocalIrrefutableMode,
5913                                      &mut HashMap::new());
5914
5915                 match optional_label {
5916                     None => {}
5917                     Some(label) => {
5918                         self.label_ribs
5919                             .push(Rib::new(NormalRibKind));
5920                         let def_like = DlDef(DefLabel(expr.id));
5921
5922                         {
5923                             let rib = self.label_ribs.last_mut().unwrap();
5924                             let renamed = mtwt::resolve(label);
5925                             rib.bindings.insert(renamed, def_like);
5926                         }
5927                     }
5928                 }
5929
5930                 self.resolve_block(&**body);
5931
5932                 if optional_label.is_some() {
5933                     drop(self.label_ribs.pop())
5934                 }
5935
5936                 self.value_ribs.pop();
5937             }
5938
5939             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5940                 let renamed = mtwt::resolve(label);
5941                 match self.search_ribs(self.label_ribs.as_slice(),
5942                                        renamed, expr.span) {
5943                     None => {
5944                         self.resolve_error(
5945                             expr.span,
5946                             format!("use of undeclared label `{}`",
5947                                     token::get_ident(label)).as_slice())
5948                     }
5949                     Some(DlDef(def @ DefLabel(_))) => {
5950                         // Since this def is a label, it is never read.
5951                         self.record_def(expr.id, (def, LastMod(AllPublic)))
5952                     }
5953                     Some(_) => {
5954                         self.session.span_bug(expr.span,
5955                                               "label wasn't mapped to a \
5956                                                label def!")
5957                     }
5958                 }
5959             }
5960
5961             _ => {
5962                 visit::walk_expr(self, expr);
5963             }
5964         }
5965     }
5966
5967     fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5968         match expr.node {
5969             ExprField(_, ident) => {
5970                 // FIXME(#6890): Even though you can't treat a method like a
5971                 // field, we need to add any trait methods we find that match
5972                 // the field name so that we can do some nice error reporting
5973                 // later on in typeck.
5974                 let traits = self.search_for_traits_containing_method(ident.node.name);
5975                 self.trait_map.insert(expr.id, traits);
5976             }
5977             ExprMethodCall(ident, _, _) => {
5978                 debug!("(recording candidate traits for expr) recording \
5979                         traits for {}",
5980                        expr.id);
5981                 let traits = self.search_for_traits_containing_method(ident.node.name);
5982                 self.trait_map.insert(expr.id, traits);
5983             }
5984             _ => {
5985                 // Nothing to do.
5986             }
5987         }
5988     }
5989
5990     fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5991         debug!("(searching for traits containing method) looking for '{}'",
5992                token::get_name(name));
5993
5994         fn add_trait_info(found_traits: &mut Vec<DefId>,
5995                           trait_def_id: DefId,
5996                           name: Name) {
5997             debug!("(adding trait info) found trait {}:{} for method '{}'",
5998                 trait_def_id.krate,
5999                 trait_def_id.node,
6000                 token::get_name(name));
6001             found_traits.push(trait_def_id);
6002         }
6003
6004         let mut found_traits = Vec::new();
6005         let mut search_module = self.current_module.clone();
6006         loop {
6007             // Look for the current trait.
6008             match self.current_trait_ref {
6009                 Some((trait_def_id, _)) => {
6010                     if self.trait_item_map.contains_key(&(name, trait_def_id)) {
6011                         add_trait_info(&mut found_traits, trait_def_id, name);
6012                     }
6013                 }
6014                 None => {} // Nothing to do.
6015             }
6016
6017             // Look for trait children.
6018             self.populate_module_if_necessary(&search_module);
6019
6020             {
6021                 for (_, child_names) in search_module.children.borrow().iter() {
6022                     let def = match child_names.def_for_namespace(TypeNS) {
6023                         Some(def) => def,
6024                         None => continue
6025                     };
6026                     let trait_def_id = match def {
6027                         DefTrait(trait_def_id) => trait_def_id,
6028                         _ => continue,
6029                     };
6030                     if self.trait_item_map.contains_key(&(name, trait_def_id)) {
6031                         add_trait_info(&mut found_traits, trait_def_id, name);
6032                     }
6033                 }
6034             }
6035
6036             // Look for imports.
6037             for (_, import) in search_module.import_resolutions.borrow().iter() {
6038                 let target = match import.target_for_namespace(TypeNS) {
6039                     None => continue,
6040                     Some(target) => target,
6041                 };
6042                 let did = match target.bindings.def_for_namespace(TypeNS) {
6043                     Some(DefTrait(trait_def_id)) => trait_def_id,
6044                     Some(..) | None => continue,
6045                 };
6046                 if self.trait_item_map.contains_key(&(name, did)) {
6047                     add_trait_info(&mut found_traits, did, name);
6048                     self.used_imports.insert((import.type_id, TypeNS));
6049                     if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
6050                         self.used_crates.insert(kid);
6051                     }
6052                 }
6053             }
6054
6055             match search_module.parent_link.clone() {
6056                 NoParentLink | ModuleParentLink(..) => break,
6057                 BlockParentLink(parent_module, _) => {
6058                     search_module = parent_module.upgrade().unwrap();
6059                 }
6060             }
6061         }
6062
6063         found_traits
6064     }
6065
6066     fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
6067         debug!("(recording def) recording {} for {}, last private {}",
6068                 def, node_id, lp);
6069         assert!(match lp {LastImport{..} => false, _ => true},
6070                 "Import should only be used for `use` directives");
6071         self.last_private.insert(node_id, lp);
6072
6073         match self.def_map.borrow_mut().entry(node_id) {
6074             // Resolve appears to "resolve" the same ID multiple
6075             // times, so here is a sanity check it at least comes to
6076             // the same conclusion! - nmatsakis
6077             Occupied(entry) => if def != *entry.get() {
6078                 self.session
6079                     .bug(format!("node_id {} resolved first to {} and \
6080                                   then {}",
6081                                  node_id,
6082                                  *entry.get(),
6083                                  def).as_slice());
6084             },
6085             Vacant(entry) => { entry.set(def); },
6086         }
6087     }
6088
6089     fn enforce_default_binding_mode(&mut self,
6090                                         pat: &Pat,
6091                                         pat_binding_mode: BindingMode,
6092                                         descr: &str) {
6093         match pat_binding_mode {
6094             BindByValue(_) => {}
6095             BindByRef(..) => {
6096                 self.resolve_error(pat.span,
6097                                    format!("cannot use `ref` binding mode \
6098                                             with {}",
6099                                            descr).as_slice());
6100             }
6101         }
6102     }
6103
6104     //
6105     // Unused import checking
6106     //
6107     // Although this is mostly a lint pass, it lives in here because it depends on
6108     // resolve data structures and because it finalises the privacy information for
6109     // `use` directives.
6110     //
6111
6112     fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
6113         let mut visitor = UnusedImportCheckVisitor{ resolver: self };
6114         visit::walk_crate(&mut visitor, krate);
6115     }
6116
6117     fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
6118         // Ignore is_public import statements because there's no way to be sure
6119         // whether they're used or not. Also ignore imports with a dummy span
6120         // because this means that they were generated in some fashion by the
6121         // compiler and we don't need to consider them.
6122         if vi.vis == Public { return }
6123         if vi.span == DUMMY_SP { return }
6124
6125         match vi.node {
6126             ViewItemExternCrate(_, _, id) => {
6127                 if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
6128                     if !self.used_crates.contains(&crate_num) {
6129                         self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
6130                                               id,
6131                                               vi.span,
6132                                               "unused extern crate".to_string());
6133                     }
6134                 }
6135             },
6136             ViewItemUse(ref p) => {
6137                 match p.node {
6138                     ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
6139
6140                     ViewPathList(_, ref list, _) => {
6141                         for i in list.iter() {
6142                             self.finalize_import(i.node.id(), i.span);
6143                         }
6144                     },
6145                     ViewPathGlob(_, id) => {
6146                         if !self.used_imports.contains(&(id, TypeNS)) &&
6147                            !self.used_imports.contains(&(id, ValueNS)) {
6148                             self.session
6149                                 .add_lint(lint::builtin::UNUSED_IMPORTS,
6150                                           id,
6151                                           p.span,
6152                                           "unused import".to_string());
6153                         }
6154                     },
6155                 }
6156             }
6157         }
6158     }
6159
6160     // We have information about whether `use` (import) directives are actually used now.
6161     // If an import is not used at all, we signal a lint error. If an import is only used
6162     // for a single namespace, we remove the other namespace from the recorded privacy
6163     // information. That means in privacy.rs, we will only check imports and namespaces
6164     // which are used. In particular, this means that if an import could name either a
6165     // public or private item, we will check the correct thing, dependent on how the import
6166     // is used.
6167     fn finalize_import(&mut self, id: NodeId, span: Span) {
6168         debug!("finalizing import uses for {}",
6169                self.session.codemap().span_to_snippet(span));
6170
6171         if !self.used_imports.contains(&(id, TypeNS)) &&
6172            !self.used_imports.contains(&(id, ValueNS)) {
6173             self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
6174                                   id,
6175                                   span,
6176                                   "unused import".to_string());
6177         }
6178
6179         let (v_priv, t_priv) = match self.last_private.get(&id) {
6180             Some(&LastImport {
6181                 value_priv: v,
6182                 value_used: _,
6183                 type_priv: t,
6184                 type_used: _
6185             }) => (v, t),
6186             Some(_) => {
6187                 panic!("we should only have LastImport for `use` directives")
6188             }
6189             _ => return,
6190         };
6191
6192         let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
6193             Used
6194         } else {
6195             Unused
6196         };
6197         let t_used = if self.used_imports.contains(&(id, TypeNS)) {
6198             Used
6199         } else {
6200             Unused
6201         };
6202
6203         match (v_priv, t_priv) {
6204             // Since some items may be both in the value _and_ type namespaces (e.g., structs)
6205             // we might have two LastPrivates pointing at the same thing. There is no point
6206             // checking both, so lets not check the value one.
6207             (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
6208             _ => {},
6209         }
6210
6211         self.last_private.insert(id, LastImport{value_priv: v_priv,
6212                                                 value_used: v_used,
6213                                                 type_priv: t_priv,
6214                                                 type_used: t_used});
6215     }
6216
6217     //
6218     // Diagnostics
6219     //
6220     // Diagnostics are not particularly efficient, because they're rarely
6221     // hit.
6222     //
6223
6224     /// A somewhat inefficient routine to obtain the name of a module.
6225     fn module_to_string(&self, module: &Module) -> String {
6226         let mut names = Vec::new();
6227
6228         fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
6229             match module.parent_link {
6230                 NoParentLink => {}
6231                 ModuleParentLink(ref module, name) => {
6232                     names.push(name);
6233                     collect_mod(names, &*module.upgrade().unwrap());
6234                 }
6235                 BlockParentLink(ref module, _) => {
6236                     // danger, shouldn't be ident?
6237                     names.push(special_idents::opaque.name);
6238                     collect_mod(names, &*module.upgrade().unwrap());
6239                 }
6240             }
6241         }
6242         collect_mod(&mut names, module);
6243
6244         if names.len() == 0 {
6245             return "???".to_string();
6246         }
6247         self.names_to_string(names.into_iter().rev()
6248                                   .collect::<Vec<ast::Name>>()
6249                                   .as_slice())
6250     }
6251
6252     #[allow(dead_code)]   // useful for debugging
6253     fn dump_module(&mut self, module_: Rc<Module>) {
6254         debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6255
6256         debug!("Children:");
6257         self.populate_module_if_necessary(&module_);
6258         for (&name, _) in module_.children.borrow().iter() {
6259             debug!("* {}", token::get_name(name));
6260         }
6261
6262         debug!("Import resolutions:");
6263         let import_resolutions = module_.import_resolutions.borrow();
6264         for (&name, import_resolution) in import_resolutions.iter() {
6265             let value_repr;
6266             match import_resolution.target_for_namespace(ValueNS) {
6267                 None => { value_repr = "".to_string(); }
6268                 Some(_) => {
6269                     value_repr = " value:?".to_string();
6270                     // FIXME #4954
6271                 }
6272             }
6273
6274             let type_repr;
6275             match import_resolution.target_for_namespace(TypeNS) {
6276                 None => { type_repr = "".to_string(); }
6277                 Some(_) => {
6278                     type_repr = " type:?".to_string();
6279                     // FIXME #4954
6280                 }
6281             }
6282
6283             debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6284         }
6285     }
6286 }
6287
6288 pub struct CrateMap {
6289     pub def_map: DefMap,
6290     pub freevars: RefCell<FreevarMap>,
6291     pub capture_mode_map: RefCell<CaptureModeMap>,
6292     pub exp_map2: ExportMap2,
6293     pub trait_map: TraitMap,
6294     pub external_exports: ExternalExports,
6295     pub last_private_map: LastPrivateMap,
6296 }
6297
6298 /// Entry point to crate resolution.
6299 pub fn resolve_crate(session: &Session,
6300                      _: &LanguageItems,
6301                      krate: &Crate)
6302                   -> CrateMap {
6303     let mut resolver = Resolver::new(session, krate.span);
6304     resolver.resolve(krate);
6305     CrateMap {
6306         def_map: resolver.def_map,
6307         freevars: resolver.freevars,
6308         capture_mode_map: RefCell::new(resolver.capture_mode_map),
6309         exp_map2: resolver.export_map2,
6310         trait_map: resolver.trait_map,
6311         external_exports: resolver.external_exports,
6312         last_private_map: resolver.last_private,
6313     }
6314 }