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