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