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