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