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