]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/resolve.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / librustc / middle / resolve.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_camel_case_types)]
12
13 use driver::session::Session;
14 use lint;
15 use metadata::csearch;
16 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
17 use middle::def::*;
18 use middle::lang_items::LanguageItems;
19 use middle::pat_util::pat_bindings;
20 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
21 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
22 use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
23 use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
24
25 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
26 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
27 use syntax::ast::{ExprFnBlock, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
28 use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
29 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
30 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
31 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
32 use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local};
33 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
34 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
35 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
36 use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
37 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
38 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
39 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
40 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
41 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyQPath};
42 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
43 use syntax::ast::{TypeImplItem, UnboxedFnTyParamBound, UnnamedField};
44 use syntax::ast::{UnsafeFn, Variant, ViewItem, ViewItemExternCrate};
45 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
46 use syntax::ast::{Visibility};
47 use syntax::ast;
48 use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
49 use syntax::ast_util;
50 use syntax::attr::AttrMetaMethods;
51 use syntax::ext::mtwt;
52 use syntax::parse::token::special_names;
53 use syntax::parse::token::special_idents;
54 use syntax::parse::token;
55 use syntax::codemap::{Span, DUMMY_SP, Pos};
56 use syntax::owned_slice::OwnedSlice;
57 use syntax::ptr::P;
58 use syntax::visit;
59 use syntax::visit::Visitor;
60
61 use std::collections::{HashMap, HashSet};
62 use std::cell::{Cell, RefCell};
63 use std::mem::replace;
64 use std::rc::{Rc, Weak};
65 use std::uint;
66
67 // Definition mapping
68 pub type DefMap = RefCell<NodeMap<Def>>;
69
70 struct binding_info {
71     span: Span,
72     binding_mode: BindingMode,
73 }
74
75 // Map from the name in a pattern to its binding mode.
76 type BindingMap = HashMap<Name,binding_info>;
77
78 // Trait method resolution
79 pub type TraitMap = NodeMap<Vec<DefId> >;
80
81 // This is the replacement export map. It maps a module to all of the exports
82 // within.
83 pub type ExportMap2 = RefCell<NodeMap<Vec<Export2> >>;
84
85 pub struct Export2 {
86     pub name: String,        // The name of the target.
87     pub def_id: DefId,     // The definition of the target.
88 }
89
90 // This set contains all exported definitions from external crates. The set does
91 // not contain any entries from local crates.
92 pub type ExternalExports = DefIdSet;
93
94 // FIXME: dox
95 pub type LastPrivateMap = NodeMap<LastPrivate>;
96
97 pub enum LastPrivate {
98     LastMod(PrivateDep),
99     // `use` directives (imports) can refer to two separate definitions in the
100     // type and value namespaces. We record here the last private node for each
101     // and whether the import is in fact used for each.
102     // If the Option<PrivateDep> fields are None, it means there is no definition
103     // in that namespace.
104     LastImport{pub value_priv: Option<PrivateDep>,
105                pub value_used: ImportUse,
106                pub type_priv: Option<PrivateDep>,
107                pub type_used: ImportUse},
108 }
109
110 pub enum PrivateDep {
111     AllPublic,
112     DependsOn(DefId),
113 }
114
115 // How an import is used.
116 #[deriving(PartialEq)]
117 pub enum ImportUse {
118     Unused,       // The import is not used.
119     Used,         // The import is used.
120 }
121
122 impl LastPrivate {
123     fn or(self, other: LastPrivate) -> LastPrivate {
124         match (self, other) {
125             (me, LastMod(AllPublic)) => me,
126             (_, other) => other,
127         }
128     }
129 }
130
131 #[deriving(PartialEq)]
132 enum PatternBindingMode {
133     RefutableMode,
134     LocalIrrefutableMode,
135     ArgumentIrrefutableMode,
136 }
137
138 #[deriving(PartialEq, Eq, Hash)]
139 enum Namespace {
140     TypeNS,
141     ValueNS
142 }
143
144 #[deriving(PartialEq)]
145 enum NamespaceError {
146     NoError,
147     ModuleError,
148     TypeError,
149     ValueError
150 }
151
152 /// A NamespaceResult represents the result of resolving an import in
153 /// a particular namespace. The result is either definitely-resolved,
154 /// definitely- unresolved, or unknown.
155 #[deriving(Clone)]
156 enum NamespaceResult {
157     /// Means that resolve hasn't gathered enough information yet to determine
158     /// whether the name is bound in this namespace. (That is, it hasn't
159     /// resolved all `use` directives yet.)
160     UnknownResult,
161     /// Means that resolve has determined that the name is definitely
162     /// not bound in the namespace.
163     UnboundResult,
164     /// Means that resolve has determined that the name is bound in the Module
165     /// argument, and specified by the NameBindings argument.
166     BoundResult(Rc<Module>, Rc<NameBindings>)
167 }
168
169 impl NamespaceResult {
170     fn is_unknown(&self) -> bool {
171         match *self {
172             UnknownResult => true,
173             _ => false
174         }
175     }
176     fn is_unbound(&self) -> bool {
177         match *self {
178             UnboundResult => true,
179             _ => false
180         }
181     }
182 }
183
184 enum NameDefinition {
185     NoNameDefinition,           //< The name was unbound.
186     ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
187     ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
188 }
189
190 impl<'a, 'v> Visitor<'v> for Resolver<'a> {
191     fn visit_item(&mut self, item: &Item) {
192         self.resolve_item(item);
193     }
194     fn visit_arm(&mut self, arm: &Arm) {
195         self.resolve_arm(arm);
196     }
197     fn visit_block(&mut self, block: &Block) {
198         self.resolve_block(block);
199     }
200     fn visit_expr(&mut self, expr: &Expr) {
201         self.resolve_expr(expr);
202     }
203     fn visit_local(&mut self, local: &Local) {
204         self.resolve_local(local);
205     }
206     fn visit_ty(&mut self, ty: &Ty) {
207         self.resolve_type(ty);
208     }
209 }
210
211 /// Contains data for specific types of import directives.
212 enum ImportDirectiveSubclass {
213     SingleImport(Ident /* target */, Ident /* source */),
214     GlobImport
215 }
216
217 /// The context that we thread through while building the reduced graph.
218 #[deriving(Clone)]
219 enum ReducedGraphParent {
220     ModuleReducedGraphParent(Rc<Module>)
221 }
222
223 impl ReducedGraphParent {
224     fn module(&self) -> Rc<Module> {
225         match *self {
226             ModuleReducedGraphParent(ref m) => {
227                 m.clone()
228             }
229         }
230     }
231 }
232
233 type ErrorMessage = Option<(Span, String)>;
234
235 enum ResolveResult<T> {
236     Failed(ErrorMessage),   // Failed to resolve the name, optional helpful error message.
237     Indeterminate,          // Couldn't determine due to unresolved globs.
238     Success(T)              // Successfully resolved the import.
239 }
240
241 impl<T> ResolveResult<T> {
242     fn indeterminate(&self) -> bool {
243         match *self { Indeterminate => true, _ => false }
244     }
245 }
246
247 enum FallbackSuggestion {
248     NoSuggestion,
249     Field,
250     Method,
251     TraitItem,
252     StaticMethod(String),
253     StaticTraitMethod(String),
254 }
255
256 enum TypeParameters<'a> {
257     NoTypeParameters,
258     HasTypeParameters(
259         // Type parameters.
260         &'a Generics,
261
262         // Identifies the things that these parameters
263         // were declared on (type, fn, etc)
264         ParamSpace,
265
266         // ID of the enclosing item.
267         NodeId,
268
269         // The kind of the rib used for type parameters.
270         RibKind)
271 }
272
273 // The rib kind controls the translation of local
274 // definitions (`DefLocal`) to upvars (`DefUpvar`).
275
276 enum RibKind {
277     // No translation needs to be applied.
278     NormalRibKind,
279
280     // We passed through a closure scope at the given node ID.
281     // Translate upvars as appropriate.
282     ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
283
284     // We passed through an impl or trait and are now in one of its
285     // methods. Allow references to ty params that impl or trait
286     // binds. Disallow any other upvars (including other ty params that are
287     // upvars).
288               // parent;   method itself
289     MethodRibKind(NodeId, MethodSort),
290
291     // We passed through an item scope. Disallow upvars.
292     ItemRibKind,
293
294     // We're in a constant item. Can't refer to dynamic stuff.
295     ConstantItemRibKind
296 }
297
298 // Methods can be required or provided. RequiredMethod methods only occur in traits.
299 enum MethodSort {
300     RequiredMethod,
301     ProvidedMethod(NodeId)
302 }
303
304 enum UseLexicalScopeFlag {
305     DontUseLexicalScope,
306     UseLexicalScope
307 }
308
309 enum ModulePrefixResult {
310     NoPrefixFound,
311     PrefixFound(Rc<Module>, uint)
312 }
313
314 #[deriving(Clone, Eq, PartialEq)]
315 pub enum TraitItemKind {
316     NonstaticMethodTraitItemKind,
317     StaticMethodTraitItemKind,
318     TypeTraitItemKind,
319 }
320
321 impl TraitItemKind {
322     pub fn from_explicit_self_category(explicit_self_category:
323                                        ExplicitSelfCategory)
324                                        -> TraitItemKind {
325         if explicit_self_category == StaticExplicitSelfCategory {
326             StaticMethodTraitItemKind
327         } else {
328             NonstaticMethodTraitItemKind
329         }
330     }
331 }
332
333 #[deriving(PartialEq)]
334 enum NameSearchType {
335     /// We're doing a name search in order to resolve a `use` directive.
336     ImportSearch,
337
338     /// We're doing a name search in order to resolve a path type, a path
339     /// expression, or a path pattern.
340     PathSearch,
341 }
342
343 enum BareIdentifierPatternResolution {
344     FoundStructOrEnumVariant(Def, LastPrivate),
345     FoundConst(Def, LastPrivate),
346     BareIdentifierPatternUnresolved
347 }
348
349 // Specifies how duplicates should be handled when adding a child item if
350 // another item exists with the same name in some namespace.
351 #[deriving(PartialEq)]
352 enum DuplicateCheckingMode {
353     ForbidDuplicateModules,
354     ForbidDuplicateTypesAndModules,
355     ForbidDuplicateValues,
356     ForbidDuplicateTypesAndValues,
357     OverwriteDuplicates
358 }
359
360 /// One local scope.
361 struct Rib {
362     bindings: RefCell<HashMap<Name, DefLike>>,
363     kind: RibKind,
364 }
365
366 impl Rib {
367     fn new(kind: RibKind) -> Rib {
368         Rib {
369             bindings: RefCell::new(HashMap::new()),
370             kind: kind
371         }
372     }
373 }
374
375 /// One import directive.
376 struct ImportDirective {
377     module_path: Vec<Ident>,
378     subclass: ImportDirectiveSubclass,
379     span: Span,
380     id: NodeId,
381     is_public: bool, // see note in ImportResolution about how to use this
382     shadowable: bool,
383 }
384
385 impl ImportDirective {
386     fn new(module_path: Vec<Ident> ,
387            subclass: ImportDirectiveSubclass,
388            span: Span,
389            id: NodeId,
390            is_public: bool,
391            shadowable: bool)
392            -> ImportDirective {
393         ImportDirective {
394             module_path: module_path,
395             subclass: subclass,
396             span: span,
397             id: id,
398             is_public: is_public,
399             shadowable: shadowable,
400         }
401     }
402 }
403
404 /// The item that an import resolves to.
405 #[deriving(Clone)]
406 struct Target {
407     target_module: Rc<Module>,
408     bindings: Rc<NameBindings>,
409     shadowable: bool,
410 }
411
412 impl Target {
413     fn new(target_module: Rc<Module>,
414            bindings: Rc<NameBindings>,
415            shadowable: bool)
416            -> Target {
417         Target {
418             target_module: target_module,
419             bindings: bindings,
420             shadowable: shadowable,
421         }
422     }
423 }
424
425 /// An ImportResolution represents a particular `use` directive.
426 struct ImportResolution {
427     /// Whether this resolution came from a `use` or a `pub use`. Note that this
428     /// should *not* be used whenever resolution is being performed, this is
429     /// only looked at for glob imports statements currently. Privacy testing
430     /// occurs during a later phase of compilation.
431     is_public: bool,
432
433     // The number of outstanding references to this name. When this reaches
434     // zero, outside modules can count on the targets being correct. Before
435     // then, all bets are off; future imports could override this name.
436     outstanding_references: uint,
437
438     /// The value that this `use` directive names, if there is one.
439     value_target: Option<Target>,
440     /// The source node of the `use` directive leading to the value target
441     /// being non-none
442     value_id: NodeId,
443
444     /// The type that this `use` directive names, if there is one.
445     type_target: Option<Target>,
446     /// The source node of the `use` directive leading to the type target
447     /// being non-none
448     type_id: NodeId,
449 }
450
451 impl ImportResolution {
452     fn new(id: NodeId, is_public: bool) -> ImportResolution {
453         ImportResolution {
454             type_id: id,
455             value_id: id,
456             outstanding_references: 0,
457             value_target: None,
458             type_target: None,
459             is_public: is_public,
460         }
461     }
462
463     fn target_for_namespace(&self, namespace: Namespace)
464                                 -> Option<Target> {
465         match namespace {
466             TypeNS  => self.type_target.clone(),
467             ValueNS => self.value_target.clone(),
468         }
469     }
470
471     fn id(&self, namespace: Namespace) -> NodeId {
472         match namespace {
473             TypeNS  => self.type_id,
474             ValueNS => self.value_id,
475         }
476     }
477 }
478
479 /// The link from a module up to its nearest parent node.
480 #[deriving(Clone)]
481 enum ParentLink {
482     NoParentLink,
483     ModuleParentLink(Weak<Module>, Ident),
484     BlockParentLink(Weak<Module>, NodeId)
485 }
486
487 /// The type of module this is.
488 #[deriving(PartialEq)]
489 enum ModuleKind {
490     NormalModuleKind,
491     ExternModuleKind,
492     TraitModuleKind,
493     ImplModuleKind,
494     AnonymousModuleKind,
495 }
496
497 /// One node in the tree of modules.
498 struct Module {
499     parent_link: ParentLink,
500     def_id: Cell<Option<DefId>>,
501     kind: Cell<ModuleKind>,
502     is_public: bool,
503
504     children: RefCell<HashMap<Name, Rc<NameBindings>>>,
505     imports: RefCell<Vec<ImportDirective>>,
506
507     // The external module children of this node that were declared with
508     // `extern crate`.
509     external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
510
511     // The anonymous children of this node. Anonymous children are pseudo-
512     // modules that are implicitly created around items contained within
513     // blocks.
514     //
515     // For example, if we have this:
516     //
517     //  fn f() {
518     //      fn g() {
519     //          ...
520     //      }
521     //  }
522     //
523     // There will be an anonymous module created around `g` with the ID of the
524     // entry block for `f`.
525     anonymous_children: RefCell<NodeMap<Rc<Module>>>,
526
527     // The status of resolving each import in this module.
528     import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
529
530     // The number of unresolved globs that this module exports.
531     glob_count: Cell<uint>,
532
533     // The index of the import we're resolving.
534     resolved_import_count: Cell<uint>,
535
536     // Whether this module is populated. If not populated, any attempt to
537     // access the children must be preceded with a
538     // `populate_module_if_necessary` call.
539     populated: Cell<bool>,
540 }
541
542 impl Module {
543     fn new(parent_link: ParentLink,
544            def_id: Option<DefId>,
545            kind: ModuleKind,
546            external: bool,
547            is_public: bool)
548            -> Module {
549         Module {
550             parent_link: parent_link,
551             def_id: Cell::new(def_id),
552             kind: Cell::new(kind),
553             is_public: is_public,
554             children: RefCell::new(HashMap::new()),
555             imports: RefCell::new(Vec::new()),
556             external_module_children: RefCell::new(HashMap::new()),
557             anonymous_children: RefCell::new(NodeMap::new()),
558             import_resolutions: RefCell::new(HashMap::new()),
559             glob_count: Cell::new(0),
560             resolved_import_count: Cell::new(0),
561             populated: Cell::new(!external),
562         }
563     }
564
565     fn all_imports_resolved(&self) -> bool {
566         self.imports.borrow().len() == self.resolved_import_count.get()
567     }
568 }
569
570 // Records a possibly-private type definition.
571 #[deriving(Clone)]
572 struct TypeNsDef {
573     is_public: bool, // see note in ImportResolution about how to use this
574     module_def: Option<Rc<Module>>,
575     type_def: Option<Def>,
576     type_span: Option<Span>
577 }
578
579 // Records a possibly-private value definition.
580 #[deriving(Clone)]
581 struct ValueNsDef {
582     is_public: bool, // see note in ImportResolution about how to use this
583     def: Def,
584     value_span: Option<Span>,
585 }
586
587 // Records the definitions (at most one for each namespace) that a name is
588 // bound to.
589 struct NameBindings {
590     type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
591     value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
592 }
593
594 /// Ways in which a trait can be referenced
595 enum TraitReferenceType {
596     TraitImplementation,             // impl SomeTrait for T { ... }
597     TraitDerivation,                 // trait T : SomeTrait { ... }
598     TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
599 }
600
601 impl NameBindings {
602     fn new() -> NameBindings {
603         NameBindings {
604             type_def: RefCell::new(None),
605             value_def: RefCell::new(None),
606         }
607     }
608
609     /// Creates a new module in this set of name bindings.
610     fn define_module(&self,
611                      parent_link: ParentLink,
612                      def_id: Option<DefId>,
613                      kind: ModuleKind,
614                      external: bool,
615                      is_public: bool,
616                      sp: Span) {
617         // Merges the module with the existing type def or creates a new one.
618         let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
619                                           is_public));
620         let type_def = self.type_def.borrow().clone();
621         match type_def {
622             None => {
623                 *self.type_def.borrow_mut() = Some(TypeNsDef {
624                     is_public: is_public,
625                     module_def: Some(module_),
626                     type_def: None,
627                     type_span: Some(sp)
628                 });
629             }
630             Some(type_def) => {
631                 *self.type_def.borrow_mut() = Some(TypeNsDef {
632                     is_public: is_public,
633                     module_def: Some(module_),
634                     type_span: Some(sp),
635                     type_def: type_def.type_def
636                 });
637             }
638         }
639     }
640
641     /// Sets the kind of the module, creating a new one if necessary.
642     fn set_module_kind(&self,
643                        parent_link: ParentLink,
644                        def_id: Option<DefId>,
645                        kind: ModuleKind,
646                        external: bool,
647                        is_public: bool,
648                        _sp: Span) {
649         let type_def = self.type_def.borrow().clone();
650         match type_def {
651             None => {
652                 let module = Module::new(parent_link, def_id, kind,
653                                          external, is_public);
654                 *self.type_def.borrow_mut() = Some(TypeNsDef {
655                     is_public: is_public,
656                     module_def: Some(Rc::new(module)),
657                     type_def: None,
658                     type_span: None,
659                 });
660             }
661             Some(type_def) => {
662                 match type_def.module_def {
663                     None => {
664                         let module = Module::new(parent_link,
665                                                  def_id,
666                                                  kind,
667                                                  external,
668                                                  is_public);
669                         *self.type_def.borrow_mut() = Some(TypeNsDef {
670                             is_public: is_public,
671                             module_def: Some(Rc::new(module)),
672                             type_def: type_def.type_def,
673                             type_span: None,
674                         });
675                     }
676                     Some(module_def) => module_def.kind.set(kind),
677                 }
678             }
679         }
680     }
681
682     /// Records a type definition.
683     fn define_type(&self, def: Def, sp: Span, is_public: bool) {
684         // Merges the type with the existing type def or creates a new one.
685         let type_def = self.type_def.borrow().clone();
686         match type_def {
687             None => {
688                 *self.type_def.borrow_mut() = Some(TypeNsDef {
689                     module_def: None,
690                     type_def: Some(def),
691                     type_span: Some(sp),
692                     is_public: is_public,
693                 });
694             }
695             Some(type_def) => {
696                 *self.type_def.borrow_mut() = Some(TypeNsDef {
697                     type_def: Some(def),
698                     type_span: Some(sp),
699                     module_def: type_def.module_def,
700                     is_public: is_public,
701                 });
702             }
703         }
704     }
705
706     /// Records a value definition.
707     fn define_value(&self, def: Def, sp: Span, is_public: bool) {
708         *self.value_def.borrow_mut() = Some(ValueNsDef {
709             def: def,
710             value_span: Some(sp),
711             is_public: is_public,
712         });
713     }
714
715     /// Returns the module node if applicable.
716     fn get_module_if_available(&self) -> Option<Rc<Module>> {
717         match *self.type_def.borrow() {
718             Some(ref type_def) => type_def.module_def.clone(),
719             None => None
720         }
721     }
722
723     /**
724      * Returns the module node. Fails if this node does not have a module
725      * definition.
726      */
727     fn get_module(&self) -> Rc<Module> {
728         match self.get_module_if_available() {
729             None => {
730                 fail!("get_module called on a node with no module \
731                        definition!")
732             }
733             Some(module_def) => module_def
734         }
735     }
736
737     fn defined_in_namespace(&self, namespace: Namespace) -> bool {
738         match namespace {
739             TypeNS   => return self.type_def.borrow().is_some(),
740             ValueNS  => return self.value_def.borrow().is_some()
741         }
742     }
743
744     fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
745         match namespace {
746             TypeNS => match *self.type_def.borrow() {
747                 Some(ref def) => def.is_public, None => false
748             },
749             ValueNS => match *self.value_def.borrow() {
750                 Some(ref def) => def.is_public, None => false
751             }
752         }
753     }
754
755     fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
756         match namespace {
757             TypeNS => {
758                 match *self.type_def.borrow() {
759                     None => None,
760                     Some(ref type_def) => {
761                         match type_def.type_def {
762                             Some(type_def) => Some(type_def),
763                             None => {
764                                 match type_def.module_def {
765                                     Some(ref module) => {
766                                         match module.def_id.get() {
767                                             Some(did) => Some(DefMod(did)),
768                                             None => None,
769                                         }
770                                     }
771                                     None => None,
772                                 }
773                             }
774                         }
775                     }
776                 }
777             }
778             ValueNS => {
779                 match *self.value_def.borrow() {
780                     None => None,
781                     Some(value_def) => Some(value_def.def)
782                 }
783             }
784         }
785     }
786
787     fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
788         if self.defined_in_namespace(namespace) {
789             match namespace {
790                 TypeNS  => {
791                     match *self.type_def.borrow() {
792                         None => None,
793                         Some(ref type_def) => type_def.type_span
794                     }
795                 }
796                 ValueNS => {
797                     match *self.value_def.borrow() {
798                         None => None,
799                         Some(ref value_def) => value_def.value_span
800                     }
801                 }
802             }
803         } else {
804             None
805         }
806     }
807 }
808
809 /// Interns the names of the primitive types.
810 struct PrimitiveTypeTable {
811     primitive_types: HashMap<Name, PrimTy>,
812 }
813
814 impl PrimitiveTypeTable {
815     fn new() -> PrimitiveTypeTable {
816         let mut table = PrimitiveTypeTable {
817             primitive_types: HashMap::new()
818         };
819
820         table.intern("bool",    TyBool);
821         table.intern("char",    TyChar);
822         table.intern("f32",     TyFloat(TyF32));
823         table.intern("f64",     TyFloat(TyF64));
824         table.intern("int",     TyInt(TyI));
825         table.intern("i8",      TyInt(TyI8));
826         table.intern("i16",     TyInt(TyI16));
827         table.intern("i32",     TyInt(TyI32));
828         table.intern("i64",     TyInt(TyI64));
829         table.intern("str",     TyStr);
830         table.intern("uint",    TyUint(TyU));
831         table.intern("u8",      TyUint(TyU8));
832         table.intern("u16",     TyUint(TyU16));
833         table.intern("u32",     TyUint(TyU32));
834         table.intern("u64",     TyUint(TyU64));
835
836         table
837     }
838
839     fn intern(&mut self, string: &str, primitive_type: PrimTy) {
840         self.primitive_types.insert(token::intern(string), primitive_type);
841     }
842 }
843
844
845 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
846     match ns {
847         NoError                 => "",
848         ModuleError | TypeError => "type or module",
849         ValueError              => "value",
850     }
851 }
852
853 /// The main resolver class.
854 struct Resolver<'a> {
855     session: &'a Session,
856
857     graph_root: NameBindings,
858
859     trait_item_map: RefCell<FnvHashMap<(Name, DefId), TraitItemKind>>,
860
861     structs: FnvHashMap<DefId, Vec<Name>>,
862
863     // The number of imports that are currently unresolved.
864     unresolved_imports: uint,
865
866     // The module that represents the current item scope.
867     current_module: Rc<Module>,
868
869     // The current set of local scopes, for values.
870     // FIXME #4948: Reuse ribs to avoid allocation.
871     value_ribs: RefCell<Vec<Rib>>,
872
873     // The current set of local scopes, for types.
874     type_ribs: RefCell<Vec<Rib>>,
875
876     // The current set of local scopes, for labels.
877     label_ribs: RefCell<Vec<Rib>>,
878
879     // The trait that the current context can refer to.
880     current_trait_ref: Option<(DefId, TraitRef)>,
881
882     // The current self type if inside an impl (used for better errors).
883     current_self_type: Option<Ty>,
884
885     // The ident for the keyword "self".
886     self_name: Name,
887     // The ident for the non-keyword "Self".
888     type_self_name: Name,
889
890     // The idents for the primitive types.
891     primitive_type_table: PrimitiveTypeTable,
892
893     def_map: DefMap,
894     freevars: RefCell<FreevarMap>,
895     freevars_seen: RefCell<NodeMap<NodeSet>>,
896     capture_mode_map: RefCell<CaptureModeMap>,
897     export_map2: ExportMap2,
898     trait_map: TraitMap,
899     external_exports: ExternalExports,
900     last_private: LastPrivateMap,
901
902     // Whether or not to print error messages. Can be set to true
903     // when getting additional info for error message suggestions,
904     // so as to avoid printing duplicate errors
905     emit_errors: bool,
906
907     used_imports: HashSet<(NodeId, Namespace)>,
908     used_crates: HashSet<CrateNum>,
909 }
910
911 struct BuildReducedGraphVisitor<'a, 'b:'a> {
912     resolver: &'a mut Resolver<'b>,
913     parent: ReducedGraphParent
914 }
915
916 impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
917
918     fn visit_item(&mut self, item: &Item) {
919         let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
920         let old_parent = replace(&mut self.parent, p);
921         visit::walk_item(self, item);
922         self.parent = old_parent;
923     }
924
925     fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
926         let parent = self.parent.clone();
927         self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
928                                                            parent.clone(),
929                                                            |r| {
930             let mut v = BuildReducedGraphVisitor {
931                 resolver: r,
932                 parent: parent.clone()
933             };
934             visit::walk_foreign_item(&mut v, foreign_item);
935         })
936     }
937
938     fn visit_view_item(&mut self, view_item: &ViewItem) {
939         self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
940     }
941
942     fn visit_block(&mut self, block: &Block) {
943         let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
944         let old_parent = replace(&mut self.parent, np);
945         visit::walk_block(self, block);
946         self.parent = old_parent;
947     }
948
949 }
950
951 struct UnusedImportCheckVisitor<'a, 'b:'a> {
952     resolver: &'a mut Resolver<'b>
953 }
954
955 impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
956     fn visit_view_item(&mut self, vi: &ViewItem) {
957         self.resolver.check_for_item_unused_imports(vi);
958         visit::walk_view_item(self, vi);
959     }
960 }
961
962 impl<'a> Resolver<'a> {
963     fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
964         let graph_root = NameBindings::new();
965
966         graph_root.define_module(NoParentLink,
967                                  Some(DefId { krate: 0, node: 0 }),
968                                  NormalModuleKind,
969                                  false,
970                                  true,
971                                  crate_span);
972
973         let current_module = graph_root.get_module();
974
975         Resolver {
976             session: session,
977
978             // The outermost module has def ID 0; this is not reflected in the
979             // AST.
980
981             graph_root: graph_root,
982
983             trait_item_map: RefCell::new(FnvHashMap::new()),
984             structs: FnvHashMap::new(),
985
986             unresolved_imports: 0,
987
988             current_module: current_module,
989             value_ribs: RefCell::new(Vec::new()),
990             type_ribs: RefCell::new(Vec::new()),
991             label_ribs: RefCell::new(Vec::new()),
992
993             current_trait_ref: None,
994             current_self_type: None,
995
996             self_name: special_names::self_,
997             type_self_name: special_names::type_self,
998
999             primitive_type_table: PrimitiveTypeTable::new(),
1000
1001             def_map: RefCell::new(NodeMap::new()),
1002             freevars: RefCell::new(NodeMap::new()),
1003             freevars_seen: RefCell::new(NodeMap::new()),
1004             capture_mode_map: RefCell::new(NodeMap::new()),
1005             export_map2: RefCell::new(NodeMap::new()),
1006             trait_map: NodeMap::new(),
1007             used_imports: HashSet::new(),
1008             used_crates: HashSet::new(),
1009             external_exports: DefIdSet::new(),
1010             last_private: NodeMap::new(),
1011
1012             emit_errors: true,
1013         }
1014     }
1015     /// The main name resolution procedure.
1016     fn resolve(&mut self, krate: &ast::Crate) {
1017         self.build_reduced_graph(krate);
1018         self.session.abort_if_errors();
1019
1020         self.resolve_imports();
1021         self.session.abort_if_errors();
1022
1023         self.record_exports();
1024         self.session.abort_if_errors();
1025
1026         self.resolve_crate(krate);
1027         self.session.abort_if_errors();
1028
1029         self.check_for_unused_imports(krate);
1030     }
1031
1032     //
1033     // Reduced graph building
1034     //
1035     // Here we build the "reduced graph": the graph of the module tree without
1036     // any imports resolved.
1037     //
1038
1039     /// Constructs the reduced graph for the entire crate.
1040     fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1041         let parent = ModuleReducedGraphParent(self.graph_root.get_module());
1042         let mut visitor = BuildReducedGraphVisitor {
1043             resolver: self,
1044             parent: parent
1045         };
1046         visit::walk_crate(&mut visitor, krate);
1047     }
1048
1049     /**
1050      * Adds a new child item to the module definition of the parent node and
1051      * returns its corresponding name bindings as well as the current parent.
1052      * Or, if we're inside a block, creates (or reuses) an anonymous module
1053      * corresponding to the innermost block ID and returns the name bindings
1054      * as well as the newly-created parent.
1055      *
1056      * If this node does not have a module definition and we are not inside
1057      * a block, fails.
1058      */
1059     fn add_child(&self,
1060                  name: Ident,
1061                  reduced_graph_parent: ReducedGraphParent,
1062                  duplicate_checking_mode: DuplicateCheckingMode,
1063                  // For printing errors
1064                  sp: Span)
1065                  -> Rc<NameBindings> {
1066         // If this is the immediate descendant of a module, then we add the
1067         // child name directly. Otherwise, we create or reuse an anonymous
1068         // module and add the child to that.
1069
1070         let module_ = reduced_graph_parent.module();
1071
1072         self.check_for_conflicts_between_external_crates_and_items(&*module_,
1073                                                                    name.name,
1074                                                                    sp);
1075
1076         // Add or reuse the child.
1077         let child = module_.children.borrow().find_copy(&name.name);
1078         match child {
1079             None => {
1080                 let child = Rc::new(NameBindings::new());
1081                 module_.children.borrow_mut().insert(name.name, child.clone());
1082                 child
1083             }
1084             Some(child) => {
1085                 // Enforce the duplicate checking mode:
1086                 //
1087                 // * If we're requesting duplicate module checking, check that
1088                 //   there isn't a module in the module with the same name.
1089                 //
1090                 // * If we're requesting duplicate type checking, check that
1091                 //   there isn't a type in the module with the same name.
1092                 //
1093                 // * If we're requesting duplicate value checking, check that
1094                 //   there isn't a value in the module with the same name.
1095                 //
1096                 // * If we're requesting duplicate type checking and duplicate
1097                 //   value checking, check that there isn't a duplicate type
1098                 //   and a duplicate value with the same name.
1099                 //
1100                 // * If no duplicate checking was requested at all, do
1101                 //   nothing.
1102
1103                 let mut duplicate_type = NoError;
1104                 let ns = match duplicate_checking_mode {
1105                     ForbidDuplicateModules => {
1106                         if child.get_module_if_available().is_some() {
1107                             duplicate_type = ModuleError;
1108                         }
1109                         Some(TypeNS)
1110                     }
1111                     ForbidDuplicateTypesAndModules => {
1112                         match child.def_for_namespace(TypeNS) {
1113                             None => {}
1114                             Some(_) if child.get_module_if_available()
1115                                             .map(|m| m.kind.get()) ==
1116                                        Some(ImplModuleKind) => {}
1117                             Some(_) => duplicate_type = TypeError
1118                         }
1119                         Some(TypeNS)
1120                     }
1121                     ForbidDuplicateValues => {
1122                         if child.defined_in_namespace(ValueNS) {
1123                             duplicate_type = ValueError;
1124                         }
1125                         Some(ValueNS)
1126                     }
1127                     ForbidDuplicateTypesAndValues => {
1128                         let mut n = None;
1129                         match child.def_for_namespace(TypeNS) {
1130                             Some(DefMod(_)) | None => {}
1131                             Some(_) => {
1132                                 n = Some(TypeNS);
1133                                 duplicate_type = TypeError;
1134                             }
1135                         };
1136                         if child.defined_in_namespace(ValueNS) {
1137                             duplicate_type = ValueError;
1138                             n = Some(ValueNS);
1139                         }
1140                         n
1141                     }
1142                     OverwriteDuplicates => None
1143                 };
1144                 if duplicate_type != NoError {
1145                     // Return an error here by looking up the namespace that
1146                     // had the duplicate.
1147                     let ns = ns.unwrap();
1148                     self.resolve_error(sp,
1149                         format!("duplicate definition of {} `{}`",
1150                              namespace_error_to_string(duplicate_type),
1151                              token::get_ident(name)).as_slice());
1152                     {
1153                         let r = child.span_for_namespace(ns);
1154                         for sp in r.iter() {
1155                             self.session.span_note(*sp,
1156                                  format!("first definition of {} `{}` here",
1157                                       namespace_error_to_string(duplicate_type),
1158                                       token::get_ident(name)).as_slice());
1159                         }
1160                     }
1161                 }
1162                 child
1163             }
1164         }
1165     }
1166
1167     fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1168         // If the block has view items, we need an anonymous module.
1169         if block.view_items.len() > 0 {
1170             return true;
1171         }
1172
1173         // Check each statement.
1174         for statement in block.stmts.iter() {
1175             match statement.node {
1176                 StmtDecl(ref declaration, _) => {
1177                     match declaration.node {
1178                         DeclItem(_) => {
1179                             return true;
1180                         }
1181                         _ => {
1182                             // Keep searching.
1183                         }
1184                     }
1185                 }
1186                 _ => {
1187                     // Keep searching.
1188                 }
1189             }
1190         }
1191
1192         // If we found neither view items nor items, we don't need to create
1193         // an anonymous module.
1194
1195         return false;
1196     }
1197
1198     fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1199                            -> ParentLink {
1200         match parent {
1201             ModuleReducedGraphParent(module_) => {
1202                 return ModuleParentLink(module_.downgrade(), name);
1203             }
1204         }
1205     }
1206
1207     /// Constructs the reduced graph for one item.
1208     fn build_reduced_graph_for_item(&mut self,
1209                                     item: &Item,
1210                                     parent: ReducedGraphParent)
1211                                     -> ReducedGraphParent
1212     {
1213         let ident = item.ident;
1214         let sp = item.span;
1215         let is_public = item.vis == ast::Public;
1216
1217         match item.node {
1218             ItemMod(..) => {
1219                 let name_bindings =
1220                     self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp);
1221
1222                 let parent_link = self.get_parent_link(parent, ident);
1223                 let def_id = DefId { krate: 0, node: item.id };
1224                 name_bindings.define_module(parent_link,
1225                                             Some(def_id),
1226                                             NormalModuleKind,
1227                                             false,
1228                                             item.vis == ast::Public,
1229                                             sp);
1230
1231                 ModuleReducedGraphParent(name_bindings.get_module())
1232             }
1233
1234             ItemForeignMod(..) => parent,
1235
1236             // These items live in the value namespace.
1237             ItemStatic(_, m, _) => {
1238                 let name_bindings =
1239                     self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1240                 let mutbl = m == ast::MutMutable;
1241
1242                 name_bindings.define_value
1243                     (DefStatic(local_def(item.id), mutbl), sp, is_public);
1244                 parent
1245             }
1246             ItemFn(_, fn_style, _, _, _) => {
1247                 let name_bindings =
1248                     self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1249
1250                 let def = DefFn(local_def(item.id), fn_style);
1251                 name_bindings.define_value(def, sp, is_public);
1252                 parent
1253             }
1254
1255             // These items live in the type namespace.
1256             ItemTy(..) => {
1257                 let name_bindings =
1258                     self.add_child(ident,
1259                                    parent.clone(),
1260                                    ForbidDuplicateTypesAndModules,
1261                                    sp);
1262
1263                 name_bindings.define_type
1264                     (DefTy(local_def(item.id), false), sp, is_public);
1265                 parent
1266             }
1267
1268             ItemEnum(ref enum_definition, _) => {
1269                 let name_bindings =
1270                     self.add_child(ident,
1271                                    parent.clone(),
1272                                    ForbidDuplicateTypesAndModules,
1273                                    sp);
1274
1275                 name_bindings.define_type
1276                     (DefTy(local_def(item.id), true), sp, is_public);
1277
1278                 for variant in (*enum_definition).variants.iter() {
1279                     self.build_reduced_graph_for_variant(
1280                         &**variant,
1281                         local_def(item.id),
1282                         parent.clone(),
1283                         is_public);
1284                 }
1285                 parent
1286             }
1287
1288             // These items live in both the type and value namespaces.
1289             ItemStruct(ref struct_def, _) => {
1290                 // Adding to both Type and Value namespaces or just Type?
1291                 let (forbid, ctor_id) = match struct_def.ctor_id {
1292                     Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1293                     None            => (ForbidDuplicateTypesAndModules, None)
1294                 };
1295
1296                 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
1297
1298                 // Define a name in the type namespace.
1299                 name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public);
1300
1301                 // If this is a newtype or unit-like struct, define a name
1302                 // in the value namespace as well
1303                 ctor_id.while_some(|cid| {
1304                     name_bindings.define_value(DefStruct(local_def(cid)), sp,
1305                                                is_public);
1306                     None
1307                 });
1308
1309                 // Record the def ID and fields of this struct.
1310                 let named_fields = struct_def.fields.iter().filter_map(|f| {
1311                     match f.node.kind {
1312                         NamedField(ident, _) => Some(ident.name),
1313                         UnnamedField(_) => None
1314                     }
1315                 }).collect();
1316                 self.structs.insert(local_def(item.id), named_fields);
1317
1318                 parent
1319             }
1320
1321             ItemImpl(_, None, ref ty, ref impl_items) => {
1322                 // If this implements an anonymous trait, then add all the
1323                 // methods within to a new module, if the type was defined
1324                 // within this module.
1325
1326                 // Create the module and add all methods.
1327                 match ty.node {
1328                     TyPath(ref path, _, _) if path.segments.len() == 1 => {
1329                         let name = path.segments.last().unwrap().identifier;
1330
1331                         let parent_opt = parent.module().children.borrow()
1332                                                .find_copy(&name.name);
1333                         let new_parent = match parent_opt {
1334                             // It already exists
1335                             Some(ref child) if child.get_module_if_available()
1336                                                 .is_some() &&
1337                                            child.get_module().kind.get() ==
1338                                                 ImplModuleKind => {
1339                                 ModuleReducedGraphParent(child.get_module())
1340                             }
1341                             // Create the module
1342                             _ => {
1343                                 let name_bindings =
1344                                     self.add_child(name,
1345                                                    parent.clone(),
1346                                                    ForbidDuplicateModules,
1347                                                    sp);
1348
1349                                 let parent_link =
1350                                     self.get_parent_link(parent.clone(), ident);
1351                                 let def_id = local_def(item.id);
1352                                 let ns = TypeNS;
1353                                 let is_public =
1354                                     !name_bindings.defined_in_namespace(ns) ||
1355                                      name_bindings.defined_in_public_namespace(ns);
1356
1357                                 name_bindings.define_module(parent_link,
1358                                                             Some(def_id),
1359                                                             ImplModuleKind,
1360                                                             false,
1361                                                             is_public,
1362                                                             sp);
1363
1364                                 ModuleReducedGraphParent(
1365                                     name_bindings.get_module())
1366                             }
1367                         };
1368
1369                         // For each implementation item...
1370                         for impl_item in impl_items.iter() {
1371                             match *impl_item {
1372                                 MethodImplItem(ref method) => {
1373                                     // Add the method to the module.
1374                                     let ident = method.pe_ident();
1375                                     let method_name_bindings =
1376                                         self.add_child(ident,
1377                                                        new_parent.clone(),
1378                                                        ForbidDuplicateValues,
1379                                                        method.span);
1380                                     let def = match method.pe_explicit_self()
1381                                                           .node {
1382                                         SelfStatic => {
1383                                             // Static methods become
1384                                             // `def_static_method`s.
1385                                             DefStaticMethod(
1386                                                 local_def(method.id),
1387                                                 FromImpl(local_def(item.id)),
1388                                                          method.pe_fn_style())
1389                                         }
1390                                         _ => {
1391                                             // Non-static methods become
1392                                             // `def_method`s.
1393                                             DefMethod(local_def(method.id),
1394                                                       None)
1395                                         }
1396                                     };
1397
1398                                     let is_public =
1399                                         method.pe_vis() == ast::Public;
1400                                     method_name_bindings.define_value(
1401                                         def,
1402                                         method.span,
1403                                         is_public);
1404                                 }
1405                                 TypeImplItem(ref typedef) => {
1406                                     // Add the typedef to the module.
1407                                     let ident = typedef.ident;
1408                                     let typedef_name_bindings =
1409                                         self.add_child(
1410                                             ident,
1411                                             new_parent.clone(),
1412                                             ForbidDuplicateTypesAndModules,
1413                                             typedef.span);
1414                                     let def = DefAssociatedTy(local_def(
1415                                             typedef.id));
1416                                     let is_public = typedef.vis ==
1417                                         ast::Public;
1418                                     typedef_name_bindings.define_type(
1419                                         def,
1420                                         typedef.span,
1421                                         is_public);
1422                                 }
1423                             }
1424                         }
1425                     }
1426                     _ => {
1427                         self.resolve_error(ty.span,
1428                                            "inherent implementations may \
1429                                             only be implemented in the same \
1430                                             module as the type they are \
1431                                             implemented for")
1432                     }
1433                 }
1434
1435                 parent
1436             }
1437
1438             ItemImpl(_, Some(_), _, _) => parent,
1439
1440             ItemTrait(_, _, _, ref methods) => {
1441                 let name_bindings =
1442                     self.add_child(ident,
1443                                    parent.clone(),
1444                                    ForbidDuplicateTypesAndModules,
1445                                    sp);
1446
1447                 // Add all the methods within to a new module.
1448                 let parent_link = self.get_parent_link(parent.clone(), ident);
1449                 name_bindings.define_module(parent_link,
1450                                             Some(local_def(item.id)),
1451                                             TraitModuleKind,
1452                                             false,
1453                                             item.vis == ast::Public,
1454                                             sp);
1455                 let module_parent = ModuleReducedGraphParent(name_bindings.
1456                                                              get_module());
1457
1458                 let def_id = local_def(item.id);
1459
1460                 // Add the names of all the methods to the trait info.
1461                 for method in methods.iter() {
1462                     let (ident, kind) = match *method {
1463                         ast::RequiredMethod(_) |
1464                         ast::ProvidedMethod(_) => {
1465                             let ty_m =
1466                                 ast_util::trait_item_to_ty_method(method);
1467
1468                             let ident = ty_m.ident;
1469
1470                             // Add it as a name in the trait module.
1471                             let (def, static_flag) = match ty_m.explicit_self
1472                                                                .node {
1473                                 SelfStatic => {
1474                                     // Static methods become
1475                                     // `def_static_method`s.
1476                                     (DefStaticMethod(
1477                                             local_def(ty_m.id),
1478                                             FromTrait(local_def(item.id)),
1479                                             ty_m.fn_style),
1480                                      StaticMethodTraitItemKind)
1481                                 }
1482                                 _ => {
1483                                     // Non-static methods become
1484                                     // `def_method`s.
1485                                     (DefMethod(local_def(ty_m.id),
1486                                                Some(local_def(item.id))),
1487                                      NonstaticMethodTraitItemKind)
1488                                 }
1489                             };
1490
1491                             let method_name_bindings =
1492                                 self.add_child(ident,
1493                                                module_parent.clone(),
1494                                                ForbidDuplicateTypesAndValues,
1495                                                ty_m.span);
1496                             method_name_bindings.define_value(def,
1497                                                               ty_m.span,
1498                                                               true);
1499
1500                             (ident, static_flag)
1501                         }
1502                         ast::TypeTraitItem(ref associated_type) => {
1503                             let def = DefAssociatedTy(local_def(
1504                                     associated_type.id));
1505
1506                             let name_bindings =
1507                                 self.add_child(associated_type.ident,
1508                                                module_parent.clone(),
1509                                                ForbidDuplicateTypesAndValues,
1510                                                associated_type.span);
1511                             name_bindings.define_type(def,
1512                                                       associated_type.span,
1513                                                       true);
1514
1515                             (associated_type.ident, TypeTraitItemKind)
1516                         }
1517                     };
1518
1519                     self.trait_item_map
1520                         .borrow_mut()
1521                         .insert((ident.name, def_id), kind);
1522                 }
1523
1524                 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1525                 parent
1526             }
1527             ItemMac(..) => parent
1528         }
1529     }
1530
1531     // Constructs the reduced graph for one variant. Variants exist in the
1532     // type and value namespaces.
1533     fn build_reduced_graph_for_variant(&mut self,
1534                                        variant: &Variant,
1535                                        item_id: DefId,
1536                                        parent: ReducedGraphParent,
1537                                        is_public: bool) {
1538         let ident = variant.node.name;
1539         let is_exported = match variant.node.kind {
1540             TupleVariantKind(_) => false,
1541             StructVariantKind(_) => {
1542                 // Not adding fields for variants as they are not accessed with a self receiver
1543                 self.structs.insert(local_def(variant.node.id), Vec::new());
1544                 true
1545             }
1546         };
1547
1548         let child = self.add_child(ident, parent,
1549                                    ForbidDuplicateTypesAndValues,
1550                                    variant.span);
1551         child.define_value(DefVariant(item_id,
1552                                       local_def(variant.node.id), is_exported),
1553                            variant.span, is_public);
1554         child.define_type(DefVariant(item_id,
1555                                      local_def(variant.node.id), is_exported),
1556                           variant.span, is_public);
1557     }
1558
1559     /// Constructs the reduced graph for one 'view item'. View items consist
1560     /// of imports and use directives.
1561     fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1562                                          parent: ReducedGraphParent) {
1563         match view_item.node {
1564             ViewItemUse(ref view_path) => {
1565                 // Extract and intern the module part of the path. For
1566                 // globs and lists, the path is found directly in the AST;
1567                 // for simple paths we have to munge the path a little.
1568                 let module_path = match view_path.node {
1569                     ViewPathSimple(_, ref full_path, _) => {
1570                         full_path.segments
1571                             .as_slice().init()
1572                             .iter().map(|ident| ident.identifier)
1573                             .collect()
1574                     }
1575
1576                     ViewPathGlob(ref module_ident_path, _) |
1577                     ViewPathList(ref module_ident_path, _, _) => {
1578                         module_ident_path.segments
1579                             .iter().map(|ident| ident.identifier).collect()
1580                     }
1581                 };
1582
1583                 // Build up the import directives.
1584                 let module_ = parent.module();
1585                 let is_public = view_item.vis == ast::Public;
1586                 let shadowable =
1587                     view_item.attrs
1588                              .iter()
1589                              .any(|attr| {
1590                                  attr.name() == token::get_ident(
1591                                     special_idents::prelude_import)
1592                              });
1593
1594                 match view_path.node {
1595                     ViewPathSimple(binding, ref full_path, id) => {
1596                         let source_ident =
1597                             full_path.segments.last().unwrap().identifier;
1598                         if token::get_ident(source_ident).get() == "mod" {
1599                             self.resolve_error(view_path.span,
1600                                 "`mod` imports are only allowed within a { } list");
1601                         }
1602
1603                         let subclass = SingleImport(binding,
1604                                                     source_ident);
1605                         self.build_import_directive(&*module_,
1606                                                     module_path,
1607                                                     subclass,
1608                                                     view_path.span,
1609                                                     id,
1610                                                     is_public,
1611                                                     shadowable);
1612                     }
1613                     ViewPathList(_, ref source_items, _) => {
1614                         // Make sure there's at most one `mod` import in the list.
1615                         let mod_spans = source_items.iter().filter_map(|item| match item.node {
1616                             PathListMod { .. } => Some(item.span),
1617                             _ => None
1618                         }).collect::<Vec<Span>>();
1619                         if mod_spans.len() > 1 {
1620                             self.resolve_error(mod_spans[0],
1621                                 "`mod` import can only appear once in the list");
1622                             for other_span in mod_spans.iter().skip(1) {
1623                                 self.session.span_note(*other_span,
1624                                     "another `mod` import appears here");
1625                             }
1626                         }
1627
1628                         for source_item in source_items.iter() {
1629                             let (module_path, name) = match source_item.node {
1630                                 PathListIdent { name, .. } =>
1631                                     (module_path.clone(), name),
1632                                 PathListMod { .. } => {
1633                                     let name = match module_path.last() {
1634                                         Some(ident) => ident.clone(),
1635                                         None => {
1636                                             self.resolve_error(source_item.span,
1637                                                 "`mod` import can only appear in an import list \
1638                                                  with a non-empty prefix");
1639                                             continue;
1640                                         }
1641                                     };
1642                                     let module_path = module_path.as_slice().init();
1643                                     (Vec::from_slice(module_path), name)
1644                                 }
1645                             };
1646                             self.build_import_directive(
1647                                 &*module_,
1648                                 module_path,
1649                                 SingleImport(name, name),
1650                                 source_item.span,
1651                                 source_item.node.id(),
1652                                 is_public,
1653                                 shadowable);
1654                         }
1655                     }
1656                     ViewPathGlob(_, id) => {
1657                         self.build_import_directive(&*module_,
1658                                                     module_path,
1659                                                     GlobImport,
1660                                                     view_path.span,
1661                                                     id,
1662                                                     is_public,
1663                                                     shadowable);
1664                     }
1665                 }
1666             }
1667
1668             ViewItemExternCrate(name, _, node_id) => {
1669                 // n.b. we don't need to look at the path option here, because cstore already did
1670                 for &crate_id in self.session.cstore
1671                                      .find_extern_mod_stmt_cnum(node_id).iter() {
1672                     let def_id = DefId { krate: crate_id, node: 0 };
1673                     self.external_exports.insert(def_id);
1674                     let parent_link =
1675                         ModuleParentLink(parent.module().downgrade(), name);
1676                     let external_module = Rc::new(Module::new(parent_link,
1677                                                               Some(def_id),
1678                                                               NormalModuleKind,
1679                                                               false,
1680                                                               true));
1681                     debug!("(build reduced graph for item) found extern `{}`",
1682                             self.module_to_string(&*external_module));
1683                     self.check_for_conflicts_between_external_crates(
1684                         &*parent.module(),
1685                         name.name,
1686                         view_item.span);
1687                     parent.module().external_module_children.borrow_mut()
1688                                    .insert(name.name, external_module.clone());
1689                     self.build_reduced_graph_for_external_crate(external_module);
1690                 }
1691             }
1692         }
1693     }
1694
1695     /// Constructs the reduced graph for one foreign item.
1696     fn build_reduced_graph_for_foreign_item(&mut self,
1697                                             foreign_item: &ForeignItem,
1698                                             parent: ReducedGraphParent,
1699                                             f: |&mut Resolver|) {
1700         let name = foreign_item.ident;
1701         let is_public = foreign_item.vis == ast::Public;
1702         let name_bindings =
1703             self.add_child(name, parent, ForbidDuplicateValues,
1704                            foreign_item.span);
1705
1706         match foreign_item.node {
1707             ForeignItemFn(_, ref generics) => {
1708                 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1709                 name_bindings.define_value(def, foreign_item.span, is_public);
1710
1711                 self.with_type_parameter_rib(
1712                     HasTypeParameters(generics,
1713                                       FnSpace,
1714                                       foreign_item.id,
1715                                       NormalRibKind),
1716                     f);
1717             }
1718             ForeignItemStatic(_, m) => {
1719                 let def = DefStatic(local_def(foreign_item.id), m);
1720                 name_bindings.define_value(def, foreign_item.span, is_public);
1721
1722                 f(self)
1723             }
1724         }
1725     }
1726
1727     fn build_reduced_graph_for_block(&mut self,
1728                                          block: &Block,
1729                                          parent: ReducedGraphParent)
1730                                             -> ReducedGraphParent
1731     {
1732         if self.block_needs_anonymous_module(block) {
1733             let block_id = block.id;
1734
1735             debug!("(building reduced graph for block) creating a new \
1736                     anonymous module for block {}",
1737                    block_id);
1738
1739             let parent_module = parent.module();
1740             let new_module = Rc::new(Module::new(
1741                 BlockParentLink(parent_module.downgrade(), block_id),
1742                 None,
1743                 AnonymousModuleKind,
1744                 false,
1745                 false));
1746             parent_module.anonymous_children.borrow_mut()
1747                          .insert(block_id, new_module.clone());
1748             ModuleReducedGraphParent(new_module)
1749         } else {
1750             parent
1751         }
1752     }
1753
1754     fn handle_external_def(&mut self,
1755                            def: Def,
1756                            vis: Visibility,
1757                            child_name_bindings: &NameBindings,
1758                            final_ident: &str,
1759                            ident: Ident,
1760                            new_parent: ReducedGraphParent) {
1761         debug!("(building reduced graph for \
1762                 external crate) building external def, priv {:?}",
1763                vis);
1764         let is_public = vis == ast::Public;
1765         let is_exported = is_public && match new_parent {
1766             ModuleReducedGraphParent(ref module) => {
1767                 match module.def_id.get() {
1768                     None => true,
1769                     Some(did) => self.external_exports.contains(&did)
1770                 }
1771             }
1772         };
1773         if is_exported {
1774             self.external_exports.insert(def.def_id());
1775         }
1776
1777         let kind = match def {
1778             DefStruct(..) | DefTy(..) => ImplModuleKind,
1779             _ => NormalModuleKind
1780         };
1781
1782         match def {
1783           DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1784           DefTy(def_id, _) => {
1785             let type_def = child_name_bindings.type_def.borrow().clone();
1786             match type_def {
1787               Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1788                 debug!("(building reduced graph for external crate) \
1789                         already created module");
1790                 module_def.def_id.set(Some(def_id));
1791               }
1792               Some(_) | None => {
1793                 debug!("(building reduced graph for \
1794                         external crate) building module \
1795                         {}", final_ident);
1796                 let parent_link = self.get_parent_link(new_parent.clone(), ident);
1797
1798                 child_name_bindings.define_module(parent_link,
1799                                                   Some(def_id),
1800                                                   kind,
1801                                                   true,
1802                                                   is_public,
1803                                                   DUMMY_SP);
1804               }
1805             }
1806           }
1807           _ => {}
1808         }
1809
1810         match def {
1811           DefMod(_) | DefForeignMod(_) => {}
1812           DefVariant(enum_did, variant_id, is_struct) => {
1813             debug!("(building reduced graph for external crate) building \
1814                     variant {}",
1815                    final_ident);
1816             // If this variant is public, then it was publicly reexported,
1817             // otherwise we need to inherit the visibility of the enum
1818             // definition.
1819             let is_exported = is_public ||
1820                               self.external_exports.contains(&enum_did);
1821             if is_struct {
1822                 child_name_bindings.define_type(def, DUMMY_SP, is_exported);
1823                 // Not adding fields for variants as they are not accessed with a self receiver
1824                 self.structs.insert(variant_id, Vec::new());
1825             } else {
1826                 child_name_bindings.define_value(def, DUMMY_SP, is_exported);
1827             }
1828           }
1829           DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1830             debug!("(building reduced graph for external \
1831                     crate) building value (fn/static) {}", final_ident);
1832             child_name_bindings.define_value(def, DUMMY_SP, is_public);
1833           }
1834           DefTrait(def_id) => {
1835               debug!("(building reduced graph for external \
1836                       crate) building type {}", final_ident);
1837
1838               // If this is a trait, add all the trait item names to the trait
1839               // info.
1840
1841               let trait_item_def_ids =
1842                 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1843               for trait_item_def_id in trait_item_def_ids.iter() {
1844                   let (trait_item_name, trait_item_kind) =
1845                       csearch::get_trait_item_name_and_kind(
1846                           &self.session.cstore,
1847                           trait_item_def_id.def_id());
1848
1849                   debug!("(building reduced graph for external crate) ... \
1850                           adding trait item '{}'",
1851                          token::get_ident(trait_item_name));
1852
1853                   self.trait_item_map
1854                       .borrow_mut()
1855                       .insert((trait_item_name.name, def_id),
1856                               trait_item_kind);
1857
1858                   if is_exported {
1859                       self.external_exports
1860                           .insert(trait_item_def_id.def_id());
1861                   }
1862               }
1863
1864               child_name_bindings.define_type(def, DUMMY_SP, is_public);
1865
1866               // Define a module if necessary.
1867               let parent_link = self.get_parent_link(new_parent, ident);
1868               child_name_bindings.set_module_kind(parent_link,
1869                                                   Some(def_id),
1870                                                   TraitModuleKind,
1871                                                   true,
1872                                                   is_public,
1873                                                   DUMMY_SP)
1874           }
1875           DefTy(..) | DefAssociatedTy(..) => {
1876               debug!("(building reduced graph for external \
1877                       crate) building type {}", final_ident);
1878
1879               child_name_bindings.define_type(def, DUMMY_SP, is_public);
1880           }
1881           DefStruct(def_id) => {
1882             debug!("(building reduced graph for external \
1883                     crate) building type and value for {}",
1884                    final_ident);
1885             child_name_bindings.define_type(def, DUMMY_SP, is_public);
1886             let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
1887                 f.name
1888             }).collect::<Vec<_>>();
1889
1890             if fields.len() == 0 {
1891                 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1892             }
1893
1894             // Record the def ID and fields of this struct.
1895             self.structs.insert(def_id, fields);
1896           }
1897           DefMethod(..) => {
1898               debug!("(building reduced graph for external crate) \
1899                       ignoring {:?}", def);
1900               // Ignored; handled elsewhere.
1901           }
1902           DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
1903           DefUse(..) | DefUpvar(..) | DefRegion(..) |
1904           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1905             fail!("didn't expect `{:?}`", def);
1906           }
1907         }
1908     }
1909
1910     /// Builds the reduced graph for a single item in an external crate.
1911     fn build_reduced_graph_for_external_crate_def(&mut self,
1912                                                   root: Rc<Module>,
1913                                                   def_like: DefLike,
1914                                                   ident: Ident,
1915                                                   visibility: Visibility) {
1916         match def_like {
1917             DlDef(def) => {
1918                 // Add the new child item, if necessary.
1919                 match def {
1920                     DefForeignMod(def_id) => {
1921                         // Foreign modules have no names. Recur and populate
1922                         // eagerly.
1923                         csearch::each_child_of_item(&self.session.cstore,
1924                                                     def_id,
1925                                                     |def_like,
1926                                                      child_ident,
1927                                                      vis| {
1928                             self.build_reduced_graph_for_external_crate_def(
1929                                 root.clone(),
1930                                 def_like,
1931                                 child_ident,
1932                                 vis)
1933                         });
1934                     }
1935                     _ => {
1936                         let child_name_bindings =
1937                             self.add_child(ident,
1938                                            ModuleReducedGraphParent(root.clone()),
1939                                            OverwriteDuplicates,
1940                                            DUMMY_SP);
1941
1942                         self.handle_external_def(def,
1943                                                  visibility,
1944                                                  &*child_name_bindings,
1945                                                  token::get_ident(ident).get(),
1946                                                  ident,
1947                                                  ModuleReducedGraphParent(root));
1948                     }
1949                 }
1950             }
1951             DlImpl(def) => {
1952                 // We only process static methods of impls here.
1953                 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1954                     None => {}
1955                     Some(final_ident) => {
1956                         let static_methods_opt =
1957                             csearch::get_static_methods_if_impl(&self.session.cstore, def);
1958                         match static_methods_opt {
1959                             Some(ref static_methods) if
1960                                 static_methods.len() >= 1 => {
1961                                 debug!("(building reduced graph for \
1962                                         external crate) processing \
1963                                         static methods for type name {}",
1964                                         token::get_ident(final_ident));
1965
1966                                 let child_name_bindings =
1967                                     self.add_child(
1968                                         final_ident,
1969                                         ModuleReducedGraphParent(root.clone()),
1970                                         OverwriteDuplicates,
1971                                         DUMMY_SP);
1972
1973                                 // Process the static methods. First,
1974                                 // create the module.
1975                                 let type_module;
1976                                 let type_def = child_name_bindings.type_def.borrow().clone();
1977                                 match type_def {
1978                                     Some(TypeNsDef {
1979                                         module_def: Some(module_def),
1980                                         ..
1981                                     }) => {
1982                                         // We already have a module. This
1983                                         // is OK.
1984                                         type_module = module_def;
1985
1986                                         // Mark it as an impl module if
1987                                         // necessary.
1988                                         type_module.kind.set(ImplModuleKind);
1989                                     }
1990                                     Some(_) | None => {
1991                                         let parent_link =
1992                                             self.get_parent_link(ModuleReducedGraphParent(root),
1993                                                                  final_ident);
1994                                         child_name_bindings.define_module(
1995                                             parent_link,
1996                                             Some(def),
1997                                             ImplModuleKind,
1998                                             true,
1999                                             true,
2000                                             DUMMY_SP);
2001                                         type_module =
2002                                             child_name_bindings.
2003                                                 get_module();
2004                                     }
2005                                 }
2006
2007                                 // Add each static method to the module.
2008                                 let new_parent =
2009                                     ModuleReducedGraphParent(type_module);
2010                                 for static_method_info in
2011                                         static_methods.iter() {
2012                                     let ident = static_method_info.ident;
2013                                     debug!("(building reduced graph for \
2014                                              external crate) creating \
2015                                              static method '{}'",
2016                                            token::get_ident(ident));
2017
2018                                     let method_name_bindings =
2019                                         self.add_child(ident,
2020                                                        new_parent.clone(),
2021                                                        OverwriteDuplicates,
2022                                                        DUMMY_SP);
2023                                     let def = DefFn(
2024                                         static_method_info.def_id,
2025                                         static_method_info.fn_style);
2026
2027                                     method_name_bindings.define_value(
2028                                         def, DUMMY_SP,
2029                                         visibility == ast::Public);
2030                                 }
2031                             }
2032
2033                             // Otherwise, do nothing.
2034                             Some(_) | None => {}
2035                         }
2036                     }
2037                 }
2038             }
2039             DlField => {
2040                 debug!("(building reduced graph for external crate) \
2041                         ignoring field");
2042             }
2043         }
2044     }
2045
2046     /// Builds the reduced graph rooted at the given external module.
2047     fn populate_external_module(&mut self, module: Rc<Module>) {
2048         debug!("(populating external module) attempting to populate {}",
2049                self.module_to_string(&*module));
2050
2051         let def_id = match module.def_id.get() {
2052             None => {
2053                 debug!("(populating external module) ... no def ID!");
2054                 return
2055             }
2056             Some(def_id) => def_id,
2057         };
2058
2059         csearch::each_child_of_item(&self.session.cstore,
2060                                     def_id,
2061                                     |def_like, child_ident, visibility| {
2062             debug!("(populating external module) ... found ident: {}",
2063                    token::get_ident(child_ident));
2064             self.build_reduced_graph_for_external_crate_def(module.clone(),
2065                                                             def_like,
2066                                                             child_ident,
2067                                                             visibility)
2068         });
2069         module.populated.set(true)
2070     }
2071
2072     /// Ensures that the reduced graph rooted at the given external module
2073     /// is built, building it if it is not.
2074     fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2075         if !module.populated.get() {
2076             self.populate_external_module(module.clone())
2077         }
2078         assert!(module.populated.get())
2079     }
2080
2081     /// Builds the reduced graph rooted at the 'use' directive for an external
2082     /// crate.
2083     fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2084         csearch::each_top_level_item_of_crate(&self.session.cstore,
2085                                               root.def_id
2086                                                   .get()
2087                                                   .unwrap()
2088                                                   .krate,
2089                                               |def_like, ident, visibility| {
2090             self.build_reduced_graph_for_external_crate_def(root.clone(),
2091                                                             def_like,
2092                                                             ident,
2093                                                             visibility)
2094         });
2095     }
2096
2097     /// Creates and adds an import directive to the given module.
2098     fn build_import_directive(&mut self,
2099                               module_: &Module,
2100                               module_path: Vec<Ident> ,
2101                               subclass: ImportDirectiveSubclass,
2102                               span: Span,
2103                               id: NodeId,
2104                               is_public: bool,
2105                               shadowable: bool) {
2106         module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2107                                                                subclass,
2108                                                                span,
2109                                                                id,
2110                                                                is_public,
2111                                                                shadowable));
2112         self.unresolved_imports += 1;
2113         // Bump the reference count on the name. Or, if this is a glob, set
2114         // the appropriate flag.
2115
2116         match subclass {
2117             SingleImport(target, _) => {
2118                 debug!("(building import directive) building import \
2119                         directive: {}::{}",
2120                        self.idents_to_string(module_.imports.borrow().last().unwrap()
2121                                                  .module_path.as_slice()),
2122                        token::get_ident(target));
2123
2124                 let mut import_resolutions = module_.import_resolutions
2125                                                     .borrow_mut();
2126                 match import_resolutions.find_mut(&target.name) {
2127                     Some(resolution) => {
2128                         debug!("(building import directive) bumping \
2129                                 reference");
2130                         resolution.outstanding_references += 1;
2131
2132                         // the source of this name is different now
2133                         resolution.type_id = id;
2134                         resolution.value_id = id;
2135                         resolution.is_public = is_public;
2136                         return;
2137                     }
2138                     None => {}
2139                 }
2140                 debug!("(building import directive) creating new");
2141                 let mut resolution = ImportResolution::new(id, is_public);
2142                 resolution.outstanding_references = 1;
2143                 import_resolutions.insert(target.name, resolution);
2144             }
2145             GlobImport => {
2146                 // Set the glob flag. This tells us that we don't know the
2147                 // module's exports ahead of time.
2148
2149                 module_.glob_count.set(module_.glob_count.get() + 1);
2150             }
2151         }
2152     }
2153
2154     // Import resolution
2155     //
2156     // This is a fixed-point algorithm. We resolve imports until our efforts
2157     // are stymied by an unresolved import; then we bail out of the current
2158     // module and continue. We terminate successfully once no more imports
2159     // remain or unsuccessfully when no forward progress in resolving imports
2160     // is made.
2161
2162     /// Resolves all imports for the crate. This method performs the fixed-
2163     /// point iteration.
2164     fn resolve_imports(&mut self) {
2165         let mut i = 0u;
2166         let mut prev_unresolved_imports = 0;
2167         loop {
2168             debug!("(resolving imports) iteration {}, {} imports left",
2169                    i, self.unresolved_imports);
2170
2171             let module_root = self.graph_root.get_module();
2172             self.resolve_imports_for_module_subtree(module_root.clone());
2173
2174             if self.unresolved_imports == 0 {
2175                 debug!("(resolving imports) success");
2176                 break;
2177             }
2178
2179             if self.unresolved_imports == prev_unresolved_imports {
2180                 self.report_unresolved_imports(module_root);
2181                 break;
2182             }
2183
2184             i += 1;
2185             prev_unresolved_imports = self.unresolved_imports;
2186         }
2187     }
2188
2189     /// Attempts to resolve imports for the given module and all of its
2190     /// submodules.
2191     fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2192         debug!("(resolving imports for module subtree) resolving {}",
2193                self.module_to_string(&*module_));
2194         let orig_module = replace(&mut self.current_module, module_.clone());
2195         self.resolve_imports_for_module(module_.clone());
2196         self.current_module = orig_module;
2197
2198         self.populate_module_if_necessary(&module_);
2199         for (_, child_node) in module_.children.borrow().iter() {
2200             match child_node.get_module_if_available() {
2201                 None => {
2202                     // Nothing to do.
2203                 }
2204                 Some(child_module) => {
2205                     self.resolve_imports_for_module_subtree(child_module);
2206                 }
2207             }
2208         }
2209
2210         for (_, child_module) in module_.anonymous_children.borrow().iter() {
2211             self.resolve_imports_for_module_subtree(child_module.clone());
2212         }
2213     }
2214
2215     /// Attempts to resolve imports for the given module only.
2216     fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2217         if module.all_imports_resolved() {
2218             debug!("(resolving imports for module) all imports resolved for \
2219                    {}",
2220                    self.module_to_string(&*module));
2221             return;
2222         }
2223
2224         let imports = module.imports.borrow();
2225         let import_count = imports.len();
2226         while module.resolved_import_count.get() < import_count {
2227             let import_index = module.resolved_import_count.get();
2228             let import_directive = imports.get(import_index);
2229             match self.resolve_import_for_module(module.clone(),
2230                                                  import_directive) {
2231                 Failed(err) => {
2232                     let (span, help) = match err {
2233                         Some((span, msg)) => (span, format!(". {}", msg)),
2234                         None => (import_directive.span, String::new())
2235                     };
2236                     let msg = format!("unresolved import `{}`{}",
2237                                       self.import_path_to_string(
2238                                           import_directive.module_path
2239                                                           .as_slice(),
2240                                           import_directive.subclass),
2241                                       help);
2242                     self.resolve_error(span, msg.as_slice());
2243                 }
2244                 Indeterminate => break, // Bail out. We'll come around next time.
2245                 Success(()) => () // Good. Continue.
2246             }
2247
2248             module.resolved_import_count
2249                   .set(module.resolved_import_count.get() + 1);
2250         }
2251     }
2252
2253     fn idents_to_string(&self, idents: &[Ident]) -> String {
2254         let mut first = true;
2255         let mut result = String::new();
2256         for ident in idents.iter() {
2257             if first {
2258                 first = false
2259             } else {
2260                 result.push_str("::")
2261             }
2262             result.push_str(token::get_ident(*ident).get());
2263         };
2264         result
2265     }
2266
2267     fn path_idents_to_string(&self, path: &Path) -> String {
2268         let identifiers: Vec<ast::Ident> = path.segments
2269                                              .iter()
2270                                              .map(|seg| seg.identifier)
2271                                              .collect();
2272         self.idents_to_string(identifiers.as_slice())
2273     }
2274
2275     fn import_directive_subclass_to_string(&mut self,
2276                                         subclass: ImportDirectiveSubclass)
2277                                         -> String {
2278         match subclass {
2279             SingleImport(_, source) => {
2280                 token::get_ident(source).get().to_string()
2281             }
2282             GlobImport => "*".to_string()
2283         }
2284     }
2285
2286     fn import_path_to_string(&mut self,
2287                           idents: &[Ident],
2288                           subclass: ImportDirectiveSubclass)
2289                           -> String {
2290         if idents.is_empty() {
2291             self.import_directive_subclass_to_string(subclass)
2292         } else {
2293             (format!("{}::{}",
2294                      self.idents_to_string(idents),
2295                      self.import_directive_subclass_to_string(
2296                          subclass))).to_string()
2297         }
2298     }
2299
2300     /// Attempts to resolve the given import. The return value indicates
2301     /// failure if we're certain the name does not exist, indeterminate if we
2302     /// don't know whether the name exists at the moment due to other
2303     /// currently-unresolved imports, or success if we know the name exists.
2304     /// If successful, the resolved bindings are written into the module.
2305     fn resolve_import_for_module(&mut self,
2306                                  module_: Rc<Module>,
2307                                  import_directive: &ImportDirective)
2308                                  -> ResolveResult<()> {
2309         let mut resolution_result = Failed(None);
2310         let module_path = &import_directive.module_path;
2311
2312         debug!("(resolving import for module) resolving import `{}::...` in \
2313                 `{}`",
2314                self.idents_to_string(module_path.as_slice()),
2315                self.module_to_string(&*module_));
2316
2317         // First, resolve the module path for the directive, if necessary.
2318         let container = if module_path.len() == 0 {
2319             // Use the crate root.
2320             Some((self.graph_root.get_module(), LastMod(AllPublic)))
2321         } else {
2322             match self.resolve_module_path(module_.clone(),
2323                                            module_path.as_slice(),
2324                                            DontUseLexicalScope,
2325                                            import_directive.span,
2326                                            ImportSearch) {
2327                 Failed(err) => {
2328                     resolution_result = Failed(err);
2329                     None
2330                 },
2331                 Indeterminate => {
2332                     resolution_result = Indeterminate;
2333                     None
2334                 }
2335                 Success(container) => Some(container),
2336             }
2337         };
2338
2339         match container {
2340             None => {}
2341             Some((containing_module, lp)) => {
2342                 // We found the module that the target is contained
2343                 // within. Attempt to resolve the import within it.
2344
2345                 match import_directive.subclass {
2346                     SingleImport(target, source) => {
2347                         resolution_result =
2348                             self.resolve_single_import(&*module_,
2349                                                        containing_module,
2350                                                        target,
2351                                                        source,
2352                                                        import_directive,
2353                                                        lp);
2354                     }
2355                     GlobImport => {
2356                         resolution_result =
2357                             self.resolve_glob_import(&*module_,
2358                                                      containing_module,
2359                                                      import_directive,
2360                                                      lp);
2361                     }
2362                 }
2363             }
2364         }
2365
2366         // Decrement the count of unresolved imports.
2367         match resolution_result {
2368             Success(()) => {
2369                 assert!(self.unresolved_imports >= 1);
2370                 self.unresolved_imports -= 1;
2371             }
2372             _ => {
2373                 // Nothing to do here; just return the error.
2374             }
2375         }
2376
2377         // Decrement the count of unresolved globs if necessary. But only if
2378         // the resolution result is indeterminate -- otherwise we'll stop
2379         // processing imports here. (See the loop in
2380         // resolve_imports_for_module.)
2381
2382         if !resolution_result.indeterminate() {
2383             match import_directive.subclass {
2384                 GlobImport => {
2385                     assert!(module_.glob_count.get() >= 1);
2386                     module_.glob_count.set(module_.glob_count.get() - 1);
2387                 }
2388                 SingleImport(..) => {
2389                     // Ignore.
2390                 }
2391             }
2392         }
2393
2394         return resolution_result;
2395     }
2396
2397     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2398         NameBindings {
2399             type_def: RefCell::new(Some(TypeNsDef {
2400                 is_public: false,
2401                 module_def: Some(module),
2402                 type_def: None,
2403                 type_span: None
2404             })),
2405             value_def: RefCell::new(None),
2406         }
2407     }
2408
2409     fn resolve_single_import(&mut self,
2410                              module_: &Module,
2411                              containing_module: Rc<Module>,
2412                              target: Ident,
2413                              source: Ident,
2414                              directive: &ImportDirective,
2415                              lp: LastPrivate)
2416                                  -> ResolveResult<()> {
2417         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2418                 `{}` id {}, last private {:?}",
2419                token::get_ident(target),
2420                self.module_to_string(&*containing_module),
2421                token::get_ident(source),
2422                self.module_to_string(module_),
2423                directive.id,
2424                lp);
2425
2426         let lp = match lp {
2427             LastMod(lp) => lp,
2428             LastImport {..} => {
2429                 self.session
2430                     .span_bug(directive.span,
2431                               "not expecting Import here, must be LastMod")
2432             }
2433         };
2434
2435         // We need to resolve both namespaces for this to succeed.
2436         //
2437
2438         let mut value_result = UnknownResult;
2439         let mut type_result = UnknownResult;
2440
2441         // Search for direct children of the containing module.
2442         self.populate_module_if_necessary(&containing_module);
2443
2444         match containing_module.children.borrow().find(&source.name) {
2445             None => {
2446                 // Continue.
2447             }
2448             Some(ref child_name_bindings) => {
2449                 if child_name_bindings.defined_in_namespace(ValueNS) {
2450                     debug!("(resolving single import) found value binding");
2451                     value_result = BoundResult(containing_module.clone(),
2452                                                (*child_name_bindings).clone());
2453                 }
2454                 if child_name_bindings.defined_in_namespace(TypeNS) {
2455                     debug!("(resolving single import) found type binding");
2456                     type_result = BoundResult(containing_module.clone(),
2457                                               (*child_name_bindings).clone());
2458                 }
2459             }
2460         }
2461
2462         // Unless we managed to find a result in both namespaces (unlikely),
2463         // search imports as well.
2464         let mut value_used_reexport = false;
2465         let mut type_used_reexport = false;
2466         match (value_result.clone(), type_result.clone()) {
2467             (BoundResult(..), BoundResult(..)) => {} // Continue.
2468             _ => {
2469                 // If there is an unresolved glob at this point in the
2470                 // containing module, bail out. We don't know enough to be
2471                 // able to resolve this import.
2472
2473                 if containing_module.glob_count.get() > 0 {
2474                     debug!("(resolving single import) unresolved glob; \
2475                             bailing out");
2476                     return Indeterminate;
2477                 }
2478
2479                 // Now search the exported imports within the containing module.
2480                 match containing_module.import_resolutions.borrow().find(&source.name) {
2481                     None => {
2482                         debug!("(resolving single import) no import");
2483                         // The containing module definitely doesn't have an
2484                         // exported import with the name in question. We can
2485                         // therefore accurately report that the names are
2486                         // unbound.
2487
2488                         if value_result.is_unknown() {
2489                             value_result = UnboundResult;
2490                         }
2491                         if type_result.is_unknown() {
2492                             type_result = UnboundResult;
2493                         }
2494                     }
2495                     Some(import_resolution)
2496                             if import_resolution.outstanding_references == 0 => {
2497
2498                         fn get_binding(this: &mut Resolver,
2499                                        import_resolution: &ImportResolution,
2500                                        namespace: Namespace)
2501                                     -> NamespaceResult {
2502
2503                             // Import resolutions must be declared with "pub"
2504                             // in order to be exported.
2505                             if !import_resolution.is_public {
2506                                 return UnboundResult;
2507                             }
2508
2509                             match import_resolution.
2510                                     target_for_namespace(namespace) {
2511                                 None => {
2512                                     return UnboundResult;
2513                                 }
2514                                 Some(Target {
2515                                     target_module,
2516                                     bindings,
2517                                     shadowable: _
2518                                 }) => {
2519                                     debug!("(resolving single import) found \
2520                                             import in ns {:?}", namespace);
2521                                     let id = import_resolution.id(namespace);
2522                                     // track used imports and extern crates as well
2523                                     this.used_imports.insert((id, namespace));
2524                                     match target_module.def_id.get() {
2525                                         Some(DefId{krate: kid, ..}) => {
2526                                             this.used_crates.insert(kid);
2527                                         },
2528                                         _ => {}
2529                                     }
2530                                     return BoundResult(target_module, bindings);
2531                                 }
2532                             }
2533                         }
2534
2535                         // The name is an import which has been fully
2536                         // resolved. We can, therefore, just follow it.
2537                         if value_result.is_unknown() {
2538                             value_result = get_binding(self, import_resolution,
2539                                                        ValueNS);
2540                             value_used_reexport = import_resolution.is_public;
2541                         }
2542                         if type_result.is_unknown() {
2543                             type_result = get_binding(self, import_resolution,
2544                                                       TypeNS);
2545                             type_used_reexport = import_resolution.is_public;
2546                         }
2547
2548                     }
2549                     Some(_) => {
2550                         // The import is unresolved. Bail out.
2551                         debug!("(resolving single import) unresolved import; \
2552                                 bailing out");
2553                         return Indeterminate;
2554                     }
2555                 }
2556             }
2557         }
2558
2559         // If we didn't find a result in the type namespace, search the
2560         // external modules.
2561         let mut value_used_public = false;
2562         let mut type_used_public = false;
2563         match type_result {
2564             BoundResult(..) => {}
2565             _ => {
2566                 match containing_module.external_module_children.borrow_mut()
2567                                        .find_copy(&source.name) {
2568                     None => {} // Continue.
2569                     Some(module) => {
2570                         debug!("(resolving single import) found external \
2571                                 module");
2572                         // track the module as used.
2573                         match module.def_id.get() {
2574                             Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
2575                             _ => {}
2576                         }
2577                         let name_bindings =
2578                             Rc::new(Resolver::create_name_bindings_from_module(
2579                                 module));
2580                         type_result = BoundResult(containing_module.clone(),
2581                                                   name_bindings);
2582                         type_used_public = true;
2583                     }
2584                 }
2585             }
2586         }
2587
2588         // We've successfully resolved the import. Write the results in.
2589         let mut import_resolutions = module_.import_resolutions.borrow_mut();
2590         let import_resolution = import_resolutions.get_mut(&target.name);
2591
2592         match value_result {
2593             BoundResult(ref target_module, ref name_bindings) => {
2594                 debug!("(resolving single import) found value target");
2595                 self.check_for_conflicting_import(
2596                     &import_resolution.value_target,
2597                     directive.span,
2598                     target.name,
2599                     ValueNS);
2600
2601                 import_resolution.value_target =
2602                     Some(Target::new(target_module.clone(),
2603                                      name_bindings.clone(),
2604                                      directive.shadowable));
2605                 import_resolution.value_id = directive.id;
2606                 import_resolution.is_public = directive.is_public;
2607                 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2608             }
2609             UnboundResult => { /* Continue. */ }
2610             UnknownResult => {
2611                 fail!("value result should be known at this point");
2612             }
2613         }
2614         match type_result {
2615             BoundResult(ref target_module, ref name_bindings) => {
2616                 debug!("(resolving single import) found type target: {:?}",
2617                        { name_bindings.type_def.borrow().clone().unwrap().type_def });
2618                 self.check_for_conflicting_import(
2619                     &import_resolution.type_target,
2620                     directive.span,
2621                     target.name,
2622                     TypeNS);
2623
2624                 import_resolution.type_target =
2625                     Some(Target::new(target_module.clone(),
2626                                      name_bindings.clone(),
2627                                      directive.shadowable));
2628                 import_resolution.type_id = directive.id;
2629                 import_resolution.is_public = directive.is_public;
2630                 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2631             }
2632             UnboundResult => { /* Continue. */ }
2633             UnknownResult => {
2634                 fail!("type result should be known at this point");
2635             }
2636         }
2637
2638         self.check_for_conflicts_between_imports_and_items(
2639             module_,
2640             import_resolution,
2641             directive.span,
2642             target.name);
2643
2644         if value_result.is_unbound() && type_result.is_unbound() {
2645             let msg = format!("There is no `{}` in `{}`",
2646                               token::get_ident(source),
2647                               self.module_to_string(&*containing_module));
2648             return Failed(Some((directive.span, msg)));
2649         }
2650         let value_used_public = value_used_reexport || value_used_public;
2651         let type_used_public = type_used_reexport || type_used_public;
2652
2653         assert!(import_resolution.outstanding_references >= 1);
2654         import_resolution.outstanding_references -= 1;
2655
2656         // record what this import resolves to for later uses in documentation,
2657         // this may resolve to either a value or a type, but for documentation
2658         // purposes it's good enough to just favor one over the other.
2659         let value_private = match import_resolution.value_target {
2660             Some(ref target) => {
2661                 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2662                 self.def_map.borrow_mut().insert(directive.id, def);
2663                 let did = def.def_id();
2664                 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2665             },
2666             // AllPublic here and below is a dummy value, it should never be used because
2667             // _exists is false.
2668             None => None,
2669         };
2670         let type_private = match import_resolution.type_target {
2671             Some(ref target) => {
2672                 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2673                 self.def_map.borrow_mut().insert(directive.id, def);
2674                 let did = def.def_id();
2675                 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2676             },
2677             None => None,
2678         };
2679
2680         self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2681                                                           value_used: Used,
2682                                                           type_priv: type_private,
2683                                                           type_used: Used});
2684
2685         debug!("(resolving single import) successfully resolved import");
2686         return Success(());
2687     }
2688
2689     // Resolves a glob import. Note that this function cannot fail; it either
2690     // succeeds or bails out (as importing * from an empty module or a module
2691     // that exports nothing is valid).
2692     fn resolve_glob_import(&mut self,
2693                            module_: &Module,
2694                            containing_module: Rc<Module>,
2695                            import_directive: &ImportDirective,
2696                            lp: LastPrivate)
2697                            -> ResolveResult<()> {
2698         let id = import_directive.id;
2699         let is_public = import_directive.is_public;
2700
2701         // This function works in a highly imperative manner; it eagerly adds
2702         // everything it can to the list of import resolutions of the module
2703         // node.
2704         debug!("(resolving glob import) resolving glob import {}", id);
2705
2706         // We must bail out if the node has unresolved imports of any kind
2707         // (including globs).
2708         if !(*containing_module).all_imports_resolved() {
2709             debug!("(resolving glob import) target module has unresolved \
2710                     imports; bailing out");
2711             return Indeterminate;
2712         }
2713
2714         assert_eq!(containing_module.glob_count.get(), 0);
2715
2716         // Add all resolved imports from the containing module.
2717         let import_resolutions = containing_module.import_resolutions
2718                                                   .borrow();
2719         for (ident, target_import_resolution) in import_resolutions.iter() {
2720             debug!("(resolving glob import) writing module resolution \
2721                     {:?} into `{}`",
2722                    target_import_resolution.type_target.is_none(),
2723                    self.module_to_string(module_));
2724
2725             if !target_import_resolution.is_public {
2726                 debug!("(resolving glob import) nevermind, just kidding");
2727                 continue
2728             }
2729
2730             // Here we merge two import resolutions.
2731             let mut import_resolutions = module_.import_resolutions.borrow_mut();
2732             match import_resolutions.find_mut(ident) {
2733                 Some(dest_import_resolution) => {
2734                     // Merge the two import resolutions at a finer-grained
2735                     // level.
2736
2737                     match target_import_resolution.value_target {
2738                         None => {
2739                             // Continue.
2740                         }
2741                         Some(ref value_target) => {
2742                             dest_import_resolution.value_target =
2743                                 Some(value_target.clone());
2744                         }
2745                     }
2746                     match target_import_resolution.type_target {
2747                         None => {
2748                             // Continue.
2749                         }
2750                         Some(ref type_target) => {
2751                             dest_import_resolution.type_target =
2752                                 Some(type_target.clone());
2753                         }
2754                     }
2755                     dest_import_resolution.is_public = is_public;
2756                     continue;
2757                 }
2758                 None => {}
2759             }
2760
2761             // Simple: just copy the old import resolution.
2762             let mut new_import_resolution = ImportResolution::new(id, is_public);
2763             new_import_resolution.value_target =
2764                 target_import_resolution.value_target.clone();
2765             new_import_resolution.type_target =
2766                 target_import_resolution.type_target.clone();
2767
2768             import_resolutions.insert(*ident, new_import_resolution);
2769         }
2770
2771         // Add all children from the containing module.
2772         self.populate_module_if_necessary(&containing_module);
2773
2774         for (&name, name_bindings) in containing_module.children
2775                                                        .borrow().iter() {
2776             self.merge_import_resolution(module_,
2777                                          containing_module.clone(),
2778                                          import_directive,
2779                                          name,
2780                                          name_bindings.clone());
2781
2782         }
2783
2784         // Add external module children from the containing module.
2785         for (&name, module) in containing_module.external_module_children
2786                                                 .borrow().iter() {
2787             let name_bindings =
2788                 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2789             self.merge_import_resolution(module_,
2790                                          containing_module.clone(),
2791                                          import_directive,
2792                                          name,
2793                                          name_bindings);
2794         }
2795
2796         // Record the destination of this import
2797         match containing_module.def_id.get() {
2798             Some(did) => {
2799                 self.def_map.borrow_mut().insert(id, DefMod(did));
2800                 self.last_private.insert(id, lp);
2801             }
2802             None => {}
2803         }
2804
2805         debug!("(resolving glob import) successfully resolved import");
2806         return Success(());
2807     }
2808
2809     fn merge_import_resolution(&mut self,
2810                                module_: &Module,
2811                                containing_module: Rc<Module>,
2812                                import_directive: &ImportDirective,
2813                                name: Name,
2814                                name_bindings: Rc<NameBindings>) {
2815         let id = import_directive.id;
2816         let is_public = import_directive.is_public;
2817
2818         let mut import_resolutions = module_.import_resolutions.borrow_mut();
2819         let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
2820             // Create a new import resolution from this child.
2821             ImportResolution::new(id, is_public)
2822         });
2823
2824         debug!("(resolving glob import) writing resolution `{}` in `{}` \
2825                to `{}`",
2826                token::get_name(name).get().to_string(),
2827                self.module_to_string(&*containing_module),
2828                self.module_to_string(module_));
2829
2830         // Merge the child item into the import resolution.
2831         if name_bindings.defined_in_public_namespace(ValueNS) {
2832             debug!("(resolving glob import) ... for value target");
2833             dest_import_resolution.value_target =
2834                 Some(Target::new(containing_module.clone(),
2835                                  name_bindings.clone(),
2836                                  import_directive.shadowable));
2837             dest_import_resolution.value_id = id;
2838         }
2839         if name_bindings.defined_in_public_namespace(TypeNS) {
2840             debug!("(resolving glob import) ... for type target");
2841             dest_import_resolution.type_target =
2842                 Some(Target::new(containing_module,
2843                                  name_bindings.clone(),
2844                                  import_directive.shadowable));
2845             dest_import_resolution.type_id = id;
2846         }
2847         dest_import_resolution.is_public = is_public;
2848
2849         self.check_for_conflicts_between_imports_and_items(
2850             module_,
2851             dest_import_resolution,
2852             import_directive.span,
2853             name);
2854     }
2855
2856     /// Checks that imported names and items don't have the same name.
2857     fn check_for_conflicting_import(&mut self,
2858                                     target: &Option<Target>,
2859                                     import_span: Span,
2860                                     name: Name,
2861                                     namespace: Namespace) {
2862         if self.session.features.borrow().import_shadowing {
2863             return
2864         }
2865
2866         match *target {
2867             Some(ref target) if !target.shadowable => {
2868                 let msg = format!("a {} named `{}` has already been imported \
2869                                    in this module",
2870                                   match namespace {
2871                                     TypeNS => "type",
2872                                     ValueNS => "value",
2873                                   },
2874                                   token::get_name(name).get());
2875                 self.session.span_err(import_span, msg.as_slice());
2876             }
2877             Some(_) | None => {}
2878         }
2879     }
2880
2881     /// Checks that imported names and items don't have the same name.
2882     fn check_for_conflicts_between_imports_and_items(&mut self,
2883                                                      module: &Module,
2884                                                      import_resolution:
2885                                                      &mut ImportResolution,
2886                                                      import_span: Span,
2887                                                      name: Name) {
2888         if self.session.features.borrow().import_shadowing {
2889             return
2890         }
2891
2892         // First, check for conflicts between imports and `extern crate`s.
2893         if module.external_module_children
2894                  .borrow()
2895                  .contains_key(&name) {
2896             match import_resolution.type_target {
2897                 Some(ref target) if !target.shadowable => {
2898                     let msg = format!("import `{}` conflicts with imported \
2899                                        crate in this module",
2900                                       token::get_name(name).get());
2901                     self.session.span_err(import_span, msg.as_slice());
2902                 }
2903                 Some(_) | None => {}
2904             }
2905         }
2906
2907         // Check for item conflicts.
2908         let children = module.children.borrow();
2909         let name_bindings = match children.find(&name) {
2910             None => {
2911                 // There can't be any conflicts.
2912                 return
2913             }
2914             Some(ref name_bindings) => (*name_bindings).clone(),
2915         };
2916
2917         match import_resolution.value_target {
2918             Some(ref target) if !target.shadowable => {
2919                 match *name_bindings.value_def.borrow() {
2920                     None => {}
2921                     Some(ref value) => {
2922                         let msg = format!("import `{}` conflicts with value \
2923                                            in this module",
2924                                           token::get_name(name).get());
2925                         self.session.span_err(import_span, msg.as_slice());
2926                         match value.value_span {
2927                             None => {}
2928                             Some(span) => {
2929                                 self.session
2930                                     .span_note(span,
2931                                                "note conflicting value here");
2932                             }
2933                         }
2934                     }
2935                 }
2936             }
2937             Some(_) | None => {}
2938         }
2939
2940         match import_resolution.type_target {
2941             Some(ref target) if !target.shadowable => {
2942                 match *name_bindings.type_def.borrow() {
2943                     None => {}
2944                     Some(ref ty) => {
2945                         let msg = format!("import `{}` conflicts with type in \
2946                                            this module",
2947                                           token::get_name(name).get());
2948                         self.session.span_err(import_span, msg.as_slice());
2949                         match ty.type_span {
2950                             None => {}
2951                             Some(span) => {
2952                                 self.session
2953                                     .span_note(span,
2954                                                "note conflicting type here")
2955                             }
2956                         }
2957                     }
2958                 }
2959             }
2960             Some(_) | None => {}
2961         }
2962     }
2963
2964     /// Checks that the names of external crates don't collide with other
2965     /// external crates.
2966     fn check_for_conflicts_between_external_crates(&self,
2967                                                    module: &Module,
2968                                                    name: Name,
2969                                                    span: Span) {
2970         if self.session.features.borrow().import_shadowing {
2971             return
2972         }
2973
2974         if module.external_module_children.borrow().contains_key(&name) {
2975             self.session
2976                 .span_err(span,
2977                           format!("an external crate named `{}` has already \
2978                                    been imported into this module",
2979                                   token::get_name(name).get()).as_slice());
2980         }
2981     }
2982
2983     /// Checks that the names of items don't collide with external crates.
2984     fn check_for_conflicts_between_external_crates_and_items(&self,
2985                                                              module: &Module,
2986                                                              name: Name,
2987                                                              span: Span) {
2988         if self.session.features.borrow().import_shadowing {
2989             return
2990         }
2991
2992         if module.external_module_children.borrow().contains_key(&name) {
2993             self.session
2994                 .span_err(span,
2995                           format!("the name `{}` conflicts with an external \
2996                                    crate that has been imported into this \
2997                                    module",
2998                                   token::get_name(name).get()).as_slice());
2999         }
3000     }
3001
3002     /// Resolves the given module path from the given root `module_`.
3003     fn resolve_module_path_from_root(&mut self,
3004                                      module_: Rc<Module>,
3005                                      module_path: &[Ident],
3006                                      index: uint,
3007                                      span: Span,
3008                                      name_search_type: NameSearchType,
3009                                      lp: LastPrivate)
3010                                 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3011         fn search_parent_externals(needle: Name, module: &Rc<Module>)
3012                                 -> Option<Rc<Module>> {
3013             module.external_module_children.borrow()
3014                                             .find_copy(&needle)
3015                                             .map(|_| module.clone())
3016                                             .or_else(|| {
3017                 match module.parent_link.clone() {
3018                     ModuleParentLink(parent, _) => {
3019                         search_parent_externals(needle,
3020                                                 &parent.upgrade().unwrap())
3021                     }
3022                    _ => None
3023                 }
3024             })
3025         }
3026
3027         let mut search_module = module_;
3028         let mut index = index;
3029         let module_path_len = module_path.len();
3030         let mut closest_private = lp;
3031
3032         // Resolve the module part of the path. This does not involve looking
3033         // upward though scope chains; we simply resolve names directly in
3034         // modules as we go.
3035         while index < module_path_len {
3036             let name = module_path[index];
3037             match self.resolve_name_in_module(search_module.clone(),
3038                                               name.name,
3039                                               TypeNS,
3040                                               name_search_type,
3041                                               false) {
3042                 Failed(None) => {
3043                     let segment_name = token::get_ident(name);
3044                     let module_name = self.module_to_string(&*search_module);
3045                     let mut span = span;
3046                     let msg = if "???" == module_name.as_slice() {
3047                         span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3048
3049                         match search_parent_externals(name.name,
3050                                                      &self.current_module) {
3051                             Some(module) => {
3052                                 let path_str = self.idents_to_string(module_path);
3053                                 let target_mod_str = self.module_to_string(&*module);
3054                                 let current_mod_str =
3055                                     self.module_to_string(&*self.current_module);
3056
3057                                 let prefix = if target_mod_str == current_mod_str {
3058                                     "self::".to_string()
3059                                 } else {
3060                                     format!("{}::", target_mod_str)
3061                                 };
3062
3063                                 format!("Did you mean `{}{}`?", prefix, path_str)
3064                             },
3065                             None => format!("Maybe a missing `extern crate {}`?",
3066                                             segment_name),
3067                         }
3068                     } else {
3069                         format!("Could not find `{}` in `{}`.",
3070                                 segment_name,
3071                                 module_name)
3072                     };
3073
3074                     return Failed(Some((span, msg)));
3075                 }
3076                 Failed(err) => return Failed(err),
3077                 Indeterminate => {
3078                     debug!("(resolving module path for import) module \
3079                             resolution is indeterminate: {}",
3080                             token::get_ident(name));
3081                     return Indeterminate;
3082                 }
3083                 Success((target, used_proxy)) => {
3084                     // Check to see whether there are type bindings, and, if
3085                     // so, whether there is a module within.
3086                     match *target.bindings.type_def.borrow() {
3087                         Some(ref type_def) => {
3088                             match type_def.module_def {
3089                                 None => {
3090                                     let msg = format!("Not a module `{}`",
3091                                                         token::get_ident(name));
3092
3093                                     return Failed(Some((span, msg)));
3094                                 }
3095                                 Some(ref module_def) => {
3096                                     // If we're doing the search for an
3097                                     // import, do not allow traits and impls
3098                                     // to be selected.
3099                                     match (name_search_type,
3100                                            module_def.kind.get()) {
3101                                         (ImportSearch, TraitModuleKind) |
3102                                         (ImportSearch, ImplModuleKind) => {
3103                                             let msg =
3104                                                 "Cannot import from a trait or \
3105                                                 type implementation".to_string();
3106                                             return Failed(Some((span, msg)));
3107                                         }
3108                                         (_, _) => {
3109                                             search_module = module_def.clone();
3110
3111                                             // track extern crates for unused_extern_crate lint
3112                                             match module_def.def_id.get() {
3113                                                 Some(did) => {
3114                                                     self.used_crates.insert(did.krate);
3115                                                 }
3116                                                 _ => {}
3117                                             }
3118
3119                                             // Keep track of the closest
3120                                             // private module used when
3121                                             // resolving this import chain.
3122                                             if !used_proxy &&
3123                                                !search_module.is_public {
3124                                                 match search_module.def_id
3125                                                                    .get() {
3126                                                     Some(did) => {
3127                                                         closest_private =
3128                                                             LastMod(DependsOn(did));
3129                                                     }
3130                                                     None => {}
3131                                                 }
3132                                             }
3133                                         }
3134                                     }
3135                                 }
3136                             }
3137                         }
3138                         None => {
3139                             // There are no type bindings at all.
3140                             let msg = format!("Not a module `{}`",
3141                                               token::get_ident(name));
3142                             return Failed(Some((span, msg)));
3143                         }
3144                     }
3145                 }
3146             }
3147
3148             index += 1;
3149         }
3150
3151         return Success((search_module, closest_private));
3152     }
3153
3154     /// Attempts to resolve the module part of an import directive or path
3155     /// rooted at the given module.
3156     ///
3157     /// On success, returns the resolved module, and the closest *private*
3158     /// module found to the destination when resolving this path.
3159     fn resolve_module_path(&mut self,
3160                            module_: Rc<Module>,
3161                            module_path: &[Ident],
3162                            use_lexical_scope: UseLexicalScopeFlag,
3163                            span: Span,
3164                            name_search_type: NameSearchType)
3165                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
3166         let module_path_len = module_path.len();
3167         assert!(module_path_len > 0);
3168
3169         debug!("(resolving module path for import) processing `{}` rooted at \
3170                `{}`",
3171                self.idents_to_string(module_path),
3172                self.module_to_string(&*module_));
3173
3174         // Resolve the module prefix, if any.
3175         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3176                                                               module_path);
3177
3178         let search_module;
3179         let start_index;
3180         let last_private;
3181         match module_prefix_result {
3182             Failed(None) => {
3183                 let mpath = self.idents_to_string(module_path);
3184                 let mpath = mpath.as_slice();
3185                 match mpath.rfind(':') {
3186                     Some(idx) => {
3187                         let msg = format!("Could not find `{}` in `{}`",
3188                                             // idx +- 1 to account for the
3189                                             // colons on either side
3190                                             mpath.slice_from(idx + 1),
3191                                             mpath.slice_to(idx - 1));
3192                         return Failed(Some((span, msg)));
3193                     },
3194                     None => return Failed(None),
3195                 }
3196             }
3197             Failed(err) => return Failed(err),
3198             Indeterminate => {
3199                 debug!("(resolving module path for import) indeterminate; \
3200                         bailing");
3201                 return Indeterminate;
3202             }
3203             Success(NoPrefixFound) => {
3204                 // There was no prefix, so we're considering the first element
3205                 // of the path. How we handle this depends on whether we were
3206                 // instructed to use lexical scope or not.
3207                 match use_lexical_scope {
3208                     DontUseLexicalScope => {
3209                         // This is a crate-relative path. We will start the
3210                         // resolution process at index zero.
3211                         search_module = self.graph_root.get_module();
3212                         start_index = 0;
3213                         last_private = LastMod(AllPublic);
3214                     }
3215                     UseLexicalScope => {
3216                         // This is not a crate-relative path. We resolve the
3217                         // first component of the path in the current lexical
3218                         // scope and then proceed to resolve below that.
3219                         match self.resolve_module_in_lexical_scope(
3220                                                             module_,
3221                                                             module_path[0]) {
3222                             Failed(err) => return Failed(err),
3223                             Indeterminate => {
3224                                 debug!("(resolving module path for import) \
3225                                         indeterminate; bailing");
3226                                 return Indeterminate;
3227                             }
3228                             Success(containing_module) => {
3229                                 search_module = containing_module;
3230                                 start_index = 1;
3231                                 last_private = LastMod(AllPublic);
3232                             }
3233                         }
3234                     }
3235                 }
3236             }
3237             Success(PrefixFound(ref containing_module, index)) => {
3238                 search_module = containing_module.clone();
3239                 start_index = index;
3240                 last_private = LastMod(DependsOn(containing_module.def_id
3241                                                                   .get()
3242                                                                   .unwrap()));
3243             }
3244         }
3245
3246         self.resolve_module_path_from_root(search_module,
3247                                            module_path,
3248                                            start_index,
3249                                            span,
3250                                            name_search_type,
3251                                            last_private)
3252     }
3253
3254     /// Invariant: This must only be called during main resolution, not during
3255     /// import resolution.
3256     fn resolve_item_in_lexical_scope(&mut self,
3257                                      module_: Rc<Module>,
3258                                      name: Ident,
3259                                      namespace: Namespace)
3260                                     -> ResolveResult<(Target, bool)> {
3261         debug!("(resolving item in lexical scope) resolving `{}` in \
3262                 namespace {:?} in `{}`",
3263                token::get_ident(name),
3264                namespace,
3265                self.module_to_string(&*module_));
3266
3267         // The current module node is handled specially. First, check for
3268         // its immediate children.
3269         self.populate_module_if_necessary(&module_);
3270
3271         match module_.children.borrow().find(&name.name) {
3272             Some(name_bindings)
3273                     if name_bindings.defined_in_namespace(namespace) => {
3274                 debug!("top name bindings succeeded");
3275                 return Success((Target::new(module_.clone(),
3276                                             name_bindings.clone(),
3277                                             false),
3278                                false));
3279             }
3280             Some(_) | None => { /* Not found; continue. */ }
3281         }
3282
3283         // Now check for its import directives. We don't have to have resolved
3284         // all its imports in the usual way; this is because chains of
3285         // adjacent import statements are processed as though they mutated the
3286         // current scope.
3287         match module_.import_resolutions.borrow().find(&name.name) {
3288             None => {
3289                 // Not found; continue.
3290             }
3291             Some(import_resolution) => {
3292                 match (*import_resolution).target_for_namespace(namespace) {
3293                     None => {
3294                         // Not found; continue.
3295                         debug!("(resolving item in lexical scope) found \
3296                                 import resolution, but not in namespace {:?}",
3297                                namespace);
3298                     }
3299                     Some(target) => {
3300                         debug!("(resolving item in lexical scope) using \
3301                                 import resolution");
3302                         // track used imports and extern crates as well
3303                         self.used_imports.insert((import_resolution.id(namespace), namespace));
3304                         match target.target_module.def_id.get() {
3305                             Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
3306                             _ => {}
3307                         }
3308                         return Success((target, false));
3309                     }
3310                 }
3311             }
3312         }
3313
3314         // Search for external modules.
3315         if namespace == TypeNS {
3316             match module_.external_module_children.borrow().find_copy(&name.name) {
3317                 None => {}
3318                 Some(module) => {
3319                     let name_bindings =
3320                         Rc::new(Resolver::create_name_bindings_from_module(module));
3321                     debug!("lower name bindings succeeded");
3322                     return Success((Target::new(module_,
3323                                                 name_bindings,
3324                                                 false),
3325                                     false));
3326                 }
3327             }
3328         }
3329
3330         // Finally, proceed up the scope chain looking for parent modules.
3331         let mut search_module = module_;
3332         loop {
3333             // Go to the next parent.
3334             match search_module.parent_link.clone() {
3335                 NoParentLink => {
3336                     // No more parents. This module was unresolved.
3337                     debug!("(resolving item in lexical scope) unresolved \
3338                             module");
3339                     return Failed(None);
3340                 }
3341                 ModuleParentLink(parent_module_node, _) => {
3342                     match search_module.kind.get() {
3343                         NormalModuleKind => {
3344                             // We stop the search here.
3345                             debug!("(resolving item in lexical \
3346                                     scope) unresolved module: not \
3347                                     searching through module \
3348                                     parents");
3349                             return Failed(None);
3350                         }
3351                         ExternModuleKind |
3352                         TraitModuleKind |
3353                         ImplModuleKind |
3354                         AnonymousModuleKind => {
3355                             search_module = parent_module_node.upgrade().unwrap();
3356                         }
3357                     }
3358                 }
3359                 BlockParentLink(ref parent_module_node, _) => {
3360                     search_module = parent_module_node.upgrade().unwrap();
3361                 }
3362             }
3363
3364             // Resolve the name in the parent module.
3365             match self.resolve_name_in_module(search_module.clone(),
3366                                               name.name,
3367                                               namespace,
3368                                               PathSearch,
3369                                               true) {
3370                 Failed(Some((span, msg))) =>
3371                     self.resolve_error(span, format!("failed to resolve. {}",
3372                                                      msg)),
3373                 Failed(None) => (), // Continue up the search chain.
3374                 Indeterminate => {
3375                     // We couldn't see through the higher scope because of an
3376                     // unresolved import higher up. Bail.
3377
3378                     debug!("(resolving item in lexical scope) indeterminate \
3379                             higher scope; bailing");
3380                     return Indeterminate;
3381                 }
3382                 Success((target, used_reexport)) => {
3383                     // We found the module.
3384                     debug!("(resolving item in lexical scope) found name \
3385                             in module, done");
3386                     return Success((target, used_reexport));
3387                 }
3388             }
3389         }
3390     }
3391
3392     /// Resolves a module name in the current lexical scope.
3393     fn resolve_module_in_lexical_scope(&mut self,
3394                                        module_: Rc<Module>,
3395                                        name: Ident)
3396                                 -> ResolveResult<Rc<Module>> {
3397         // If this module is an anonymous module, resolve the item in the
3398         // lexical scope. Otherwise, resolve the item from the crate root.
3399         let resolve_result = self.resolve_item_in_lexical_scope(
3400             module_, name, TypeNS);
3401         match resolve_result {
3402             Success((target, _)) => {
3403                 let bindings = &*target.bindings;
3404                 match *bindings.type_def.borrow() {
3405                     Some(ref type_def) => {
3406                         match type_def.module_def {
3407                             None => {
3408                                 debug!("!!! (resolving module in lexical \
3409                                         scope) module wasn't actually a \
3410                                         module!");
3411                                 return Failed(None);
3412                             }
3413                             Some(ref module_def) => {
3414                                 return Success(module_def.clone());
3415                             }
3416                         }
3417                     }
3418                     None => {
3419                         debug!("!!! (resolving module in lexical scope) module
3420                                 wasn't actually a module!");
3421                         return Failed(None);
3422                     }
3423                 }
3424             }
3425             Indeterminate => {
3426                 debug!("(resolving module in lexical scope) indeterminate; \
3427                         bailing");
3428                 return Indeterminate;
3429             }
3430             Failed(err) => {
3431                 debug!("(resolving module in lexical scope) failed to resolve");
3432                 return Failed(err);
3433             }
3434         }
3435     }
3436
3437     /// Returns the nearest normal module parent of the given module.
3438     fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3439                                             -> Option<Rc<Module>> {
3440         let mut module_ = module_;
3441         loop {
3442             match module_.parent_link.clone() {
3443                 NoParentLink => return None,
3444                 ModuleParentLink(new_module, _) |
3445                 BlockParentLink(new_module, _) => {
3446                     let new_module = new_module.upgrade().unwrap();
3447                     match new_module.kind.get() {
3448                         NormalModuleKind => return Some(new_module),
3449                         ExternModuleKind |
3450                         TraitModuleKind |
3451                         ImplModuleKind |
3452                         AnonymousModuleKind => module_ = new_module,
3453                     }
3454                 }
3455             }
3456         }
3457     }
3458
3459     /// Returns the nearest normal module parent of the given module, or the
3460     /// module itself if it is a normal module.
3461     fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3462                                                 -> Rc<Module> {
3463         match module_.kind.get() {
3464             NormalModuleKind => return module_,
3465             ExternModuleKind |
3466             TraitModuleKind |
3467             ImplModuleKind |
3468             AnonymousModuleKind => {
3469                 match self.get_nearest_normal_module_parent(module_.clone()) {
3470                     None => module_,
3471                     Some(new_module) => new_module
3472                 }
3473             }
3474         }
3475     }
3476
3477     /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3478     /// (b) some chain of `super::`.
3479     /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3480     fn resolve_module_prefix(&mut self,
3481                              module_: Rc<Module>,
3482                              module_path: &[Ident])
3483                                  -> ResolveResult<ModulePrefixResult> {
3484         // Start at the current module if we see `self` or `super`, or at the
3485         // top of the crate otherwise.
3486         let mut containing_module;
3487         let mut i;
3488         let first_module_path_string = token::get_ident(module_path[0]);
3489         if "self" == first_module_path_string.get() {
3490             containing_module =
3491                 self.get_nearest_normal_module_parent_or_self(module_);
3492             i = 1;
3493         } else if "super" == first_module_path_string.get() {
3494             containing_module =
3495                 self.get_nearest_normal_module_parent_or_self(module_);
3496             i = 0;  // We'll handle `super` below.
3497         } else {
3498             return Success(NoPrefixFound);
3499         }
3500
3501         // Now loop through all the `super`s we find.
3502         while i < module_path.len() {
3503             let string = token::get_ident(module_path[i]);
3504             if "super" != string.get() {
3505                 break
3506             }
3507             debug!("(resolving module prefix) resolving `super` at {}",
3508                    self.module_to_string(&*containing_module));
3509             match self.get_nearest_normal_module_parent(containing_module) {
3510                 None => return Failed(None),
3511                 Some(new_module) => {
3512                     containing_module = new_module;
3513                     i += 1;
3514                 }
3515             }
3516         }
3517
3518         debug!("(resolving module prefix) finished resolving prefix at {}",
3519                self.module_to_string(&*containing_module));
3520
3521         return Success(PrefixFound(containing_module, i));
3522     }
3523
3524     /// Attempts to resolve the supplied name in the given module for the
3525     /// given namespace. If successful, returns the target corresponding to
3526     /// the name.
3527     ///
3528     /// The boolean returned on success is an indicator of whether this lookup
3529     /// passed through a public re-export proxy.
3530     fn resolve_name_in_module(&mut self,
3531                               module_: Rc<Module>,
3532                               name: Name,
3533                               namespace: Namespace,
3534                               name_search_type: NameSearchType,
3535                               allow_private_imports: bool)
3536                               -> ResolveResult<(Target, bool)> {
3537         debug!("(resolving name in module) resolving `{}` in `{}`",
3538                token::get_name(name).get(),
3539                self.module_to_string(&*module_));
3540
3541         // First, check the direct children of the module.
3542         self.populate_module_if_necessary(&module_);
3543
3544         match module_.children.borrow().find(&name) {
3545             Some(name_bindings)
3546                     if name_bindings.defined_in_namespace(namespace) => {
3547                 debug!("(resolving name in module) found node as child");
3548                 return Success((Target::new(module_.clone(),
3549                                             name_bindings.clone(),
3550                                             false),
3551                                false));
3552             }
3553             Some(_) | None => {
3554                 // Continue.
3555             }
3556         }
3557
3558         // Next, check the module's imports if necessary.
3559
3560         // If this is a search of all imports, we should be done with glob
3561         // resolution at this point.
3562         if name_search_type == PathSearch {
3563             assert_eq!(module_.glob_count.get(), 0);
3564         }
3565
3566         // Check the list of resolved imports.
3567         match module_.import_resolutions.borrow().find(&name) {
3568             Some(import_resolution) if allow_private_imports ||
3569                                        import_resolution.is_public => {
3570
3571                 if import_resolution.is_public &&
3572                         import_resolution.outstanding_references != 0 {
3573                     debug!("(resolving name in module) import \
3574                            unresolved; bailing out");
3575                     return Indeterminate;
3576                 }
3577                 match import_resolution.target_for_namespace(namespace) {
3578                     None => {
3579                         debug!("(resolving name in module) name found, \
3580                                 but not in namespace {:?}",
3581                                namespace);
3582                     }
3583                     Some(target) => {
3584                         debug!("(resolving name in module) resolved to \
3585                                 import");
3586                         // track used imports and extern crates as well
3587                         self.used_imports.insert((import_resolution.id(namespace), namespace));
3588                         match target.target_module.def_id.get() {
3589                             Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
3590                             _ => {}
3591                         }
3592                         return Success((target, true));
3593                     }
3594                 }
3595             }
3596             Some(..) | None => {} // Continue.
3597         }
3598
3599         // Finally, search through external children.
3600         if namespace == TypeNS {
3601             match module_.external_module_children.borrow().find_copy(&name) {
3602                 None => {}
3603                 Some(module) => {
3604                     let name_bindings =
3605                         Rc::new(Resolver::create_name_bindings_from_module(module));
3606                     return Success((Target::new(module_,
3607                                                 name_bindings,
3608                                                 false),
3609                                     false));
3610                 }
3611             }
3612         }
3613
3614         // We're out of luck.
3615         debug!("(resolving name in module) failed to resolve `{}`",
3616                token::get_name(name).get());
3617         return Failed(None);
3618     }
3619
3620     fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3621         let index = module_.resolved_import_count.get();
3622         let imports = module_.imports.borrow();
3623         let import_count = imports.len();
3624         if index != import_count {
3625             let sn = self.session
3626                          .codemap()
3627                          .span_to_snippet(imports.get(index).span)
3628                          .unwrap();
3629             if sn.as_slice().contains("::") {
3630                 self.resolve_error(imports.get(index).span,
3631                                    "unresolved import");
3632             } else {
3633                 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3634                                   sn.as_slice().slice(0, sn.len()));
3635                 self.resolve_error(imports.get(index).span, err.as_slice());
3636             }
3637         }
3638
3639         // Descend into children and anonymous children.
3640         self.populate_module_if_necessary(&module_);
3641
3642         for (_, child_node) in module_.children.borrow().iter() {
3643             match child_node.get_module_if_available() {
3644                 None => {
3645                     // Continue.
3646                 }
3647                 Some(child_module) => {
3648                     self.report_unresolved_imports(child_module);
3649                 }
3650             }
3651         }
3652
3653         for (_, module_) in module_.anonymous_children.borrow().iter() {
3654             self.report_unresolved_imports(module_.clone());
3655         }
3656     }
3657
3658     // Export recording
3659     //
3660     // This pass simply determines what all "export" keywords refer to and
3661     // writes the results into the export map.
3662     //
3663     // FIXME #4953 This pass will be removed once exports change to per-item.
3664     // Then this operation can simply be performed as part of item (or import)
3665     // processing.
3666
3667     fn record_exports(&mut self) {
3668         let root_module = self.graph_root.get_module();
3669         self.record_exports_for_module_subtree(root_module);
3670     }
3671
3672     fn record_exports_for_module_subtree(&mut self,
3673                                              module_: Rc<Module>) {
3674         // If this isn't a local krate, then bail out. We don't need to record
3675         // exports for nonlocal crates.
3676
3677         match module_.def_id.get() {
3678             Some(def_id) if def_id.krate == LOCAL_CRATE => {
3679                 // OK. Continue.
3680                 debug!("(recording exports for module subtree) recording \
3681                         exports for local module `{}`",
3682                        self.module_to_string(&*module_));
3683             }
3684             None => {
3685                 // Record exports for the root module.
3686                 debug!("(recording exports for module subtree) recording \
3687                         exports for root module `{}`",
3688                        self.module_to_string(&*module_));
3689             }
3690             Some(_) => {
3691                 // Bail out.
3692                 debug!("(recording exports for module subtree) not recording \
3693                         exports for `{}`",
3694                        self.module_to_string(&*module_));
3695                 return;
3696             }
3697         }
3698
3699         self.record_exports_for_module(&*module_);
3700         self.populate_module_if_necessary(&module_);
3701
3702         for (_, child_name_bindings) in module_.children.borrow().iter() {
3703             match child_name_bindings.get_module_if_available() {
3704                 None => {
3705                     // Nothing to do.
3706                 }
3707                 Some(child_module) => {
3708                     self.record_exports_for_module_subtree(child_module);
3709                 }
3710             }
3711         }
3712
3713         for (_, child_module) in module_.anonymous_children.borrow().iter() {
3714             self.record_exports_for_module_subtree(child_module.clone());
3715         }
3716     }
3717
3718     fn record_exports_for_module(&mut self, module_: &Module) {
3719         let mut exports2 = Vec::new();
3720
3721         self.add_exports_for_module(&mut exports2, module_);
3722         match module_.def_id.get() {
3723             Some(def_id) => {
3724                 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3725                 debug!("(computing exports) writing exports for {} (some)",
3726                        def_id.node);
3727             }
3728             None => {}
3729         }
3730     }
3731
3732     fn add_exports_of_namebindings(&mut self,
3733                                    exports2: &mut Vec<Export2> ,
3734                                    name: Name,
3735                                    namebindings: &NameBindings,
3736                                    ns: Namespace) {
3737         match namebindings.def_for_namespace(ns) {
3738             Some(d) => {
3739                 let name = token::get_name(name);
3740                 debug!("(computing exports) YES: export '{}' => {:?}",
3741                        name, d.def_id());
3742                 exports2.push(Export2 {
3743                     name: name.get().to_string(),
3744                     def_id: d.def_id()
3745                 });
3746             }
3747             d_opt => {
3748                 debug!("(computing exports) NO: {:?}", d_opt);
3749             }
3750         }
3751     }
3752
3753     fn add_exports_for_module(&mut self,
3754                               exports2: &mut Vec<Export2> ,
3755                               module_: &Module) {
3756         for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3757             if !importresolution.is_public {
3758                 continue
3759             }
3760             let xs = [TypeNS, ValueNS];
3761             for &ns in xs.iter() {
3762                 match importresolution.target_for_namespace(ns) {
3763                     Some(target) => {
3764                         debug!("(computing exports) maybe export '{}'",
3765                                token::get_name(*name));
3766                         self.add_exports_of_namebindings(exports2,
3767                                                          *name,
3768                                                          &*target.bindings,
3769                                                          ns)
3770                     }
3771                     _ => ()
3772                 }
3773             }
3774         }
3775     }
3776
3777     // AST resolution
3778     //
3779     // We maintain a list of value ribs and type ribs.
3780     //
3781     // Simultaneously, we keep track of the current position in the module
3782     // graph in the `current_module` pointer. When we go to resolve a name in
3783     // the value or type namespaces, we first look through all the ribs and
3784     // then query the module graph. When we resolve a name in the module
3785     // namespace, we can skip all the ribs (since nested modules are not
3786     // allowed within blocks in Rust) and jump straight to the current module
3787     // graph node.
3788     //
3789     // Named implementations are handled separately. When we find a method
3790     // call, we consult the module node to find all of the implementations in
3791     // scope. This information is lazily cached in the module node. We then
3792     // generate a fake "implementation scope" containing all the
3793     // implementations thus found, for compatibility with old resolve pass.
3794
3795     fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3796         let orig_module = self.current_module.clone();
3797
3798         // Move down in the graph.
3799         match name {
3800             None => {
3801                 // Nothing to do.
3802             }
3803             Some(name) => {
3804                 self.populate_module_if_necessary(&orig_module);
3805
3806                 match orig_module.children.borrow().find(&name.name) {
3807                     None => {
3808                         debug!("!!! (with scope) didn't find `{}` in `{}`",
3809                                token::get_ident(name),
3810                                self.module_to_string(&*orig_module));
3811                     }
3812                     Some(name_bindings) => {
3813                         match (*name_bindings).get_module_if_available() {
3814                             None => {
3815                                 debug!("!!! (with scope) didn't find module \
3816                                         for `{}` in `{}`",
3817                                        token::get_ident(name),
3818                                        self.module_to_string(&*orig_module));
3819                             }
3820                             Some(module_) => {
3821                                 self.current_module = module_;
3822                             }
3823                         }
3824                     }
3825                 }
3826             }
3827         }
3828
3829         f(self);
3830
3831         self.current_module = orig_module;
3832     }
3833
3834     /// Wraps the given definition in the appropriate number of `DefUpvar`
3835     /// wrappers.
3836     fn upvarify(&self,
3837                 ribs: &[Rib],
3838                 def_like: DefLike,
3839                 span: Span)
3840                 -> Option<DefLike> {
3841         match def_like {
3842             DlDef(d @ DefUpvar(..)) => {
3843                 self.session.span_bug(span,
3844                     format!("unexpected {} in bindings", d).as_slice())
3845             }
3846             DlDef(d @ DefLocal(_)) => {
3847                 let node_id = d.def_id().node;
3848                 let mut def = d;
3849                 let mut last_proc_body_id = ast::DUMMY_NODE_ID;
3850                 for rib in ribs.iter() {
3851                     match rib.kind {
3852                         NormalRibKind => {
3853                             // Nothing to do. Continue.
3854                         }
3855                         ClosureRibKind(function_id, maybe_proc_body) => {
3856                             let prev_def = def;
3857                             if maybe_proc_body != ast::DUMMY_NODE_ID {
3858                                 last_proc_body_id = maybe_proc_body;
3859                             }
3860                             def = DefUpvar(node_id, function_id, last_proc_body_id);
3861
3862                             let mut seen = self.freevars_seen.borrow_mut();
3863                             let seen = seen.find_or_insert(function_id, NodeSet::new());
3864                             if seen.contains(&node_id) {
3865                                 continue;
3866                             }
3867                             self.freevars.borrow_mut().find_or_insert(function_id, vec![])
3868                                          .push(Freevar { def: prev_def, span: span });
3869                             seen.insert(node_id);
3870                         }
3871                         MethodRibKind(item_id, _) => {
3872                             // If the def is a ty param, and came from the parent
3873                             // item, it's ok
3874                             match def {
3875                                 DefTyParam(_, did, _) if {
3876                                     self.def_map.borrow().find_copy(&did.node)
3877                                         == Some(DefTyParamBinder(item_id))
3878                                 } => {} // ok
3879                                 DefSelfTy(did) if did == item_id => {} // ok
3880                                 _ => {
3881                                     // This was an attempt to access an upvar inside a
3882                                     // named function item. This is not allowed, so we
3883                                     // report an error.
3884
3885                                     self.resolve_error(
3886                                         span,
3887                                         "can't capture dynamic environment in a fn item; \
3888                                         use the || { ... } closure form instead");
3889
3890                                     return None;
3891                                 }
3892                             }
3893                         }
3894                         ItemRibKind => {
3895                             // This was an attempt to access an upvar inside a
3896                             // named function item. This is not allowed, so we
3897                             // report an error.
3898
3899                             self.resolve_error(
3900                                 span,
3901                                 "can't capture dynamic environment in a fn item; \
3902                                 use the || { ... } closure form instead");
3903
3904                             return None;
3905                         }
3906                         ConstantItemRibKind => {
3907                             // Still doesn't deal with upvars
3908                             self.resolve_error(span,
3909                                                "attempt to use a non-constant \
3910                                                 value in a constant");
3911
3912                         }
3913                     }
3914                 }
3915                 Some(DlDef(def))
3916             }
3917             DlDef(def @ DefTyParam(..)) |
3918             DlDef(def @ DefSelfTy(..)) => {
3919                 for rib in ribs.iter() {
3920                     match rib.kind {
3921                         NormalRibKind | ClosureRibKind(..) => {
3922                             // Nothing to do. Continue.
3923                         }
3924                         MethodRibKind(item_id, _) => {
3925                             // If the def is a ty param, and came from the parent
3926                             // item, it's ok
3927                             match def {
3928                                 DefTyParam(_, did, _) if {
3929                                     self.def_map.borrow().find_copy(&did.node)
3930                                         == Some(DefTyParamBinder(item_id))
3931                                 } => {} // ok
3932                                 DefSelfTy(did) if did == item_id => {} // ok
3933
3934                                 _ => {
3935                                     // This was an attempt to use a type parameter outside
3936                                     // its scope.
3937
3938                                     self.resolve_error(span,
3939                                                         "can't use type parameters from \
3940                                                         outer function; try using a local \
3941                                                         type parameter instead");
3942
3943                                     return None;
3944                                 }
3945                             }
3946                         }
3947                         ItemRibKind => {
3948                             // This was an attempt to use a type parameter outside
3949                             // its scope.
3950
3951                             self.resolve_error(span,
3952                                                "can't use type parameters from \
3953                                                 outer function; try using a local \
3954                                                 type parameter instead");
3955
3956                             return None;
3957                         }
3958                         ConstantItemRibKind => {
3959                             // see #9186
3960                             self.resolve_error(span,
3961                                                "cannot use an outer type \
3962                                                 parameter in this context");
3963
3964                         }
3965                     }
3966                 }
3967                 Some(DlDef(def))
3968             }
3969             _ => Some(def_like)
3970         }
3971     }
3972
3973     fn search_ribs(&self,
3974                    ribs: &[Rib],
3975                    name: Name,
3976                    span: Span)
3977                    -> Option<DefLike> {
3978         // FIXME #4950: Try caching?
3979
3980         for (i, rib) in ribs.iter().enumerate().rev() {
3981             match rib.bindings.borrow().find_copy(&name) {
3982                 Some(def_like) => {
3983                     return self.upvarify(ribs.slice_from(i + 1), def_like, span);
3984                 }
3985                 None => {
3986                     // Continue.
3987                 }
3988             }
3989         }
3990
3991         None
3992     }
3993
3994     fn resolve_crate(&mut self, krate: &ast::Crate) {
3995         debug!("(resolving crate) starting");
3996
3997         visit::walk_crate(self, krate);
3998     }
3999
4000     fn resolve_item(&mut self, item: &Item) {
4001         debug!("(resolving item) resolving {}",
4002                token::get_ident(item.ident));
4003
4004         match item.node {
4005
4006             // enum item: resolve all the variants' discrs,
4007             // then resolve the ty params
4008             ItemEnum(ref enum_def, ref generics) => {
4009                 for variant in (*enum_def).variants.iter() {
4010                     for dis_expr in variant.node.disr_expr.iter() {
4011                         // resolve the discriminator expr
4012                         // as a constant
4013                         self.with_constant_rib(|this| {
4014                             this.resolve_expr(&**dis_expr);
4015                         });
4016                     }
4017                 }
4018
4019                 // n.b. the discr expr gets visited twice.
4020                 // but maybe it's okay since the first time will signal an
4021                 // error if there is one? -- tjc
4022                 self.with_type_parameter_rib(HasTypeParameters(generics,
4023                                                                TypeSpace,
4024                                                                item.id,
4025                                                                ItemRibKind),
4026                                              |this| {
4027                     this.resolve_type_parameters(&generics.ty_params);
4028                     this.resolve_where_clause(&generics.where_clause);
4029                     visit::walk_item(this, item);
4030                 });
4031             }
4032
4033             ItemTy(_, ref generics) => {
4034                 self.with_type_parameter_rib(HasTypeParameters(generics,
4035                                                                TypeSpace,
4036                                                                item.id,
4037                                                                ItemRibKind),
4038                                              |this| {
4039                     this.resolve_type_parameters(&generics.ty_params);
4040                     visit::walk_item(this, item);
4041                 });
4042             }
4043
4044             ItemImpl(ref generics,
4045                      ref implemented_traits,
4046                      ref self_type,
4047                      ref impl_items) => {
4048                 self.resolve_implementation(item.id,
4049                                             generics,
4050                                             implemented_traits,
4051                                             &**self_type,
4052                                             impl_items.as_slice());
4053             }
4054
4055             ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
4056                 // Create a new rib for the self type.
4057                 let self_type_rib = Rib::new(ItemRibKind);
4058
4059                 // plain insert (no renaming, types are not currently hygienic....)
4060                 let name = self.type_self_name;
4061                 self_type_rib.bindings.borrow_mut()
4062                              .insert(name, DlDef(DefSelfTy(item.id)));
4063                 self.type_ribs.borrow_mut().push(self_type_rib);
4064
4065                 // Create a new rib for the trait-wide type parameters.
4066                 self.with_type_parameter_rib(HasTypeParameters(generics,
4067                                                                TypeSpace,
4068                                                                item.id,
4069                                                                NormalRibKind),
4070                                              |this| {
4071                     this.resolve_type_parameters(&generics.ty_params);
4072                     this.resolve_where_clause(&generics.where_clause);
4073
4074                     this.resolve_type_parameter_bounds(item.id, bounds,
4075                                                        TraitDerivation);
4076
4077                     match unbound {
4078                         &Some(ast::TraitTyParamBound(ref tpb)) => {
4079                             this.resolve_trait_reference(item.id, tpb, TraitDerivation);
4080                         }
4081                         _ => {}
4082                     }
4083
4084                     for method in (*methods).iter() {
4085                         // Create a new rib for the method-specific type
4086                         // parameters.
4087                         //
4088                         // FIXME #4951: Do we need a node ID here?
4089
4090                         match *method {
4091                           ast::RequiredMethod(ref ty_m) => {
4092                             this.with_type_parameter_rib
4093                                 (HasTypeParameters(&ty_m.generics,
4094                                                    FnSpace,
4095                                                    item.id,
4096                                         MethodRibKind(item.id, RequiredMethod)),
4097                                  |this| {
4098
4099                                 // Resolve the method-specific type
4100                                 // parameters.
4101                                 this.resolve_type_parameters(
4102                                     &ty_m.generics.ty_params);
4103                                 this.resolve_where_clause(&ty_m.generics
4104                                                                .where_clause);
4105
4106                                 for argument in ty_m.decl.inputs.iter() {
4107                                     this.resolve_type(&*argument.ty);
4108                                 }
4109
4110                                 match ty_m.explicit_self.node {
4111                                     SelfExplicit(ref typ, _) => {
4112                                         this.resolve_type(&**typ)
4113                                     }
4114                                     _ => {}
4115                                 }
4116
4117                                 this.resolve_type(&*ty_m.decl.output);
4118                             });
4119                           }
4120                           ast::ProvidedMethod(ref m) => {
4121                               this.resolve_method(MethodRibKind(item.id,
4122                                                                 ProvidedMethod(m.id)),
4123                                                   &**m)
4124                           }
4125                           ast::TypeTraitItem(_) => {
4126                               visit::walk_trait_item(this, method);
4127                           }
4128                         }
4129                     }
4130                 });
4131
4132                 self.type_ribs.borrow_mut().pop();
4133             }
4134
4135             ItemStruct(ref struct_def, ref generics) => {
4136                 self.resolve_struct(item.id,
4137                                     generics,
4138                                     &struct_def.super_struct,
4139                                     struct_def.fields.as_slice());
4140             }
4141
4142             ItemMod(ref module_) => {
4143                 self.with_scope(Some(item.ident), |this| {
4144                     this.resolve_module(module_, item.span, item.ident,
4145                                         item.id);
4146                 });
4147             }
4148
4149             ItemForeignMod(ref foreign_module) => {
4150                 self.with_scope(Some(item.ident), |this| {
4151                     for foreign_item in foreign_module.items.iter() {
4152                         match foreign_item.node {
4153                             ForeignItemFn(_, ref generics) => {
4154                                 this.with_type_parameter_rib(
4155                                     HasTypeParameters(
4156                                         generics, FnSpace, foreign_item.id,
4157                                         ItemRibKind),
4158                                     |this| visit::walk_foreign_item(this,
4159                                                                     &**foreign_item));
4160                             }
4161                             ForeignItemStatic(..) => {
4162                                 visit::walk_foreign_item(this,
4163                                                          &**foreign_item);
4164                             }
4165                         }
4166                     }
4167                 });
4168             }
4169
4170             ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4171                 self.resolve_function(ItemRibKind,
4172                                       Some(&**fn_decl),
4173                                       HasTypeParameters
4174                                         (generics,
4175                                          FnSpace,
4176                                          item.id,
4177                                          ItemRibKind),
4178                                       &**block);
4179             }
4180
4181             ItemStatic(..) => {
4182                 self.with_constant_rib(|this| {
4183                     visit::walk_item(this, item);
4184                 });
4185             }
4186
4187            ItemMac(..) => {
4188                 // do nothing, these are just around to be encoded
4189            }
4190         }
4191     }
4192
4193     fn with_type_parameter_rib(&mut self,
4194                                type_parameters: TypeParameters,
4195                                f: |&mut Resolver|) {
4196         match type_parameters {
4197             HasTypeParameters(generics, space, node_id,
4198                               rib_kind) => {
4199
4200                 let function_type_rib = Rib::new(rib_kind);
4201
4202                 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4203                     let ident = type_parameter.ident;
4204                     debug!("with_type_parameter_rib: {} {}", node_id,
4205                            type_parameter.id);
4206                     let def_like = DlDef(DefTyParam(space,
4207                                                     local_def(type_parameter.id),
4208                                                     index));
4209                     // Associate this type parameter with
4210                     // the item that bound it
4211                     self.record_def(type_parameter.id,
4212                                     (DefTyParamBinder(node_id), LastMod(AllPublic)));
4213                     // plain insert (no renaming)
4214                     function_type_rib.bindings.borrow_mut()
4215                                      .insert(ident.name, def_like);
4216                 }
4217                 self.type_ribs.borrow_mut().push(function_type_rib);
4218             }
4219
4220             NoTypeParameters => {
4221                 // Nothing to do.
4222             }
4223         }
4224
4225         f(self);
4226
4227         match type_parameters {
4228             HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
4229             NoTypeParameters => { }
4230         }
4231     }
4232
4233     fn with_label_rib(&mut self, f: |&mut Resolver|) {
4234         self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4235         f(self);
4236         self.label_ribs.borrow_mut().pop();
4237     }
4238
4239     fn with_constant_rib(&mut self, f: |&mut Resolver|) {
4240         self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4241         self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4242         f(self);
4243         self.type_ribs.borrow_mut().pop();
4244         self.value_ribs.borrow_mut().pop();
4245     }
4246
4247     fn resolve_function(&mut self,
4248                         rib_kind: RibKind,
4249                         optional_declaration: Option<&FnDecl>,
4250                         type_parameters: TypeParameters,
4251                         block: &Block) {
4252         // Create a value rib for the function.
4253         let function_value_rib = Rib::new(rib_kind);
4254         self.value_ribs.borrow_mut().push(function_value_rib);
4255
4256         // Create a label rib for the function.
4257         let function_label_rib = Rib::new(rib_kind);
4258         self.label_ribs.borrow_mut().push(function_label_rib);
4259
4260         // If this function has type parameters, add them now.
4261         self.with_type_parameter_rib(type_parameters, |this| {
4262             // Resolve the type parameters.
4263             match type_parameters {
4264                 NoTypeParameters => {
4265                     // Continue.
4266                 }
4267                 HasTypeParameters(ref generics, _, _, _) => {
4268                     this.resolve_type_parameters(&generics.ty_params);
4269                     this.resolve_where_clause(&generics.where_clause);
4270                 }
4271             }
4272
4273             // Add each argument to the rib.
4274             match optional_declaration {
4275                 None => {
4276                     // Nothing to do.
4277                 }
4278                 Some(declaration) => {
4279                     for argument in declaration.inputs.iter() {
4280                         let mut bindings_list = HashMap::new();
4281                         this.resolve_pattern(&*argument.pat,
4282                                              ArgumentIrrefutableMode,
4283                                              &mut bindings_list);
4284
4285                         this.resolve_type(&*argument.ty);
4286
4287                         debug!("(resolving function) recorded argument");
4288                     }
4289
4290                     this.resolve_type(&*declaration.output);
4291                 }
4292             }
4293
4294             // Resolve the function body.
4295             this.resolve_block(&*block);
4296
4297             debug!("(resolving function) leaving function");
4298         });
4299
4300         self.label_ribs.borrow_mut().pop();
4301         self.value_ribs.borrow_mut().pop();
4302     }
4303
4304     fn resolve_type_parameters(&mut self,
4305                                type_parameters: &OwnedSlice<TyParam>) {
4306         for type_parameter in type_parameters.iter() {
4307             for bound in type_parameter.bounds.iter() {
4308                 self.resolve_type_parameter_bound(type_parameter.id, bound,
4309                                                   TraitBoundingTypeParameter);
4310             }
4311             match &type_parameter.unbound {
4312                 &Some(ref unbound) =>
4313                     self.resolve_type_parameter_bound(
4314                         type_parameter.id, unbound, TraitBoundingTypeParameter),
4315                 &None => {}
4316             }
4317             match type_parameter.default {
4318                 Some(ref ty) => self.resolve_type(&**ty),
4319                 None => {}
4320             }
4321         }
4322     }
4323
4324     fn resolve_type_parameter_bounds(&mut self,
4325                                      id: NodeId,
4326                                      type_parameter_bounds: &OwnedSlice<TyParamBound>,
4327                                      reference_type: TraitReferenceType) {
4328         for type_parameter_bound in type_parameter_bounds.iter() {
4329             self.resolve_type_parameter_bound(id, type_parameter_bound,
4330                                               reference_type);
4331         }
4332     }
4333
4334     fn resolve_type_parameter_bound(&mut self,
4335                                     id: NodeId,
4336                                     type_parameter_bound: &TyParamBound,
4337                                     reference_type: TraitReferenceType) {
4338         match *type_parameter_bound {
4339             TraitTyParamBound(ref tref) => {
4340                 self.resolve_trait_reference(id, tref, reference_type)
4341             }
4342             UnboxedFnTyParamBound(ref unboxed_function) => {
4343                 match self.resolve_path(unboxed_function.ref_id,
4344                                         &unboxed_function.path,
4345                                         TypeNS,
4346                                         true) {
4347                     None => {
4348                         let path_str = self.path_idents_to_string(
4349                             &unboxed_function.path);
4350                         self.resolve_error(unboxed_function.path.span,
4351                                            format!("unresolved trait `{}`",
4352                                                    path_str).as_slice())
4353                     }
4354                     Some(def) => {
4355                         match def {
4356                             (DefTrait(_), _) => {
4357                                 self.record_def(unboxed_function.ref_id, def);
4358                             }
4359                             _ => {
4360                                 let msg =
4361                                     format!("`{}` is not a trait",
4362                                             self.path_idents_to_string(
4363                                                 &unboxed_function.path));
4364                                 self.resolve_error(unboxed_function.path.span,
4365                                                    msg.as_slice());
4366                             }
4367                         }
4368                     }
4369                 }
4370
4371                 for argument in unboxed_function.decl.inputs.iter() {
4372                     self.resolve_type(&*argument.ty);
4373                 }
4374
4375                 self.resolve_type(&*unboxed_function.decl.output);
4376             }
4377             RegionTyParamBound(..) => {}
4378         }
4379     }
4380
4381     fn resolve_trait_reference(&mut self,
4382                                id: NodeId,
4383                                trait_reference: &TraitRef,
4384                                reference_type: TraitReferenceType) {
4385         match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4386             None => {
4387                 let path_str = self.path_idents_to_string(&trait_reference.path);
4388                 let usage_str = match reference_type {
4389                     TraitBoundingTypeParameter => "bound type parameter with",
4390                     TraitImplementation        => "implement",
4391                     TraitDerivation            => "derive",
4392                 };
4393
4394                 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4395                 self.resolve_error(trait_reference.path.span, msg.as_slice());
4396             }
4397             Some(def) => {
4398                 match def {
4399                     (DefTrait(_), _) => {
4400                         debug!("(resolving trait) found trait def: {:?}", def);
4401                         self.record_def(trait_reference.ref_id, def);
4402                     }
4403                     (def, _) => {
4404                         self.resolve_error(trait_reference.path.span,
4405                                            format!("`{}` is not a trait",
4406                                                    self.path_idents_to_string(
4407                                                         &trait_reference.path)));
4408
4409                         // If it's a typedef, give a note
4410                         match def {
4411                             DefTy(..) => {
4412                                 self.session.span_note(
4413                                                 trait_reference.path.span,
4414                                                 format!("`type` aliases cannot \
4415                                                         be used for traits")
4416                                                         .as_slice());
4417                             }
4418                             _ => {}
4419                         }
4420                     }
4421                 }
4422
4423             }
4424         }
4425     }
4426
4427     fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4428         for predicate in where_clause.predicates.iter() {
4429             match self.resolve_identifier(predicate.ident,
4430                                           TypeNS,
4431                                           true,
4432                                           predicate.span) {
4433                 Some((def @ DefTyParam(_, _, _), last_private)) => {
4434                     self.record_def(predicate.id, (def, last_private));
4435                 }
4436                 _ => {
4437                     self.resolve_error(
4438                         predicate.span,
4439                         format!("undeclared type parameter `{}`",
4440                                 token::get_ident(
4441                                     predicate.ident)).as_slice());
4442                 }
4443             }
4444
4445             for bound in predicate.bounds.iter() {
4446                 self.resolve_type_parameter_bound(predicate.id, bound,
4447                                                   TraitBoundingTypeParameter);
4448             }
4449         }
4450     }
4451
4452     fn resolve_struct(&mut self,
4453                       id: NodeId,
4454                       generics: &Generics,
4455                       super_struct: &Option<P<Ty>>,
4456                       fields: &[StructField]) {
4457         // If applicable, create a rib for the type parameters.
4458         self.with_type_parameter_rib(HasTypeParameters(generics,
4459                                                        TypeSpace,
4460                                                        id,
4461                                                        ItemRibKind),
4462                                      |this| {
4463             // Resolve the type parameters.
4464             this.resolve_type_parameters(&generics.ty_params);
4465             this.resolve_where_clause(&generics.where_clause);
4466
4467             // Resolve the super struct.
4468             match *super_struct {
4469                 Some(ref t) => match t.node {
4470                     TyPath(ref path, None, path_id) => {
4471                         match this.resolve_path(id, path, TypeNS, true) {
4472                             Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
4473                                 let def = DefStruct(def_id);
4474                                 debug!("(resolving struct) resolved `{}` to type {:?}",
4475                                        token::get_ident(path.segments
4476                                                             .last().unwrap()
4477                                                             .identifier),
4478                                        def);
4479                                 debug!("(resolving struct) writing resolution for `{}` (id {})",
4480                                        this.path_idents_to_string(path),
4481                                        path_id);
4482                                 this.record_def(path_id, (def, lp));
4483                             }
4484                             Some((DefStruct(_), _)) => {
4485                                 span_err!(this.session, t.span, E0154,
4486                                     "super-struct is defined in a different crate");
4487                             },
4488                             Some(_) => {
4489                                 span_err!(this.session, t.span, E0155,
4490                                     "super-struct is not a struct type");
4491                             }
4492                             None => {
4493                                 span_err!(this.session, t.span, E0156,
4494                                     "super-struct could not be resolved");
4495                             }
4496                         }
4497                     },
4498                     _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4499                 },
4500                 None => {}
4501             }
4502
4503             // Resolve fields.
4504             for field in fields.iter() {
4505                 this.resolve_type(&*field.node.ty);
4506             }
4507         });
4508     }
4509
4510     // Does this really need to take a RibKind or is it always going
4511     // to be NormalRibKind?
4512     fn resolve_method(&mut self,
4513                       rib_kind: RibKind,
4514                       method: &ast::Method) {
4515         let method_generics = method.pe_generics();
4516         let type_parameters = HasTypeParameters(method_generics,
4517                                                 FnSpace,
4518                                                 method.id,
4519                                                 rib_kind);
4520
4521         match method.pe_explicit_self().node {
4522             SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
4523             _ => {}
4524         }
4525
4526         self.resolve_function(rib_kind,
4527                               Some(method.pe_fn_decl()),
4528                               type_parameters,
4529                               method.pe_body());
4530     }
4531
4532     fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4533         // Handle nested impls (inside fn bodies)
4534         let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4535         let result = f(self);
4536         self.current_self_type = previous_value;
4537         result
4538     }
4539
4540     fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4541                                   opt_trait_ref: &Option<TraitRef>,
4542                                   f: |&mut Resolver| -> T) -> T {
4543         let new_val = match *opt_trait_ref {
4544             Some(ref trait_ref) => {
4545                 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4546
4547                 match self.def_map.borrow().find(&trait_ref.ref_id) {
4548                     Some(def) => {
4549                         let did = def.def_id();
4550                         Some((did, trait_ref.clone()))
4551                     }
4552                     None => None
4553                 }
4554             }
4555             None => None
4556         };
4557         let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4558         let result = f(self);
4559         self.current_trait_ref = original_trait_ref;
4560         result
4561     }
4562
4563     fn resolve_implementation(&mut self,
4564                               id: NodeId,
4565                               generics: &Generics,
4566                               opt_trait_reference: &Option<TraitRef>,
4567                               self_type: &Ty,
4568                               impl_items: &[ImplItem]) {
4569         // If applicable, create a rib for the type parameters.
4570         self.with_type_parameter_rib(HasTypeParameters(generics,
4571                                                        TypeSpace,
4572                                                        id,
4573                                                        NormalRibKind),
4574                                      |this| {
4575             // Resolve the type parameters.
4576             this.resolve_type_parameters(&generics.ty_params);
4577             this.resolve_where_clause(&generics.where_clause);
4578
4579             // Resolve the trait reference, if necessary.
4580             this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4581                 // Resolve the self type.
4582                 this.resolve_type(self_type);
4583
4584                 this.with_current_self_type(self_type, |this| {
4585                     for impl_item in impl_items.iter() {
4586                         match *impl_item {
4587                             MethodImplItem(ref method) => {
4588                                 // If this is a trait impl, ensure the method
4589                                 // exists in trait
4590                                 this.check_trait_item(method.pe_ident(),
4591                                                       method.span);
4592
4593                                 // We also need a new scope for the method-
4594                                 // specific type parameters.
4595                                 this.resolve_method(
4596                                     MethodRibKind(id,
4597                                                   ProvidedMethod(method.id)),
4598                                     &**method);
4599                             }
4600                             TypeImplItem(ref typedef) => {
4601                                 // If this is a trait impl, ensure the method
4602                                 // exists in trait
4603                                 this.check_trait_item(typedef.ident,
4604                                                       typedef.span);
4605
4606                                 this.resolve_type(&*typedef.typ);
4607                             }
4608                         }
4609                     }
4610                 });
4611             });
4612         });
4613     }
4614
4615     fn check_trait_item(&self, ident: Ident, span: Span) {
4616         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4617         for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4618             let method_name = ident.name;
4619
4620             if self.trait_item_map.borrow().find(&(method_name, did)).is_none() {
4621                 let path_str = self.path_idents_to_string(&trait_ref.path);
4622                 self.resolve_error(span,
4623                                     format!("method `{}` is not a member of trait `{}`",
4624                                             token::get_name(method_name),
4625                                             path_str).as_slice());
4626             }
4627         }
4628     }
4629
4630     fn resolve_module(&mut self, module: &Mod, _span: Span,
4631                       _name: Ident, id: NodeId) {
4632         // Write the implementations in scope into the module metadata.
4633         debug!("(resolving module) resolving module ID {}", id);
4634         visit::walk_mod(self, module);
4635     }
4636
4637     fn resolve_local(&mut self, local: &Local) {
4638         // Resolve the type.
4639         self.resolve_type(&*local.ty);
4640
4641         // Resolve the initializer, if necessary.
4642         match local.init {
4643             None => {
4644                 // Nothing to do.
4645             }
4646             Some(ref initializer) => {
4647                 self.resolve_expr(&**initializer);
4648             }
4649         }
4650
4651         // Resolve the pattern.
4652         let mut bindings_list = HashMap::new();
4653         self.resolve_pattern(&*local.pat,
4654                              LocalIrrefutableMode,
4655                              &mut bindings_list);
4656     }
4657
4658     // build a map from pattern identifiers to binding-info's.
4659     // this is done hygienically. This could arise for a macro
4660     // that expands into an or-pattern where one 'x' was from the
4661     // user and one 'x' came from the macro.
4662     fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4663         let mut result = HashMap::new();
4664         pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4665             let name = mtwt::resolve(path1.node);
4666             result.insert(name,
4667                           binding_info {span: sp,
4668                                         binding_mode: binding_mode});
4669         });
4670         return result;
4671     }
4672
4673     // check that all of the arms in an or-pattern have exactly the
4674     // same set of bindings, with the same binding modes for each.
4675     fn check_consistent_bindings(&mut self, arm: &Arm) {
4676         if arm.pats.len() == 0 {
4677             return
4678         }
4679         let map_0 = self.binding_mode_map(&**arm.pats.get(0));
4680         for (i, p) in arm.pats.iter().enumerate() {
4681             let map_i = self.binding_mode_map(&**p);
4682
4683             for (&key, &binding_0) in map_0.iter() {
4684                 match map_i.find(&key) {
4685                   None => {
4686                     self.resolve_error(
4687                         p.span,
4688                         format!("variable `{}` from pattern #1 is \
4689                                   not bound in pattern #{}",
4690                                 token::get_name(key),
4691                                 i + 1).as_slice());
4692                   }
4693                   Some(binding_i) => {
4694                     if binding_0.binding_mode != binding_i.binding_mode {
4695                         self.resolve_error(
4696                             binding_i.span,
4697                             format!("variable `{}` is bound with different \
4698                                       mode in pattern #{} than in pattern #1",
4699                                     token::get_name(key),
4700                                     i + 1).as_slice());
4701                     }
4702                   }
4703                 }
4704             }
4705
4706             for (&key, &binding) in map_i.iter() {
4707                 if !map_0.contains_key(&key) {
4708                     self.resolve_error(
4709                         binding.span,
4710                         format!("variable `{}` from pattern {}{} is \
4711                                   not bound in pattern {}1",
4712                                 token::get_name(key),
4713                                 "#", i + 1, "#").as_slice());
4714                 }
4715             }
4716         }
4717     }
4718
4719     fn resolve_arm(&mut self, arm: &Arm) {
4720         self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4721
4722         let mut bindings_list = HashMap::new();
4723         for pattern in arm.pats.iter() {
4724             self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4725         }
4726
4727         // This has to happen *after* we determine which
4728         // pat_idents are variants
4729         self.check_consistent_bindings(arm);
4730
4731         visit::walk_expr_opt(self, &arm.guard);
4732         self.resolve_expr(&*arm.body);
4733
4734         self.value_ribs.borrow_mut().pop();
4735     }
4736
4737     fn resolve_block(&mut self, block: &Block) {
4738         debug!("(resolving block) entering block");
4739         self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4740
4741         // Move down in the graph, if there's an anonymous module rooted here.
4742         let orig_module = self.current_module.clone();
4743         match orig_module.anonymous_children.borrow().find(&block.id) {
4744             None => { /* Nothing to do. */ }
4745             Some(anonymous_module) => {
4746                 debug!("(resolving block) found anonymous module, moving \
4747                         down");
4748                 self.current_module = anonymous_module.clone();
4749             }
4750         }
4751
4752         // Descend into the block.
4753         visit::walk_block(self, block);
4754
4755         // Move back up.
4756         self.current_module = orig_module;
4757
4758         self.value_ribs.borrow_mut().pop();
4759         debug!("(resolving block) leaving block");
4760     }
4761
4762     fn resolve_type(&mut self, ty: &Ty) {
4763         match ty.node {
4764             // Like path expressions, the interpretation of path types depends
4765             // on whether the path has multiple elements in it or not.
4766
4767             TyPath(ref path, ref bounds, path_id) => {
4768                 // This is a path in the type namespace. Walk through scopes
4769                 // looking for it.
4770                 let mut result_def = None;
4771
4772                 // First, check to see whether the name is a primitive type.
4773                 if path.segments.len() == 1 {
4774                     let id = path.segments.last().unwrap().identifier;
4775
4776                     match self.primitive_type_table
4777                             .primitive_types
4778                             .find(&id.name) {
4779
4780                         Some(&primitive_type) => {
4781                             result_def =
4782                                 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4783
4784                             if path.segments
4785                                    .iter()
4786                                    .any(|s| !s.lifetimes.is_empty()) {
4787                                 span_err!(self.session, path.span, E0157,
4788                                     "lifetime parameters are not allowed on this type");
4789                             } else if path.segments
4790                                           .iter()
4791                                           .any(|s| s.types.len() > 0) {
4792                                 span_err!(self.session, path.span, E0153,
4793                                     "type parameters are not allowed on this type");
4794                             }
4795                         }
4796                         None => {
4797                             // Continue.
4798                         }
4799                     }
4800                 }
4801
4802                 match result_def {
4803                     None => {
4804                         match self.resolve_path(ty.id, path, TypeNS, true) {
4805                             Some(def) => {
4806                                 debug!("(resolving type) resolved `{}` to \
4807                                         type {:?}",
4808                                        token::get_ident(path.segments
4809                                                             .last().unwrap()
4810                                                             .identifier),
4811                                        def);
4812                                 result_def = Some(def);
4813                             }
4814                             None => {
4815                                 result_def = None;
4816                             }
4817                         }
4818                     }
4819                     Some(_) => {}   // Continue.
4820                 }
4821
4822                 match result_def {
4823                     Some(def) => {
4824                         // Write the result into the def map.
4825                         debug!("(resolving type) writing resolution for `{}` \
4826                                 (id {})",
4827                                self.path_idents_to_string(path),
4828                                path_id);
4829                         self.record_def(path_id, def);
4830                     }
4831                     None => {
4832                         let msg = format!("use of undeclared type name `{}`",
4833                                           self.path_idents_to_string(path));
4834                         self.resolve_error(ty.span, msg.as_slice());
4835                     }
4836                 }
4837
4838                 bounds.as_ref().map(|bound_vec| {
4839                     self.resolve_type_parameter_bounds(ty.id, bound_vec,
4840                                                        TraitBoundingTypeParameter);
4841                 });
4842             }
4843
4844             TyQPath(ref qpath) => {
4845                 self.resolve_type(&*qpath.for_type);
4846
4847                 let current_module = self.current_module.clone();
4848                 let module_path_idents: Vec<_> =
4849                     qpath.trait_name
4850                          .segments
4851                          .iter()
4852                          .map(|ps| ps.identifier)
4853                          .collect();
4854                 match self.resolve_module_path(
4855                         current_module,
4856                         module_path_idents.as_slice(),
4857                         UseLexicalScope,
4858                         qpath.trait_name.span,
4859                         PathSearch) {
4860                     Success((ref module, _)) if module.kind.get() ==
4861                             TraitModuleKind => {
4862                         match self.resolve_definition_of_name_in_module(
4863                                 (*module).clone(),
4864                                 qpath.item_name.name,
4865                                 TypeNS) {
4866                             ChildNameDefinition(def, lp) |
4867                             ImportNameDefinition(def, lp) => {
4868                                 match def {
4869                                     DefAssociatedTy(trait_type_id) => {
4870                                         let def = DefAssociatedTy(
4871                                             trait_type_id);
4872                                         self.record_def(ty.id, (def, lp));
4873                                     }
4874                                     _ => {
4875                                         self.resolve_error(
4876                                             ty.span,
4877                                             "not an associated type");
4878                                     }
4879                                 }
4880                             }
4881                             NoNameDefinition => {
4882                                 self.resolve_error(ty.span,
4883                                                    "unresolved associated \
4884                                                     type");
4885                             }
4886                         }
4887                     }
4888                     Success(..) => self.resolve_error(ty.span, "not a trait"),
4889                     Indeterminate => {
4890                         self.session.span_bug(ty.span,
4891                                               "indeterminate result when \
4892                                                resolving associated type")
4893                     }
4894                     Failed(error) => {
4895                         let (span, help) = match error {
4896                             Some((span, msg)) => (span, format!("; {}", msg)),
4897                             None => (ty.span, String::new()),
4898                         };
4899                         self.resolve_error(span,
4900                                            format!("unresolved trait: {}",
4901                                                    help).as_slice())
4902                     }
4903                 }
4904             }
4905
4906             TyClosure(ref c) | TyProc(ref c) => {
4907                 self.resolve_type_parameter_bounds(
4908                     ty.id,
4909                     &c.bounds,
4910                     TraitBoundingTypeParameter);
4911                 visit::walk_ty(self, ty);
4912             }
4913
4914             _ => {
4915                 // Just resolve embedded types.
4916                 visit::walk_ty(self, ty);
4917             }
4918         }
4919     }
4920
4921     fn resolve_pattern(&mut self,
4922                        pattern: &Pat,
4923                        mode: PatternBindingMode,
4924                        // Maps idents to the node ID for the (outermost)
4925                        // pattern that binds them
4926                        bindings_list: &mut HashMap<Name,NodeId>) {
4927         let pat_id = pattern.id;
4928         walk_pat(pattern, |pattern| {
4929             match pattern.node {
4930                 PatIdent(binding_mode, ref path1, _) => {
4931
4932                     // The meaning of pat_ident with no type parameters
4933                     // depends on whether an enum variant or unit-like struct
4934                     // with that name is in scope. The probing lookup has to
4935                     // be careful not to emit spurious errors. Only matching
4936                     // patterns (match) can match nullary variants or
4937                     // unit-like structs. For binding patterns (let), matching
4938                     // such a value is simply disallowed (since it's rarely
4939                     // what you want).
4940
4941                     let ident = path1.node;
4942                     let renamed = mtwt::resolve(ident);
4943
4944                     match self.resolve_bare_identifier_pattern(ident, pattern.span) {
4945                         FoundStructOrEnumVariant(ref def, lp)
4946                                 if mode == RefutableMode => {
4947                             debug!("(resolving pattern) resolving `{}` to \
4948                                     struct or enum variant",
4949                                    token::get_name(renamed));
4950
4951                             self.enforce_default_binding_mode(
4952                                 pattern,
4953                                 binding_mode,
4954                                 "an enum variant");
4955                             self.record_def(pattern.id, (def.clone(), lp));
4956                         }
4957                         FoundStructOrEnumVariant(..) => {
4958                             self.resolve_error(
4959                                 pattern.span,
4960                                 format!("declaration of `{}` shadows an enum \
4961                                          variant or unit-like struct in \
4962                                          scope",
4963                                         token::get_name(renamed)).as_slice());
4964                         }
4965                         FoundConst(ref def, lp) if mode == RefutableMode => {
4966                             debug!("(resolving pattern) resolving `{}` to \
4967                                     constant",
4968                                    token::get_name(renamed));
4969
4970                             self.enforce_default_binding_mode(
4971                                 pattern,
4972                                 binding_mode,
4973                                 "a constant");
4974                             self.record_def(pattern.id, (def.clone(), lp));
4975                         }
4976                         FoundConst(..) => {
4977                             self.resolve_error(pattern.span,
4978                                                   "only irrefutable patterns \
4979                                                    allowed here");
4980                         }
4981                         BareIdentifierPatternUnresolved => {
4982                             debug!("(resolving pattern) binding `{}`",
4983                                    token::get_name(renamed));
4984
4985                             let def = DefLocal(pattern.id);
4986
4987                             // Record the definition so that later passes
4988                             // will be able to distinguish variants from
4989                             // locals in patterns.
4990
4991                             self.record_def(pattern.id, (def, LastMod(AllPublic)));
4992
4993                             // Add the binding to the local ribs, if it
4994                             // doesn't already exist in the bindings list. (We
4995                             // must not add it if it's in the bindings list
4996                             // because that breaks the assumptions later
4997                             // passes make about or-patterns.)
4998
4999                             if !bindings_list.contains_key(&renamed) {
5000                                 let this = &mut *self;
5001                                 let value_ribs = this.value_ribs.borrow();
5002                                 let length = value_ribs.len();
5003                                 let last_rib = value_ribs.get(
5004                                     length - 1);
5005                                 last_rib.bindings.borrow_mut()
5006                                         .insert(renamed, DlDef(def));
5007                                 bindings_list.insert(renamed, pat_id);
5008                             } else if bindings_list.find(&renamed) ==
5009                                     Some(&pat_id) {
5010                                 // Then this is a duplicate variable in the
5011                                 // same disjunction, which is an error.
5012                                 self.resolve_error(pattern.span,
5013                                     format!("identifier `{}` is bound \
5014                                              more than once in the same \
5015                                              pattern",
5016                                             token::get_ident(ident)).as_slice());
5017                             }
5018                             // Else, not bound in the same pattern: do
5019                             // nothing.
5020                         }
5021                     }
5022                 }
5023
5024                 PatEnum(ref path, _) => {
5025                     // This must be an enum variant, struct or const.
5026                     match self.resolve_path(pat_id, path, ValueNS, false) {
5027                         Some(def @ (DefFn(..), _))      |
5028                         Some(def @ (DefVariant(..), _)) |
5029                         Some(def @ (DefStruct(..), _))  |
5030                         Some(def @ (DefStatic(..), _)) => {
5031                             self.record_def(pattern.id, def);
5032                         }
5033                         Some(_) => {
5034                             self.resolve_error(path.span,
5035                                 format!("`{}` is not an enum variant, struct or const",
5036                                     token::get_ident(
5037                                         path.segments
5038                                             .last()
5039                                             .unwrap()
5040                                             .identifier)).as_slice());
5041                         }
5042                         None => {
5043                             self.resolve_error(path.span,
5044                                 format!("unresolved enum variant, struct or const `{}`",
5045                                     token::get_ident(
5046                                         path.segments
5047                                             .last()
5048                                             .unwrap()
5049                                             .identifier)).as_slice());
5050                         }
5051                     }
5052
5053                     // Check the types in the path pattern.
5054                     for ty in path.segments
5055                                   .iter()
5056                                   .flat_map(|s| s.types.iter()) {
5057                         self.resolve_type(&**ty);
5058                     }
5059                 }
5060
5061                 PatLit(ref expr) => {
5062                     self.resolve_expr(&**expr);
5063                 }
5064
5065                 PatRange(ref first_expr, ref last_expr) => {
5066                     self.resolve_expr(&**first_expr);
5067                     self.resolve_expr(&**last_expr);
5068                 }
5069
5070                 PatStruct(ref path, _, _) => {
5071                     match self.resolve_path(pat_id, path, TypeNS, false) {
5072                         Some(definition) => {
5073                             self.record_def(pattern.id, definition);
5074                         }
5075                         result => {
5076                             debug!("(resolving pattern) didn't find struct \
5077                                     def: {:?}", result);
5078                             let msg = format!("`{}` does not name a structure",
5079                                               self.path_idents_to_string(path));
5080                             self.resolve_error(path.span, msg.as_slice());
5081                         }
5082                     }
5083                 }
5084
5085                 _ => {
5086                     // Nothing to do.
5087                 }
5088             }
5089             true
5090         });
5091     }
5092
5093     fn resolve_bare_identifier_pattern(&mut self, name: Ident, span: Span)
5094                                        -> BareIdentifierPatternResolution {
5095         let module = self.current_module.clone();
5096         match self.resolve_item_in_lexical_scope(module,
5097                                                  name,
5098                                                  ValueNS) {
5099             Success((target, _)) => {
5100                 debug!("(resolve bare identifier pattern) succeeded in \
5101                          finding {} at {:?}",
5102                         token::get_ident(name),
5103                         target.bindings.value_def.borrow());
5104                 match *target.bindings.value_def.borrow() {
5105                     None => {
5106                         fail!("resolved name in the value namespace to a \
5107                               set of name bindings with no def?!");
5108                     }
5109                     Some(def) => {
5110                         // For the two success cases, this lookup can be
5111                         // considered as not having a private component because
5112                         // the lookup happened only within the current module.
5113                         match def.def {
5114                             def @ DefVariant(..) | def @ DefStruct(..) => {
5115                                 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5116                             }
5117                             def @ DefStatic(_, false) => {
5118                                 return FoundConst(def, LastMod(AllPublic));
5119                             }
5120                             DefStatic(_, true) => {
5121                                 self.resolve_error(span,
5122                                     "mutable static variables cannot be referenced in a pattern");
5123                                 return BareIdentifierPatternUnresolved;
5124                             }
5125                             _ => {
5126                                 return BareIdentifierPatternUnresolved;
5127                             }
5128                         }
5129                     }
5130                 }
5131             }
5132
5133             Indeterminate => {
5134                 fail!("unexpected indeterminate result");
5135             }
5136             Failed(err) => {
5137                 match err {
5138                     Some((span, msg)) => {
5139                         self.resolve_error(span, format!("failed to resolve: {}",
5140                                                          msg));
5141                     }
5142                     None => ()
5143                 }
5144
5145                 debug!("(resolve bare identifier pattern) failed to find {}",
5146                         token::get_ident(name));
5147                 return BareIdentifierPatternUnresolved;
5148             }
5149         }
5150     }
5151
5152     /// If `check_ribs` is true, checks the local definitions first; i.e.
5153     /// doesn't skip straight to the containing module.
5154     fn resolve_path(&mut self,
5155                     id: NodeId,
5156                     path: &Path,
5157                     namespace: Namespace,
5158                     check_ribs: bool) -> Option<(Def, LastPrivate)> {
5159         // First, resolve the types.
5160         for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
5161             self.resolve_type(&**ty);
5162         }
5163
5164         if path.global {
5165             return self.resolve_crate_relative_path(path, namespace);
5166         }
5167
5168         let unqualified_def =
5169                 self.resolve_identifier(path.segments
5170                                             .last().unwrap()
5171                                             .identifier,
5172                                         namespace,
5173                                         check_ribs,
5174                                         path.span);
5175
5176         if path.segments.len() > 1 {
5177             let def = self.resolve_module_relative_path(path, namespace);
5178             match (def, unqualified_def) {
5179                 (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5180                     self.session
5181                         .add_lint(lint::builtin::UNNECESSARY_QUALIFICATION,
5182                                   id,
5183                                   path.span,
5184                                   "unnecessary qualification".to_string());
5185                 }
5186                 _ => ()
5187             }
5188
5189             return def;
5190         }
5191
5192         return unqualified_def;
5193     }
5194
5195     // resolve a single identifier (used as a varref)
5196     fn resolve_identifier(&mut self,
5197                               identifier: Ident,
5198                               namespace: Namespace,
5199                               check_ribs: bool,
5200                               span: Span)
5201                               -> Option<(Def, LastPrivate)> {
5202         if check_ribs {
5203             match self.resolve_identifier_in_local_ribs(identifier,
5204                                                       namespace,
5205                                                       span) {
5206                 Some(def) => {
5207                     return Some((def, LastMod(AllPublic)));
5208                 }
5209                 None => {
5210                     // Continue.
5211                 }
5212             }
5213         }
5214
5215         return self.resolve_item_by_identifier_in_lexical_scope(identifier,
5216                                                                 namespace);
5217     }
5218
5219     // FIXME #4952: Merge me with resolve_name_in_module?
5220     fn resolve_definition_of_name_in_module(&mut self,
5221                                             containing_module: Rc<Module>,
5222                                             name: Name,
5223                                             namespace: Namespace)
5224                                                 -> NameDefinition {
5225         // First, search children.
5226         self.populate_module_if_necessary(&containing_module);
5227
5228         match containing_module.children.borrow().find(&name) {
5229             Some(child_name_bindings) => {
5230                 match child_name_bindings.def_for_namespace(namespace) {
5231                     Some(def) => {
5232                         // Found it. Stop the search here.
5233                         let p = child_name_bindings.defined_in_public_namespace(
5234                                         namespace);
5235                         let lp = if p {LastMod(AllPublic)} else {
5236                             LastMod(DependsOn(def.def_id()))
5237                         };
5238                         return ChildNameDefinition(def, lp);
5239                     }
5240                     None => {}
5241                 }
5242             }
5243             None => {}
5244         }
5245
5246         // Next, search import resolutions.
5247         match containing_module.import_resolutions.borrow().find(&name) {
5248             Some(import_resolution) if import_resolution.is_public => {
5249                 match (*import_resolution).target_for_namespace(namespace) {
5250                     Some(target) => {
5251                         match target.bindings.def_for_namespace(namespace) {
5252                             Some(def) => {
5253                                 // Found it.
5254                                 let id = import_resolution.id(namespace);
5255                                 // track imports and extern crates as well
5256                                 self.used_imports.insert((id, namespace));
5257                                 match target.target_module.def_id.get() {
5258                                     Some(DefId{krate: kid, ..}) => {
5259                                         self.used_crates.insert(kid);
5260                                     },
5261                                     _ => {}
5262                                 }
5263                                 return ImportNameDefinition(def, LastMod(AllPublic));
5264                             }
5265                             None => {
5266                                 // This can happen with external impls, due to
5267                                 // the imperfect way we read the metadata.
5268                             }
5269                         }
5270                     }
5271                     None => {}
5272                 }
5273             }
5274             Some(..) | None => {} // Continue.
5275         }
5276
5277         // Finally, search through external children.
5278         if namespace == TypeNS {
5279             match containing_module.external_module_children.borrow()
5280                                    .find_copy(&name) {
5281                 None => {}
5282                 Some(module) => {
5283                     match module.def_id.get() {
5284                         None => {} // Continue.
5285                         Some(def_id) => {
5286                             // track used crates
5287                             self.used_crates.insert(def_id.krate);
5288                             let lp = if module.is_public {LastMod(AllPublic)} else {
5289                                 LastMod(DependsOn(def_id))
5290                             };
5291                             return ChildNameDefinition(DefMod(def_id), lp);
5292                         }
5293                     }
5294                 }
5295             }
5296         }
5297
5298         return NoNameDefinition;
5299     }
5300
5301     // resolve a "module-relative" path, e.g. a::b::c
5302     fn resolve_module_relative_path(&mut self,
5303                                         path: &Path,
5304                                         namespace: Namespace)
5305                                         -> Option<(Def, LastPrivate)> {
5306         let module_path_idents = path.segments.init().iter()
5307                                                      .map(|ps| ps.identifier)
5308                                                      .collect::<Vec<_>>();
5309
5310         let containing_module;
5311         let last_private;
5312         let module = self.current_module.clone();
5313         match self.resolve_module_path(module,
5314                                        module_path_idents.as_slice(),
5315                                        UseLexicalScope,
5316                                        path.span,
5317                                        PathSearch) {
5318             Failed(err) => {
5319                 let (span, msg) = match err {
5320                     Some((span, msg)) => (span, msg),
5321                     None => {
5322                         let msg = format!("Use of undeclared module `{}`",
5323                                           self.idents_to_string(
5324                                                module_path_idents.as_slice()));
5325                         (path.span, msg)
5326                     }
5327                 };
5328
5329                 self.resolve_error(span, format!("failed to resolve. {}",
5330                                                  msg.as_slice()));
5331                 return None;
5332             }
5333             Indeterminate => fail!("indeterminate unexpected"),
5334             Success((resulting_module, resulting_last_private)) => {
5335                 containing_module = resulting_module;
5336                 last_private = resulting_last_private;
5337             }
5338         }
5339
5340         let ident = path.segments.last().unwrap().identifier;
5341         let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5342                                                         ident.name,
5343                                                         namespace) {
5344             NoNameDefinition => {
5345                 // We failed to resolve the name. Report an error.
5346                 return None;
5347             }
5348             ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5349                 (def, last_private.or(lp))
5350             }
5351         };
5352         match containing_module.kind.get() {
5353             TraitModuleKind | ImplModuleKind => {
5354                 match containing_module.def_id.get() {
5355                     Some(def_id) => {
5356                         match self.trait_item_map.borrow().find(&(ident.name, def_id)) {
5357                             Some(&StaticMethodTraitItemKind) => (),
5358                             Some(&TypeTraitItemKind) => (),
5359                             None => (),
5360                             Some(&NonstaticMethodTraitItemKind) => {
5361                                 debug!("containing module was a trait or impl \
5362                                 and name was a method -> not resolved");
5363                                 return None;
5364                             }
5365                         }
5366                     },
5367                     _ => (),
5368                 }
5369             },
5370             _ => (),
5371         }
5372         match containing_module.def_id.get() {
5373             Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
5374             _ => {}
5375         }
5376         return Some(def);
5377     }
5378
5379     /// Invariant: This must be called only during main resolution, not during
5380     /// import resolution.
5381     fn resolve_crate_relative_path(&mut self,
5382                                    path: &Path,
5383                                    namespace: Namespace)
5384                                        -> Option<(Def, LastPrivate)> {
5385         let module_path_idents = path.segments.init().iter()
5386                                                      .map(|ps| ps.identifier)
5387                                                      .collect::<Vec<_>>();
5388
5389         let root_module = self.graph_root.get_module();
5390
5391         let containing_module;
5392         let last_private;
5393         match self.resolve_module_path_from_root(root_module,
5394                                                  module_path_idents.as_slice(),
5395                                                  0,
5396                                                  path.span,
5397                                                  PathSearch,
5398                                                  LastMod(AllPublic)) {
5399             Failed(err) => {
5400                 let (span, msg) = match err {
5401                     Some((span, msg)) => (span, msg),
5402                     None => {
5403                         let msg = format!("Use of undeclared module `::{}`",
5404                                           self.idents_to_string(
5405                                                module_path_idents.as_slice()));
5406                         (path.span, msg)
5407                     }
5408                 };
5409
5410                 self.resolve_error(span, format!("failed to resolve. {}",
5411                                                  msg.as_slice()));
5412                 return None;
5413             }
5414
5415             Indeterminate => {
5416                 fail!("indeterminate unexpected");
5417             }
5418
5419             Success((resulting_module, resulting_last_private)) => {
5420                 containing_module = resulting_module;
5421                 last_private = resulting_last_private;
5422             }
5423         }
5424
5425         let name = path.segments.last().unwrap().identifier.name;
5426         match self.resolve_definition_of_name_in_module(containing_module,
5427                                                         name,
5428                                                         namespace) {
5429             NoNameDefinition => {
5430                 // We failed to resolve the name. Report an error.
5431                 return None;
5432             }
5433             ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5434                 return Some((def, last_private.or(lp)));
5435             }
5436         }
5437     }
5438
5439     fn resolve_identifier_in_local_ribs(&mut self,
5440                                             ident: Ident,
5441                                             namespace: Namespace,
5442                                             span: Span)
5443                                             -> Option<Def> {
5444         // Check the local set of ribs.
5445         let search_result = match namespace {
5446             ValueNS => {
5447                 let renamed = mtwt::resolve(ident);
5448                 self.search_ribs(self.value_ribs.borrow().as_slice(),
5449                                  renamed, span)
5450             }
5451             TypeNS => {
5452                 let name = ident.name;
5453                 self.search_ribs(self.type_ribs.borrow().as_slice(), name, span)
5454             }
5455         };
5456
5457         match search_result {
5458             Some(DlDef(def)) => {
5459                 debug!("(resolving path in local ribs) resolved `{}` to \
5460                         local: {:?}",
5461                        token::get_ident(ident),
5462                        def);
5463                 return Some(def);
5464             }
5465             Some(DlField) | Some(DlImpl(_)) | None => {
5466                 return None;
5467             }
5468         }
5469     }
5470
5471     fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5472                                                    ident: Ident,
5473                                                    namespace: Namespace)
5474                                                 -> Option<(Def, LastPrivate)> {
5475         // Check the items.
5476         let module = self.current_module.clone();
5477         match self.resolve_item_in_lexical_scope(module,
5478                                                  ident,
5479                                                  namespace) {
5480             Success((target, _)) => {
5481                 match (*target.bindings).def_for_namespace(namespace) {
5482                     None => {
5483                         // This can happen if we were looking for a type and
5484                         // found a module instead. Modules don't have defs.
5485                         debug!("(resolving item path by identifier in lexical \
5486                                  scope) failed to resolve {} after success...",
5487                                  token::get_ident(ident));
5488                         return None;
5489                     }
5490                     Some(def) => {
5491                         debug!("(resolving item path in lexical scope) \
5492                                 resolved `{}` to item",
5493                                token::get_ident(ident));
5494                         // This lookup is "all public" because it only searched
5495                         // for one identifier in the current module (couldn't
5496                         // have passed through reexports or anything like that.
5497                         return Some((def, LastMod(AllPublic)));
5498                     }
5499                 }
5500             }
5501             Indeterminate => {
5502                 fail!("unexpected indeterminate result");
5503             }
5504             Failed(err) => {
5505                 match err {
5506                     Some((span, msg)) =>
5507                         self.resolve_error(span, format!("failed to resolve. {}", msg)),
5508                     None => ()
5509                 }
5510
5511                 debug!("(resolving item path by identifier in lexical scope) \
5512                          failed to resolve {}", token::get_ident(ident));
5513                 return None;
5514             }
5515         }
5516     }
5517
5518     fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5519         self.emit_errors = false;
5520         let rs = f(self);
5521         self.emit_errors = true;
5522         rs
5523     }
5524
5525     fn resolve_error<T: Str>(&self, span: Span, s: T) {
5526         if self.emit_errors {
5527             self.session.span_err(span, s.as_slice());
5528         }
5529     }
5530
5531     fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5532         #[deriving(PartialEq)]
5533         enum FallbackChecks {
5534             Everything,
5535             OnlyTraitAndStatics
5536         }
5537
5538         fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5539                                                     -> Option<(Path, NodeId, FallbackChecks)> {
5540             match t.node {
5541                 TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
5542                 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5543                 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5544                 // This doesn't handle the remaining `Ty` variants as they are not
5545                 // that commonly the self_type, it might be interesting to provide
5546                 // support for those in future.
5547                 _ => None,
5548             }
5549         }
5550
5551         fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
5552                             -> Option<Rc<Module>> {
5553             let root = this.current_module.clone();
5554             let last_name = ident_path.last().unwrap().name;
5555
5556             if ident_path.len() == 1 {
5557                 match this.primitive_type_table.primitive_types.find(&last_name) {
5558                     Some(_) => None,
5559                     None => {
5560                         match this.current_module.children.borrow().find(&last_name) {
5561                             Some(child) => child.get_module_if_available(),
5562                             None => None
5563                         }
5564                     }
5565                 }
5566             } else {
5567                 match this.resolve_module_path(root,
5568                                                 ident_path.as_slice(),
5569                                                 UseLexicalScope,
5570                                                 span,
5571                                                 PathSearch) {
5572                     Success((module, _)) => Some(module),
5573                     _ => None
5574                 }
5575             }
5576         }
5577
5578         let (path, node_id, allowed) = match self.current_self_type {
5579             Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5580                 Some(x) => x,
5581                 None => return NoSuggestion,
5582             },
5583             None => return NoSuggestion,
5584         };
5585
5586         if allowed == Everything {
5587             // Look for a field with the same name in the current self_type.
5588             match self.def_map.borrow().find(&node_id) {
5589                  Some(&DefTy(did, _))
5590                 | Some(&DefStruct(did))
5591                 | Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
5592                     None => {}
5593                     Some(fields) => {
5594                         if fields.iter().any(|&field_name| name == field_name) {
5595                             return Field;
5596                         }
5597                     }
5598                 },
5599                 _ => {} // Self type didn't resolve properly
5600             }
5601         }
5602
5603         let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
5604
5605         // Look for a method in the current self type's impl module.
5606         match get_module(self, path.span, ident_path.as_slice()) {
5607             Some(module) => match module.children.borrow().find(&name) {
5608                 Some(binding) => {
5609                     let p_str = self.path_idents_to_string(&path);
5610                     match binding.def_for_namespace(ValueNS) {
5611                         Some(DefStaticMethod(_, provenance, _)) => {
5612                             match provenance {
5613                                 FromImpl(_) => return StaticMethod(p_str),
5614                                 FromTrait(_) => unreachable!()
5615                             }
5616                         }
5617                         Some(DefMethod(_, None)) if allowed == Everything => return Method,
5618                         Some(DefMethod(_, Some(_))) => return TraitItem,
5619                         _ => ()
5620                     }
5621                 }
5622                 None => {}
5623             },
5624             None => {}
5625         }
5626
5627         // Look for a method in the current trait.
5628         let trait_item_map = self.trait_item_map.borrow();
5629         match self.current_trait_ref {
5630             Some((did, ref trait_ref)) => {
5631                 let path_str = self.path_idents_to_string(&trait_ref.path);
5632
5633                 match trait_item_map.find(&(name, did)) {
5634                     Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
5635                     Some(_) => return TraitItem,
5636                     None => {}
5637                 }
5638             }
5639             None => {}
5640         }
5641
5642         NoSuggestion
5643     }
5644
5645     fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5646                                 -> Option<String> {
5647         let this = &mut *self;
5648
5649         let mut maybes: Vec<token::InternedString> = Vec::new();
5650         let mut values: Vec<uint> = Vec::new();
5651
5652         let mut j = this.value_ribs.borrow().len();
5653         while j != 0 {
5654             j -= 1;
5655             let value_ribs = this.value_ribs.borrow();
5656             let bindings = value_ribs.get(j).bindings.borrow();
5657             for (&k, _) in bindings.iter() {
5658                 maybes.push(token::get_name(k));
5659                 values.push(uint::MAX);
5660             }
5661         }
5662
5663         let mut smallest = 0;
5664         for (i, other) in maybes.iter().enumerate() {
5665             *values.get_mut(i) = name.lev_distance(other.get());
5666
5667             if *values.get(i) <= *values.get(smallest) {
5668                 smallest = i;
5669             }
5670         }
5671
5672         if values.len() > 0 &&
5673             *values.get(smallest) != uint::MAX &&
5674             *values.get(smallest) < name.len() + 2 &&
5675             *values.get(smallest) <= max_distance &&
5676             name != maybes.get(smallest).get() {
5677
5678             Some(maybes.get(smallest).get().to_string())
5679
5680         } else {
5681             None
5682         }
5683     }
5684
5685     fn resolve_expr(&mut self, expr: &Expr) {
5686         // First, record candidate traits for this expression if it could
5687         // result in the invocation of a method call.
5688
5689         self.record_candidate_traits_for_expr_if_necessary(expr);
5690
5691         // Next, resolve the node.
5692         match expr.node {
5693             // The interpretation of paths depends on whether the path has
5694             // multiple elements in it or not.
5695
5696             ExprPath(ref path) => {
5697                 // This is a local path in the value namespace. Walk through
5698                 // scopes looking for it.
5699
5700                 match self.resolve_path(expr.id, path, ValueNS, true) {
5701                     Some(def) => {
5702                         // Write the result into the def map.
5703                         debug!("(resolving expr) resolved `{}`",
5704                                self.path_idents_to_string(path));
5705
5706                         // First-class methods are not supported yet; error
5707                         // out here.
5708                         match def {
5709                             (DefMethod(..), _) => {
5710                                 self.resolve_error(expr.span,
5711                                                       "first-class methods \
5712                                                        are not supported");
5713                                 self.session.span_note(expr.span,
5714                                                        "call the method \
5715                                                         using the `.` \
5716                                                         syntax");
5717                             }
5718                             _ => {}
5719                         }
5720
5721                         self.record_def(expr.id, def);
5722                     }
5723                     None => {
5724                         let wrong_name = self.path_idents_to_string(path);
5725                         // Be helpful if the name refers to a struct
5726                         // (The pattern matching def_tys where the id is in self.structs
5727                         // matches on regular structs while excluding tuple- and enum-like
5728                         // structs, which wouldn't result in this error.)
5729                         match self.with_no_errors(|this|
5730                             this.resolve_path(expr.id, path, TypeNS, false)) {
5731                             Some((DefTy(struct_id, _), _))
5732                               if self.structs.contains_key(&struct_id) => {
5733                                 self.resolve_error(expr.span,
5734                                         format!("`{}` is a structure name, but \
5735                                                  this expression \
5736                                                  uses it like a function name",
5737                                                 wrong_name).as_slice());
5738
5739                                 self.session.span_note(expr.span,
5740                                     format!("Did you mean to write: \
5741                                             `{} {{ /* fields */ }}`?",
5742                                             wrong_name).as_slice());
5743
5744                             }
5745                             _ => {
5746                                 let mut method_scope = false;
5747                                 self.value_ribs.borrow().iter().rev().all(|rib| {
5748                                     let res = match *rib {
5749                                         Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5750                                         Rib { bindings: _, kind: ItemRibKind } => false,
5751                                         _ => return true, // Keep advancing
5752                                     };
5753
5754                                     method_scope = res;
5755                                     false // Stop advancing
5756                                 });
5757
5758                                 if method_scope && token::get_name(self.self_name).get()
5759                                                                    == wrong_name.as_slice() {
5760                                         self.resolve_error(
5761                                             expr.span,
5762                                             "`self` is not available \
5763                                              in a static method. Maybe a \
5764                                              `self` argument is missing?");
5765                                 } else {
5766                                     let last_name = path.segments.last().unwrap().identifier.name;
5767                                     let mut msg = match self.find_fallback_in_self_type(last_name) {
5768                                         NoSuggestion => {
5769                                             // limit search to 5 to reduce the number
5770                                             // of stupid suggestions
5771                                             self.find_best_match_for_name(wrong_name.as_slice(), 5)
5772                                                                 .map_or("".to_string(),
5773                                                                         |x| format!("`{}`", x))
5774                                         }
5775                                         Field =>
5776                                             format!("`self.{}`", wrong_name),
5777                                         Method
5778                                         | TraitItem =>
5779                                             format!("to call `self.{}`", wrong_name),
5780                                         StaticTraitMethod(path_str)
5781                                         | StaticMethod(path_str) =>
5782                                             format!("to call `{}::{}`", path_str, wrong_name)
5783                                     };
5784
5785                                     if msg.len() > 0 {
5786                                         msg = format!(" Did you mean {}?", msg)
5787                                     }
5788
5789                                     self.resolve_error(
5790                                         expr.span,
5791                                         format!("unresolved name `{}`.{}",
5792                                                 wrong_name,
5793                                                 msg).as_slice());
5794                                 }
5795                             }
5796                         }
5797                     }
5798                 }
5799
5800                 visit::walk_expr(self, expr);
5801             }
5802
5803             ExprFnBlock(_, ref fn_decl, ref block) => {
5804                 // NOTE(stage0): After snapshot, change to:
5805                 //
5806                 //self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
5807                 self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByRef);
5808                 self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
5809                                       Some(&**fn_decl), NoTypeParameters,
5810                                       &**block);
5811             }
5812             ExprProc(ref fn_decl, ref block) => {
5813                 self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByValue);
5814                 self.resolve_function(ClosureRibKind(expr.id, block.id),
5815                                       Some(&**fn_decl), NoTypeParameters,
5816                                       &**block);
5817             }
5818             ExprUnboxedFn(capture_clause, _, ref fn_decl, ref block) => {
5819                 self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
5820                 self.resolve_function(ClosureRibKind(expr.id, block.id),
5821                                       Some(&**fn_decl), NoTypeParameters,
5822                                       &**block);
5823             }
5824
5825             ExprStruct(ref path, _, _) => {
5826                 // Resolve the path to the structure it goes to. We don't
5827                 // check to ensure that the path is actually a structure; that
5828                 // is checked later during typeck.
5829                 match self.resolve_path(expr.id, path, TypeNS, false) {
5830                     Some(definition) => self.record_def(expr.id, definition),
5831                     result => {
5832                         debug!("(resolving expression) didn't find struct \
5833                                 def: {:?}", result);
5834                         let msg = format!("`{}` does not name a structure",
5835                                           self.path_idents_to_string(path));
5836                         self.resolve_error(path.span, msg.as_slice());
5837                     }
5838                 }
5839
5840                 visit::walk_expr(self, expr);
5841             }
5842
5843             ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5844                 self.with_label_rib(|this| {
5845                     let def_like = DlDef(DefLabel(expr.id));
5846
5847                     {
5848                         let label_ribs = this.label_ribs.borrow();
5849                         let length = label_ribs.len();
5850                         let rib = label_ribs.get(length - 1);
5851                         let renamed = mtwt::resolve(label);
5852                         rib.bindings.borrow_mut().insert(renamed, def_like);
5853                     }
5854
5855                     visit::walk_expr(this, expr);
5856                 })
5857             }
5858
5859             ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5860                 self.resolve_expr(&**head);
5861
5862                 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
5863
5864                 self.resolve_pattern(&**pattern,
5865                                      LocalIrrefutableMode,
5866                                      &mut HashMap::new());
5867
5868                 match optional_label {
5869                     None => {}
5870                     Some(label) => {
5871                         self.label_ribs
5872                             .borrow_mut()
5873                             .push(Rib::new(NormalRibKind));
5874                         let def_like = DlDef(DefLabel(expr.id));
5875
5876                         {
5877                             let label_ribs = self.label_ribs.borrow();
5878                             let length = label_ribs.len();
5879                             let rib = label_ribs.get(length - 1);
5880                             let renamed = mtwt::resolve(label);
5881                             rib.bindings.borrow_mut().insert(renamed,
5882                                                              def_like);
5883                         }
5884                     }
5885                 }
5886
5887                 self.resolve_block(&**body);
5888
5889                 if optional_label.is_some() {
5890                     drop(self.label_ribs.borrow_mut().pop())
5891                 }
5892
5893                 self.value_ribs.borrow_mut().pop();
5894             }
5895
5896             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5897                 let renamed = mtwt::resolve(label);
5898                 match self.search_ribs(self.label_ribs.borrow().as_slice(),
5899                                        renamed, expr.span) {
5900                     None => {
5901                         self.resolve_error(
5902                             expr.span,
5903                             format!("use of undeclared label `{}`",
5904                                     token::get_ident(label)).as_slice())
5905                     }
5906                     Some(DlDef(def @ DefLabel(_))) => {
5907                         // Since this def is a label, it is never read.
5908                         self.record_def(expr.id, (def, LastMod(AllPublic)))
5909                     }
5910                     Some(_) => {
5911                         self.session.span_bug(expr.span,
5912                                               "label wasn't mapped to a \
5913                                                label def!")
5914                     }
5915                 }
5916             }
5917
5918             _ => {
5919                 visit::walk_expr(self, expr);
5920             }
5921         }
5922     }
5923
5924     fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5925         match expr.node {
5926             ExprField(_, ident, _) => {
5927                 // FIXME(#6890): Even though you can't treat a method like a
5928                 // field, we need to add any trait methods we find that match
5929                 // the field name so that we can do some nice error reporting
5930                 // later on in typeck.
5931                 let traits = self.search_for_traits_containing_method(ident.node.name);
5932                 self.trait_map.insert(expr.id, traits);
5933             }
5934             ExprMethodCall(ident, _, _) => {
5935                 debug!("(recording candidate traits for expr) recording \
5936                         traits for {}",
5937                        expr.id);
5938                 let traits = self.search_for_traits_containing_method(ident.node.name);
5939                 self.trait_map.insert(expr.id, traits);
5940             }
5941             _ => {
5942                 // Nothing to do.
5943             }
5944         }
5945     }
5946
5947     fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5948         debug!("(searching for traits containing method) looking for '{}'",
5949                token::get_name(name));
5950
5951         fn add_trait_info(found_traits: &mut Vec<DefId>,
5952                           trait_def_id: DefId,
5953                           name: Name) {
5954             debug!("(adding trait info) found trait {}:{} for method '{}'",
5955                 trait_def_id.krate,
5956                 trait_def_id.node,
5957                 token::get_name(name));
5958             found_traits.push(trait_def_id);
5959         }
5960
5961         let mut found_traits = Vec::new();
5962         let mut search_module = self.current_module.clone();
5963         loop {
5964             // Look for the current trait.
5965             match self.current_trait_ref {
5966                 Some((trait_def_id, _)) => {
5967                     let trait_item_map = self.trait_item_map.borrow();
5968
5969                     if trait_item_map.contains_key(&(name, trait_def_id)) {
5970                         add_trait_info(&mut found_traits, trait_def_id, name);
5971                     }
5972                 }
5973                 None => {} // Nothing to do.
5974             }
5975
5976             // Look for trait children.
5977             self.populate_module_if_necessary(&search_module);
5978
5979             {
5980                 let trait_item_map = self.trait_item_map.borrow();
5981                 for (_, child_names) in search_module.children.borrow().iter() {
5982                     let def = match child_names.def_for_namespace(TypeNS) {
5983                         Some(def) => def,
5984                         None => continue
5985                     };
5986                     let trait_def_id = match def {
5987                         DefTrait(trait_def_id) => trait_def_id,
5988                         _ => continue,
5989                     };
5990                     if trait_item_map.contains_key(&(name, trait_def_id)) {
5991                         add_trait_info(&mut found_traits, trait_def_id, name);
5992                     }
5993                 }
5994             }
5995
5996             // Look for imports.
5997             for (_, import) in search_module.import_resolutions.borrow().iter() {
5998                 let target = match import.target_for_namespace(TypeNS) {
5999                     None => continue,
6000                     Some(target) => target,
6001                 };
6002                 let did = match target.bindings.def_for_namespace(TypeNS) {
6003                     Some(DefTrait(trait_def_id)) => trait_def_id,
6004                     Some(..) | None => continue,
6005                 };
6006                 if self.trait_item_map.borrow().contains_key(&(name, did)) {
6007                     add_trait_info(&mut found_traits, did, name);
6008                     self.used_imports.insert((import.type_id, TypeNS));
6009                     match target.target_module.def_id.get() {
6010                         Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
6011                         _ => {}
6012                     }
6013                 }
6014             }
6015
6016             match search_module.parent_link.clone() {
6017                 NoParentLink | ModuleParentLink(..) => break,
6018                 BlockParentLink(parent_module, _) => {
6019                     search_module = parent_module.upgrade().unwrap();
6020                 }
6021             }
6022         }
6023
6024         found_traits
6025     }
6026
6027     fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
6028         debug!("(recording def) recording {:?} for {:?}, last private {:?}",
6029                 def, node_id, lp);
6030         assert!(match lp {LastImport{..} => false, _ => true},
6031                 "Import should only be used for `use` directives");
6032         self.last_private.insert(node_id, lp);
6033         self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
6034             // Resolve appears to "resolve" the same ID multiple
6035             // times, so here is a sanity check it at least comes to
6036             // the same conclusion! - nmatsakis
6037             if def != *old_value {
6038                 self.session
6039                     .bug(format!("node_id {:?} resolved first to {:?} and \
6040                                   then {:?}",
6041                                  node_id,
6042                                  *old_value,
6043                                  def).as_slice());
6044             }
6045         });
6046     }
6047
6048     fn enforce_default_binding_mode(&mut self,
6049                                         pat: &Pat,
6050                                         pat_binding_mode: BindingMode,
6051                                         descr: &str) {
6052         match pat_binding_mode {
6053             BindByValue(_) => {}
6054             BindByRef(..) => {
6055                 self.resolve_error(pat.span,
6056                                    format!("cannot use `ref` binding mode \
6057                                             with {}",
6058                                            descr).as_slice());
6059             }
6060         }
6061     }
6062
6063     //
6064     // Unused import checking
6065     //
6066     // Although this is mostly a lint pass, it lives in here because it depends on
6067     // resolve data structures and because it finalises the privacy information for
6068     // `use` directives.
6069     //
6070
6071     fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
6072         let mut visitor = UnusedImportCheckVisitor{ resolver: self };
6073         visit::walk_crate(&mut visitor, krate);
6074     }
6075
6076     fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
6077         // Ignore is_public import statements because there's no way to be sure
6078         // whether they're used or not. Also ignore imports with a dummy span
6079         // because this means that they were generated in some fashion by the
6080         // compiler and we don't need to consider them.
6081         if vi.vis == Public { return }
6082         if vi.span == DUMMY_SP { return }
6083
6084         match vi.node {
6085             ViewItemExternCrate(_, _, id) => {
6086                 match self.session.cstore.find_extern_mod_stmt_cnum(id)
6087                 {
6088                     Some(crate_num) => if !self.used_crates.contains(&crate_num) {
6089                     self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATE,
6090                                           id,
6091                                           vi.span,
6092                                           "unused extern crate".to_string());
6093                     },
6094                     _ => {}
6095                 }
6096             },
6097             ViewItemUse(ref p) => {
6098                 match p.node {
6099                     ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
6100
6101                     ViewPathList(_, ref list, _) => {
6102                         for i in list.iter() {
6103                             self.finalize_import(i.node.id(), i.span);
6104                         }
6105                     },
6106                     ViewPathGlob(_, id) => {
6107                         if !self.used_imports.contains(&(id, TypeNS)) &&
6108                            !self.used_imports.contains(&(id, ValueNS)) {
6109                             self.session
6110                                 .add_lint(lint::builtin::UNUSED_IMPORTS,
6111                                           id,
6112                                           p.span,
6113                                           "unused import".to_string());
6114                         }
6115                     },
6116                 }
6117             }
6118         }
6119     }
6120
6121     // We have information about whether `use` (import) directives are actually used now.
6122     // If an import is not used at all, we signal a lint error. If an import is only used
6123     // for a single namespace, we remove the other namespace from the recorded privacy
6124     // information. That means in privacy.rs, we will only check imports and namespaces
6125     // which are used. In particular, this means that if an import could name either a
6126     // public or private item, we will check the correct thing, dependent on how the import
6127     // is used.
6128     fn finalize_import(&mut self, id: NodeId, span: Span) {
6129         debug!("finalizing import uses for {}",
6130                self.session.codemap().span_to_snippet(span));
6131
6132         if !self.used_imports.contains(&(id, TypeNS)) &&
6133            !self.used_imports.contains(&(id, ValueNS)) {
6134             self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
6135                                   id,
6136                                   span,
6137                                   "unused import".to_string());
6138         }
6139
6140         let (v_priv, t_priv) = match self.last_private.find(&id) {
6141             Some(&LastImport {
6142                 value_priv: v,
6143                 value_used: _,
6144                 type_priv: t,
6145                 type_used: _
6146             }) => (v, t),
6147             Some(_) => {
6148                 fail!("we should only have LastImport for `use` directives")
6149             }
6150             _ => return,
6151         };
6152
6153         let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
6154             Used
6155         } else {
6156             Unused
6157         };
6158         let t_used = if self.used_imports.contains(&(id, TypeNS)) {
6159             Used
6160         } else {
6161             Unused
6162         };
6163
6164         match (v_priv, t_priv) {
6165             // Since some items may be both in the value _and_ type namespaces (e.g., structs)
6166             // we might have two LastPrivates pointing at the same thing. There is no point
6167             // checking both, so lets not check the value one.
6168             (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
6169             _ => {},
6170         }
6171
6172         self.last_private.insert(id, LastImport{value_priv: v_priv,
6173                                                 value_used: v_used,
6174                                                 type_priv: t_priv,
6175                                                 type_used: t_used});
6176     }
6177
6178     //
6179     // Diagnostics
6180     //
6181     // Diagnostics are not particularly efficient, because they're rarely
6182     // hit.
6183     //
6184
6185     /// A somewhat inefficient routine to obtain the name of a module.
6186     fn module_to_string(&self, module: &Module) -> String {
6187         let mut idents = Vec::new();
6188
6189         fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
6190             match module.parent_link {
6191                 NoParentLink => {}
6192                 ModuleParentLink(ref module, name) => {
6193                     idents.push(name);
6194                     collect_mod(idents, &*module.upgrade().unwrap());
6195                 }
6196                 BlockParentLink(ref module, _) => {
6197                     // danger, shouldn't be ident?
6198                     idents.push(special_idents::opaque);
6199                     collect_mod(idents, &*module.upgrade().unwrap());
6200                 }
6201             }
6202         }
6203         collect_mod(&mut idents, module);
6204
6205         if idents.len() == 0 {
6206             return "???".to_string();
6207         }
6208         self.idents_to_string(idents.into_iter().rev()
6209                                  .collect::<Vec<ast::Ident>>()
6210                                  .as_slice())
6211     }
6212
6213     #[allow(dead_code)]   // useful for debugging
6214     fn dump_module(&mut self, module_: Rc<Module>) {
6215         debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6216
6217         debug!("Children:");
6218         self.populate_module_if_necessary(&module_);
6219         for (&name, _) in module_.children.borrow().iter() {
6220             debug!("* {}", token::get_name(name));
6221         }
6222
6223         debug!("Import resolutions:");
6224         let import_resolutions = module_.import_resolutions.borrow();
6225         for (&name, import_resolution) in import_resolutions.iter() {
6226             let value_repr;
6227             match import_resolution.target_for_namespace(ValueNS) {
6228                 None => { value_repr = "".to_string(); }
6229                 Some(_) => {
6230                     value_repr = " value:?".to_string();
6231                     // FIXME #4954
6232                 }
6233             }
6234
6235             let type_repr;
6236             match import_resolution.target_for_namespace(TypeNS) {
6237                 None => { type_repr = "".to_string(); }
6238                 Some(_) => {
6239                     type_repr = " type:?".to_string();
6240                     // FIXME #4954
6241                 }
6242             }
6243
6244             debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6245         }
6246     }
6247 }
6248
6249 pub struct CrateMap {
6250     pub def_map: DefMap,
6251     pub freevars: RefCell<FreevarMap>,
6252     pub capture_mode_map: RefCell<CaptureModeMap>,
6253     pub exp_map2: ExportMap2,
6254     pub trait_map: TraitMap,
6255     pub external_exports: ExternalExports,
6256     pub last_private_map: LastPrivateMap,
6257 }
6258
6259 /// Entry point to crate resolution.
6260 pub fn resolve_crate(session: &Session,
6261                      _: &LanguageItems,
6262                      krate: &Crate)
6263                   -> CrateMap {
6264     let mut resolver = Resolver::new(session, krate.span);
6265     resolver.resolve(krate);
6266     CrateMap {
6267         def_map: resolver.def_map,
6268         freevars: resolver.freevars,
6269         capture_mode_map: resolver.capture_mode_map,
6270         exp_map2: resolver.export_map2,
6271         trait_map: resolver.trait_map,
6272         external_exports: resolver.external_exports,
6273         last_private_map: resolver.last_private,
6274     }
6275 }