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