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