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