lib.rs 252.0 KB
Newer Older
C
Chris Wong 已提交
1
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#![crate_name = "rustc_resolve"]
#![experimental]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
      html_favicon_url = "http://www.rust-lang.org/favicon.ico",
      html_root_url = "http://doc.rust-lang.org/nightly/")]

#![feature(globs, phase, slicing_syntax)]
#![feature(rustc_diagnostic_macros)]

#[phase(plugin, link)] extern crate log;
#[phase(plugin, link)] extern crate syntax;

extern crate rustc;

S
Steven Fackler 已提交
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::NamespaceError::*;
use self::NamespaceResult::*;
use self::NameDefinition::*;
use self::ImportDirectiveSubclass::*;
use self::ReducedGraphParent::*;
use self::ResolveResult::*;
use self::FallbackSuggestion::*;
use self::TypeParameters::*;
use self::RibKind::*;
use self::MethodSort::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::DuplicateCheckingMode::*;
use self::ParentLink::*;
use self::ModuleKind::*;
use self::TraitReferenceType::*;
use self::FallbackChecks::*;

49 50 51 52 53 54 55 56 57
use rustc::session::Session;
use rustc::lint;
use rustc::metadata::csearch;
use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use rustc::middle::def::*;
use rustc::middle::lang_items::LanguageItems;
use rustc::middle::pat_util::pat_bindings;
use rustc::middle::privacy::*;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
N
Nick Cameron 已提交
58
use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap, GlobMap};
59
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
A
Alex Crichton 已提交
60
use rustc::util::lev_distance::lev_distance;
61

62
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
63
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
64
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
65
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
66
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
67 68
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
N
Nick Cameron 已提交
69
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
70
use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
71
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
72
use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
N
Niko Matsakis 已提交
73
use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
74
use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
75 76
use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
77
use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
78
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
79
use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
80
use syntax::ast::{TypeImplItem, UnnamedField};
81
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
82 83
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Visibility};
P
Patrick Walton 已提交
84
use syntax::ast;
85
use syntax::ast_map;
86
use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
87
use syntax::attr::AttrMetaMethods;
88
use syntax::ext::mtwt;
89
use syntax::parse::token::{mod, special_names, special_idents};
K
klutzy 已提交
90
use syntax::codemap::{Span, DUMMY_SP, Pos};
91
use syntax::owned_slice::OwnedSlice;
92
use syntax::visit::{mod, Visitor};
93

94
use std::collections::{HashMap, HashSet};
C
Corey Farwell 已提交
95
use std::collections::hash_map::Entry::{Occupied, Vacant};
96
use std::cell::{Cell, RefCell};
97
use std::mem::replace;
E
Eduard Burtescu 已提交
98
use std::rc::{Rc, Weak};
99
use std::uint;
100

A
Alex Crichton 已提交
101 102
mod check_unused;
mod record_exports;
103

J
Jorge Aparicio 已提交
104
#[deriving(Copy)]
105
struct BindingInfo {
106
    span: Span,
107
    binding_mode: BindingMode,
108 109 110
}

// Map from the name in a pattern to its binding mode.
111
type BindingMap = HashMap<Name, BindingInfo>;
112

J
Jorge Aparicio 已提交
113
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
114
enum PatternBindingMode {
115
    RefutableMode,
116
    LocalIrrefutableMode,
117
    ArgumentIrrefutableMode,
118 119
}

J
Jorge Aparicio 已提交
120
#[deriving(Copy, PartialEq, Eq, Hash, Show)]
F
Felix S. Klock II 已提交
121
enum Namespace {
122
    TypeNS,
123
    ValueNS
124 125
}

J
Jorge Aparicio 已提交
126
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
127
enum NamespaceError {
128 129 130 131 132 133
    NoError,
    ModuleError,
    TypeError,
    ValueError
}

B
Brian Anderson 已提交
134 135 136
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
E
Eduard Burtescu 已提交
137
#[deriving(Clone)]
F
Felix S. Klock II 已提交
138
enum NamespaceResult {
T
Tim Chevalier 已提交
139 140 141
    /// Means that resolve hasn't gathered enough information yet to determine
    /// whether the name is bound in this namespace. (That is, it hasn't
    /// resolved all `use` directives yet.)
142
    UnknownResult,
B
Brian Anderson 已提交
143 144
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
145
    UnboundResult,
T
Tim Chevalier 已提交
146 147
    /// Means that resolve has determined that the name is bound in the Module
    /// argument, and specified by the NameBindings argument.
E
Eduard Burtescu 已提交
148
    BoundResult(Rc<Module>, Rc<NameBindings>)
149 150
}

151
impl NamespaceResult {
F
Felix S. Klock II 已提交
152
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
153
        match *self {
154 155 156 157
            UnknownResult => true,
            _ => false
        }
    }
158 159 160 161 162 163
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
            _ => false
        }
    }
164 165
}

F
Felix S. Klock II 已提交
166
enum NameDefinition {
167
    NoNameDefinition,           //< The name was unbound.
168 169
    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
170 171
}

172
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
173
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
174
        self.resolve_item(item);
175
    }
176
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
177
        self.resolve_arm(arm);
178
    }
179
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
180
        self.resolve_block(block);
181
    }
182
    fn visit_expr(&mut self, expr: &Expr) {
A
Alex Crichton 已提交
183
        self.resolve_expr(expr);
184
    }
185
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
186
        self.resolve_local(local);
187
    }
188
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
189
        self.resolve_type(ty);
190 191
    }
}
192

193
/// Contains data for specific types of import directives.
J
Jorge Aparicio 已提交
194
#[deriving(Copy)]
F
Felix S. Klock II 已提交
195
enum ImportDirectiveSubclass {
196
    SingleImport(Name /* target */, Name /* source */),
197 198 199
    GlobImport
}

200
/// The context that we thread through while building the reduced graph.
201
#[deriving(Clone)]
F
Felix S. Klock II 已提交
202
enum ReducedGraphParent {
E
Eduard Burtescu 已提交
203
    ModuleReducedGraphParent(Rc<Module>)
204 205
}

206
impl ReducedGraphParent {
E
Eduard Burtescu 已提交
207
    fn module(&self) -> Rc<Module> {
208
        match *self {
E
Eduard Burtescu 已提交
209 210
            ModuleReducedGraphParent(ref m) => {
                m.clone()
211 212 213 214 215
            }
        }
    }
}

216 217
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
218
enum ResolveResult<T> {
219 220 221
    Failed(ErrorMessage),   // Failed to resolve the name, optional helpful error message.
    Indeterminate,          // Couldn't determine due to unresolved globs.
    Success(T)              // Successfully resolved the import.
222 223
}

224
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
225
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
226
        match *self { Indeterminate => true, _ => false }
227 228 229
    }
}

230 231 232 233
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
234
    TraitItem,
235
    StaticMethod(String),
236
    TraitMethod(String),
237 238
}

J
Jorge Aparicio 已提交
239
#[deriving(Copy)]
E
Erik Price 已提交
240
enum TypeParameters<'a> {
241 242 243 244 245 246 247 248 249 250 251 252 253 254
    NoTypeParameters,
    HasTypeParameters(
        // Type parameters.
        &'a Generics,

        // Identifies the things that these parameters
        // were declared on (type, fn, etc)
        ParamSpace,

        // ID of the enclosing item.
        NodeId,

        // The kind of the rib used for type parameters.
        RibKind)
255 256
}

257 258
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
J
Jorge Aparicio 已提交
259
#[deriving(Copy, Show)]
F
Felix S. Klock II 已提交
260
enum RibKind {
261 262
    // No translation needs to be applied.
    NormalRibKind,
263

264 265
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
266
    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
267

268
    // We passed through an impl or trait and are now in one of its
269
    // methods. Allow references to ty params that impl or trait
270 271 272
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
              // parent;   method itself
273
    MethodRibKind(NodeId, MethodSort),
274

275 276
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
277 278 279

    // We're in a constant item. Can't refer to dynamic stuff.
    ConstantItemRibKind
280 281
}

282
// Methods can be required or provided. RequiredMethod methods only occur in traits.
J
Jorge Aparicio 已提交
283
#[deriving(Copy, Show)]
F
Felix S. Klock II 已提交
284
enum MethodSort {
285 286
    RequiredMethod,
    ProvidedMethod(NodeId)
287 288
}

J
Jorge Aparicio 已提交
289
#[deriving(Copy)]
F
Felix S. Klock II 已提交
290
enum UseLexicalScopeFlag {
291 292 293 294
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
295
enum ModulePrefixResult {
296
    NoPrefixFound,
E
Eduard Burtescu 已提交
297
    PrefixFound(Rc<Module>, uint)
298 299
}

J
Jorge Aparicio 已提交
300
#[deriving(Copy, PartialEq)]
301
enum NameSearchType {
302 303 304 305
    /// We're doing a name search in order to resolve a `use` directive.
    ImportSearch,

    /// We're doing a name search in order to resolve a path type, a path
306 307
    /// expression, or a path pattern.
    PathSearch,
308 309
}

J
Jorge Aparicio 已提交
310
#[deriving(Copy)]
F
Felix S. Klock II 已提交
311
enum BareIdentifierPatternResolution {
312 313
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
314
    BareIdentifierPatternUnresolved
315 316
}

317 318
// Specifies how duplicates should be handled when adding a child item if
// another item exists with the same name in some namespace.
J
Jorge Aparicio 已提交
319
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
320
enum DuplicateCheckingMode {
321
    ForbidDuplicateModules,
322
    ForbidDuplicateTypesAndModules,
323 324 325 326 327
    ForbidDuplicateValues,
    ForbidDuplicateTypesAndValues,
    OverwriteDuplicates
}

328
/// One local scope.
329
#[deriving(Show)]
F
Felix S. Klock II 已提交
330
struct Rib {
331
    bindings: HashMap<Name, DefLike>,
332
    kind: RibKind,
B
Brian Anderson 已提交
333
}
334

335
impl Rib {
F
Felix S. Klock II 已提交
336
    fn new(kind: RibKind) -> Rib {
337
        Rib {
338
            bindings: HashMap::new(),
339 340
            kind: kind
        }
341 342 343
    }
}

344
/// Whether an import can be shadowed by another import.
N
Nick Cameron 已提交
345
#[deriving(Show,PartialEq,Clone,Copy)]
346 347 348 349 350
enum Shadowable {
    Always,
    Never
}

351
/// One import directive.
F
Felix S. Klock II 已提交
352
struct ImportDirective {
353
    module_path: Vec<Name>,
E
Eduard Burtescu 已提交
354
    subclass: ImportDirectiveSubclass,
355
    span: Span,
356
    id: NodeId,
357
    is_public: bool, // see note in ImportResolution about how to use this
358
    shadowable: Shadowable,
B
Brian Anderson 已提交
359
}
360

361
impl ImportDirective {
362
    fn new(module_path: Vec<Name> ,
E
Eduard Burtescu 已提交
363
           subclass: ImportDirectiveSubclass,
364 365
           span: Span,
           id: NodeId,
366
           is_public: bool,
367
           shadowable: Shadowable)
368
           -> ImportDirective {
369 370 371 372
        ImportDirective {
            module_path: module_path,
            subclass: subclass,
            span: span,
373 374
            id: id,
            is_public: is_public,
375
            shadowable: shadowable,
376
        }
377 378 379
    }
}

380
/// The item that an import resolves to.
381
#[deriving(Clone)]
F
Felix S. Klock II 已提交
382
struct Target {
E
Eduard Burtescu 已提交
383 384
    target_module: Rc<Module>,
    bindings: Rc<NameBindings>,
385
    shadowable: Shadowable,
B
Brian Anderson 已提交
386
}
387

388
impl Target {
389 390
    fn new(target_module: Rc<Module>,
           bindings: Rc<NameBindings>,
391
           shadowable: Shadowable)
392
           -> Target {
393 394
        Target {
            target_module: target_module,
395 396
            bindings: bindings,
            shadowable: shadowable,
397
        }
398 399 400
    }
}

T
Tim Chevalier 已提交
401
/// An ImportResolution represents a particular `use` directive.
F
Felix S. Klock II 已提交
402
struct ImportResolution {
403 404 405 406
    /// Whether this resolution came from a `use` or a `pub use`. Note that this
    /// should *not* be used whenever resolution is being performed, this is
    /// only looked at for glob imports statements currently. Privacy testing
    /// occurs during a later phase of compilation.
E
Eduard Burtescu 已提交
407
    is_public: bool,
408

409 410 411
    // The number of outstanding references to this name. When this reaches
    // zero, outside modules can count on the targets being correct. Before
    // then, all bets are off; future imports could override this name.
E
Eduard Burtescu 已提交
412
    outstanding_references: uint,
413

T
Tim Chevalier 已提交
414
    /// The value that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
415
    value_target: Option<Target>,
416 417
    /// The source node of the `use` directive leading to the value target
    /// being non-none
E
Eduard Burtescu 已提交
418
    value_id: NodeId,
419

T
Tim Chevalier 已提交
420
    /// The type that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
421
    type_target: Option<Target>,
422 423
    /// The source node of the `use` directive leading to the type target
    /// being non-none
E
Eduard Burtescu 已提交
424
    type_id: NodeId,
E
Erick Tryzelaar 已提交
425 426
}

427
impl ImportResolution {
428
    fn new(id: NodeId, is_public: bool) -> ImportResolution {
429
        ImportResolution {
E
Eduard Burtescu 已提交
430 431 432 433 434 435
            type_id: id,
            value_id: id,
            outstanding_references: 0,
            value_target: None,
            type_target: None,
            is_public: is_public,
436
        }
B
Brian Anderson 已提交
437 438
    }

F
Felix S. Klock II 已提交
439
    fn target_for_namespace(&self, namespace: Namespace)
440
                                -> Option<Target> {
441
        match namespace {
E
Eduard Burtescu 已提交
442 443
            TypeNS  => self.type_target.clone(),
            ValueNS => self.value_target.clone(),
444 445
        }
    }
446

447
    fn id(&self, namespace: Namespace) -> NodeId {
448
        match namespace {
E
Eduard Burtescu 已提交
449 450
            TypeNS  => self.type_id,
            ValueNS => self.value_id,
451 452
        }
    }
453 454 455 456 457 458 459 460 461

    fn shadowable(&self, namespace: Namespace) -> Shadowable {
        let target = self.target_for_namespace(namespace);
        if target.is_none() {
            return Shadowable::Always;
        }

        target.unwrap().shadowable
    }
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477

    fn set_target_and_id(&mut self,
                         namespace: Namespace,
                         target: Option<Target>,
                         id: NodeId) {
        match namespace {
            TypeNS  => {
                self.type_target = target;
                self.type_id = id;
            }
            ValueNS => {
                self.value_target = target;
                self.value_id = id;
            }
        }
    }
478 479
}

480
/// The link from a module up to its nearest parent node.
E
Eduard Burtescu 已提交
481
#[deriving(Clone)]
F
Felix S. Klock II 已提交
482
enum ParentLink {
483
    NoParentLink,
484
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
485
    BlockParentLink(Weak<Module>, NodeId)
486 487
}

488
/// The type of module this is.
J
Jorge Aparicio 已提交
489
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
490
enum ModuleKind {
491 492
    NormalModuleKind,
    TraitModuleKind,
493
    ImplModuleKind,
494
    EnumModuleKind,
495 496 497
    AnonymousModuleKind,
}

498
/// One node in the tree of modules.
F
Felix S. Klock II 已提交
499
struct Module {
500
    parent_link: ParentLink,
501
    def_id: Cell<Option<DefId>>,
502
    kind: Cell<ModuleKind>,
503
    is_public: bool,
504

E
Eduard Burtescu 已提交
505 506
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
507

508
    // The external module children of this node that were declared with
A
Alex Crichton 已提交
509
    // `extern crate`.
E
Eduard Burtescu 已提交
510
    external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
511

512 513 514 515 516 517 518 519 520 521 522 523 524 525
    // The anonymous children of this node. Anonymous children are pseudo-
    // modules that are implicitly created around items contained within
    // blocks.
    //
    // For example, if we have this:
    //
    //  fn f() {
    //      fn g() {
    //          ...
    //      }
    //  }
    //
    // There will be an anonymous module created around `g` with the ID of the
    // entry block for `f`.
E
Eduard Burtescu 已提交
526
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
527 528

    // The status of resolving each import in this module.
E
Eduard Burtescu 已提交
529
    import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
530 531

    // The number of unresolved globs that this module exports.
532
    glob_count: Cell<uint>,
533 534

    // The index of the import we're resolving.
535
    resolved_import_count: Cell<uint>,
536 537 538 539

    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
540
    populated: Cell<bool>,
541 542
}

543
impl Module {
F
Felix S. Klock II 已提交
544
    fn new(parent_link: ParentLink,
545 546 547 548
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
549
           -> Module {
550 551
        Module {
            parent_link: parent_link,
552
            def_id: Cell::new(def_id),
553
            kind: Cell::new(kind),
554
            is_public: is_public,
555
            children: RefCell::new(HashMap::new()),
556
            imports: RefCell::new(Vec::new()),
557
            external_module_children: RefCell::new(HashMap::new()),
558
            anonymous_children: RefCell::new(NodeMap::new()),
559
            import_resolutions: RefCell::new(HashMap::new()),
560
            glob_count: Cell::new(0),
561
            resolved_import_count: Cell::new(0),
562
            populated: Cell::new(!external),
563
        }
B
Brian Anderson 已提交
564 565
    }

F
Felix S. Klock II 已提交
566
    fn all_imports_resolved(&self) -> bool {
567
        self.imports.borrow().len() == self.resolved_import_count.get()
568 569 570
    }
}

571 572 573 574 575 576 577 578
bitflags! {
    #[deriving(Show)]
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

579
// Records a possibly-private type definition.
580
#[deriving(Clone)]
F
Felix S. Klock II 已提交
581
struct TypeNsDef {
582
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
583
    module_def: Option<Rc<Module>>,
584
    type_def: Option<Def>,
585
    type_span: Option<Span>
586 587 588
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
589
#[deriving(Clone, Copy, Show)]
F
Felix S. Klock II 已提交
590
struct ValueNsDef {
591
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
592
    def: Def,
593
    value_span: Option<Span>,
594 595
}

596 597
// Records the definitions (at most one for each namespace) that a name is
// bound to.
F
Felix S. Klock II 已提交
598
struct NameBindings {
599
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
600
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
601 602
}

603
/// Ways in which a trait can be referenced
J
Jorge Aparicio 已提交
604
#[deriving(Copy)]
605 606 607 608
enum TraitReferenceType {
    TraitImplementation,             // impl SomeTrait for T { ... }
    TraitDerivation,                 // trait T : SomeTrait { ... }
    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
N
Niko Matsakis 已提交
609
    TraitObject,                     // Box<for<'a> SomeTrait>
610
    TraitQPath,                      // <T as SomeTrait>::
611 612
}

613
impl NameBindings {
K
Kevin Butler 已提交
614 615 616 617 618 619 620
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

621
    /// Creates a new module in this set of name bindings.
622
    fn define_module(&self,
623 624 625 626 627 628
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
629
        // Merges the module with the existing type def or creates a new one.
630
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
631 632 633 634
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
635
                                          is_public));
E
Erick Tryzelaar 已提交
636 637
        let type_def = self.type_def.borrow().clone();
        match type_def {
638
            None => {
E
Erick Tryzelaar 已提交
639
                *self.type_def.borrow_mut() = Some(TypeNsDef {
640
                    modifiers: modifiers,
641
                    module_def: Some(module_),
642 643
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
644
                });
645
            }
646
            Some(type_def) => {
E
Erick Tryzelaar 已提交
647
                *self.type_def.borrow_mut() = Some(TypeNsDef {
648
                    modifiers: modifiers,
649
                    module_def: Some(module_),
650
                    type_span: Some(sp),
651
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
652
                });
653
            }
654 655 656
        }
    }

657
    /// Sets the kind of the module, creating a new one if necessary.
658
    fn set_module_kind(&self,
659 660 661 662 663 664
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
665
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
E
Erick Tryzelaar 已提交
666 667
        let type_def = self.type_def.borrow().clone();
        match type_def {
668
            None => {
669 670 671 672 673
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
674
                *self.type_def.borrow_mut() = Some(TypeNsDef {
675
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
676
                    module_def: Some(Rc::new(module)),
677 678
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
679
                });
680 681 682 683
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
684 685 686 687 688
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
689
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
690
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
691
                            module_def: Some(Rc::new(module)),
692 693
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
694
                        });
695
                    }
696
                    Some(module_def) => module_def.kind.set(kind),
697 698 699 700 701
                }
            }
        }
    }

702
    /// Records a type definition.
703 704
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
        debug!("defining type for def {} with modifiers {}", def, modifiers);
705
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
706 707
        let type_def = self.type_def.borrow().clone();
        match type_def {
708
            None => {
E
Erick Tryzelaar 已提交
709
                *self.type_def.borrow_mut() = Some(TypeNsDef {
710
                    module_def: None,
711
                    type_def: Some(def),
712
                    type_span: Some(sp),
713
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
714
                });
715
            }
716
            Some(type_def) => {
E
Erick Tryzelaar 已提交
717
                *self.type_def.borrow_mut() = Some(TypeNsDef {
718
                    module_def: type_def.module_def,
719
                    type_def: Some(def),
720
                    type_span: Some(sp),
721
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
722
                });
723 724
            }
        }
725 726
    }

727
    /// Records a value definition.
728 729
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
        debug!("defining value for def {} with modifiers {}", def, modifiers);
E
Erick Tryzelaar 已提交
730
        *self.value_def.borrow_mut() = Some(ValueNsDef {
731 732
            def: def,
            value_span: Some(sp),
733
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
734
        });
735 736
    }

737
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
738
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
739
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
740
            Some(ref type_def) => type_def.module_def.clone(),
741
            None => None
742 743 744
        }
    }

S
Steve Klabnik 已提交
745 746
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
747
    fn get_module(&self) -> Rc<Module> {
748 749
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
750
                panic!("get_module called on a node with no module \
751
                       definition!")
752
            }
753
            Some(module_def) => module_def
754 755 756
        }
    }

F
Felix S. Klock II 已提交
757
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
758
        match namespace {
E
Erick Tryzelaar 已提交
759 760
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
761 762 763
        }
    }

F
Felix S. Klock II 已提交
764
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
765 766 767 768
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
769
        match namespace {
E
Erick Tryzelaar 已提交
770
            TypeNS => match *self.type_def.borrow() {
771
                Some(ref def) => def.modifiers.contains(modifiers), None => false
772
            },
E
Erick Tryzelaar 已提交
773
            ValueNS => match *self.value_def.borrow() {
774
                Some(ref def) => def.modifiers.contains(modifiers), None => false
775 776 777 778
            }
        }
    }

F
Felix S. Klock II 已提交
779
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
780
        match namespace {
781
            TypeNS => {
E
Erick Tryzelaar 已提交
782
                match *self.type_def.borrow() {
783
                    None => None,
E
Eduard Burtescu 已提交
784
                    Some(ref type_def) => {
785
                        match type_def.type_def {
786
                            Some(type_def) => Some(type_def),
787 788
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
789
                                    Some(ref module) => {
790
                                        match module.def_id.get() {
791
                                            Some(did) => Some(DefMod(did)),
792 793 794 795 796 797
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
798
                        }
799 800
                    }
                }
801 802
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
803
                match *self.value_def.borrow() {
804 805 806 807 808 809 810
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
811
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
812
        if self.defined_in_namespace(namespace) {
813
            match namespace {
814
                TypeNS  => {
E
Erick Tryzelaar 已提交
815
                    match *self.type_def.borrow() {
816
                        None => None,
E
Eduard Burtescu 已提交
817
                        Some(ref type_def) => type_def.type_span
818 819 820
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
821
                    match *self.value_def.borrow() {
822
                        None => None,
E
Eduard Burtescu 已提交
823
                        Some(ref value_def) => value_def.value_span
824 825
                    }
                }
826
            }
827 828
        } else {
            None
829 830
        }
    }
831 832
}

833
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
834
struct PrimitiveTypeTable {
835
    primitive_types: HashMap<Name, PrimTy>,
836
}
837

838
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
    fn new() -> PrimitiveTypeTable {
        let mut table = PrimitiveTypeTable {
            primitive_types: HashMap::new()
        };

        table.intern("bool",    TyBool);
        table.intern("char",    TyChar);
        table.intern("f32",     TyFloat(TyF32));
        table.intern("f64",     TyFloat(TyF64));
        table.intern("int",     TyInt(TyI));
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
        table.intern("uint",    TyUint(TyU));
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

863
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
864
        self.primitive_types.insert(token::intern(string), primitive_type);
865 866 867
    }
}

B
Brian Anderson 已提交
868

869
fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
870
    match ns {
871 872 873
        NoError                 => "",
        ModuleError | TypeError => "type or module",
        ValueError              => "value",
874 875 876
    }
}

877
/// The main resolver class.
878
struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
879
    session: &'a Session,
880

881 882
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
883
    graph_root: NameBindings,
884

885
    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
886

887
    structs: FnvHashMap<DefId, Vec<Name>>,
888

889
    // The number of imports that are currently unresolved.
890
    unresolved_imports: uint,
891 892

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
893
    current_module: Rc<Module>,
894 895

    // The current set of local scopes, for values.
896
    // FIXME #4948: Reuse ribs to avoid allocation.
897
    value_ribs: Vec<Rib>,
898 899

    // The current set of local scopes, for types.
900
    type_ribs: Vec<Rib>,
901

902
    // The current set of local scopes, for labels.
903
    label_ribs: Vec<Rib>,
904

905
    // The trait that the current context can refer to.
906 907 908 909
    current_trait_ref: Option<(DefId, TraitRef)>,

    // The current self type if inside an impl (used for better errors).
    current_self_type: Option<Ty>,
910

911
    // The ident for the keyword "self".
J
John Clements 已提交
912
    self_name: Name,
913
    // The ident for the non-keyword "Self".
J
John Clements 已提交
914
    type_self_name: Name,
915

916
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
917
    primitive_type_table: PrimitiveTypeTable,
918

919
    def_map: DefMap,
920 921
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
922
    capture_mode_map: CaptureModeMap,
923
    export_map: ExportMap,
924
    trait_map: TraitMap,
925 926
    external_exports: ExternalExports,
    last_private: LastPrivateMap,
927

928 929 930 931 932
    // Whether or not to print error messages. Can be set to true
    // when getting additional info for error message suggestions,
    // so as to avoid printing duplicate errors
    emit_errors: bool,

933 934 935 936 937
    make_glob_map: bool,
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
    glob_map: GlobMap,

938
    used_imports: HashSet<(NodeId, Namespace)>,
939
    used_crates: HashSet<CrateNum>,
940 941
}

942 943
struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
    resolver: &'a mut Resolver<'b, 'tcx>,
944
    parent: ReducedGraphParent
945 946
}

947
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
948

949 950 951 952 953
    fn visit_item(&mut self, item: &Item) {
        let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
        let old_parent = replace(&mut self.parent, p);
        visit::walk_item(self, item);
        self.parent = old_parent;
954 955
    }

956 957
    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
        let parent = self.parent.clone();
958
        self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
959
                                                           parent.clone(),
E
Eduard Burtescu 已提交
960
                                                           |r| {
961 962 963 964 965
            let mut v = BuildReducedGraphVisitor {
                resolver: r,
                parent: parent.clone()
            };
            visit::walk_foreign_item(&mut v, foreign_item);
966
        })
967 968
    }

969 970
    fn visit_view_item(&mut self, view_item: &ViewItem) {
        self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
971 972
    }

973 974 975 976 977
    fn visit_block(&mut self, block: &Block) {
        let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
        let old_parent = replace(&mut self.parent, np);
        visit::walk_block(self, block);
        self.parent = old_parent;
978 979 980 981
    }

}

S
Steven Fackler 已提交
982 983 984 985 986 987 988
#[deriving(PartialEq)]
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}


989 990 991 992 993
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
           ast_map: &'a ast_map::Map<'tcx>,
           crate_span: Span,
           make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> {
K
Kevin Butler 已提交
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
        let graph_root = NameBindings::new();

        graph_root.define_module(NoParentLink,
                                 Some(DefId { krate: 0, node: 0 }),
                                 NormalModuleKind,
                                 false,
                                 true,
                                 crate_span);

        let current_module = graph_root.get_module();

        Resolver {
            session: session,

1008 1009
            ast_map: ast_map,

K
Kevin Butler 已提交
1010 1011 1012 1013 1014
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

1015
            trait_item_map: FnvHashMap::new(),
K
Kevin Butler 已提交
1016 1017 1018 1019 1020
            structs: FnvHashMap::new(),

            unresolved_imports: 0,

            current_module: current_module,
1021 1022 1023
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1024 1025 1026 1027

            current_trait_ref: None,
            current_self_type: None,

J
John Clements 已提交
1028 1029
            self_name: special_names::self_,
            type_self_name: special_names::type_self,
K
Kevin Butler 已提交
1030 1031 1032 1033

            primitive_type_table: PrimitiveTypeTable::new(),

            def_map: RefCell::new(NodeMap::new()),
1034 1035
            freevars: RefCell::new(NodeMap::new()),
            freevars_seen: RefCell::new(NodeMap::new()),
1036
            capture_mode_map: NodeMap::new(),
1037
            export_map: NodeMap::new(),
K
Kevin Butler 已提交
1038 1039
            trait_map: NodeMap::new(),
            used_imports: HashSet::new(),
1040
            used_crates: HashSet::new(),
K
Kevin Butler 已提交
1041 1042 1043 1044
            external_exports: DefIdSet::new(),
            last_private: NodeMap::new(),

            emit_errors: true,
1045 1046
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
1047 1048
        }
    }
1049 1050 1051 1052 1053 1054 1055 1056

    //
    // Reduced graph building
    //
    // Here we build the "reduced graph": the graph of the module tree without
    // any imports resolved.
    //

1057
    /// Constructs the reduced graph for the entire crate.
1058
    fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1059 1060 1061 1062 1063 1064
        let parent = ModuleReducedGraphParent(self.graph_root.get_module());
        let mut visitor = BuildReducedGraphVisitor {
            resolver: self,
            parent: parent
        };
        visit::walk_crate(&mut visitor, krate);
1065 1066
    }

S
Steve Klabnik 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
    /// Adds a new child item to the module definition of the parent node and
    /// returns its corresponding name bindings as well as the current parent.
    /// Or, if we're inside a block, creates (or reuses) an anonymous module
    /// corresponding to the innermost block ID and returns the name bindings
    /// as well as the newly-created parent.
    ///
    /// # Panics
    ///
    /// Panics if this node does not have a module definition and we are not inside
    /// a block.
E
Eduard Burtescu 已提交
1077
    fn add_child(&self,
1078
                 name: Name,
E
Eduard Burtescu 已提交
1079 1080 1081 1082
                 reduced_graph_parent: ReducedGraphParent,
                 duplicate_checking_mode: DuplicateCheckingMode,
                 // For printing errors
                 sp: Span)
E
Eduard Burtescu 已提交
1083
                 -> Rc<NameBindings> {
1084 1085 1086 1087
        // If this is the immediate descendant of a module, then we add the
        // child name directly. Otherwise, we create or reuse an anonymous
        // module and add the child to that.

E
Eduard Burtescu 已提交
1088
        let module_ = reduced_graph_parent.module();
1089

1090
        self.check_for_conflicts_between_external_crates_and_items(&*module_,
1091
                                                                   name,
1092 1093
                                                                   sp);

1094
        // Add or reuse the child.
1095
        let child = module_.children.borrow().get(&name).cloned();
E
Eduard Burtescu 已提交
1096
        match child {
B
Brian Anderson 已提交
1097
            None => {
K
Kevin Butler 已提交
1098
                let child = Rc::new(NameBindings::new());
1099
                module_.children.borrow_mut().insert(name, child.clone());
E
Eduard Burtescu 已提交
1100
                child
1101
            }
1102
            Some(child) => {
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
                // Enforce the duplicate checking mode:
                //
                // * If we're requesting duplicate module checking, check that
                //   there isn't a module in the module with the same name.
                //
                // * If we're requesting duplicate type checking, check that
                //   there isn't a type in the module with the same name.
                //
                // * If we're requesting duplicate value checking, check that
                //   there isn't a value in the module with the same name.
                //
                // * If we're requesting duplicate type checking and duplicate
                //   value checking, check that there isn't a duplicate type
                //   and a duplicate value with the same name.
                //
                // * If no duplicate checking was requested at all, do
                //   nothing.
1120

1121
                let mut duplicate_type = NoError;
1122
                let ns = match duplicate_checking_mode {
1123
                    ForbidDuplicateModules => {
H
Huon Wilson 已提交
1124
                        if child.get_module_if_available().is_some() {
1125 1126
                            duplicate_type = ModuleError;
                        }
1127
                        Some(TypeNS)
1128
                    }
1129
                    ForbidDuplicateTypesAndModules => {
1130
                        match child.def_for_namespace(TypeNS) {
1131 1132 1133 1134
                            None => {}
                            Some(_) if child.get_module_if_available()
                                            .map(|m| m.kind.get()) ==
                                       Some(ImplModuleKind) => {}
1135
                            Some(_) => duplicate_type = TypeError
1136
                        }
1137
                        Some(TypeNS)
1138 1139
                    }
                    ForbidDuplicateValues => {
1140 1141 1142
                        if child.defined_in_namespace(ValueNS) {
                            duplicate_type = ValueError;
                        }
1143
                        Some(ValueNS)
1144 1145
                    }
                    ForbidDuplicateTypesAndValues => {
1146
                        let mut n = None;
1147
                        match child.def_for_namespace(TypeNS) {
1148
                            Some(DefMod(_)) | None => {}
1149 1150
                            Some(_) => {
                                n = Some(TypeNS);
1151
                                duplicate_type = TypeError;
1152
                            }
1153 1154
                        };
                        if child.defined_in_namespace(ValueNS) {
1155
                            duplicate_type = ValueError;
1156
                            n = Some(ValueNS);
1157
                        }
1158
                        n
1159
                    }
1160 1161
                    OverwriteDuplicates => None
                };
H
Huon Wilson 已提交
1162
                if duplicate_type != NoError {
1163 1164
                    // Return an error here by looking up the namespace that
                    // had the duplicate.
1165
                    let ns = ns.unwrap();
1166
                    self.resolve_error(sp,
A
Alex Crichton 已提交
1167
                        format!("duplicate definition of {} `{}`",
1168
                             namespace_error_to_string(duplicate_type),
A
Alex Crichton 已提交
1169
                             token::get_name(name))[]);
1170 1171
                    {
                        let r = child.span_for_namespace(ns);
D
Daniel Micay 已提交
1172
                        for sp in r.iter() {
1173
                            self.session.span_note(*sp,
A
Alex Crichton 已提交
1174
                                 format!("first definition of {} `{}` here",
1175
                                      namespace_error_to_string(duplicate_type),
A
Alex Crichton 已提交
1176
                                      token::get_name(name))[]);
1177
                        }
1178
                    }
1179
                }
E
Eduard Burtescu 已提交
1180
                child
1181 1182 1183 1184
            }
        }
    }

F
Felix S. Klock II 已提交
1185
    fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1186
        // If the block has view items, we need an anonymous module.
1187
        if block.view_items.len() > 0 {
B
Brian Anderson 已提交
1188
            return true;
1189 1190 1191
        }

        // Check each statement.
D
Daniel Micay 已提交
1192
        for statement in block.stmts.iter() {
1193
            match statement.node {
1194
                StmtDecl(ref declaration, _) => {
1195
                    match declaration.node {
1196
                        DeclItem(_) => {
B
Brian Anderson 已提交
1197
                            return true;
1198
                        }
B
Brian Anderson 已提交
1199
                        _ => {
1200 1201 1202 1203
                            // Keep searching.
                        }
                    }
                }
B
Brian Anderson 已提交
1204
                _ => {
1205 1206 1207 1208 1209 1210 1211 1212
                    // Keep searching.
                }
            }
        }

        // If we found neither view items nor items, we don't need to create
        // an anonymous module.

B
Brian Anderson 已提交
1213
        return false;
1214 1215
    }

1216
    fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
1217
                       -> ParentLink {
1218
        match parent {
B
Brian Anderson 已提交
1219
            ModuleReducedGraphParent(module_) => {
E
Eduard Burtescu 已提交
1220
                return ModuleParentLink(module_.downgrade(), name);
1221 1222 1223 1224
            }
        }
    }

1225
    /// Constructs the reduced graph for one item.
F
Felix S. Klock II 已提交
1226
    fn build_reduced_graph_for_item(&mut self,
1227 1228 1229
                                    item: &Item,
                                    parent: ReducedGraphParent)
                                    -> ReducedGraphParent
A
Alex Crichton 已提交
1230
    {
1231
        let name = item.ident.name;
1232
        let sp = item.span;
1233
        let is_public = item.vis == ast::Public;
1234
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1235

1236
        match item.node {
1237
            ItemMod(..) => {
E
Eduard Burtescu 已提交
1238
                let name_bindings =
1239
                    self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
1240

1241
                let parent_link = self.get_parent_link(parent, name);
1242
                let def_id = DefId { krate: 0, node: item.id };
1243
                name_bindings.define_module(parent_link,
1244 1245
                                            Some(def_id),
                                            NormalModuleKind,
1246
                                            false,
1247
                                            item.vis == ast::Public,
1248
                                            sp);
1249

A
Alex Crichton 已提交
1250
                ModuleReducedGraphParent(name_bindings.get_module())
1251
            }
1252

1253
            ItemForeignMod(..) => parent,
1254 1255

            // These items live in the value namespace.
1256
            ItemStatic(_, m, _) => {
E
Eduard Burtescu 已提交
1257
                let name_bindings =
1258
                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1259
                let mutbl = m == ast::MutMutable;
1260

1261
                name_bindings.define_value
1262
                    (DefStatic(local_def(item.id), mutbl), sp, modifiers);
A
Alex Crichton 已提交
1263
                parent
1264
            }
1265
            ItemConst(_, _) => {
1266
                self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
1267
                    .define_value(DefConst(local_def(item.id)),
1268
                                  sp, modifiers);
1269 1270
                parent
            }
1271
            ItemFn(_, _, _, _, _) => {
E
Eduard Burtescu 已提交
1272
                let name_bindings =
1273
                    self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1274

1275
                let def = DefFn(local_def(item.id), false);
1276
                name_bindings.define_value(def, sp, modifiers);
E
Eduard Burtescu 已提交
1277
                parent
1278 1279 1280
            }

            // These items live in the type namespace.
1281
            ItemTy(..) => {
E
Eduard Burtescu 已提交
1282
                let name_bindings =
1283
                    self.add_child(name,
1284 1285 1286
                                   parent.clone(),
                                   ForbidDuplicateTypesAndModules,
                                   sp);
1287

1288
                name_bindings.define_type
1289
                    (DefTy(local_def(item.id), false), sp, modifiers);
A
Alex Crichton 已提交
1290
                parent
1291 1292
            }

1293
            ItemEnum(ref enum_definition, _) => {
E
Eduard Burtescu 已提交
1294
                let name_bindings =
1295
                    self.add_child(name,
1296 1297 1298
                                   parent.clone(),
                                   ForbidDuplicateTypesAndModules,
                                   sp);
1299

1300
                name_bindings.define_type
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
                    (DefTy(local_def(item.id), true), sp, modifiers);

                let parent_link = self.get_parent_link(parent.clone(), name);
                // We want to make sure the module type is EnumModuleKind
                // even if there's already an ImplModuleKind module defined,
                // since that's how we prevent duplicate enum definitions
                name_bindings.set_module_kind(parent_link,
                                              Some(local_def(item.id)),
                                              EnumModuleKind,
                                              false,
                                              is_public,
                                              sp);
1313

1314
                for variant in (*enum_definition).variants.iter() {
1315 1316 1317
                    self.build_reduced_graph_for_variant(
                        &**variant,
                        local_def(item.id),
S
Steven Fackler 已提交
1318
                        ModuleReducedGraphParent(name_bindings.get_module()));
1319
                }
A
Alex Crichton 已提交
1320
                parent
1321
            }
1322 1323

            // These items live in both the type and value namespaces.
1324
            ItemStruct(ref struct_def, _) => {
1325 1326 1327
                // Adding to both Type and Value namespaces or just Type?
                let (forbid, ctor_id) = match struct_def.ctor_id {
                    Some(ctor_id)   => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1328
                    None            => (ForbidDuplicateTypesAndModules, None)
1329
                };
1330

1331
                let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
1332 1333

                // Define a name in the type namespace.
1334
                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
1335 1336 1337

                // If this is a newtype or unit-like struct, define a name
                // in the value namespace as well
1338 1339 1340
                match ctor_id {
                    Some(cid) => {
                        name_bindings.define_value(DefStruct(local_def(cid)),
1341
                                                   sp, modifiers);
1342 1343 1344
                    }
                    None => {}
                }
1345

1346 1347 1348 1349 1350 1351 1352 1353
                // Record the def ID and fields of this struct.
                let named_fields = struct_def.fields.iter().filter_map(|f| {
                    match f.node.kind {
                        NamedField(ident, _) => Some(ident.name),
                        UnnamedField(_) => None
                    }
                }).collect();
                self.structs.insert(local_def(item.id), named_fields);
1354

E
Eduard Burtescu 已提交
1355
                parent
1356 1357
            }

1358
            ItemImpl(_, _, None, ref ty, ref impl_items) => {
1359 1360 1361
                // If this implements an anonymous trait, then add all the
                // methods within to a new module, if the type was defined
                // within this module.
1362

1363 1364
                let mod_name = match ty.node {
                    TyPath(ref path, _) if path.segments.len() == 1 => {
1365 1366
                        // FIXME(18446) we should distinguish between the name of
                        // a trait and the name of an impl of that trait.
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
                        Some(path.segments.last().unwrap().identifier.name)
                    }
                    TyObjectSum(ref lhs_ty, _) => {
                        match lhs_ty.node {
                            TyPath(ref path, _) if path.segments.len() == 1 => {
                                Some(path.segments.last().unwrap().identifier.name)
                            }
                            _ => {
                                None
                            }
                        }
                    }
                    _ => {
                        None
                    }
                };
1383

1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
                match mod_name {
                    None => {
                        self.resolve_error(ty.span,
                                           "inherent implementations may \
                                            only be implemented in the same \
                                            module as the type they are \
                                            implemented for")
                    }
                    Some(mod_name) => {
                        // Create the module and add all methods.
1394
                        let parent_opt = parent.module().children.borrow()
1395
                            .get(&mod_name).cloned();
1396
                        let new_parent = match parent_opt {
1397
                            // It already exists
E
Eduard Burtescu 已提交
1398
                            Some(ref child) if child.get_module_if_available()
1399 1400 1401 1402 1403
                                .is_some() &&
                                (child.get_module().kind.get() == ImplModuleKind ||
                                 child.get_module().kind.get() == TraitModuleKind) => {
                                    ModuleReducedGraphParent(child.get_module())
                                }
1404
                            Some(ref child) if child.get_module_if_available()
1405 1406 1407 1408 1409
                                .is_some() &&
                                child.get_module().kind.get() ==
                                EnumModuleKind => {
                                    ModuleReducedGraphParent(child.get_module())
                                }
1410 1411
                            // Create the module
                            _ => {
E
Eduard Burtescu 已提交
1412
                                let name_bindings =
1413
                                    self.add_child(mod_name,
E
Eduard Burtescu 已提交
1414
                                                   parent.clone(),
1415 1416 1417
                                                   ForbidDuplicateModules,
                                                   sp);

1418
                                let parent_link =
1419
                                    self.get_parent_link(parent.clone(), name);
1420
                                let def_id = local_def(item.id);
1421 1422 1423
                                let ns = TypeNS;
                                let is_public =
                                    !name_bindings.defined_in_namespace(ns) ||
1424
                                    name_bindings.defined_in_public_namespace(ns);
1425

1426
                                name_bindings.define_module(parent_link,
1427 1428
                                                            Some(def_id),
                                                            ImplModuleKind,
1429
                                                            false,
1430
                                                            is_public,
1431 1432
                                                            sp);

1433 1434
                                ModuleReducedGraphParent(
                                    name_bindings.get_module())
1435 1436
                            }
                        };
1437

1438 1439 1440
                        // For each implementation item...
                        for impl_item in impl_items.iter() {
                            match *impl_item {
1441
                                MethodImplItem(ref method) => {
1442
                                    // Add the method to the module.
1443
                                    let name = method.pe_ident().name;
1444
                                    let method_name_bindings =
1445
                                        self.add_child(name,
1446 1447 1448 1449
                                                       new_parent.clone(),
                                                       ForbidDuplicateValues,
                                                       method.span);
                                    let def = match method.pe_explicit_self()
1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464
                                        .node {
                                            SelfStatic => {
                                                // Static methods become
                                                // `DefStaticMethod`s.
                                                DefStaticMethod(local_def(method.id),
                                                                FromImpl(local_def(item.id)))
                                            }
                                            _ => {
                                                // Non-static methods become
                                                // `DefMethod`s.
                                                DefMethod(local_def(method.id),
                                                          None,
                                                          FromImpl(local_def(item.id)))
                                            }
                                        };
1465

1466 1467 1468 1469 1470 1471
                                    // NB: not IMPORTABLE
                                    let modifiers = if method.pe_vis() == ast::Public {
                                        PUBLIC
                                    } else {
                                        DefModifiers::empty()
                                    };
1472 1473 1474
                                    method_name_bindings.define_value(
                                        def,
                                        method.span,
1475
                                        modifiers);
1476
                                }
1477 1478
                                TypeImplItem(ref typedef) => {
                                    // Add the typedef to the module.
1479
                                    let name = typedef.ident.name;
1480 1481
                                    let typedef_name_bindings =
                                        self.add_child(
1482
                                            name,
1483 1484 1485 1486
                                            new_parent.clone(),
                                            ForbidDuplicateTypesAndModules,
                                            typedef.span);
                                    let def = DefAssociatedTy(local_def(
1487
                                        typedef.id));
1488 1489 1490 1491 1492 1493
                                    // NB: not IMPORTABLE
                                    let modifiers = if typedef.vis == ast::Public {
                                        PUBLIC
                                    } else {
                                        DefModifiers::empty()
                                    };
1494 1495 1496
                                    typedef_name_bindings.define_type(
                                        def,
                                        typedef.span,
1497
                                        modifiers);
1498
                                }
1499
                            }
1500 1501 1502 1503
                        }
                    }
                }

A
Alex Crichton 已提交
1504
                parent
1505 1506
            }

1507
            ItemImpl(_, _, Some(_), _, _) => parent,
1508

1509
            ItemTrait(_, _, _, _, ref items) => {
E
Eduard Burtescu 已提交
1510
                let name_bindings =
1511
                    self.add_child(name,
1512 1513 1514
                                   parent.clone(),
                                   ForbidDuplicateTypesAndModules,
                                   sp);
1515

1516
                // Add all the items within to a new module.
1517
                let parent_link = self.get_parent_link(parent.clone(), name);
1518
                name_bindings.define_module(parent_link,
1519 1520
                                            Some(local_def(item.id)),
                                            TraitModuleKind,
1521
                                            false,
1522
                                            item.vis == ast::Public,
1523 1524 1525
                                            sp);
                let module_parent = ModuleReducedGraphParent(name_bindings.
                                                             get_module());
1526

E
Eduard Burtescu 已提交
1527 1528
                let def_id = local_def(item.id);

1529 1530 1531
                // Add the names of all the items to the trait info.
                for trait_item in items.iter() {
                    let (name, kind) = match *trait_item {
1532 1533
                        ast::RequiredMethod(_) |
                        ast::ProvidedMethod(_) => {
1534
                            let ty_m = ast_util::trait_item_to_ty_method(trait_item);
1535

1536
                            let name = ty_m.ident.name;
1537 1538 1539 1540 1541

                            // Add it as a name in the trait module.
                            let (def, static_flag) = match ty_m.explicit_self
                                                               .node {
                                SelfStatic => {
1542
                                    // Static methods become `DefStaticMethod`s.
1543 1544
                                    (DefStaticMethod(
                                            local_def(ty_m.id),
1545
                                            FromTrait(local_def(item.id))),
1546 1547 1548
                                     StaticMethodTraitItemKind)
                                }
                                _ => {
1549
                                    // Non-static methods become `DefMethod`s.
1550
                                    (DefMethod(local_def(ty_m.id),
1551 1552
                                               Some(local_def(item.id)),
                                               FromTrait(local_def(item.id))),
1553 1554 1555 1556 1557
                                     NonstaticMethodTraitItemKind)
                                }
                            };

                            let method_name_bindings =
1558
                                self.add_child(name,
1559 1560 1561
                                               module_parent.clone(),
                                               ForbidDuplicateTypesAndValues,
                                               ty_m.span);
1562
                            // NB: not IMPORTABLE
1563 1564
                            method_name_bindings.define_value(def,
                                                              ty_m.span,
1565
                                                              PUBLIC);
1566

1567
                            (name, static_flag)
1568
                        }
1569 1570
                        ast::TypeTraitItem(ref associated_type) => {
                            let def = DefAssociatedTy(local_def(
1571
                                    associated_type.ty_param.id));
1572 1573

                            let name_bindings =
1574
                                self.add_child(associated_type.ty_param.ident.name,
1575 1576
                                               module_parent.clone(),
                                               ForbidDuplicateTypesAndValues,
1577
                                               associated_type.ty_param.span);
1578
                            // NB: not IMPORTABLE
1579
                            name_bindings.define_type(def,
1580
                                                      associated_type.ty_param.span,
1581
                                                      PUBLIC);
1582

1583
                            (associated_type.ty_param.ident.name, TypeTraitItemKind)
1584 1585 1586
                        }
                    };

1587
                    self.trait_item_map.insert((name, def_id), kind);
1588
                }
1589

1590
                name_bindings.define_type(DefTrait(def_id), sp, modifiers);
E
Eduard Burtescu 已提交
1591
                parent
1592
            }
1593
            ItemMac(..) => parent
1594 1595 1596
        }
    }

1597
    // Constructs the reduced graph for one variant. Variants exist in the
1598
    // type and value namespaces.
F
Felix S. Klock II 已提交
1599
    fn build_reduced_graph_for_variant(&mut self,
1600
                                       variant: &Variant,
1601
                                       item_id: DefId,
S
Steven Fackler 已提交
1602
                                       parent: ReducedGraphParent) {
1603
        let name = variant.node.name.name;
1604 1605
        let is_exported = match variant.node.kind {
            TupleVariantKind(_) => false,
1606
            StructVariantKind(_) => {
1607 1608
                // Not adding fields for variants as they are not accessed with a self receiver
                self.structs.insert(local_def(variant.node.id), Vec::new());
1609
                true
1610
            }
1611 1612
        };

1613
        let child = self.add_child(name, parent,
1614 1615
                                   ForbidDuplicateTypesAndValues,
                                   variant.span);
S
Steven Fackler 已提交
1616 1617
        // variants are always treated as importable to allow them to be glob
        // used
1618 1619
        child.define_value(DefVariant(item_id,
                                      local_def(variant.node.id), is_exported),
S
Steven Fackler 已提交
1620
                           variant.span, PUBLIC | IMPORTABLE);
1621 1622
        child.define_type(DefVariant(item_id,
                                     local_def(variant.node.id), is_exported),
S
Steven Fackler 已提交
1623
                          variant.span, PUBLIC | IMPORTABLE);
1624 1625
    }

1626 1627
    /// Constructs the reduced graph for one 'view item'. View items consist
    /// of imports and use directives.
1628 1629
    fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
                                         parent: ReducedGraphParent) {
1630
        match view_item.node {
1631 1632 1633 1634
            ViewItemUse(ref view_path) => {
                // Extract and intern the module part of the path. For
                // globs and lists, the path is found directly in the AST;
                // for simple paths we have to munge the path a little.
J
Jakub Wieczorek 已提交
1635
                let module_path = match view_path.node {
1636
                    ViewPathSimple(_, ref full_path, _) => {
J
Jakub Wieczorek 已提交
1637
                        full_path.segments
1638
                            .init()
1639
                            .iter().map(|ident| ident.identifier.name)
J
Jakub Wieczorek 已提交
1640
                            .collect()
1641 1642
                    }

1643 1644
                    ViewPathGlob(ref module_ident_path, _) |
                    ViewPathList(ref module_ident_path, _, _) => {
J
Jakub Wieczorek 已提交
1645
                        module_ident_path.segments
1646
                            .iter().map(|ident| ident.identifier.name).collect()
1647
                    }
J
Jakub Wieczorek 已提交
1648
                };
1649 1650 1651 1652

                // Build up the import directives.
                let module_ = parent.module();
                let is_public = view_item.vis == ast::Public;
1653 1654 1655 1656
                let shadowable =
                    view_item.attrs
                             .iter()
                             .any(|attr| {
1657 1658
                                 attr.name() == token::get_name(
                                    special_idents::prelude_import.name)
1659
                             });
1660 1661 1662 1663 1664
                let shadowable = if shadowable {
                    Shadowable::Always
                } else {
                    Shadowable::Never
                };
1665

1666 1667
                match view_path.node {
                    ViewPathSimple(binding, ref full_path, id) => {
1668 1669 1670
                        let source_name =
                            full_path.segments.last().unwrap().identifier.name;
                        if token::get_name(source_name).get() == "mod" {
J
Jakub Wieczorek 已提交
1671 1672 1673 1674
                            self.resolve_error(view_path.span,
                                "`mod` imports are only allowed within a { } list");
                        }

1675 1676
                        let subclass = SingleImport(binding.name,
                                                    source_name);
1677 1678 1679 1680 1681
                        self.build_import_directive(&*module_,
                                                    module_path,
                                                    subclass,
                                                    view_path.span,
                                                    id,
1682 1683
                                                    is_public,
                                                    shadowable);
1684
                    }
J
Jakub Wieczorek 已提交
1685 1686 1687 1688 1689 1690
                    ViewPathList(_, ref source_items, _) => {
                        // Make sure there's at most one `mod` import in the list.
                        let mod_spans = source_items.iter().filter_map(|item| match item.node {
                            PathListMod { .. } => Some(item.span),
                            _ => None
                        }).collect::<Vec<Span>>();
1691 1692 1693 1694 1695 1696 1697
                        if mod_spans.len() > 1 {
                            self.resolve_error(mod_spans[0],
                                "`mod` import can only appear once in the list");
                            for other_span in mod_spans.iter().skip(1) {
                                self.session.span_note(*other_span,
                                    "another `mod` import appears here");
                            }
J
Jakub Wieczorek 已提交
1698 1699 1700 1701 1702
                        }

                        for source_item in source_items.iter() {
                            let (module_path, name) = match source_item.node {
                                PathListIdent { name, .. } =>
1703
                                    (module_path.clone(), name.name),
J
Jakub Wieczorek 已提交
1704 1705
                                PathListMod { .. } => {
                                    let name = match module_path.last() {
1706
                                        Some(name) => *name,
J
Jakub Wieczorek 已提交
1707 1708 1709 1710 1711 1712 1713
                                        None => {
                                            self.resolve_error(source_item.span,
                                                "`mod` import can only appear in an import list \
                                                 with a non-empty prefix");
                                            continue;
                                        }
                                    };
1714
                                    let module_path = module_path.init();
1715
                                    (module_path.to_vec(), name)
J
Jakub Wieczorek 已提交
1716 1717
                                }
                            };
1718 1719
                            self.build_import_directive(
                                &*module_,
J
Jakub Wieczorek 已提交
1720
                                module_path,
1721
                                SingleImport(name, name),
J
Jakub Wieczorek 已提交
1722
                                source_item.span,
1723 1724 1725
                                source_item.node.id(),
                                is_public,
                                shadowable);
1726 1727
                        }
                    }
1728 1729 1730 1731 1732 1733
                    ViewPathGlob(_, id) => {
                        self.build_import_directive(&*module_,
                                                    module_path,
                                                    GlobImport,
                                                    view_path.span,
                                                    id,
1734
                                                    is_public,
1735
                                                    shadowable);
1736
                    }
1737 1738 1739
                }
            }

1740
            ViewItemExternCrate(name, _, node_id) => {
1741
                // n.b. we don't need to look at the path option here, because cstore already did
1742 1743
                for &crate_id in self.session.cstore
                                     .find_extern_mod_stmt_cnum(node_id).iter() {
1744 1745
                    let def_id = DefId { krate: crate_id, node: 0 };
                    self.external_exports.insert(def_id);
1746
                    let parent_link =
1747
                        ModuleParentLink(parent.module().downgrade(), name.name);
1748 1749 1750 1751 1752 1753
                    let external_module = Rc::new(Module::new(parent_link,
                                                              Some(def_id),
                                                              NormalModuleKind,
                                                              false,
                                                              true));
                    debug!("(build reduced graph for item) found extern `{}`",
1754
                            self.module_to_string(&*external_module));
1755 1756 1757 1758
                    self.check_for_conflicts_between_external_crates(
                        &*parent.module(),
                        name.name,
                        view_item.span);
1759
                    parent.module().external_module_children.borrow_mut()
1760
                                   .insert(name.name, external_module.clone());
1761
                    self.build_reduced_graph_for_external_crate(external_module);
1762 1763 1764 1765 1766
                }
            }
        }
    }

1767
    /// Constructs the reduced graph for one foreign item.
J
Jorge Aparicio 已提交
1768 1769 1770 1771 1772 1773
    fn build_reduced_graph_for_foreign_item<F>(&mut self,
                                               foreign_item: &ForeignItem,
                                               parent: ReducedGraphParent,
                                               f: F) where
        F: FnOnce(&mut Resolver),
    {
1774
        let name = foreign_item.ident.name;
1775
        let is_public = foreign_item.vis == ast::Public;
1776
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
E
Eduard Burtescu 已提交
1777
        let name_bindings =
1778 1779
            self.add_child(name, parent, ForbidDuplicateValues,
                           foreign_item.span);
1780

1781
        match foreign_item.node {
1782
            ForeignItemFn(_, ref generics) => {
1783
                let def = DefFn(local_def(foreign_item.id), false);
1784
                name_bindings.define_value(def, foreign_item.span, modifiers);
1785

1786 1787
                self.with_type_parameter_rib(
                    HasTypeParameters(generics,
1788
                                      FnSpace,
1789 1790
                                      foreign_item.id,
                                      NormalRibKind),
E
Eduard Burtescu 已提交
1791
                    f);
1792
            }
1793
            ForeignItemStatic(_, m) => {
1794
                let def = DefStatic(local_def(foreign_item.id), m);
1795
                name_bindings.define_value(def, foreign_item.span, modifiers);
1796

E
Eduard Burtescu 已提交
1797
                f(self)
1798 1799
            }
        }
1800 1801
    }

F
Felix S. Klock II 已提交
1802
    fn build_reduced_graph_for_block(&mut self,
1803
                                         block: &Block,
A
Alex Crichton 已提交
1804 1805 1806
                                         parent: ReducedGraphParent)
                                            -> ReducedGraphParent
    {
1807
        if self.block_needs_anonymous_module(block) {
1808
            let block_id = block.id;
1809

1810
            debug!("(building reduced graph for block) creating a new \
A
Alex Crichton 已提交
1811
                    anonymous module for block {}",
P
Paul Stansifer 已提交
1812
                   block_id);
1813

E
Eduard Burtescu 已提交
1814 1815 1816
            let parent_module = parent.module();
            let new_module = Rc::new(Module::new(
                BlockParentLink(parent_module.downgrade(), block_id),
1817
                None,
1818
                AnonymousModuleKind,
1819
                false,
E
Eduard Burtescu 已提交
1820
                false));
1821
            parent_module.anonymous_children.borrow_mut()
E
Eduard Burtescu 已提交
1822
                         .insert(block_id, new_module.clone());
1823
            ModuleReducedGraphParent(new_module)
1824
        } else {
A
Alex Crichton 已提交
1825
            parent
1826 1827 1828
        }
    }

A
Alex Crichton 已提交
1829
    fn handle_external_def(&mut self,
1830
                           def: Def,
1831
                           vis: Visibility,
E
Eduard Burtescu 已提交
1832
                           child_name_bindings: &NameBindings,
P
Patrick Walton 已提交
1833
                           final_ident: &str,
1834
                           name: Name,
P
Patrick Walton 已提交
1835
                           new_parent: ReducedGraphParent) {
1836
        debug!("(building reduced graph for \
L
Luqman Aden 已提交
1837
                external crate) building external def, priv {}",
1838
               vis);
1839
        let is_public = vis == ast::Public;
1840
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1841
        let is_exported = is_public && match new_parent {
E
Eduard Burtescu 已提交
1842
            ModuleReducedGraphParent(ref module) => {
1843
                match module.def_id.get() {
1844 1845 1846 1847 1848 1849
                    None => true,
                    Some(did) => self.external_exports.contains(&did)
                }
            }
        };
        if is_exported {
1850
            self.external_exports.insert(def.def_id());
1851
        }
1852 1853

        let kind = match def {
1854
            DefTy(_, true) => EnumModuleKind,
1855 1856 1857 1858
            DefStruct(..) | DefTy(..) => ImplModuleKind,
            _ => NormalModuleKind
        };

1859
        match def {
1860
          DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1861
          DefTy(def_id, _) => {
E
Erick Tryzelaar 已提交
1862 1863
            let type_def = child_name_bindings.type_def.borrow().clone();
            match type_def {
A
Alex Crichton 已提交
1864
              Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1865
                debug!("(building reduced graph for external crate) \
1866
                        already created module");
1867
                module_def.def_id.set(Some(def_id));
1868 1869
              }
              Some(_) | None => {
1870
                debug!("(building reduced graph for \
1871
                        external crate) building module \
A
Alex Crichton 已提交
1872
                        {}", final_ident);
1873
                let parent_link = self.get_parent_link(new_parent.clone(), name);
1874

1875
                child_name_bindings.define_module(parent_link,
P
Patrick Walton 已提交
1876
                                                  Some(def_id),
1877
                                                  kind,
1878
                                                  true,
1879
                                                  is_public,
K
klutzy 已提交
1880
                                                  DUMMY_SP);
1881 1882 1883
              }
            }
          }
1884 1885 1886 1887
          _ => {}
        }

        match def {
1888
          DefMod(_) | DefForeignMod(_) => {}
S
Steven Fackler 已提交
1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902
          DefVariant(_, variant_id, is_struct) => {
              debug!("(building reduced graph for external crate) building \
                      variant {}",
                      final_ident);
              // variants are always treated as importable to allow them to be
              // glob used
              let modifiers = PUBLIC | IMPORTABLE;
              if is_struct {
                  child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                  // Not adding fields for variants as they are not accessed with a self receiver
                  self.structs.insert(variant_id, Vec::new());
              } else {
                  child_name_bindings.define_value(def, DUMMY_SP, modifiers);
              }
1903
          }
1904
          DefFn(ctor_id, true) => {
1905 1906
            child_name_bindings.define_value(
                csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
1907
                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
1908
          }
1909
          DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
1910
            debug!("(building reduced graph for external \
A
Alex Crichton 已提交
1911
                    crate) building value (fn/static) {}", final_ident);
1912 1913 1914 1915 1916 1917 1918 1919 1920
            // impl methods have already been defined with the correct importability modifier
            let mut modifiers = match *child_name_bindings.value_def.borrow() {
                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
                None => modifiers
            };
            if new_parent.module().kind.get() != NormalModuleKind {
                modifiers = modifiers & !IMPORTABLE;
            }
            child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1921
          }
1922
          DefTrait(def_id) => {
1923
              debug!("(building reduced graph for external \
A
Alex Crichton 已提交
1924
                      crate) building type {}", final_ident);
1925

1926 1927
              // If this is a trait, add all the trait item names to the trait
              // info.
1928

1929 1930 1931 1932 1933 1934 1935
              let trait_item_def_ids =
                csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
              for trait_item_def_id in trait_item_def_ids.iter() {
                  let (trait_item_name, trait_item_kind) =
                      csearch::get_trait_item_name_and_kind(
                          &self.session.cstore,
                          trait_item_def_id.def_id());
1936

1937 1938
                  debug!("(building reduced graph for external crate) ... \
                          adding trait item '{}'",
1939
                         token::get_name(trait_item_name));
1940

1941
                  self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
1942

1943
                  if is_exported {
1944 1945
                      self.external_exports
                          .insert(trait_item_def_id.def_id());
1946
                  }
1947 1948
              }

1949
              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1950 1951

              // Define a module if necessary.
1952
              let parent_link = self.get_parent_link(new_parent, name);
1953
              child_name_bindings.set_module_kind(parent_link,
1954 1955
                                                  Some(def_id),
                                                  TraitModuleKind,
1956
                                                  true,
1957
                                                  is_public,
K
klutzy 已提交
1958
                                                  DUMMY_SP)
1959
          }
1960
          DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
1961
              debug!("(building reduced graph for external \
A
Alex Crichton 已提交
1962
                      crate) building type {}", final_ident);
1963

1964
              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1965
          }
1966
          DefStruct(def_id) => {
1967
            debug!("(building reduced graph for external \
A
Alex Crichton 已提交
1968
                    crate) building type and value for {}",
1969
                   final_ident);
1970
            child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1971 1972 1973 1974 1975
            let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
                f.name
            }).collect::<Vec<_>>();

            if fields.len() == 0 {
1976
                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1977
            }
1978 1979 1980

            // Record the def ID and fields of this struct.
            self.structs.insert(def_id, fields);
1981
          }
1982
          DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
A
Alex Crichton 已提交
1983 1984
          DefUse(..) | DefUpvar(..) | DefRegion(..) |
          DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
S
Steve Klabnik 已提交
1985
            panic!("didn't expect `{}`", def);
1986 1987 1988 1989
          }
        }
    }

P
Patrick Walton 已提交
1990
    /// Builds the reduced graph for a single item in an external crate.
A
Alex Crichton 已提交
1991
    fn build_reduced_graph_for_external_crate_def(&mut self,
E
Eduard Burtescu 已提交
1992
                                                  root: Rc<Module>,
1993
                                                  def_like: DefLike,
1994
                                                  name: Name,
1995
                                                  visibility: Visibility) {
P
Patrick Walton 已提交
1996
        match def_like {
1997
            DlDef(def) => {
P
Patrick Walton 已提交
1998
                // Add the new child item, if necessary.
1999
                match def {
2000
                    DefForeignMod(def_id) => {
2001 2002
                        // Foreign modules have no names. Recur and populate
                        // eagerly.
E
Eduard Burtescu 已提交
2003
                        csearch::each_child_of_item(&self.session.cstore,
2004 2005
                                                    def_id,
                                                    |def_like,
2006
                                                     child_name,
2007
                                                     vis| {
2008
                            self.build_reduced_graph_for_external_crate_def(
E
Eduard Burtescu 已提交
2009
                                root.clone(),
2010
                                def_like,
2011
                                child_name,
2012
                                vis)
2013
                        });
2014
                    }
P
Patrick Walton 已提交
2015
                    _ => {
E
Eduard Burtescu 已提交
2016
                        let child_name_bindings =
2017
                            self.add_child(name,
E
Eduard Burtescu 已提交
2018
                                           ModuleReducedGraphParent(root.clone()),
P
Patrick Walton 已提交
2019
                                           OverwriteDuplicates,
K
klutzy 已提交
2020
                                           DUMMY_SP);
P
Patrick Walton 已提交
2021 2022

                        self.handle_external_def(def,
2023
                                                 visibility,
E
Eduard Burtescu 已提交
2024
                                                 &*child_name_bindings,
2025 2026
                                                 token::get_name(name).get(),
                                                 name,
E
Eduard Burtescu 已提交
2027
                                                 ModuleReducedGraphParent(root));
2028 2029 2030
                    }
                }
            }
2031
            DlImpl(def) => {
E
Eduard Burtescu 已提交
2032
                match csearch::get_type_name_if_impl(&self.session.cstore, def) {
P
Patrick Walton 已提交
2033
                    None => {}
2034
                    Some(final_name) => {
N
Nick Cameron 已提交
2035 2036 2037 2038 2039
                        let methods_opt =
                            csearch::get_methods_if_impl(&self.session.cstore, def);
                        match methods_opt {
                            Some(ref methods) if
                                methods.len() >= 1 => {
2040
                                debug!("(building reduced graph for \
P
Patrick Walton 已提交
2041
                                        external crate) processing \
A
Alex Crichton 已提交
2042
                                        static methods for type name {}",
2043
                                        token::get_name(final_name));
P
Patrick Walton 已提交
2044

E
Eduard Burtescu 已提交
2045
                                let child_name_bindings =
P
Patrick Walton 已提交
2046
                                    self.add_child(
2047
                                        final_name,
E
Eduard Burtescu 已提交
2048
                                        ModuleReducedGraphParent(root.clone()),
P
Patrick Walton 已提交
2049
                                        OverwriteDuplicates,
K
klutzy 已提交
2050
                                        DUMMY_SP);
P
Patrick Walton 已提交
2051 2052 2053 2054

                                // Process the static methods. First,
                                // create the module.
                                let type_module;
E
Erick Tryzelaar 已提交
2055 2056
                                let type_def = child_name_bindings.type_def.borrow().clone();
                                match type_def {
P
Patrick Walton 已提交
2057 2058
                                    Some(TypeNsDef {
                                        module_def: Some(module_def),
A
Alex Crichton 已提交
2059
                                        ..
P
Patrick Walton 已提交
2060 2061 2062 2063 2064 2065 2066
                                    }) => {
                                        // We already have a module. This
                                        // is OK.
                                        type_module = module_def;

                                        // Mark it as an impl module if
                                        // necessary.
2067
                                        type_module.kind.set(ImplModuleKind);
2068
                                    }
P
Patrick Walton 已提交
2069 2070
                                    Some(_) | None => {
                                        let parent_link =
E
Eduard Burtescu 已提交
2071
                                            self.get_parent_link(ModuleReducedGraphParent(root),
2072
                                                                 final_name);
P
Patrick Walton 已提交
2073 2074 2075 2076
                                        child_name_bindings.define_module(
                                            parent_link,
                                            Some(def),
                                            ImplModuleKind,
2077
                                            true,
2078
                                            true,
K
klutzy 已提交
2079
                                            DUMMY_SP);
P
Patrick Walton 已提交
2080 2081 2082
                                        type_module =
                                            child_name_bindings.
                                                get_module();
2083 2084 2085
                                    }
                                }

P
Patrick Walton 已提交
2086 2087 2088
                                // Add each static method to the module.
                                let new_parent =
                                    ModuleReducedGraphParent(type_module);
N
Nick Cameron 已提交
2089 2090
                                for method_info in methods.iter() {
                                    let name = method_info.name;
2091
                                    debug!("(building reduced graph for \
P
Patrick Walton 已提交
2092
                                             external crate) creating \
A
Alex Crichton 已提交
2093
                                             static method '{}'",
2094
                                           token::get_name(name));
P
Patrick Walton 已提交
2095

E
Eduard Burtescu 已提交
2096
                                    let method_name_bindings =
2097
                                        self.add_child(name,
E
Eduard Burtescu 已提交
2098
                                                       new_parent.clone(),
P
Patrick Walton 已提交
2099
                                                       OverwriteDuplicates,
K
klutzy 已提交
2100
                                                       DUMMY_SP);
N
Nick Cameron 已提交
2101
                                    let def = DefFn(method_info.def_id, false);
2102

2103 2104 2105 2106 2107 2108
                                    // NB: not IMPORTABLE
                                    let modifiers = if visibility == ast::Public {
                                        PUBLIC
                                    } else {
                                        DefModifiers::empty()
                                    };
P
Patrick Walton 已提交
2109
                                    method_name_bindings.define_value(
2110
                                        def, DUMMY_SP, modifiers);
P
Patrick Walton 已提交
2111
                                }
2112
                            }
P
Patrick Walton 已提交
2113 2114 2115

                            // Otherwise, do nothing.
                            Some(_) | None => {}
2116 2117
                        }
                    }
2118 2119
                }
            }
2120
            DlField => {
2121
                debug!("(building reduced graph for external crate) \
P
Patrick Walton 已提交
2122 2123 2124 2125 2126
                        ignoring field");
            }
        }
    }

2127
    /// Builds the reduced graph rooted at the given external module.
E
Eduard Burtescu 已提交
2128
    fn populate_external_module(&mut self, module: Rc<Module>) {
2129
        debug!("(populating external module) attempting to populate {}",
2130
               self.module_to_string(&*module));
2131

2132
        let def_id = match module.def_id.get() {
2133
            None => {
2134
                debug!("(populating external module) ... no def ID!");
2135 2136
                return
            }
2137 2138 2139
            Some(def_id) => def_id,
        };

E
Eduard Burtescu 已提交
2140
        csearch::each_child_of_item(&self.session.cstore,
2141
                                    def_id,
2142
                                    |def_like, child_name, visibility| {
2143
            debug!("(populating external module) ... found ident: {}",
2144
                   token::get_name(child_name));
E
Eduard Burtescu 已提交
2145
            self.build_reduced_graph_for_external_crate_def(module.clone(),
2146
                                                            def_like,
2147
                                                            child_name,
2148
                                                            visibility)
2149
        });
2150
        module.populated.set(true)
2151 2152 2153 2154
    }

    /// Ensures that the reduced graph rooted at the given external module
    /// is built, building it if it is not.
E
Eduard Burtescu 已提交
2155
    fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2156
        if !module.populated.get() {
E
Eduard Burtescu 已提交
2157
            self.populate_external_module(module.clone())
2158
        }
2159
        assert!(module.populated.get())
2160 2161
    }

P
Patrick Walton 已提交
2162 2163
    /// Builds the reduced graph rooted at the 'use' directive for an external
    /// crate.
E
Eduard Burtescu 已提交
2164
    fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
E
Eduard Burtescu 已提交
2165
        csearch::each_top_level_item_of_crate(&self.session.cstore,
2166 2167 2168
                                              root.def_id
                                                  .get()
                                                  .unwrap()
2169
                                                  .krate,
2170
                                              |def_like, name, visibility| {
E
Eduard Burtescu 已提交
2171
            self.build_reduced_graph_for_external_crate_def(root.clone(),
P
Patrick Walton 已提交
2172
                                                            def_like,
2173
                                                            name,
2174
                                                            visibility)
2175
        });
2176 2177
    }

2178
    /// Creates and adds an import directive to the given module.
F
Felix S. Klock II 已提交
2179
    fn build_import_directive(&mut self,
E
Eduard Burtescu 已提交
2180
                              module_: &Module,
2181
                              module_path: Vec<Name>,
E
Eduard Burtescu 已提交
2182
                              subclass: ImportDirectiveSubclass,
2183 2184
                              span: Span,
                              id: NodeId,
2185
                              is_public: bool,
2186
                              shadowable: Shadowable) {
E
Eduard Burtescu 已提交
2187 2188
        module_.imports.borrow_mut().push(ImportDirective::new(module_path,
                                                               subclass,
2189 2190 2191 2192
                                                               span,
                                                               id,
                                                               is_public,
                                                               shadowable));
E
Eduard Burtescu 已提交
2193
        self.unresolved_imports += 1;
2194 2195 2196
        // Bump the reference count on the name. Or, if this is a glob, set
        // the appropriate flag.

E
Eduard Burtescu 已提交
2197
        match subclass {
2198
            SingleImport(target, _) => {
2199
                debug!("(building import directive) building import \
2200
                        directive: {}::{}",
2201
                       self.names_to_string(module_.imports.borrow().last().unwrap()
A
Alex Crichton 已提交
2202
                                                 .module_path[]),
2203
                       token::get_name(target));
2204

2205 2206
                let mut import_resolutions = module_.import_resolutions
                                                    .borrow_mut();
2207
                match import_resolutions.get_mut(&target) {
E
Eduard Burtescu 已提交
2208
                    Some(resolution) => {
2209
                        debug!("(building import directive) bumping \
2210
                                reference");
E
Eduard Burtescu 已提交
2211
                        resolution.outstanding_references += 1;
2212 2213

                        // the source of this name is different now
E
Eduard Burtescu 已提交
2214 2215 2216 2217
                        resolution.type_id = id;
                        resolution.value_id = id;
                        resolution.is_public = is_public;
                        return;
2218
                    }
E
Eduard Burtescu 已提交
2219
                    None => {}
2220
                }
E
Eduard Burtescu 已提交
2221 2222 2223
                debug!("(building import directive) creating new");
                let mut resolution = ImportResolution::new(id, is_public);
                resolution.outstanding_references = 1;
2224
                import_resolutions.insert(target, resolution);
2225
            }
B
Brian Anderson 已提交
2226
            GlobImport => {
2227 2228 2229
                // Set the glob flag. This tells us that we don't know the
                // module's exports ahead of time.

2230
                module_.glob_count.set(module_.glob_count.get() + 1);
2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
            }
        }
    }

    // Import resolution
    //
    // This is a fixed-point algorithm. We resolve imports until our efforts
    // are stymied by an unresolved import; then we bail out of the current
    // module and continue. We terminate successfully once no more imports
    // remain or unsuccessfully when no forward progress in resolving imports
    // is made.

2243 2244
    /// Resolves all imports for the crate. This method performs the fixed-
    /// point iteration.
F
Felix S. Klock II 已提交
2245
    fn resolve_imports(&mut self) {
2246
        let mut i = 0u;
T
Tim Chevalier 已提交
2247
        let mut prev_unresolved_imports = 0;
2248
        loop {
2249
            debug!("(resolving imports) iteration {}, {} imports left",
P
Paul Stansifer 已提交
2250
                   i, self.unresolved_imports);
2251

2252
            let module_root = self.graph_root.get_module();
E
Eduard Burtescu 已提交
2253
            self.resolve_imports_for_module_subtree(module_root.clone());
2254

T
Tim Chevalier 已提交
2255
            if self.unresolved_imports == 0 {
2256
                debug!("(resolving imports) success");
2257 2258 2259 2260 2261 2262 2263 2264
                break;
            }

            if self.unresolved_imports == prev_unresolved_imports {
                self.report_unresolved_imports(module_root);
                break;
            }

T
Tim Chevalier 已提交
2265
            i += 1;
2266 2267 2268 2269
            prev_unresolved_imports = self.unresolved_imports;
        }
    }

2270 2271
    /// Attempts to resolve imports for the given module and all of its
    /// submodules.
E
Eduard Burtescu 已提交
2272
    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2273
        debug!("(resolving imports for module subtree) resolving {}",
2274
               self.module_to_string(&*module_));
2275
        let orig_module = replace(&mut self.current_module, module_.clone());
E
Eduard Burtescu 已提交
2276
        self.resolve_imports_for_module(module_.clone());
2277
        self.current_module = orig_module;
2278

E
Eduard Burtescu 已提交
2279 2280
        self.populate_module_if_necessary(&module_);
        for (_, child_node) in module_.children.borrow().iter() {
2281 2282 2283 2284 2285 2286
            match child_node.get_module_if_available() {
                None => {
                    // Nothing to do.
                }
                Some(child_module) => {
                    self.resolve_imports_for_module_subtree(child_module);
2287 2288 2289 2290
                }
            }
        }

E
Eduard Burtescu 已提交
2291 2292
        for (_, child_module) in module_.anonymous_children.borrow().iter() {
            self.resolve_imports_for_module_subtree(child_module.clone());
2293 2294 2295
        }
    }

2296
    /// Attempts to resolve imports for the given module only.
E
Eduard Burtescu 已提交
2297
    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2298
        if module.all_imports_resolved() {
2299
            debug!("(resolving imports for module) all imports resolved for \
A
Alex Crichton 已提交
2300
                   {}",
2301
                   self.module_to_string(&*module));
B
Brian Anderson 已提交
2302
            return;
2303 2304
        }

2305
        let imports = module.imports.borrow();
2306
        let import_count = imports.len();
2307 2308
        while module.resolved_import_count.get() < import_count {
            let import_index = module.resolved_import_count.get();
2309
            let import_directive = &(*imports)[import_index];
2310 2311
            match self.resolve_import_for_module(module.clone(),
                                                 import_directive) {
2312 2313 2314 2315 2316 2317
                Failed(err) => {
                    let (span, help) = match err {
                        Some((span, msg)) => (span, format!(". {}", msg)),
                        None => (import_directive.span, String::new())
                    };
                    let msg = format!("unresolved import `{}`{}",
2318
                                      self.import_path_to_string(
2319
                                          import_directive.module_path
A
Alex Crichton 已提交
2320
                                                          [],
2321 2322
                                          import_directive.subclass),
                                      help);
A
Alex Crichton 已提交
2323
                    self.resolve_error(span, msg[]);
2324
                }
2325 2326
                Indeterminate => break, // Bail out. We'll come around next time.
                Success(()) => () // Good. Continue.
2327 2328
            }

2329 2330
            module.resolved_import_count
                  .set(module.resolved_import_count.get() + 1);
2331 2332 2333
        }
    }

2334
    fn names_to_string(&self, names: &[Name]) -> String {
2335
        let mut first = true;
2336
        let mut result = String::new();
2337
        for name in names.iter() {
2338 2339 2340 2341 2342
            if first {
                first = false
            } else {
                result.push_str("::")
            }
2343
            result.push_str(token::get_name(*name).get());
2344
        };
2345
        result
P
Paul Stansifer 已提交
2346
    }
2347

2348 2349 2350 2351 2352
    fn path_names_to_string(&self, path: &Path) -> String {
        let names: Vec<ast::Name> = path.segments
                                        .iter()
                                        .map(|seg| seg.identifier.name)
                                        .collect();
A
Alex Crichton 已提交
2353
        self.names_to_string(names[])
2354 2355
    }

2356
    fn import_directive_subclass_to_string(&mut self,
P
Patrick Walton 已提交
2357
                                        subclass: ImportDirectiveSubclass)
2358
                                        -> String {
2359
        match subclass {
2360
            SingleImport(_, source) => {
2361
                token::get_name(source).get().to_string()
P
Patrick Walton 已提交
2362
            }
2363
            GlobImport => "*".to_string()
2364 2365
        }
    }
2366

2367
    fn import_path_to_string(&mut self,
2368
                          names: &[Name],
P
Patrick Walton 已提交
2369
                          subclass: ImportDirectiveSubclass)
2370
                          -> String {
2371
        if names.is_empty() {
2372
            self.import_directive_subclass_to_string(subclass)
2373
        } else {
A
Alex Crichton 已提交
2374
            (format!("{}::{}",
2375
                     self.names_to_string(names),
2376
                     self.import_directive_subclass_to_string(
2377
                         subclass))).to_string()
2378 2379
        }
    }
2380

2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
    #[inline]
    fn record_import_use(&mut self, import_id: NodeId, name: Name) {
        if !self.make_glob_map {
            return;
        }
        if self.glob_map.contains_key(&import_id) {
            self.glob_map[import_id].insert(name);
            return;
        }

        let mut new_set = HashSet::new();
        new_set.insert(name);
        self.glob_map.insert(import_id, new_set);
    }

    fn get_trait_name(&self, did: DefId) -> Name {
        if did.krate == LOCAL_CRATE {
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

2404 2405 2406 2407 2408
    /// Attempts to resolve the given import. The return value indicates
    /// failure if we're certain the name does not exist, indeterminate if we
    /// don't know whether the name exists at the moment due to other
    /// currently-unresolved imports, or success if we know the name exists.
    /// If successful, the resolved bindings are written into the module.
F
Felix S. Klock II 已提交
2409
    fn resolve_import_for_module(&mut self,
E
Eduard Burtescu 已提交
2410 2411
                                 module_: Rc<Module>,
                                 import_directive: &ImportDirective)
2412
                                 -> ResolveResult<()> {
2413
        let mut resolution_result = Failed(None);
A
Alex Crichton 已提交
2414
        let module_path = &import_directive.module_path;
2415

2416
        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
A
Alex Crichton 已提交
2417
               self.names_to_string(module_path[]),
2418
               self.module_to_string(&*module_));
2419

2420
        // First, resolve the module path for the directive, if necessary.
2421
        let container = if module_path.len() == 0 {
2422
            // Use the crate root.
2423
            Some((self.graph_root.get_module(), LastMod(AllPublic)))
2424
        } else {
E
Eduard Burtescu 已提交
2425
            match self.resolve_module_path(module_.clone(),
A
Alex Crichton 已提交
2426
                                           module_path[],
2427 2428 2429
                                           DontUseLexicalScope,
                                           import_directive.span,
                                           ImportSearch) {
2430 2431 2432 2433
                Failed(err) => {
                    resolution_result = Failed(err);
                    None
                },
B
Brian Anderson 已提交
2434
                Indeterminate => {
2435
                    resolution_result = Indeterminate;
2436
                    None
2437
                }
2438
                Success(container) => Some(container),
2439 2440 2441
            }
        };

2442
        match container {
2443
            None => {}
2444
            Some((containing_module, lp)) => {
2445 2446 2447
                // We found the module that the target is contained
                // within. Attempt to resolve the import within it.

E
Eduard Burtescu 已提交
2448
                match import_directive.subclass {
2449
                    SingleImport(target, source) => {
2450
                        resolution_result =
E
Eduard Burtescu 已提交
2451
                            self.resolve_single_import(&*module_,
2452 2453
                                                       containing_module,
                                                       target,
2454
                                                       source,
2455 2456
                                                       import_directive,
                                                       lp);
2457 2458 2459
                    }
                    GlobImport => {
                        resolution_result =
E
Eduard Burtescu 已提交
2460
                            self.resolve_glob_import(&*module_,
2461
                                                     containing_module,
2462
                                                     import_directive,
2463
                                                     lp);
2464 2465 2466 2467 2468 2469
                    }
                }
            }
        }

        // Decrement the count of unresolved imports.
2470
        match resolution_result {
B
Brian Anderson 已提交
2471
            Success(()) => {
P
Patrick Walton 已提交
2472
                assert!(self.unresolved_imports >= 1);
T
Tim Chevalier 已提交
2473
                self.unresolved_imports -= 1;
2474
            }
B
Brian Anderson 已提交
2475
            _ => {
2476 2477 2478 2479 2480 2481 2482 2483 2484
                // Nothing to do here; just return the error.
            }
        }

        // Decrement the count of unresolved globs if necessary. But only if
        // the resolution result is indeterminate -- otherwise we'll stop
        // processing imports here. (See the loop in
        // resolve_imports_for_module.)

2485
        if !resolution_result.indeterminate() {
E
Eduard Burtescu 已提交
2486
            match import_directive.subclass {
B
Brian Anderson 已提交
2487
                GlobImport => {
2488 2489
                    assert!(module_.glob_count.get() >= 1);
                    module_.glob_count.set(module_.glob_count.get() - 1);
2490
                }
A
Alex Crichton 已提交
2491
                SingleImport(..) => {
2492 2493 2494 2495 2496
                    // Ignore.
                }
            }
        }

B
Brian Anderson 已提交
2497
        return resolution_result;
2498 2499
    }

E
Eduard Burtescu 已提交
2500
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2501
        NameBindings {
2502
            type_def: RefCell::new(Some(TypeNsDef {
2503
                modifiers: IMPORTABLE,
2504 2505
                module_def: Some(module),
                type_def: None,
2506
                type_span: None
2507
            })),
2508
            value_def: RefCell::new(None),
2509 2510 2511
        }
    }

F
Felix S. Klock II 已提交
2512
    fn resolve_single_import(&mut self,
E
Eduard Burtescu 已提交
2513 2514
                             module_: &Module,
                             containing_module: Rc<Module>,
2515 2516
                             target: Name,
                             source: Name,
2517 2518
                             directive: &ImportDirective,
                             lp: LastPrivate)
2519
                                 -> ResolveResult<()> {
2520
        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
L
Luqman Aden 已提交
2521
                `{}` id {}, last private {}",
2522
               token::get_name(target),
2523
               self.module_to_string(&*containing_module),
2524
               token::get_name(source),
2525
               self.module_to_string(module_),
2526 2527
               directive.id,
               lp);
2528

2529 2530
        let lp = match lp {
            LastMod(lp) => lp,
2531 2532 2533 2534 2535
            LastImport {..} => {
                self.session
                    .span_bug(directive.span,
                              "not expecting Import here, must be LastMod")
            }
2536 2537
        };

2538
        // We need to resolve both namespaces for this to succeed.
2539 2540 2541 2542 2543 2544
        //

        let mut value_result = UnknownResult;
        let mut type_result = UnknownResult;

        // Search for direct children of the containing module.
E
Eduard Burtescu 已提交
2545
        self.populate_module_if_necessary(&containing_module);
2546

2547
        match containing_module.children.borrow().get(&source) {
2548 2549 2550
            None => {
                // Continue.
            }
E
Eduard Burtescu 已提交
2551
            Some(ref child_name_bindings) => {
2552
                if child_name_bindings.defined_in_namespace(ValueNS) {
2553
                    debug!("(resolving single import) found value binding");
E
Eduard Burtescu 已提交
2554 2555
                    value_result = BoundResult(containing_module.clone(),
                                               (*child_name_bindings).clone());
2556
                }
2557
                if child_name_bindings.defined_in_namespace(TypeNS) {
2558
                    debug!("(resolving single import) found type binding");
E
Eduard Burtescu 已提交
2559 2560
                    type_result = BoundResult(containing_module.clone(),
                                              (*child_name_bindings).clone());
2561 2562 2563 2564
                }
            }
        }

2565 2566
        // Unless we managed to find a result in both namespaces (unlikely),
        // search imports as well.
2567 2568
        let mut value_used_reexport = false;
        let mut type_used_reexport = false;
E
Eduard Burtescu 已提交
2569
        match (value_result.clone(), type_result.clone()) {
A
Alex Crichton 已提交
2570
            (BoundResult(..), BoundResult(..)) => {} // Continue.
B
Brian Anderson 已提交
2571
            _ => {
2572 2573 2574 2575
                // If there is an unresolved glob at this point in the
                // containing module, bail out. We don't know enough to be
                // able to resolve this import.

2576
                if containing_module.glob_count.get() > 0 {
2577
                    debug!("(resolving single import) unresolved glob; \
P
Paul Stansifer 已提交
2578
                            bailing out");
B
Brian Anderson 已提交
2579
                    return Indeterminate;
2580 2581
                }

E
Eduard Burtescu 已提交
2582
                // Now search the exported imports within the containing module.
2583
                match containing_module.import_resolutions.borrow().get(&source) {
B
Brian Anderson 已提交
2584
                    None => {
2585
                        debug!("(resolving single import) no import");
2586 2587 2588 2589 2590
                        // The containing module definitely doesn't have an
                        // exported import with the name in question. We can
                        // therefore accurately report that the names are
                        // unbound.

2591
                        if value_result.is_unknown() {
2592 2593
                            value_result = UnboundResult;
                        }
2594
                        if type_result.is_unknown() {
2595 2596 2597
                            type_result = UnboundResult;
                        }
                    }
B
Brian Anderson 已提交
2598
                    Some(import_resolution)
E
Eduard Burtescu 已提交
2599
                            if import_resolution.outstanding_references == 0 => {
2600

A
Alex Crichton 已提交
2601
                        fn get_binding(this: &mut Resolver,
E
Eduard Burtescu 已提交
2602
                                       import_resolution: &ImportResolution,
2603 2604
                                       namespace: Namespace,
                                       source: &Name)
2605
                                    -> NamespaceResult {
T
Tim Chevalier 已提交
2606

2607 2608
                            // Import resolutions must be declared with "pub"
                            // in order to be exported.
E
Eduard Burtescu 已提交
2609
                            if !import_resolution.is_public {
2610 2611 2612
                                return UnboundResult;
                            }

E
Eduard Burtescu 已提交
2613
                            match import_resolution.
2614
                                    target_for_namespace(namespace) {
B
Brian Anderson 已提交
2615
                                None => {
B
Brian Anderson 已提交
2616
                                    return UnboundResult;
2617
                                }
2618 2619 2620 2621 2622
                                Some(Target {
                                    target_module,
                                    bindings,
                                    shadowable: _
                                }) => {
2623
                                    debug!("(resolving single import) found \
L
Luqman Aden 已提交
2624
                                            import in ns {}", namespace);
2625
                                    let id = import_resolution.id(namespace);
2626
                                    // track used imports and extern crates as well
2627
                                    this.used_imports.insert((id, namespace));
2628
                                    this.record_import_use(id, *source);
2629 2630 2631 2632 2633 2634
                                    match target_module.def_id.get() {
                                        Some(DefId{krate: kid, ..}) => {
                                            this.used_crates.insert(kid);
                                        },
                                        _ => {}
                                    }
E
Eduard Burtescu 已提交
2635
                                    return BoundResult(target_module, bindings);
2636 2637 2638 2639 2640 2641
                                }
                            }
                        }

                        // The name is an import which has been fully
                        // resolved. We can, therefore, just follow it.
2642
                        if value_result.is_unknown() {
2643 2644 2645 2646
                            value_result = get_binding(self,
                                                       import_resolution,
                                                       ValueNS,
                                                       &source);
E
Eduard Burtescu 已提交
2647
                            value_used_reexport = import_resolution.is_public;
2648
                        }
2649
                        if type_result.is_unknown() {
2650 2651 2652 2653
                            type_result = get_binding(self,
                                                      import_resolution,
                                                      TypeNS,
                                                      &source);
E
Eduard Burtescu 已提交
2654
                            type_used_reexport = import_resolution.is_public;
2655
                        }
2656

2657
                    }
B
Brian Anderson 已提交
2658
                    Some(_) => {
2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686
                        // If containing_module is the same module whose import we are resolving
                        // and there it has an unresolved import with the same name as `source`,
                        // then the user is actually trying to import an item that is declared
                        // in the same scope
                        //
                        // e.g
                        // use self::submodule;
                        // pub mod submodule;
                        //
                        // In this case we continue as if we resolved the import and let the
                        // check_for_conflicts_between_imports_and_items call below handle
                        // the conflict
                        match (module_.def_id.get(),  containing_module.def_id.get()) {
                            (Some(id1), Some(id2)) if id1 == id2  => {
                                if value_result.is_unknown() {
                                    value_result = UnboundResult;
                                }
                                if type_result.is_unknown() {
                                    type_result = UnboundResult;
                                }
                            }
                            _ =>  {
                                // The import is unresolved. Bail out.
                                debug!("(resolving single import) unresolved import; \
                                        bailing out");
                                return Indeterminate;
                            }
                        }
2687 2688 2689 2690 2691
                    }
                }
            }
        }

2692 2693
        // If we didn't find a result in the type namespace, search the
        // external modules.
2694 2695
        let mut value_used_public = false;
        let mut type_used_public = false;
2696
        match type_result {
A
Alex Crichton 已提交
2697
            BoundResult(..) => {}
2698
            _ => {
2699
                match containing_module.external_module_children.borrow_mut()
2700
                                       .get(&source).cloned() {
2701 2702
                    None => {} // Continue.
                    Some(module) => {
2703 2704
                        debug!("(resolving single import) found external \
                                module");
2705 2706 2707 2708 2709
                        // track the module as used.
                        match module.def_id.get() {
                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
                            _ => {}
                        }
2710
                        let name_bindings =
E
Eduard Burtescu 已提交
2711 2712 2713
                            Rc::new(Resolver::create_name_bindings_from_module(
                                module));
                        type_result = BoundResult(containing_module.clone(),
2714
                                                  name_bindings);
2715
                        type_used_public = true;
2716 2717 2718 2719 2720
                    }
                }
            }
        }

2721
        // We've successfully resolved the import. Write the results in.
E
Eduard Burtescu 已提交
2722
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
2723
        let import_resolution = &mut (*import_resolutions)[target];
2724 2725 2726 2727 2728 2729
        {
            let check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
                let namespace_name = match namespace {
                    TypeNS => "type",
                    ValueNS => "value",
                };
2730

2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762
                match *result {
                    BoundResult(ref target_module, ref name_bindings) => {
                        debug!("(resolving single import) found {} target: {}",
                               namespace_name,
                               name_bindings.def_for_namespace(namespace));
                        self.check_for_conflicting_import(
                            &import_resolution.target_for_namespace(namespace),
                            directive.span,
                            target,
                            namespace);

                        self.check_that_import_is_importable(
                            &**name_bindings,
                            directive.span,
                            target,
                            namespace);

                        let target = Some(Target::new(target_module.clone(),
                                                      name_bindings.clone(),
                                                      directive.shadowable));
                        import_resolution.set_target_and_id(namespace, target, directive.id);
                        import_resolution.is_public = directive.is_public;
                        *used_public = name_bindings.defined_in_public_namespace(namespace);
                    }
                    UnboundResult => { /* Continue. */ }
                    UnknownResult => {
                        panic!("{} result should be known at this point", namespace_name);
                    }
                }
            };
            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
2763 2764
        }

2765 2766 2767 2768
        self.check_for_conflicts_between_imports_and_items(
            module_,
            import_resolution,
            directive.span,
2769
            target);
2770

2771
        if value_result.is_unbound() && type_result.is_unbound() {
2772
            let msg = format!("There is no `{}` in `{}`",
2773
                              token::get_name(source),
2774
                              self.module_to_string(&*containing_module));
2775
            return Failed(Some((directive.span, msg)));
2776
        }
2777 2778
        let value_used_public = value_used_reexport || value_used_public;
        let type_used_public = type_used_reexport || type_used_public;
2779

E
Eduard Burtescu 已提交
2780 2781
        assert!(import_resolution.outstanding_references >= 1);
        import_resolution.outstanding_references -= 1;
2782

A
Alex Crichton 已提交
2783 2784 2785
        // record what this import resolves to for later uses in documentation,
        // this may resolve to either a value or a type, but for documentation
        // purposes it's good enough to just favor one over the other.
E
Eduard Burtescu 已提交
2786 2787
        let value_private = match import_resolution.value_target {
            Some(ref target) => {
2788
                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2789
                self.def_map.borrow_mut().insert(directive.id, def);
2790
                let did = def.def_id();
2791 2792 2793 2794 2795 2796
                if value_used_public {Some(lp)} else {Some(DependsOn(did))}
            },
            // AllPublic here and below is a dummy value, it should never be used because
            // _exists is false.
            None => None,
        };
E
Eduard Burtescu 已提交
2797 2798
        let type_private = match import_resolution.type_target {
            Some(ref target) => {
2799
                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2800
                self.def_map.borrow_mut().insert(directive.id, def);
2801
                let did = def.def_id();
2802 2803 2804 2805 2806 2807 2808 2809 2810
                if type_used_public {Some(lp)} else {Some(DependsOn(did))}
            },
            None => None,
        };

        self.last_private.insert(directive.id, LastImport{value_priv: value_private,
                                                          value_used: Used,
                                                          type_priv: type_private,
                                                          type_used: Used});
A
Alex Crichton 已提交
2811

2812
        debug!("(resolving single import) successfully resolved import");
B
Brian Anderson 已提交
2813
        return Success(());
2814 2815
    }

2816
    // Resolves a glob import. Note that this function cannot fail; it either
2817
    // succeeds or bails out (as importing * from an empty module or a module
2818 2819
    // that exports nothing is valid). containing_module is the module we are
    // actually importing, i.e., `foo` in `use foo::*`.
F
Felix S. Klock II 已提交
2820
    fn resolve_glob_import(&mut self,
E
Eduard Burtescu 已提交
2821 2822
                           module_: &Module,
                           containing_module: Rc<Module>,
2823
                           import_directive: &ImportDirective,
2824 2825
                           lp: LastPrivate)
                           -> ResolveResult<()> {
2826 2827 2828
        let id = import_directive.id;
        let is_public = import_directive.is_public;

2829 2830 2831
        // This function works in a highly imperative manner; it eagerly adds
        // everything it can to the list of import resolutions of the module
        // node.
2832
        debug!("(resolving glob import) resolving glob import {}", id);
2833 2834 2835 2836

        // We must bail out if the node has unresolved imports of any kind
        // (including globs).
        if !(*containing_module).all_imports_resolved() {
2837
            debug!("(resolving glob import) target module has unresolved \
P
Paul Stansifer 已提交
2838
                    imports; bailing out");
B
Brian Anderson 已提交
2839
            return Indeterminate;
2840 2841
        }

2842
        assert_eq!(containing_module.glob_count.get(), 0);
2843 2844

        // Add all resolved imports from the containing module.
2845
        let import_resolutions = containing_module.import_resolutions.borrow();
2846
        for (ident, target_import_resolution) in import_resolutions.iter() {
2847
            debug!("(resolving glob import) writing module resolution \
L
Luqman Aden 已提交
2848
                    {} into `{}`",
2849
                   token::get_name(*ident),
2850
                   self.module_to_string(module_));
2851

E
Eduard Burtescu 已提交
2852
            if !target_import_resolution.is_public {
2853
                debug!("(resolving glob import) nevermind, just kidding");
2854 2855 2856
                continue
            }

2857
            // Here we merge two import resolutions.
2858
            let mut import_resolutions = module_.import_resolutions.borrow_mut();
2859
            match import_resolutions.get_mut(ident) {
E
Eduard Burtescu 已提交
2860
                Some(dest_import_resolution) => {
2861 2862 2863
                    // Merge the two import resolutions at a finer-grained
                    // level.

E
Eduard Burtescu 已提交
2864
                    match target_import_resolution.value_target {
B
Brian Anderson 已提交
2865
                        None => {
2866 2867
                            // Continue.
                        }
E
Eduard Burtescu 已提交
2868
                        Some(ref value_target) => {
2869
                            dest_import_resolution.value_target = Some(value_target.clone());
2870 2871
                        }
                    }
E
Eduard Burtescu 已提交
2872
                    match target_import_resolution.type_target {
B
Brian Anderson 已提交
2873
                        None => {
2874 2875
                            // Continue.
                        }
E
Eduard Burtescu 已提交
2876
                        Some(ref type_target) => {
2877
                            dest_import_resolution.type_target = Some(type_target.clone());
2878 2879
                        }
                    }
E
Eduard Burtescu 已提交
2880 2881
                    dest_import_resolution.is_public = is_public;
                    continue;
2882
                }
E
Eduard Burtescu 已提交
2883
                None => {}
2884
            }
E
Eduard Burtescu 已提交
2885 2886 2887 2888 2889 2890 2891 2892 2893

            // Simple: just copy the old import resolution.
            let mut new_import_resolution = ImportResolution::new(id, is_public);
            new_import_resolution.value_target =
                target_import_resolution.value_target.clone();
            new_import_resolution.type_target =
                target_import_resolution.type_target.clone();

            import_resolutions.insert(*ident, new_import_resolution);
2894 2895
        }

2896
        // Add all children from the containing module.
E
Eduard Burtescu 已提交
2897
        self.populate_module_if_necessary(&containing_module);
2898

2899
        for (&name, name_bindings) in containing_module.children.borrow().iter() {
2900 2901 2902 2903 2904 2905
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings.clone());

2906 2907 2908
        }

        // Add external module children from the containing module.
2909
        for (&name, module) in containing_module.external_module_children.borrow().iter() {
2910
            let name_bindings =
E
Eduard Burtescu 已提交
2911
                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2912 2913 2914 2915 2916
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings);
2917 2918
        }

A
Alex Crichton 已提交
2919
        // Record the destination of this import
2920
        match containing_module.def_id.get() {
A
Alex Crichton 已提交
2921
            Some(did) => {
2922
                self.def_map.borrow_mut().insert(id, DefMod(did));
2923
                self.last_private.insert(id, lp);
A
Alex Crichton 已提交
2924 2925 2926 2927
            }
            None => {}
        }

2928
        debug!("(resolving glob import) successfully resolved import");
B
Brian Anderson 已提交
2929
        return Success(());
2930 2931
    }

2932
    fn merge_import_resolution(&mut self,
E
Eduard Burtescu 已提交
2933 2934
                               module_: &Module,
                               containing_module: Rc<Module>,
2935
                               import_directive: &ImportDirective,
2936
                               name: Name,
E
Eduard Burtescu 已提交
2937
                               name_bindings: Rc<NameBindings>) {
2938 2939 2940
        let id = import_directive.id;
        let is_public = import_directive.is_public;

2941
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
2942
        let dest_import_resolution = match import_resolutions.entry(name) {
2943 2944 2945
            Occupied(entry) => {
                entry.into_mut()
            }
2946 2947 2948 2949 2950
            Vacant(entry) => {
                // Create a new import resolution from this child.
                entry.set(ImportResolution::new(id, is_public))
            }
        };
2951 2952 2953

        debug!("(resolving glob import) writing resolution `{}` in `{}` \
               to `{}`",
2954
               token::get_name(name).get(),
2955 2956
               self.module_to_string(&*containing_module),
               self.module_to_string(module_));
2957 2958

        // Merge the child item into the import resolution.
2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984
        {
            let merge_child_item = |namespace| {
                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
                    let namespace_name = match namespace {
                        TypeNS => "type",
                        ValueNS => "value",
                    };
                    debug!("(resolving glob import) ... for {} target", namespace_name);
                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
                        let msg = format!("a {} named `{}` has already been imported \
                                           in this module",
                                          namespace_name,
                                          token::get_name(name).get());
                        self.session.span_err(import_directive.span, msg.as_slice());
                    } else {
                        let target = Target::new(containing_module.clone(),
                                                 name_bindings.clone(),
                                                 import_directive.shadowable);
                        dest_import_resolution.set_target_and_id(namespace,
                                                                 Some(target),
                                                                 id);
                    }
                }
            };
            merge_child_item(ValueNS);
            merge_child_item(TypeNS);
2985
        }
2986

E
Eduard Burtescu 已提交
2987
        dest_import_resolution.is_public = is_public;
2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001

        self.check_for_conflicts_between_imports_and_items(
            module_,
            dest_import_resolution,
            import_directive.span,
            name);
    }

    /// Checks that imported names and items don't have the same name.
    fn check_for_conflicting_import(&mut self,
                                    target: &Option<Target>,
                                    import_span: Span,
                                    name: Name,
                                    namespace: Namespace) {
N
Nick Cameron 已提交
3002
        if self.session.features.borrow().import_shadowing {
3003 3004 3005
            return
        }

3006 3007 3008 3009
        debug!("check_for_conflicting_import: {}; target exists: {}",
               token::get_name(name).get(),
               target.is_some());

3010
        match *target {
3011
            Some(ref target) if target.shadowable != Shadowable::Always => {
3012 3013 3014 3015 3016 3017 3018
                let msg = format!("a {} named `{}` has already been imported \
                                   in this module",
                                  match namespace {
                                    TypeNS => "type",
                                    ValueNS => "value",
                                  },
                                  token::get_name(name).get());
A
Alex Crichton 已提交
3019
                self.session.span_err(import_span, msg[]);
3020 3021 3022 3023 3024
            }
            Some(_) | None => {}
        }
    }

3025 3026 3027 3028 3029 3030 3031 3032 3033
    /// Checks that an import is actually importable
    fn check_that_import_is_importable(&mut self,
                                       name_bindings: &NameBindings,
                                       import_span: Span,
                                       name: Name,
                                       namespace: Namespace) {
        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
            let msg = format!("`{}` is not directly importable",
                              token::get_name(name));
A
Alex Crichton 已提交
3034
            self.session.span_err(import_span, msg[]);
3035 3036 3037
        }
    }

3038 3039 3040 3041
    /// Checks that imported names and items don't have the same name.
    fn check_for_conflicts_between_imports_and_items(&mut self,
                                                     module: &Module,
                                                     import_resolution:
3042
                                                     &ImportResolution,
3043 3044
                                                     import_span: Span,
                                                     name: Name) {
N
Nick Cameron 已提交
3045
        if self.session.features.borrow().import_shadowing {
3046 3047 3048 3049 3050 3051 3052 3053
            return
        }

        // First, check for conflicts between imports and `extern crate`s.
        if module.external_module_children
                 .borrow()
                 .contains_key(&name) {
            match import_resolution.type_target {
3054
                Some(ref target) if target.shadowable != Shadowable::Always => {
3055 3056 3057
                    let msg = format!("import `{0}` conflicts with imported \
                                       crate in this module \
                                       (maybe you meant `use {0}::*`?)",
3058
                                      token::get_name(name).get());
A
Alex Crichton 已提交
3059
                    self.session.span_err(import_span, msg[]);
3060 3061 3062 3063 3064 3065 3066
                }
                Some(_) | None => {}
            }
        }

        // Check for item conflicts.
        let children = module.children.borrow();
3067
        let name_bindings = match children.get(&name) {
3068 3069 3070 3071 3072 3073 3074 3075
            None => {
                // There can't be any conflicts.
                return
            }
            Some(ref name_bindings) => (*name_bindings).clone(),
        };

        match import_resolution.value_target {
3076
            Some(ref target) if target.shadowable != Shadowable::Always => {
3077 3078 3079 3080
                if let Some(ref value) = *name_bindings.value_def.borrow() {
                    let msg = format!("import `{}` conflicts with value \
                                       in this module",
                                      token::get_name(name).get());
A
Alex Crichton 已提交
3081
                    self.session.span_err(import_span, msg[]);
3082 3083
                    if let Some(span) = value.value_span {
                        self.session.span_note(span,
C
Colin Davidson 已提交
3084
                                               "conflicting value here");
3085 3086 3087 3088 3089 3090 3091
                    }
                }
            }
            Some(_) | None => {}
        }

        match import_resolution.type_target {
3092
            Some(ref target) if target.shadowable != Shadowable::Always => {
3093 3094 3095 3096 3097 3098
                if let Some(ref ty) = *name_bindings.type_def.borrow() {
                    match ty.module_def {
                        None => {
                            let msg = format!("import `{}` conflicts with type in \
                                               this module",
                                              token::get_name(name).get());
A
Alex Crichton 已提交
3099
                            self.session.span_err(import_span, msg[]);
3100 3101
                            if let Some(span) = ty.type_span {
                                self.session.span_note(span,
3102 3103
                                                       "note conflicting type here")
                            }
3104 3105 3106 3107 3108 3109 3110 3111
                        }
                        Some(ref module_def) => {
                            match module_def.kind.get() {
                                ImplModuleKind => {
                                    if let Some(span) = ty.type_span {
                                        let msg = format!("inherent implementations \
                                                           are only allowed on types \
                                                           defined in the current module");
A
Alex Crichton 已提交
3112
                                        self.session.span_err(span, msg[]);
3113
                                        self.session.span_note(import_span,
3114 3115
                                                               "import from other module here")
                                    }
3116 3117 3118 3119 3120
                                }
                                _ => {
                                    let msg = format!("import `{}` conflicts with existing \
                                                       submodule",
                                                      token::get_name(name).get());
A
Alex Crichton 已提交
3121
                                    self.session.span_err(import_span, msg[]);
3122 3123
                                    if let Some(span) = ty.type_span {
                                        self.session.span_note(span,
3124 3125 3126
                                                               "note conflicting module here")
                                    }
                                }
3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141
                            }
                        }
                    }
                }
            }
            Some(_) | None => {}
        }
    }

    /// Checks that the names of external crates don't collide with other
    /// external crates.
    fn check_for_conflicts_between_external_crates(&self,
                                                   module: &Module,
                                                   name: Name,
                                                   span: Span) {
N
Nick Cameron 已提交
3142
        if self.session.features.borrow().import_shadowing {
3143 3144 3145 3146 3147 3148 3149 3150
            return
        }

        if module.external_module_children.borrow().contains_key(&name) {
            self.session
                .span_err(span,
                          format!("an external crate named `{}` has already \
                                   been imported into this module",
A
Alex Crichton 已提交
3151
                                  token::get_name(name).get())[]);
3152 3153 3154 3155 3156 3157 3158 3159
        }
    }

    /// Checks that the names of items don't collide with external crates.
    fn check_for_conflicts_between_external_crates_and_items(&self,
                                                             module: &Module,
                                                             name: Name,
                                                             span: Span) {
N
Nick Cameron 已提交
3160
        if self.session.features.borrow().import_shadowing {
3161 3162 3163 3164 3165 3166 3167 3168 3169
            return
        }

        if module.external_module_children.borrow().contains_key(&name) {
            self.session
                .span_err(span,
                          format!("the name `{}` conflicts with an external \
                                   crate that has been imported into this \
                                   module",
A
Alex Crichton 已提交
3170
                                  token::get_name(name).get())[]);
3171
        }
3172 3173
    }

3174
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
3175
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
3176
                                     module_: Rc<Module>,
3177
                                     module_path: &[Name],
3178 3179 3180 3181
                                     index: uint,
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
3182
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
3183 3184 3185
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
            module.external_module_children.borrow()
3186
                                            .get(&needle).cloned()
3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198
                                            .map(|_| module.clone())
                                            .or_else(|| {
                match module.parent_link.clone() {
                    ModuleParentLink(parent, _) => {
                        search_parent_externals(needle,
                                                &parent.upgrade().unwrap())
                    }
                   _ => None
                }
            })
        }

3199
        let mut search_module = module_;
3200
        let mut index = index;
A
Alex Crichton 已提交
3201
        let module_path_len = module_path.len();
3202
        let mut closest_private = lp;
3203 3204 3205 3206 3207

        // Resolve the module part of the path. This does not involve looking
        // upward though scope chains; we simply resolve names directly in
        // modules as we go.
        while index < module_path_len {
A
Alex Crichton 已提交
3208
            let name = module_path[index];
E
Eduard Burtescu 已提交
3209
            match self.resolve_name_in_module(search_module.clone(),
3210
                                              name,
3211
                                              TypeNS,
3212 3213
                                              name_search_type,
                                              false) {
3214
                Failed(None) => {
3215
                    let segment_name = token::get_name(name);
3216
                    let module_name = self.module_to_string(&*search_module);
3217
                    let mut span = span;
A
Alex Crichton 已提交
3218
                    let msg = if "???" == module_name[] {
3219
                        span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3220

3221
                        match search_parent_externals(name,
3222
                                                     &self.current_module) {
3223
                            Some(module) => {
3224
                                let path_str = self.names_to_string(module_path);
3225
                                let target_mod_str = self.module_to_string(&*module);
3226
                                let current_mod_str =
3227
                                    self.module_to_string(&*self.current_module);
3228 3229 3230 3231 3232 3233 3234

                                let prefix = if target_mod_str == current_mod_str {
                                    "self::".to_string()
                                } else {
                                    format!("{}::", target_mod_str)
                                };

3235
                                format!("Did you mean `{}{}`?", prefix, path_str)
3236
                            },
3237 3238
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
3239
                        }
3240
                    } else {
3241
                        format!("Could not find `{}` in `{}`",
3242 3243 3244
                                segment_name,
                                module_name)
                    };
3245

3246
                    return Failed(Some((span, msg)));
3247
                }
3248
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
3249
                Indeterminate => {
3250
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
3251
                            resolution is indeterminate: {}",
3252
                            token::get_name(name));
B
Brian Anderson 已提交
3253
                    return Indeterminate;
3254
                }
3255
                Success((target, used_proxy)) => {
3256 3257
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
3258
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
3259
                        Some(ref type_def) => {
3260 3261
                            match type_def.module_def {
                                None => {
3262
                                    let msg = format!("Not a module `{}`",
3263
                                                        token::get_name(name));
3264 3265

                                    return Failed(Some((span, msg)));
3266
                                }
E
Eduard Burtescu 已提交
3267
                                Some(ref module_def) => {
3268 3269 3270
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
3271 3272
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
3273
                                    }
3274

3275 3276 3277
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
3278 3279 3280
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
3281
                                        }
3282
                                    }
3283 3284 3285 3286 3287
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
3288
                            let msg = format!("Not a module `{}`",
3289
                                              token::get_name(name));
3290
                            return Failed(Some((span, msg)));
3291 3292 3293 3294 3295
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
3296
            index += 1;
3297 3298
        }

3299
        return Success((search_module, closest_private));
3300 3301
    }

3302 3303
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
3304 3305 3306
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
3307
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
3308
                           module_: Rc<Module>,
3309
                           module_path: &[Name],
3310 3311 3312
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
3313
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
3314
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
3315
        assert!(module_path_len > 0);
3316

3317
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
3318
               self.names_to_string(module_path),
3319
               self.module_to_string(&*module_));
3320

3321
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
3322
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3323
                                                              module_path);
3324

3325 3326
        let search_module;
        let start_index;
3327
        let last_private;
3328
        match module_prefix_result {
3329
            Failed(None) => {
3330
                let mpath = self.names_to_string(module_path);
A
Alex Crichton 已提交
3331
                let mpath = mpath[];
3332
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
3333
                    Some(idx) => {
3334 3335 3336
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
A
Alex Crichton 已提交
3337 3338
                                            mpath[idx + 1..],
                                            mpath[0..idx - 1]);
3339
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
3340
                    },
3341 3342 3343
                    None => {
                        return Failed(None)
                    }
3344
                }
3345
            }
3346
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
3347
            Indeterminate => {
3348
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
3349
                        bailing");
B
Brian Anderson 已提交
3350
                return Indeterminate;
3351
            }
3352 3353 3354 3355 3356 3357 3358 3359 3360 3361
            Success(NoPrefixFound) => {
                // There was no prefix, so we're considering the first element
                // of the path. How we handle this depends on whether we were
                // instructed to use lexical scope or not.
                match use_lexical_scope {
                    DontUseLexicalScope => {
                        // This is a crate-relative path. We will start the
                        // resolution process at index zero.
                        search_module = self.graph_root.get_module();
                        start_index = 0;
3362
                        last_private = LastMod(AllPublic);
3363 3364 3365 3366 3367
                    }
                    UseLexicalScope => {
                        // This is not a crate-relative path. We resolve the
                        // first component of the path in the current lexical
                        // scope and then proceed to resolve below that.
3368 3369
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
3370
                            Failed(err) => return Failed(err),
3371
                            Indeterminate => {
3372
                                debug!("(resolving module path for import) \
3373 3374 3375 3376 3377 3378
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
3379
                                last_private = LastMod(AllPublic);
3380 3381 3382 3383 3384
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
3385 3386
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
3387
                start_index = index;
3388 3389 3390
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
3391 3392 3393
            }
        }

3394 3395 3396 3397
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
3398 3399
                                           name_search_type,
                                           last_private)
3400 3401
    }

3402 3403
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3404
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
3405
                                     module_: Rc<Module>,
3406
                                     name: Name,
3407
                                     namespace: Namespace)
3408
                                    -> ResolveResult<(Target, bool)> {
3409
        debug!("(resolving item in lexical scope) resolving `{}` in \
L
Luqman Aden 已提交
3410
                namespace {} in `{}`",
3411
               token::get_name(name),
3412
               namespace,
3413
               self.module_to_string(&*module_));
3414 3415 3416

        // The current module node is handled specially. First, check for
        // its immediate children.
E
Eduard Burtescu 已提交
3417
        self.populate_module_if_necessary(&module_);
3418

3419
        match module_.children.borrow().get(&name) {
3420 3421 3422
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
3423 3424
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
3425
                                            Shadowable::Never),
3426
                               false));
3427
            }
3428
            Some(_) | None => { /* Not found; continue. */ }
3429 3430 3431 3432 3433 3434
        }

        // Now check for its import directives. We don't have to have resolved
        // all its imports in the usual way; this is because chains of
        // adjacent import statements are processed as though they mutated the
        // current scope.
3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446
        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
            match (*import_resolution).target_for_namespace(namespace) {
                None => {
                    // Not found; continue.
                    debug!("(resolving item in lexical scope) found \
                            import resolution, but not in namespace {}",
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
3447 3448 3449
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
3450
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3451
                         self.used_crates.insert(kid);
3452
                    }
3453
                    return Success((target, false));
3454 3455 3456 3457
                }
            }
        }

3458 3459
        // Search for external modules.
        if namespace == TypeNS {
3460 3461 3462 3463
            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
                debug!("lower name bindings succeeded");
3464 3465 3466
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
3467
                                false));
3468 3469 3470
            }
        }

3471
        // Finally, proceed up the scope chain looking for parent modules.
3472
        let mut search_module = module_;
3473 3474
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
3475
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
3476
                NoParentLink => {
3477
                    // No more parents. This module was unresolved.
3478
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
3479
                            module");
3480
                    return Failed(None);
3481
                }
3482
                ModuleParentLink(parent_module_node, _) => {
3483 3484 3485 3486 3487 3488 3489
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
3490
                            return Failed(None);
3491
                        }
3492 3493
                        TraitModuleKind |
                        ImplModuleKind |
3494
                        EnumModuleKind |
3495
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
3496
                            search_module = parent_module_node.upgrade().unwrap();
3497 3498 3499
                        }
                    }
                }
E
Eduard Burtescu 已提交
3500 3501
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
3502 3503 3504 3505
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
3506
            match self.resolve_name_in_module(search_module.clone(),
3507
                                              name,
3508
                                              namespace,
3509 3510
                                              PathSearch,
                                              true) {
3511 3512
                Failed(Some((span, msg))) =>
                    self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
3513
                                                     msg)[]),
3514
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
3515
                Indeterminate => {
3516 3517 3518
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

3519
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
3520
                            higher scope; bailing");
B
Brian Anderson 已提交
3521
                    return Indeterminate;
3522
                }
3523
                Success((target, used_reexport)) => {
3524
                    // We found the module.
3525
                    debug!("(resolving item in lexical scope) found name \
3526 3527
                            in module, done");
                    return Success((target, used_reexport));
3528 3529 3530 3531 3532
                }
            }
        }
    }

3533
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
3534
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
3535
                                       module_: Rc<Module>,
3536
                                       name: Name)
E
Eduard Burtescu 已提交
3537
                                -> ResolveResult<Rc<Module>> {
3538 3539
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
3540
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
3541
        match resolve_result {
3542
            Success((target, _)) => {
3543
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
3544
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
3545
                    Some(ref type_def) => {
3546
                        match type_def.module_def {
3547
                            None => {
3548
                                debug!("!!! (resolving module in lexical \
3549 3550
                                        scope) module wasn't actually a \
                                        module!");
3551
                                return Failed(None);
3552
                            }
E
Eduard Burtescu 已提交
3553 3554
                            Some(ref module_def) => {
                                return Success(module_def.clone());
3555 3556 3557 3558
                            }
                        }
                    }
                    None => {
3559
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
3560
                                wasn't actually a module!");
3561
                        return Failed(None);
3562 3563 3564
                    }
                }
            }
B
Brian Anderson 已提交
3565
            Indeterminate => {
3566
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
3567
                        bailing");
B
Brian Anderson 已提交
3568
                return Indeterminate;
3569
            }
3570 3571 3572
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
3573 3574 3575 3576
            }
        }
    }

3577
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
3578 3579
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
3580 3581
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
3582
            match module_.parent_link.clone() {
3583 3584 3585
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
3586
                    let new_module = new_module.upgrade().unwrap();
3587
                    match new_module.kind.get() {
3588 3589
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
3590
                        ImplModuleKind |
3591
                        EnumModuleKind |
3592 3593 3594 3595 3596 3597 3598
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

3599 3600
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
3601 3602
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
3603
        match module_.kind.get() {
3604
            NormalModuleKind => return module_,
3605 3606
            TraitModuleKind |
            ImplModuleKind |
3607
            EnumModuleKind |
3608
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
3609
                match self.get_nearest_normal_module_parent(module_.clone()) {
3610 3611 3612 3613 3614 3615 3616
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

3617
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3618
    /// (b) some chain of `super::`.
3619
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
3620
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
3621
                             module_: Rc<Module>,
3622
                             module_path: &[Name])
3623
                                 -> ResolveResult<ModulePrefixResult> {
3624 3625 3626 3627
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
        let mut containing_module;
        let mut i;
3628
        let first_module_path_string = token::get_name(module_path[0]);
3629
        if "self" == first_module_path_string.get() {
3630 3631 3632
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 1;
3633
        } else if "super" == first_module_path_string.get() {
3634 3635 3636 3637 3638 3639 3640 3641
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 0;  // We'll handle `super` below.
        } else {
            return Success(NoPrefixFound);
        }

        // Now loop through all the `super`s we find.
3642
        while i < module_path.len() {
3643
            let string = token::get_name(module_path[i]);
3644 3645 3646
            if "super" != string.get() {
                break
            }
3647
            debug!("(resolving module prefix) resolving `super` at {}",
3648
                   self.module_to_string(&*containing_module));
3649
            match self.get_nearest_normal_module_parent(containing_module) {
3650
                None => return Failed(None),
3651 3652 3653
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
3654 3655 3656 3657
                }
            }
        }

3658
        debug!("(resolving module prefix) finished resolving prefix at {}",
3659
               self.module_to_string(&*containing_module));
3660 3661

        return Success(PrefixFound(containing_module, i));
3662 3663
    }

3664 3665 3666
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
3667 3668 3669
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
3670
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3671
                              module_: Rc<Module>,
3672
                              name: Name,
3673
                              namespace: Namespace,
3674 3675
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
3676
                              -> ResolveResult<(Target, bool)> {
3677
        debug!("(resolving name in module) resolving `{}` in `{}`",
3678
               token::get_name(name).get(),
3679
               self.module_to_string(&*module_));
3680 3681

        // First, check the direct children of the module.
E
Eduard Burtescu 已提交
3682
        self.populate_module_if_necessary(&module_);
3683

3684
        match module_.children.borrow().get(&name) {
3685 3686 3687
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
3688 3689
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
3690
                                            Shadowable::Never),
3691 3692 3693 3694
                               false));
            }
            Some(_) | None => {
                // Continue.
3695 3696 3697
            }
        }

3698 3699 3700 3701
        // Next, check the module's imports if necessary.

        // If this is a search of all imports, we should be done with glob
        // resolution at this point.
3702
        if name_search_type == PathSearch {
3703
            assert_eq!(module_.glob_count.get(), 0);
3704 3705
        }

3706
        // Check the list of resolved imports.
3707
        match module_.import_resolutions.borrow().get(&name) {
3708
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
3709
                                       import_resolution.is_public => {
3710

E
Eduard Burtescu 已提交
3711 3712
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
3713
                    debug!("(resolving name in module) import \
3714
                           unresolved; bailing out");
B
Brian Anderson 已提交
3715
                    return Indeterminate;
3716
                }
3717
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
3718
                    None => {
3719
                        debug!("(resolving name in module) name found, \
L
Luqman Aden 已提交
3720
                                but not in namespace {}",
P
Paul Stansifer 已提交
3721
                               namespace);
3722
                    }
3723
                    Some(target) => {
3724
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
3725
                                import");
3726
                        // track used imports and extern crates as well
3727 3728 3729
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
3730 3731
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
3732
                        }
3733
                        return Success((target, true));
3734
                    }
3735 3736
                }
            }
3737
            Some(..) | None => {} // Continue.
3738 3739 3740 3741
        }

        // Finally, search through external children.
        if namespace == TypeNS {
3742 3743 3744
            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
3745 3746 3747
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
3748
                                false));
3749 3750 3751 3752
            }
        }

        // We're out of luck.
3753
        debug!("(resolving name in module) failed to resolve `{}`",
3754
               token::get_name(name).get());
3755
        return Failed(None);
3756 3757
    }

E
Eduard Burtescu 已提交
3758
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3759
        let index = module_.resolved_import_count.get();
3760 3761
        let imports = module_.imports.borrow();
        let import_count = imports.len();
3762
        if index != import_count {
3763
            let sn = self.session
E
Eduard Burtescu 已提交
3764
                         .codemap()
3765
                         .span_to_snippet((*imports)[index].span)
3766
                         .unwrap();
3767
            if sn.contains("::") {
3768
                self.resolve_error((*imports)[index].span,
3769
                                   "unresolved import");
3770
            } else {
A
Alex Crichton 已提交
3771
                let err = format!("unresolved import (maybe you meant `{}::*`?)",
A
Alex Crichton 已提交
3772 3773
                                  sn);
                self.resolve_error((*imports)[index].span, err[]);
3774
            }
3775 3776 3777
        }

        // Descend into children and anonymous children.
E
Eduard Burtescu 已提交
3778
        self.populate_module_if_necessary(&module_);
3779

E
Eduard Burtescu 已提交
3780
        for (_, child_node) in module_.children.borrow().iter() {
3781 3782 3783 3784 3785 3786
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
3787 3788 3789 3790
                }
            }
        }

E
Eduard Burtescu 已提交
3791 3792
        for (_, module_) in module_.anonymous_children.borrow().iter() {
            self.report_unresolved_imports(module_.clone());
3793 3794 3795 3796 3797
        }
    }

    // AST resolution
    //
3798
    // We maintain a list of value ribs and type ribs.
3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813
    //
    // Simultaneously, we keep track of the current position in the module
    // graph in the `current_module` pointer. When we go to resolve a name in
    // the value or type namespaces, we first look through all the ribs and
    // then query the module graph. When we resolve a name in the module
    // namespace, we can skip all the ribs (since nested modules are not
    // allowed within blocks in Rust) and jump straight to the current module
    // graph node.
    //
    // Named implementations are handled separately. When we find a method
    // call, we consult the module node to find all of the implementations in
    // scope. This information is lazily cached in the module node. We then
    // generate a fake "implementation scope" containing all the
    // implementations thus found, for compatibility with old resolve pass.

J
Jorge Aparicio 已提交
3814 3815 3816
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
3817
        let orig_module = self.current_module.clone();
3818 3819

        // Move down in the graph.
3820
        match name {
B
Brian Anderson 已提交
3821
            None => {
3822 3823
                // Nothing to do.
            }
B
Brian Anderson 已提交
3824
            Some(name) => {
E
Eduard Burtescu 已提交
3825
                self.populate_module_if_necessary(&orig_module);
3826

3827
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
3828
                    None => {
3829
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
3830
                               token::get_name(name),
3831
                               self.module_to_string(&*orig_module));
3832
                    }
B
Brian Anderson 已提交
3833
                    Some(name_bindings) => {
3834
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
3835
                            None => {
3836
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
3837
                                        for `{}` in `{}`",
3838
                                       token::get_name(name),
3839
                                       self.module_to_string(&*orig_module));
3840
                            }
B
Brian Anderson 已提交
3841
                            Some(module_) => {
3842
                                self.current_module = module_;
3843 3844 3845 3846 3847 3848 3849
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
3850
        f(self);
3851 3852 3853 3854

        self.current_module = orig_module;
    }

3855
    /// Wraps the given definition in the appropriate number of `DefUpvar`
3856
    /// wrappers.
E
Eduard Burtescu 已提交
3857
    fn upvarify(&self,
E
Eduard Burtescu 已提交
3858
                ribs: &[Rib],
E
Eduard Burtescu 已提交
3859 3860 3861
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
3862
        match def_like {
3863 3864
            DlDef(d @ DefUpvar(..)) => {
                self.session.span_bug(span,
A
Alex Crichton 已提交
3865
                    format!("unexpected {} in bindings", d)[])
3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880
            }
            DlDef(d @ DefLocal(_)) => {
                let node_id = d.def_id().node;
                let mut def = d;
                let mut last_proc_body_id = ast::DUMMY_NODE_ID;
                for rib in ribs.iter() {
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id, maybe_proc_body) => {
                            let prev_def = def;
                            if maybe_proc_body != ast::DUMMY_NODE_ID {
                                last_proc_body_id = maybe_proc_body;
                            }
3881
                            def = DefUpvar(node_id, function_id, last_proc_body_id);
3882

3883
                            let mut seen = self.freevars_seen.borrow_mut();
3884 3885 3886 3887
                            let seen = match seen.entry(function_id) {
                                Occupied(v) => v.into_mut(),
                                Vacant(v) => v.set(NodeSet::new()),
                            };
3888 3889 3890
                            if seen.contains(&node_id) {
                                continue;
                            }
3891 3892 3893 3894
                            match self.freevars.borrow_mut().entry(function_id) {
                                Occupied(v) => v.into_mut(),
                                Vacant(v) => v.set(vec![]),
                            }.push(Freevar { def: prev_def, span: span });
3895 3896 3897 3898 3899 3900 3901
                            seen.insert(node_id);
                        }
                        MethodRibKind(item_id, _) => {
                            // If the def is a ty param, and came from the parent
                            // item, it's ok
                            match def {
                                DefTyParam(_, did, _) if {
3902
                                    self.def_map.borrow().get(&did.node).cloned()
3903 3904 3905 3906 3907 3908 3909
                                        == Some(DefTyParamBinder(item_id))
                                } => {} // ok
                                DefSelfTy(did) if did == item_id => {} // ok
                                _ => {
                                    // This was an attempt to access an upvar inside a
                                    // named function item. This is not allowed, so we
                                    // report an error.
3910

3911 3912 3913 3914
                                    self.resolve_error(
                                        span,
                                        "can't capture dynamic environment in a fn item; \
                                        use the || { ... } closure form instead");
3915

3916 3917 3918 3919 3920 3921 3922 3923
                                    return None;
                                }
                            }
                        }
                        ItemRibKind => {
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
3924

3925 3926 3927 3928
                            self.resolve_error(
                                span,
                                "can't capture dynamic environment in a fn item; \
                                use the || { ... } closure form instead");
3929

3930 3931 3932 3933 3934 3935 3936
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
                            self.resolve_error(span,
                                               "attempt to use a non-constant \
                                                value in a constant");
3937

3938
                        }
3939 3940
                    }
                }
3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954
                Some(DlDef(def))
            }
            DlDef(def @ DefTyParam(..)) |
            DlDef(def @ DefSelfTy(..)) => {
                for rib in ribs.iter() {
                    match rib.kind {
                        NormalRibKind | ClosureRibKind(..) => {
                            // Nothing to do. Continue.
                        }
                        MethodRibKind(item_id, _) => {
                            // If the def is a ty param, and came from the parent
                            // item, it's ok
                            match def {
                                DefTyParam(_, did, _) if {
3955
                                    self.def_map.borrow().get(&did.node).cloned()
3956 3957 3958
                                        == Some(DefTyParamBinder(item_id))
                                } => {} // ok
                                DefSelfTy(did) if did == item_id => {} // ok
3959

3960 3961 3962
                                _ => {
                                    // This was an attempt to use a type parameter outside
                                    // its scope.
3963

3964 3965 3966 3967
                                    self.resolve_error(span,
                                                        "can't use type parameters from \
                                                        outer function; try using a local \
                                                        type parameter instead");
3968

3969 3970 3971 3972 3973 3974 3975
                                    return None;
                                }
                            }
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
3976

3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991
                            self.resolve_error(span,
                                               "can't use type parameters from \
                                                outer function; try using a local \
                                                type parameter instead");

                            return None;
                        }
                        ConstantItemRibKind => {
                            // see #9186
                            self.resolve_error(span,
                                               "cannot use an outer type \
                                                parameter in this context");

                        }
                    }
3992
                }
3993
                Some(DlDef(def))
3994
            }
3995
            _ => Some(def_like)
3996 3997 3998
        }
    }

E
Eduard Burtescu 已提交
3999
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
4000
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
4001 4002 4003
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
4004
        // FIXME #4950: Try caching?
4005

4006
        for (i, rib) in ribs.iter().enumerate().rev() {
4007
            match rib.bindings.get(&name).cloned() {
4008
                Some(def_like) => {
4009
                    return self.upvarify(ribs[i + 1..], def_like, span);
4010
                }
B
Brian Anderson 已提交
4011
                None => {
4012 4013 4014 4015 4016
                    // Continue.
                }
            }
        }

4017
        None
4018 4019
    }

4020
    fn resolve_crate(&mut self, krate: &ast::Crate) {
4021
        debug!("(resolving crate) starting");
4022

4023
        visit::walk_crate(self, krate);
4024 4025
    }

4026
    fn resolve_item(&mut self, item: &Item) {
4027 4028
        let name = item.ident.name;

4029
        debug!("(resolving item) resolving {}",
4030
               token::get_name(name));
4031

4032
        match item.node {
4033 4034 4035

            // enum item: resolve all the variants' discrs,
            // then resolve the ty params
4036
            ItemEnum(ref enum_def, ref generics) => {
D
Daniel Micay 已提交
4037 4038
                for variant in (*enum_def).variants.iter() {
                    for dis_expr in variant.node.disr_expr.iter() {
4039 4040
                        // resolve the discriminator expr
                        // as a constant
A
Alex Crichton 已提交
4041
                        self.with_constant_rib(|this| {
4042
                            this.resolve_expr(&**dis_expr);
4043 4044 4045 4046
                        });
                    }
                }

J
Joseph Crail 已提交
4047
                // n.b. the discr expr gets visited twice.
4048 4049
                // but maybe it's okay since the first time will signal an
                // error if there is one? -- tjc
4050
                self.with_type_parameter_rib(HasTypeParameters(generics,
4051
                                                               TypeSpace,
4052
                                                               item.id,
4053
                                                               ItemRibKind),
4054
                                             |this| {
N
Nick Cameron 已提交
4055
                    this.resolve_type_parameters(&generics.ty_params);
4056
                    this.resolve_where_clause(&generics.where_clause);
4057
                    visit::walk_item(this, item);
4058
                });
4059
            }
T
Tim Chevalier 已提交
4060

4061
            ItemTy(_, ref generics) => {
4062
                self.with_type_parameter_rib(HasTypeParameters(generics,
4063
                                                               TypeSpace,
4064
                                                               item.id,
4065
                                                               ItemRibKind),
4066
                                             |this| {
N
Nick Cameron 已提交
4067
                    this.resolve_type_parameters(&generics.ty_params);
4068
                    visit::walk_item(this, item);
4069
                });
4070 4071
            }

4072 4073
            ItemImpl(_,
                     ref generics,
4074 4075
                     ref implemented_traits,
                     ref self_type,
4076
                     ref impl_items) => {
4077
                self.resolve_implementation(item.id,
4078
                                            generics,
4079
                                            implemented_traits,
4080
                                            &**self_type,
A
Alex Crichton 已提交
4081
                                            impl_items[]);
4082 4083
            }

4084
            ItemTrait(_, ref generics, ref unbound, ref bounds, ref trait_items) => {
4085
                // Create a new rib for the self type.
4086
                let mut self_type_rib = Rib::new(ItemRibKind);
4087

J
John Clements 已提交
4088 4089
                // plain insert (no renaming, types are not currently hygienic....)
                let name = self.type_self_name;
4090 4091
                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
                self.type_ribs.push(self_type_rib);
4092

4093
                // Create a new rib for the trait-wide type parameters.
4094
                self.with_type_parameter_rib(HasTypeParameters(generics,
4095
                                                               TypeSpace,
4096 4097 4098
                                                               item.id,
                                                               NormalRibKind),
                                             |this| {
A
Alex Crichton 已提交
4099
                    this.resolve_type_parameters(&generics.ty_params);
4100
                    this.resolve_where_clause(&generics.where_clause);
4101

4102 4103 4104
                    this.resolve_type_parameter_bounds(item.id, bounds,
                                                       TraitDerivation);

N
Niko Matsakis 已提交
4105 4106
                    match *unbound {
                        Some(ref tpb) => {
N
Nick Cameron 已提交
4107 4108
                            this.resolve_trait_reference(item.id, tpb, TraitDerivation);
                        }
N
Niko Matsakis 已提交
4109
                        None => {}
N
Nick Cameron 已提交
4110
                    }
4111

4112 4113
                    for trait_item in (*trait_items).iter() {
                        // Create a new rib for the trait_item-specific type
4114 4115
                        // parameters.
                        //
4116
                        // FIXME #4951: Do we need a node ID here?
4117

4118
                        match *trait_item {
4119
                          ast::RequiredMethod(ref ty_m) => {
4120
                            this.with_type_parameter_rib
4121
                                (HasTypeParameters(&ty_m.generics,
4122
                                                   FnSpace,
4123
                                                   item.id,
4124
                                        MethodRibKind(item.id, RequiredMethod)),
4125
                                 |this| {
4126

4127 4128
                                // Resolve the method-specific type
                                // parameters.
A
Alex Crichton 已提交
4129 4130
                                this.resolve_type_parameters(
                                    &ty_m.generics.ty_params);
4131 4132
                                this.resolve_where_clause(&ty_m.generics
                                                               .where_clause);
4133

D
Daniel Micay 已提交
4134
                                for argument in ty_m.decl.inputs.iter() {
4135
                                    this.resolve_type(&*argument.ty);
4136
                                }
4137

4138 4139
                                if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
                                    this.resolve_type(&**typ)
4140 4141
                                }

4142 4143 4144
                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
                                    this.resolve_type(&**ret_ty);
                                }
4145
                            });
4146
                          }
4147
                          ast::ProvidedMethod(ref m) => {
A
Alex Crichton 已提交
4148
                              this.resolve_method(MethodRibKind(item.id,
4149
                                                                ProvidedMethod(m.id)),
4150
                                                  &**m)
4151
                          }
4152 4153 4154
                          ast::TypeTraitItem(ref data) => {
                              this.resolve_type_parameter(&data.ty_param);
                              visit::walk_trait_item(this, trait_item);
4155
                          }
4156 4157
                        }
                    }
4158
                });
4159

4160
                self.type_ribs.pop();
4161 4162
            }

4163
            ItemStruct(ref struct_def, ref generics) => {
4164
                self.resolve_struct(item.id,
4165
                                    generics,
A
Alex Crichton 已提交
4166
                                    struct_def.fields[]);
4167 4168
            }

4169
            ItemMod(ref module_) => {
4170 4171
                self.with_scope(Some(name), |this| {
                    this.resolve_module(module_, item.span, name,
A
Alex Crichton 已提交
4172
                                        item.id);
4173
                });
4174 4175
            }

4176
            ItemForeignMod(ref foreign_module) => {
4177
                self.with_scope(Some(name), |this| {
D
Daniel Micay 已提交
4178
                    for foreign_item in foreign_module.items.iter() {
4179
                        match foreign_item.node {
4180
                            ForeignItemFn(_, ref generics) => {
A
Alex Crichton 已提交
4181
                                this.with_type_parameter_rib(
4182
                                    HasTypeParameters(
4183
                                        generics, FnSpace, foreign_item.id,
4184
                                        ItemRibKind),
A
Alex Crichton 已提交
4185
                                    |this| visit::walk_foreign_item(this,
4186
                                                                    &**foreign_item));
4187
                            }
4188
                            ForeignItemStatic(..) => {
A
Alex Crichton 已提交
4189
                                visit::walk_foreign_item(this,
4190
                                                         &**foreign_item);
4191
                            }
4192 4193
                        }
                    }
4194
                });
4195 4196
            }

4197
            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4198
                self.resolve_function(ItemRibKind,
4199
                                      Some(&**fn_decl),
4200
                                      HasTypeParameters
4201
                                        (generics,
4202
                                         FnSpace,
4203
                                         item.id,
4204
                                         ItemRibKind),
4205
                                      &**block);
4206 4207
            }

4208
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
4209
                self.with_constant_rib(|this| {
4210
                    visit::walk_item(this, item);
4211
                });
4212
            }
4213

4214 4215 4216
           ItemMac(..) => {
                // do nothing, these are just around to be encoded
           }
4217 4218 4219
        }
    }

J
Jorge Aparicio 已提交
4220 4221 4222
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
4223
        match type_parameters {
4224
            HasTypeParameters(generics, space, node_id, rib_kind) => {
4225
                let mut function_type_rib = Rib::new(rib_kind);
4226
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
4227
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4228
                    let name = type_parameter.ident.name;
4229
                    debug!("with_type_parameter_rib: {} {}", node_id,
P
Paul Stansifer 已提交
4230
                           type_parameter.id);
4231

4232
                    if seen_bindings.contains(&name) {
4233 4234 4235 4236 4237
                        self.resolve_error(type_parameter.span,
                                           format!("the name `{}` is already \
                                                    used for a type \
                                                    parameter in this type \
                                                    parameter list",
4238
                                                   token::get_name(
A
Alex Crichton 已提交
4239
                                                       name))[])
4240
                    }
4241
                    seen_bindings.insert(name);
4242

4243 4244 4245
                    let def_like = DlDef(DefTyParam(space,
                                                    local_def(type_parameter.id),
                                                    index));
4246 4247 4248
                    // Associate this type parameter with
                    // the item that bound it
                    self.record_def(type_parameter.id,
4249
                                    (DefTyParamBinder(node_id), LastMod(AllPublic)));
4250
                    // plain insert (no renaming)
4251
                    function_type_rib.bindings.insert(name, def_like);
4252
                }
4253
                self.type_ribs.push(function_type_rib);
4254 4255
            }

B
Brian Anderson 已提交
4256
            NoTypeParameters => {
4257 4258 4259 4260
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
4261
        f(self);
4262

4263
        match type_parameters {
4264
            HasTypeParameters(..) => { self.type_ribs.pop(); }
4265
            NoTypeParameters => { }
4266 4267 4268
        }
    }

J
Jorge Aparicio 已提交
4269 4270 4271
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
4272
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
4273
        f(self);
4274
        self.label_ribs.pop();
4275
    }
4276

J
Jorge Aparicio 已提交
4277 4278 4279
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
4280 4281
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
4282
        f(self);
4283 4284
        self.type_ribs.pop();
        self.value_ribs.pop();
4285 4286
    }

F
Felix S. Klock II 已提交
4287
    fn resolve_function(&mut self,
4288
                        rib_kind: RibKind,
4289
                        optional_declaration: Option<&FnDecl>,
4290
                        type_parameters: TypeParameters,
4291
                        block: &Block) {
4292
        // Create a value rib for the function.
E
Eduard Burtescu 已提交
4293
        let function_value_rib = Rib::new(rib_kind);
4294
        self.value_ribs.push(function_value_rib);
4295

4296
        // Create a label rib for the function.
E
Eduard Burtescu 已提交
4297
        let function_label_rib = Rib::new(rib_kind);
4298
        self.label_ribs.push(function_label_rib);
4299

4300
        // If this function has type parameters, add them now.
4301
        self.with_type_parameter_rib(type_parameters, |this| {
4302
            // Resolve the type parameters.
4303
            match type_parameters {
B
Brian Anderson 已提交
4304
                NoTypeParameters => {
4305 4306
                    // Continue.
                }
4307
                HasTypeParameters(ref generics, _, _, _) => {
A
Alex Crichton 已提交
4308
                    this.resolve_type_parameters(&generics.ty_params);
4309
                    this.resolve_where_clause(&generics.where_clause);
4310 4311 4312 4313
                }
            }

            // Add each argument to the rib.
4314
            match optional_declaration {
B
Brian Anderson 已提交
4315
                None => {
4316 4317
                    // Nothing to do.
                }
B
Brian Anderson 已提交
4318
                Some(declaration) => {
4319
                    let mut bindings_list = HashMap::new();
D
Daniel Micay 已提交
4320
                    for argument in declaration.inputs.iter() {
4321
                        this.resolve_pattern(&*argument.pat,
4322
                                             ArgumentIrrefutableMode,
4323
                                             &mut bindings_list);
4324

4325
                        this.resolve_type(&*argument.ty);
4326

4327
                        debug!("(resolving function) recorded argument");
4328 4329
                    }

4330 4331 4332
                    if let ast::Return(ref ret_ty) = declaration.output {
                        this.resolve_type(&**ret_ty);
                    }
4333 4334 4335 4336
                }
            }

            // Resolve the function body.
4337
            this.resolve_block(&*block);
4338

4339
            debug!("(resolving function) leaving function");
4340
        });
4341

4342 4343
        self.label_ribs.pop();
        self.value_ribs.pop();
4344 4345
    }

F
Felix S. Klock II 已提交
4346
    fn resolve_type_parameters(&mut self,
N
Nick Cameron 已提交
4347
                               type_parameters: &OwnedSlice<TyParam>) {
D
Daniel Micay 已提交
4348
        for type_parameter in type_parameters.iter() {
4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360
            self.resolve_type_parameter(type_parameter);
        }
    }

    fn resolve_type_parameter(&mut self,
                              type_parameter: &TyParam) {
        for bound in type_parameter.bounds.iter() {
            self.resolve_type_parameter_bound(type_parameter.id, bound,
                                              TraitBoundingTypeParameter);
        }
        match &type_parameter.unbound {
            &Some(ref unbound) =>
N
Niko Matsakis 已提交
4361
                self.resolve_trait_reference(
4362 4363 4364 4365 4366 4367
                    type_parameter.id, unbound, TraitBoundingTypeParameter),
            &None => {}
        }
        match type_parameter.default {
            Some(ref ty) => self.resolve_type(&**ty),
            None => {}
4368 4369 4370
        }
    }

4371 4372 4373 4374 4375 4376 4377 4378 4379 4380
    fn resolve_type_parameter_bounds(&mut self,
                                     id: NodeId,
                                     type_parameter_bounds: &OwnedSlice<TyParamBound>,
                                     reference_type: TraitReferenceType) {
        for type_parameter_bound in type_parameter_bounds.iter() {
            self.resolve_type_parameter_bound(id, type_parameter_bound,
                                              reference_type);
        }
    }

F
Felix S. Klock II 已提交
4381
    fn resolve_type_parameter_bound(&mut self,
4382
                                    id: NodeId,
4383 4384
                                    type_parameter_bound: &TyParamBound,
                                    reference_type: TraitReferenceType) {
4385
        match *type_parameter_bound {
J
James Miller 已提交
4386
            TraitTyParamBound(ref tref) => {
N
Niko Matsakis 已提交
4387
                self.resolve_poly_trait_reference(id, tref, reference_type)
4388
            }
4389
            RegionTyParamBound(..) => {}
4390 4391 4392
        }
    }

N
Niko Matsakis 已提交
4393 4394 4395 4396 4397 4398 4399
    fn resolve_poly_trait_reference(&mut self,
                                    id: NodeId,
                                    poly_trait_reference: &PolyTraitRef,
                                    reference_type: TraitReferenceType) {
        self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
    }

F
Felix S. Klock II 已提交
4400
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
4401 4402 4403
                               id: NodeId,
                               trait_reference: &TraitRef,
                               reference_type: TraitReferenceType) {
A
Alex Crichton 已提交
4404
        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4405
            None => {
4406
                let path_str = self.path_names_to_string(&trait_reference.path);
4407
                let usage_str = match reference_type {
4408
                    TraitBoundingTypeParameter => "bound type parameter with",
4409
                    TraitImplementation        => "implement",
4410
                    TraitDerivation            => "derive",
N
Niko Matsakis 已提交
4411
                    TraitObject                => "reference",
4412
                    TraitQPath                 => "extract an associated type from",
4413 4414
                };

A
Alex Crichton 已提交
4415
                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
A
Alex Crichton 已提交
4416
                self.resolve_error(trait_reference.path.span, msg[]);
4417 4418
            }
            Some(def) => {
4419 4420
                match def {
                    (DefTrait(_), _) => {
L
Luqman Aden 已提交
4421
                        debug!("(resolving trait) found trait def: {}", def);
4422 4423 4424 4425 4426
                        self.record_def(trait_reference.ref_id, def);
                    }
                    (def, _) => {
                        self.resolve_error(trait_reference.path.span,
                                           format!("`{}` is not a trait",
4427
                                                   self.path_names_to_string(
A
Alex Crichton 已提交
4428
                                                       &trait_reference.path))[]);
4429 4430

                        // If it's a typedef, give a note
4431 4432 4433 4434
                        if let DefTy(..) = def {
                            self.session.span_note(
                                trait_reference.path.span,
                                format!("`type` aliases cannot be used for traits")
A
Alex Crichton 已提交
4435
                                    []);
4436 4437 4438
                        }
                    }
                }
4439 4440 4441 4442
            }
        }
    }

4443 4444
    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
        for predicate in where_clause.predicates.iter() {
4445
            match predicate {
N
Nick Cameron 已提交
4446
                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
4447
                    self.resolve_type(&*bound_pred.bounded_ty);
4448 4449

                    for bound in bound_pred.bounds.iter() {
4450
                        self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
4451 4452
                                                          TraitBoundingTypeParameter);
                    }
4453
                }
4454
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
4455
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
4456 4457 4458 4459 4460 4461 4462 4463 4464
                    match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
                        Some((def @ DefTyParam(..), last_private)) => {
                            self.record_def(eq_pred.id, (def, last_private));
                        }
                        _ => {
                            self.resolve_error(eq_pred.path.span,
                                               "undeclared associated type");
                        }
                    }
4465

4466 4467
                    self.resolve_type(&*eq_pred.ty);
                }
4468 4469 4470 4471
            }
        }
    }

F
Felix S. Klock II 已提交
4472
    fn resolve_struct(&mut self,
4473 4474 4475
                      id: NodeId,
                      generics: &Generics,
                      fields: &[StructField]) {
4476
        // If applicable, create a rib for the type parameters.
4477
        self.with_type_parameter_rib(HasTypeParameters(generics,
4478
                                                       TypeSpace,
4479
                                                       id,
4480
                                                       ItemRibKind),
4481
                                     |this| {
4482
            // Resolve the type parameters.
A
Alex Crichton 已提交
4483
            this.resolve_type_parameters(&generics.ty_params);
4484
            this.resolve_where_clause(&generics.where_clause);
4485

4486
            // Resolve fields.
D
Daniel Micay 已提交
4487
            for field in fields.iter() {
4488
                this.resolve_type(&*field.node.ty);
4489
            }
4490
        });
4491 4492
    }

4493 4494
    // Does this really need to take a RibKind or is it always going
    // to be NormalRibKind?
F
Felix S. Klock II 已提交
4495
    fn resolve_method(&mut self,
4496
                      rib_kind: RibKind,
4497
                      method: &ast::Method) {
4498
        let method_generics = method.pe_generics();
4499 4500 4501 4502
        let type_parameters = HasTypeParameters(method_generics,
                                                FnSpace,
                                                method.id,
                                                rib_kind);
4503

4504 4505
        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
            self.resolve_type(&**typ);
4506 4507 4508 4509 4510
        }

        self.resolve_function(rib_kind,
                              Some(method.pe_fn_decl()),
                              type_parameters,
4511
                              method.pe_body());
4512 4513
    }

J
Jorge Aparicio 已提交
4514 4515 4516
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
4517 4518 4519 4520 4521 4522 4523
        // Handle nested impls (inside fn bodies)
        let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
        let result = f(self);
        self.current_self_type = previous_value;
        result
    }

J
Jorge Aparicio 已提交
4524 4525 4526 4527 4528
    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
                                     opt_trait_ref: &Option<TraitRef>,
                                     f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
4529 4530 4531 4532
        let new_val = match *opt_trait_ref {
            Some(ref trait_ref) => {
                self.resolve_trait_reference(id, trait_ref, TraitImplementation);

4533
                match self.def_map.borrow().get(&trait_ref.ref_id) {
4534
                    Some(def) => {
4535
                        let did = def.def_id();
4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548
                        Some((did, trait_ref.clone()))
                    }
                    None => None
                }
            }
            None => None
        };
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
        let result = f(self);
        self.current_trait_ref = original_trait_ref;
        result
    }

F
Felix S. Klock II 已提交
4549
    fn resolve_implementation(&mut self,
4550 4551 4552 4553
                              id: NodeId,
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
4554
                              impl_items: &[ImplItem]) {
4555
        // If applicable, create a rib for the type parameters.
4556
        self.with_type_parameter_rib(HasTypeParameters(generics,
4557
                                                       TypeSpace,
4558 4559 4560
                                                       id,
                                                       NormalRibKind),
                                     |this| {
4561
            // Resolve the type parameters.
A
Alex Crichton 已提交
4562
            this.resolve_type_parameters(&generics.ty_params);
4563
            this.resolve_where_clause(&generics.where_clause);
4564

4565
            // Resolve the trait reference, if necessary.
4566 4567 4568 4569 4570
            this.with_optional_trait_ref(id, opt_trait_reference, |this| {
                // Resolve the self type.
                this.resolve_type(self_type);

                this.with_current_self_type(self_type, |this| {
4571 4572
                    for impl_item in impl_items.iter() {
                        match *impl_item {
4573
                            MethodImplItem(ref method) => {
4574 4575
                                // If this is a trait impl, ensure the method
                                // exists in trait
4576
                                this.check_trait_item(method.pe_ident().name,
4577 4578 4579 4580 4581
                                                      method.span);

                                // We also need a new scope for the method-
                                // specific type parameters.
                                this.resolve_method(
4582
                                    MethodRibKind(id, ProvidedMethod(method.id)),
4583
                                    &**method);
4584
                            }
4585 4586 4587
                            TypeImplItem(ref typedef) => {
                                // If this is a trait impl, ensure the method
                                // exists in trait
4588
                                this.check_trait_item(typedef.ident.name,
4589 4590 4591 4592
                                                      typedef.span);

                                this.resolve_type(&*typedef.typ);
                            }
4593
                        }
4594
                    }
4595 4596
                });
            });
4597
        });
4598 4599 4600 4601 4602 4603 4604 4605 4606 4607

        // Check that the current type is indeed a type, if we have an anonymous impl
        if opt_trait_reference.is_none() {
            match self_type.node {
                // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
                // where we created a module with the name of the type in order to implement
                // an anonymous trait. In the case that the path does not resolve to an actual
                // type, the result will be that the type name resolves to a module but not
                // a type (shadowing any imported modules or types with this name), leading
                // to weird user-visible bugs. So we ward this off here. See #15060.
4608
                TyPath(ref path, path_id) => {
4609
                    match self.def_map.borrow().get(&path_id) {
4610 4611 4612 4613
                        // FIXME: should we catch other options and give more precise errors?
                        Some(&DefMod(_)) => {
                            self.resolve_error(path.span, "inherent implementations are not \
                                                           allowed for types not defined in \
4614
                                                           the current module");
4615 4616 4617 4618 4619 4620 4621
                        }
                        _ => {}
                    }
                }
                _ => { }
            }
        }
4622 4623
    }

4624
    fn check_trait_item(&self, name: Name, span: Span) {
4625 4626
        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
        for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4627
            if self.trait_item_map.get(&(name, did)).is_none() {
4628
                let path_str = self.path_names_to_string(&trait_ref.path);
4629
                self.resolve_error(span,
4630
                                    format!("method `{}` is not a member of trait `{}`",
4631
                                            token::get_name(name),
A
Alex Crichton 已提交
4632
                                            path_str)[]);
4633 4634 4635 4636
            }
        }
    }

4637
    fn resolve_module(&mut self, module: &Mod, _span: Span,
4638
                      _name: Name, id: NodeId) {
4639
        // Write the implementations in scope into the module metadata.
4640
        debug!("(resolving module) resolving module ID {}", id);
4641
        visit::walk_mod(self, module);
4642 4643
    }

E
Eduard Burtescu 已提交
4644
    fn resolve_local(&mut self, local: &Local) {
4645
        // Resolve the type.
4646
        self.resolve_type(&*local.ty);
4647 4648

        // Resolve the initializer, if necessary.
4649
        match local.init {
B
Brian Anderson 已提交
4650
            None => {
4651 4652
                // Nothing to do.
            }
4653 4654
            Some(ref initializer) => {
                self.resolve_expr(&**initializer);
4655 4656 4657 4658
            }
        }

        // Resolve the pattern.
4659 4660 4661 4662
        let mut bindings_list = HashMap::new();
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
                             &mut bindings_list);
4663 4664
    }

J
John Clements 已提交
4665 4666 4667 4668
    // build a map from pattern identifiers to binding-info's.
    // this is done hygienically. This could arise for a macro
    // that expands into an or-pattern where one 'x' was from the
    // user and one 'x' came from the macro.
E
Eduard Burtescu 已提交
4669
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4670
        let mut result = HashMap::new();
4671 4672
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
4673 4674 4675 4676
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
4677
        });
4678
        return result;
4679 4680
    }

J
John Clements 已提交
4681 4682
    // check that all of the arms in an or-pattern have exactly the
    // same set of bindings, with the same binding modes for each.
F
Felix S. Klock II 已提交
4683
    fn check_consistent_bindings(&mut self, arm: &Arm) {
4684 4685 4686
        if arm.pats.len() == 0 {
            return
        }
4687
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
4688
        for (i, p) in arm.pats.iter().enumerate() {
4689
            let map_i = self.binding_mode_map(&**p);
4690

D
Daniel Micay 已提交
4691
            for (&key, &binding_0) in map_0.iter() {
4692
                match map_i.get(&key) {
4693 4694 4695 4696 4697 4698
                  None => {
                    self.resolve_error(
                        p.span,
                        format!("variable `{}` from pattern #1 is \
                                  not bound in pattern #{}",
                                token::get_name(key),
A
Alex Crichton 已提交
4699
                                i + 1)[]);
4700 4701 4702 4703 4704 4705 4706 4707
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
                        self.resolve_error(
                            binding_i.span,
                            format!("variable `{}` is bound with different \
                                      mode in pattern #{} than in pattern #1",
                                    token::get_name(key),
A
Alex Crichton 已提交
4708
                                    i + 1)[]);
4709 4710
                    }
                  }
4711 4712 4713
                }
            }

D
Daniel Micay 已提交
4714
            for (&key, &binding) in map_i.iter() {
4715
                if !map_0.contains_key(&key) {
4716
                    self.resolve_error(
4717
                        binding.span,
4718 4719
                        format!("variable `{}` from pattern {}{} is \
                                  not bound in pattern {}1",
4720
                                token::get_name(key),
A
Alex Crichton 已提交
4721
                                "#", i + 1, "#")[]);
4722 4723 4724
                }
            }
        }
4725 4726
    }

F
Felix S. Klock II 已提交
4727
    fn resolve_arm(&mut self, arm: &Arm) {
4728
        self.value_ribs.push(Rib::new(NormalRibKind));
4729

4730
        let mut bindings_list = HashMap::new();
D
Daniel Micay 已提交
4731
        for pattern in arm.pats.iter() {
4732
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4733 4734
        }

4735 4736 4737 4738
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

4739
        visit::walk_expr_opt(self, &arm.guard);
4740
        self.resolve_expr(&*arm.body);
4741

4742
        self.value_ribs.pop();
4743 4744
    }

E
Eduard Burtescu 已提交
4745
    fn resolve_block(&mut self, block: &Block) {
4746
        debug!("(resolving block) entering block");
4747
        self.value_ribs.push(Rib::new(NormalRibKind));
4748 4749

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
4750
        let orig_module = self.current_module.clone();
4751
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
4752
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
4753
            Some(anonymous_module) => {
4754
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
4755
                        down");
E
Eduard Burtescu 已提交
4756
                self.current_module = anonymous_module.clone();
4757 4758 4759 4760
            }
        }

        // Descend into the block.
4761
        visit::walk_block(self, block);
4762 4763 4764 4765

        // Move back up.
        self.current_module = orig_module;

4766
        self.value_ribs.pop();
4767
        debug!("(resolving block) leaving block");
4768 4769
    }

F
Felix S. Klock II 已提交
4770
    fn resolve_type(&mut self, ty: &Ty) {
4771
        match ty.node {
4772 4773 4774
            // Like path expressions, the interpretation of path types depends
            // on whether the path has multiple elements in it or not.

4775
            TyPath(ref path, path_id) => {
4776
                // This is a path in the type namespace. Walk through scopes
4777
                // looking for it.
4778
                let mut result_def = None;
4779

4780
                // First, check to see whether the name is a primitive type.
4781
                if path.segments.len() == 1 {
4782
                    let id = path.segments.last().unwrap().identifier;
4783 4784 4785

                    match self.primitive_type_table
                            .primitive_types
4786
                            .get(&id.name) {
4787

4788
                        Some(&primitive_type) => {
4789
                            result_def =
4790
                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4791

4792
                            if path.segments[0].parameters.has_lifetimes() {
J
Jakub Wieczorek 已提交
4793 4794
                                span_err!(self.session, path.span, E0157,
                                    "lifetime parameters are not allowed on this type");
4795
                            } else if !path.segments[0].parameters.is_empty() {
J
Jakub Wieczorek 已提交
4796 4797
                                span_err!(self.session, path.span, E0153,
                                    "type parameters are not allowed on this type");
4798
                            }
4799 4800 4801 4802
                        }
                        None => {
                            // Continue.
                        }
4803 4804 4805
                    }
                }

4806
                match result_def {
B
Brian Anderson 已提交
4807
                    None => {
4808
                        match self.resolve_path(ty.id, path, TypeNS, true) {
4809
                            Some(def) => {
4810
                                debug!("(resolving type) resolved `{}` to \
L
Luqman Aden 已提交
4811
                                        type {}",
4812 4813 4814
                                       token::get_ident(path.segments
                                                            .last().unwrap()
                                                            .identifier),
4815
                                       def);
4816 4817 4818 4819
                                result_def = Some(def);
                            }
                            None => {
                                result_def = None;
4820 4821 4822
                            }
                        }
                    }
4823
                    Some(_) => {}   // Continue.
4824 4825
                }

4826
                match result_def {
B
Brian Anderson 已提交
4827
                    Some(def) => {
4828
                        // Write the result into the def map.
4829
                        debug!("(resolving type) writing resolution for `{}` \
A
Alex Crichton 已提交
4830
                                (id {})",
4831
                               self.path_names_to_string(path),
P
Paul Stansifer 已提交
4832
                               path_id);
4833 4834
                        self.record_def(path_id, def);
                    }
B
Brian Anderson 已提交
4835
                    None => {
A
Alex Crichton 已提交
4836
                        let msg = format!("use of undeclared type name `{}`",
4837
                                          self.path_names_to_string(path));
A
Alex Crichton 已提交
4838
                        self.resolve_error(ty.span, msg[]);
4839 4840
                    }
                }
4841
            }
4842

4843 4844 4845
            TyObjectSum(ref ty, ref bound_vec) => {
                self.resolve_type(&**ty);
                self.resolve_type_parameter_bounds(ty.id, bound_vec,
4846
                                                       TraitBoundingTypeParameter);
4847 4848
            }

4849
            TyQPath(ref qpath) => {
4850 4851
                self.resolve_type(&*qpath.self_type);
                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
4852 4853
            }

4854
            TyClosure(ref c) => {
4855 4856 4857 4858
                self.resolve_type_parameter_bounds(
                    ty.id,
                    &c.bounds,
                    TraitBoundingTypeParameter);
4859
                visit::walk_ty(self, ty);
4860 4861
            }

4862 4863
            TyPolyTraitRef(ref bounds) => {
                self.resolve_type_parameter_bounds(
N
Niko Matsakis 已提交
4864
                    ty.id,
4865
                    bounds,
N
Niko Matsakis 已提交
4866 4867 4868
                    TraitObject);
                visit::walk_ty(self, ty);
            }
B
Brian Anderson 已提交
4869
            _ => {
4870
                // Just resolve embedded types.
4871
                visit::walk_ty(self, ty);
4872 4873 4874 4875
            }
        }
    }

F
Felix S. Klock II 已提交
4876
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
4877
                       pattern: &Pat,
4878 4879 4880
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
4881
                       bindings_list: &mut HashMap<Name, NodeId>) {
4882
        let pat_id = pattern.id;
4883
        walk_pat(pattern, |pattern| {
4884
            match pattern.node {
4885
                PatIdent(binding_mode, ref path1, _) => {
4886 4887

                    // The meaning of pat_ident with no type parameters
4888 4889 4890 4891 4892 4893 4894
                    // depends on whether an enum variant or unit-like struct
                    // with that name is in scope. The probing lookup has to
                    // be careful not to emit spurious errors. Only matching
                    // patterns (match) can match nullary variants or
                    // unit-like structs. For binding patterns (let), matching
                    // such a value is simply disallowed (since it's rarely
                    // what you want).
4895

4896
                    let ident = path1.node;
4897
                    let renamed = mtwt::resolve(ident);
4898

4899
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
4900
                        FoundStructOrEnumVariant(ref def, lp)
4901
                                if mode == RefutableMode => {
4902
                            debug!("(resolving pattern) resolving `{}` to \
4903
                                    struct or enum variant",
4904
                                   token::get_name(renamed));
4905

4906 4907 4908 4909
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
4910
                            self.record_def(pattern.id, (def.clone(), lp));
4911
                        }
A
Alex Crichton 已提交
4912
                        FoundStructOrEnumVariant(..) => {
4913 4914 4915 4916 4917
                            self.resolve_error(
                                pattern.span,
                                format!("declaration of `{}` shadows an enum \
                                         variant or unit-like struct in \
                                         scope",
A
Alex Crichton 已提交
4918
                                        token::get_name(renamed))[]);
4919
                        }
4920
                        FoundConst(ref def, lp) if mode == RefutableMode => {
4921
                            debug!("(resolving pattern) resolving `{}` to \
4922
                                    constant",
4923
                                   token::get_name(renamed));
4924

4925 4926 4927 4928
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
4929
                            self.record_def(pattern.id, (def.clone(), lp));
4930
                        }
A
Alex Crichton 已提交
4931
                        FoundConst(..) => {
4932
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
4933
                                                  "only irrefutable patterns \
4934
                                                   allowed here");
4935
                        }
4936
                        BareIdentifierPatternUnresolved => {
4937
                            debug!("(resolving pattern) binding `{}`",
4938
                                   token::get_name(renamed));
4939

4940
                            let def = DefLocal(pattern.id);
4941 4942 4943 4944 4945

                            // Record the definition so that later passes
                            // will be able to distinguish variants from
                            // locals in patterns.

4946
                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
4947 4948 4949 4950 4951 4952

                            // Add the binding to the local ribs, if it
                            // doesn't already exist in the bindings list. (We
                            // must not add it if it's in the bindings list
                            // because that breaks the assumptions later
                            // passes make about or-patterns.)
4953 4954
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
4955 4956
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
4957
                                bindings_list.insert(renamed, pat_id);
4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
                                self.resolve_error(pattern.span,
                                                   format!("identifier `{}` \
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
A
Alex Crichton 已提交
4970
                                                   [])
4971
                            } else if bindings_list.get(&renamed) ==
4972 4973 4974 4975 4976 4977 4978
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
                                self.resolve_error(pattern.span,
                                    format!("identifier `{}` is bound \
                                             more than once in the same \
                                             pattern",
A
Alex Crichton 已提交
4979
                                            token::get_ident(ident))[]);
4980
                            }
4981 4982
                            // Else, not bound in the same pattern: do
                            // nothing.
4983 4984 4985 4986
                        }
                    }
                }

4987
                PatEnum(ref path, _) => {
4988
                    // This must be an enum variant, struct or const.
A
Alex Crichton 已提交
4989
                    match self.resolve_path(pat_id, path, ValueNS, false) {
A
Alex Crichton 已提交
4990 4991
                        Some(def @ (DefVariant(..), _)) |
                        Some(def @ (DefStruct(..), _))  |
4992
                        Some(def @ (DefConst(..), _)) => {
4993 4994
                            self.record_def(pattern.id, def);
                        }
4995 4996 4997 4998 4999 5000
                        Some((DefStatic(..), _)) => {
                            self.resolve_error(path.span,
                                               "static variables cannot be \
                                                referenced in a pattern, \
                                                use a `const` instead");
                        }
5001
                        Some(_) => {
5002
                            self.resolve_error(path.span,
A
Alex Crichton 已提交
5003
                                format!("`{}` is not an enum variant, struct or const",
5004 5005 5006 5007
                                    token::get_ident(
                                        path.segments
                                            .last()
                                            .unwrap()
A
Alex Crichton 已提交
5008
                                            .identifier))[]);
5009 5010
                        }
                        None => {
5011
                            self.resolve_error(path.span,
5012
                                format!("unresolved enum variant, struct or const `{}`",
5013 5014 5015 5016
                                    token::get_ident(
                                        path.segments
                                            .last()
                                            .unwrap()
A
Alex Crichton 已提交
5017
                                            .identifier))[]);
5018 5019 5020 5021
                        }
                    }

                    // Check the types in the path pattern.
5022
                    for ty in path.segments
5023
                                  .iter()
5024
                                  .flat_map(|s| s.parameters.types().into_iter()) {
5025
                        self.resolve_type(&**ty);
5026 5027 5028
                    }
                }

5029 5030
                PatLit(ref expr) => {
                    self.resolve_expr(&**expr);
5031 5032
                }

5033 5034 5035
                PatRange(ref first_expr, ref last_expr) => {
                    self.resolve_expr(&**first_expr);
                    self.resolve_expr(&**last_expr);
5036 5037
                }

5038
                PatStruct(ref path, _, _) => {
A
Alex Crichton 已提交
5039
                    match self.resolve_path(pat_id, path, TypeNS, false) {
5040
                        Some(definition) => {
5041 5042
                            self.record_def(pattern.id, definition);
                        }
5043
                        result => {
5044
                            debug!("(resolving pattern) didn't find struct \
L
Luqman Aden 已提交
5045
                                    def: {}", result);
A
Alex Crichton 已提交
5046
                            let msg = format!("`{}` does not name a structure",
5047
                                              self.path_names_to_string(path));
A
Alex Crichton 已提交
5048
                            self.resolve_error(path.span, msg[]);
5049 5050 5051 5052
                        }
                    }
                }

5053
                _ => {
5054 5055 5056
                    // Nothing to do.
                }
            }
5057
            true
5058
        });
5059 5060
    }

5061
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
5062 5063 5064
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
5065
                                                 name,
5066
                                                 ValueNS) {
5067
            Success((target, _)) => {
5068
                debug!("(resolve bare identifier pattern) succeeded in \
L
Luqman Aden 已提交
5069
                         finding {} at {}",
5070
                        token::get_name(name),
E
Erick Tryzelaar 已提交
5071 5072
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
5073
                    None => {
S
Steve Klabnik 已提交
5074
                        panic!("resolved name in the value namespace to a \
5075
                              set of name bindings with no def?!");
5076
                    }
B
Brian Anderson 已提交
5077
                    Some(def) => {
5078 5079 5080
                        // For the two success cases, this lookup can be
                        // considered as not having a private component because
                        // the lookup happened only within the current module.
5081
                        match def.def {
A
Alex Crichton 已提交
5082
                            def @ DefVariant(..) | def @ DefStruct(..) => {
5083
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5084
                            }
5085
                            def @ DefConst(..) => {
5086
                                return FoundConst(def, LastMod(AllPublic));
5087
                            }
5088
                            DefStatic(..) => {
5089
                                self.resolve_error(span,
5090 5091 5092
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
5093 5094
                                return BareIdentifierPatternUnresolved;
                            }
5095
                            _ => {
5096
                                return BareIdentifierPatternUnresolved;
5097 5098
                            }
                        }
5099 5100 5101 5102
                    }
                }
            }

B
Brian Anderson 已提交
5103
            Indeterminate => {
S
Steve Klabnik 已提交
5104
                panic!("unexpected indeterminate result");
5105
            }
5106 5107 5108 5109
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
                        self.resolve_error(span, format!("failed to resolve: {}",
A
Alex Crichton 已提交
5110
                                                         msg)[]);
5111 5112 5113
                    }
                    None => ()
                }
5114

5115
                debug!("(resolve bare identifier pattern) failed to find {}",
5116
                        token::get_name(name));
5117
                return BareIdentifierPatternUnresolved;
5118 5119 5120 5121
            }
        }
    }

5122 5123
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
F
Felix S. Klock II 已提交
5124
    fn resolve_path(&mut self,
5125 5126 5127 5128
                    id: NodeId,
                    path: &Path,
                    namespace: Namespace,
                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
5129
        // First, resolve the types and associated type bindings.
5130
        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
5131
            self.resolve_type(&**ty);
5132
        }
5133 5134 5135
        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
            self.resolve_type(&*binding.ty);
        }
5136

5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164
        // A special case for sugared associated type paths `T::A` where `T` is
        // a type parameter and `A` is an associated type on some bound of `T`.
        if namespace == TypeNS && path.segments.len() == 2 {
            match self.resolve_identifier(path.segments[0].identifier,
                                          TypeNS,
                                          true,
                                          path.span) {
                Some((def, last_private)) => {
                    match def {
                        DefTyParam(_, did, _) => {
                            let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
                                                        path.segments.last()
                                                            .unwrap().identifier);
                            return Some((def, last_private));
                        }
                        DefSelfTy(nid) => {
                            let def = DefAssociatedPath(TyParamProvenance::FromSelf(local_def(nid)),
                                                        path.segments.last()
                                                            .unwrap().identifier);
                            return Some((def, last_private));
                        }
                        _ => {}
                    }
                }
                _ => {}
            }
        }

5165
        if path.global {
5166
            return self.resolve_crate_relative_path(path, namespace);
5167 5168
        }

5169
        // Try to find a path to an item in a module.
5170 5171
        let unqualified_def =
                self.resolve_identifier(path.segments
5172
                                            .last().unwrap()
5173 5174 5175 5176
                                            .identifier,
                                        namespace,
                                        check_ribs,
                                        path.span);
5177

5178
        if path.segments.len() > 1 {
5179
            let def = self.resolve_module_relative_path(path, namespace);
5180
            match (def, unqualified_def) {
5181
                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5182
                    self.session
A
Aaron Turon 已提交
5183
                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
5184 5185
                                  id,
                                  path.span,
5186
                                  "unnecessary qualification".to_string());
5187 5188 5189
                }
                _ => ()
            }
5190

5191
            return def;
5192 5193
        }

5194
        return unqualified_def;
5195 5196
    }

J
John Clements 已提交
5197
    // resolve a single identifier (used as a varref)
F
Felix S. Klock II 已提交
5198
    fn resolve_identifier(&mut self,
5199 5200 5201 5202 5203
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
5204
        if check_ribs {
5205
            match self.resolve_identifier_in_local_ribs(identifier,
5206 5207
                                                        namespace,
                                                        span) {
B
Brian Anderson 已提交
5208
                Some(def) => {
5209
                    return Some((def, LastMod(AllPublic)));
5210
                }
B
Brian Anderson 已提交
5211
                None => {
5212 5213 5214 5215 5216
                    // Continue.
                }
            }
        }

5217
        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
5218 5219
    }

5220
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
5221
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
5222
                                            containing_module: Rc<Module>,
5223
                                            name: Name,
5224
                                            namespace: Namespace)
5225
                                            -> NameDefinition {
5226
        // First, search children.
E
Eduard Burtescu 已提交
5227
        self.populate_module_if_necessary(&containing_module);
5228

5229
        match containing_module.children.borrow().get(&name) {
5230 5231 5232 5233 5234 5235 5236
            Some(child_name_bindings) => {
                match child_name_bindings.def_for_namespace(namespace) {
                    Some(def) => {
                        // Found it. Stop the search here.
                        let p = child_name_bindings.defined_in_public_namespace(
                                        namespace);
                        let lp = if p {LastMod(AllPublic)} else {
5237
                            LastMod(DependsOn(def.def_id()))
5238 5239
                        };
                        return ChildNameDefinition(def, lp);
5240
                    }
5241
                    None => {}
5242 5243
                }
            }
5244
            None => {}
5245 5246 5247
        }

        // Next, search import resolutions.
5248
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
5249
            Some(import_resolution) if import_resolution.is_public => {
5250 5251 5252 5253 5254 5255 5256
                if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
                    match target.bindings.def_for_namespace(namespace) {
                        Some(def) => {
                            // Found it.
                            let id = import_resolution.id(namespace);
                            // track imports and extern crates as well
                            self.used_imports.insert((id, namespace));
5257
                            self.record_import_use(id, name);
5258 5259 5260 5261 5262
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
5263
                            }
5264 5265 5266 5267 5268
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
5269 5270 5271 5272
                        }
                    }
                }
            }
A
Alex Crichton 已提交
5273
            Some(..) | None => {} // Continue.
5274 5275 5276 5277
        }

        // Finally, search through external children.
        if namespace == TypeNS {
5278 5279 5280 5281 5282 5283 5284 5285 5286
            if let Some(module) = containing_module.external_module_children.borrow()
                                                   .get(&name).cloned() {
                if let Some(def_id) = module.def_id.get() {
                    // track used crates
                    self.used_crates.insert(def_id.krate);
                    let lp = if module.is_public {LastMod(AllPublic)} else {
                        LastMod(DependsOn(def_id))
                    };
                    return ChildNameDefinition(DefMod(def_id), lp);
5287
                }
5288 5289
            }
        }
5290 5291

        return NoNameDefinition;
5292 5293
    }

5294
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
5295
    fn resolve_module_relative_path(&mut self,
5296 5297 5298
                                    path: &Path,
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
5299 5300 5301
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
5302

5303
        let containing_module;
5304
        let last_private;
E
Eduard Burtescu 已提交
5305 5306
        let module = self.current_module.clone();
        match self.resolve_module_path(module,
A
Alex Crichton 已提交
5307
                                       module_path[],
5308 5309
                                       UseLexicalScope,
                                       path.span,
5310
                                       PathSearch) {
5311 5312 5313 5314
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
5315 5316
                        let msg = format!("Use of undeclared type or module `{}`",
                                          self.names_to_string(module_path.as_slice()));
5317 5318 5319
                        (path.span, msg)
                    }
                };
5320

5321
                self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
5322
                                                 msg)[]);
5323
                return None;
5324
            }
S
Steve Klabnik 已提交
5325
            Indeterminate => panic!("indeterminate unexpected"),
5326
            Success((resulting_module, resulting_last_private)) => {
5327
                containing_module = resulting_module;
5328
                last_private = resulting_last_private;
5329 5330 5331
            }
        }

5332
        let name = path.segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
5333
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5334
                                                                  name,
5335
                                                                  namespace) {
B
Brian Anderson 已提交
5336
            NoNameDefinition => {
5337
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
5338
                return None;
5339
            }
5340 5341
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
5342
            }
5343
        };
5344 5345
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
5346
        }
5347
        return Some(def);
5348 5349
    }

5350 5351
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
5352
    fn resolve_crate_relative_path(&mut self,
5353 5354 5355
                                   path: &Path,
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
5356 5357 5358
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
5359

5360
        let root_module = self.graph_root.get_module();
5361

5362
        let containing_module;
5363
        let last_private;
5364
        match self.resolve_module_path_from_root(root_module,
A
Alex Crichton 已提交
5365
                                                 module_path[],
5366
                                                 0,
5367
                                                 path.span,
5368
                                                 PathSearch,
5369
                                                 LastMod(AllPublic)) {
5370 5371 5372 5373 5374
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
A
Alex Crichton 已提交
5375
                                          self.names_to_string(module_path[]));
5376 5377 5378 5379 5380
                        (path.span, msg)
                    }
                };

                self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
5381
                                                 msg)[]);
B
Brian Anderson 已提交
5382
                return None;
5383 5384
            }

B
Brian Anderson 已提交
5385
            Indeterminate => {
S
Steve Klabnik 已提交
5386
                panic!("indeterminate unexpected");
5387 5388
            }

5389
            Success((resulting_module, resulting_last_private)) => {
5390
                containing_module = resulting_module;
5391
                last_private = resulting_last_private;
5392 5393 5394
            }
        }

5395
        let name = path.segments.last().unwrap().identifier.name;
5396
        match self.resolve_definition_of_name_in_module(containing_module,
5397
                                                        name,
5398
                                                        namespace) {
B
Brian Anderson 已提交
5399
            NoNameDefinition => {
5400
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
5401
                return None;
5402
            }
5403 5404
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
5405 5406 5407 5408
            }
        }
    }

F
Felix S. Klock II 已提交
5409
    fn resolve_identifier_in_local_ribs(&mut self,
5410 5411 5412 5413
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
5414
        // Check the local set of ribs.
5415
        let search_result = match namespace {
B
Brian Anderson 已提交
5416
            ValueNS => {
5417
                let renamed = mtwt::resolve(ident);
5418
                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
5419
            }
B
Brian Anderson 已提交
5420
            TypeNS => {
5421
                let name = ident.name;
A
Alex Crichton 已提交
5422
                self.search_ribs(self.type_ribs[], name, span)
5423
            }
5424
        };
5425

5426
        match search_result {
5427
            Some(DlDef(def)) => {
5428
                debug!("(resolving path in local ribs) resolved `{}` to \
L
Luqman Aden 已提交
5429
                        local: {}",
5430
                       token::get_ident(ident),
P
Paul Stansifer 已提交
5431
                       def);
B
Brian Anderson 已提交
5432
                return Some(def);
5433
            }
5434
            Some(DlField) | Some(DlImpl(_)) | None => {
B
Brian Anderson 已提交
5435
                return None;
5436 5437 5438 5439
            }
        }
    }

5440 5441 5442 5443
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
5444
        // Check the items.
E
Eduard Burtescu 已提交
5445 5446
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
5447
                                                 name,
5448
                                                 namespace) {
5449
            Success((target, _)) => {
5450
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
5451
                    None => {
5452 5453
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
5454
                        debug!("(resolving item path by identifier in lexical \
5455
                                 scope) failed to resolve {} after success...",
5456
                                 token::get_name(name));
5457
                        return None;
5458
                    }
B
Brian Anderson 已提交
5459
                    Some(def) => {
5460
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
5461
                                resolved `{}` to item",
5462
                               token::get_name(name));
5463 5464 5465
                        // This lookup is "all public" because it only searched
                        // for one identifier in the current module (couldn't
                        // have passed through reexports or anything like that.
5466
                        return Some((def, LastMod(AllPublic)));
5467 5468 5469
                    }
                }
            }
B
Brian Anderson 已提交
5470
            Indeterminate => {
S
Steve Klabnik 已提交
5471
                panic!("unexpected indeterminate result");
5472
            }
5473 5474 5475
            Failed(err) => {
                match err {
                    Some((span, msg)) =>
A
Alex Crichton 已提交
5476 5477
                        self.resolve_error(span, format!("failed to resolve. {}",
                                                         msg)[]),
5478 5479 5480
                    None => ()
                }

5481
                debug!("(resolving item path by identifier in lexical scope) \
5482
                         failed to resolve {}", token::get_name(name));
B
Brian Anderson 已提交
5483
                return None;
5484 5485 5486 5487
            }
        }
    }

J
Jorge Aparicio 已提交
5488 5489 5490
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
5491
        self.emit_errors = false;
A
Alex Crichton 已提交
5492
        let rs = f(self);
5493 5494 5495 5496
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
5497
    fn resolve_error(&self, span: Span, s: &str) {
5498
        if self.emit_errors {
A
Alex Crichton 已提交
5499
            self.session.span_err(span, s);
5500 5501 5502
        }
    }

5503
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5504 5505 5506
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
5507
                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
5508 5509
                TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
                TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5510 5511 5512 5513 5514 5515 5516
                // This doesn't handle the remaining `Ty` variants as they are not
                // that commonly the self_type, it might be interesting to provide
                // support for those in future.
                _ => None,
            }
        }

5517
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
5518 5519
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
5520
            let last_name = name_path.last().unwrap();
5521

5522
            if name_path.len() == 1 {
5523
                match this.primitive_type_table.primitive_types.get(last_name) {
5524 5525
                    Some(_) => None,
                    None => {
5526
                        match this.current_module.children.borrow().get(last_name) {
5527 5528 5529 5530 5531 5532 5533
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
A
Alex Crichton 已提交
5534
                                                name_path[],
5535 5536 5537 5538 5539 5540 5541 5542 5543
                                                UseLexicalScope,
                                                span,
                                                PathSearch) {
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

5544 5545 5546 5547
        let (path, node_id, allowed) = match self.current_self_type {
            Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
                Some(x) => x,
                None => return NoSuggestion,
5548 5549 5550 5551
            },
            None => return NoSuggestion,
        };

5552 5553
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
5554
            match self.def_map.borrow().get(&node_id) {
5555
                 Some(&DefTy(did, _))
5556
                | Some(&DefStruct(did))
5557
                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
5558 5559 5560 5561 5562
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
5563
                    }
5564 5565 5566
                },
                _ => {} // Self type didn't resolve properly
            }
5567 5568
        }

5569
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
5570 5571

        // Look for a method in the current self type's impl module.
A
Alex Crichton 已提交
5572
        match get_module(self, path.span, name_path[]) {
5573
            Some(module) => match module.children.borrow().get(&name) {
5574
                Some(binding) => {
5575
                    let p_str = self.path_names_to_string(&path);
5576
                    match binding.def_for_namespace(ValueNS) {
5577
                        Some(DefStaticMethod(_, provenance)) => {
5578 5579 5580 5581 5582
                            match provenance {
                                FromImpl(_) => return StaticMethod(p_str),
                                FromTrait(_) => unreachable!()
                            }
                        }
5583 5584
                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595
                        _ => ()
                    }
                }
                None => {}
            },
            None => {}
        }

        // Look for a method in the current trait.
        match self.current_trait_ref {
            Some((did, ref trait_ref)) => {
5596
                let path_str = self.path_names_to_string(&trait_ref.path);
5597

5598
                match self.trait_item_map.get(&(name, did)) {
5599 5600 5601
                    Some(&StaticMethodTraitItemKind) => {
                        return TraitMethod(path_str)
                    }
5602
                    Some(_) => return TraitItem,
5603 5604 5605 5606 5607 5608 5609 5610 5611
                    None => {}
                }
            }
            None => {}
        }

        NoSuggestion
    }

5612
    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5613
                                -> Option<String> {
5614 5615
        let this = &mut *self;

5616 5617
        let mut maybes: Vec<token::InternedString> = Vec::new();
        let mut values: Vec<uint> = Vec::new();
5618

5619 5620
        for rib in this.value_ribs.iter().rev() {
            for (&k, _) in rib.bindings.iter() {
5621
                maybes.push(token::get_name(k));
C
Chris Wong 已提交
5622
                values.push(uint::MAX);
5623 5624 5625 5626
            }
        }

        let mut smallest = 0;
P
Patrick Walton 已提交
5627
        for (i, other) in maybes.iter().enumerate() {
A
Alex Crichton 已提交
5628
            values[i] = lev_distance(name, other.get());
5629

5630
            if values[i] <= values[smallest] {
5631 5632 5633 5634
                smallest = i;
            }
        }

Y
Youngmin Yoo 已提交
5635
        if values.len() > 0 &&
5636 5637 5638 5639
            values[smallest] != uint::MAX &&
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
            name != maybes[smallest].get() {
5640

5641
            Some(maybes[smallest].get().to_string())
5642 5643 5644 5645 5646 5647

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
5648
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
5649 5650
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
5651 5652 5653

        self.record_candidate_traits_for_expr_if_necessary(expr);

5654
        // Next, resolve the node.
5655
        match expr.node {
5656 5657 5658
            // The interpretation of paths depends on whether the path has
            // multiple elements in it or not.

5659
            ExprPath(ref path) => {
5660 5661 5662
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.

5663 5664
                let path_name = self.path_names_to_string(path);

A
Alex Crichton 已提交
5665
                match self.resolve_path(expr.id, path, ValueNS, true) {
5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678
                    // Check if struct variant
                    Some((DefVariant(_, _, true), _)) => {
                        self.resolve_error(expr.span,
                                format!("`{}` is a struct variant name, but \
                                         this expression \
                                         uses it like a function name",
                                        path_name).as_slice());

                        self.session.span_help(expr.span,
                            format!("Did you mean to write: \
                                    `{} {{ /* fields */ }}`?",
                                    path_name).as_slice());
                    }
B
Brian Anderson 已提交
5679
                    Some(def) => {
5680
                        // Write the result into the def map.
5681
                        debug!("(resolving expr) resolved `{}`",
5682
                               path_name);
5683

5684 5685
                        self.record_def(expr.id, def);
                    }
B
Brian Anderson 已提交
5686
                    None => {
A
Alex Crichton 已提交
5687 5688 5689 5690 5691 5692
                        // Be helpful if the name refers to a struct
                        // (The pattern matching def_tys where the id is in self.structs
                        // matches on regular structs while excluding tuple- and enum-like
                        // structs, which wouldn't result in this error.)
                        match self.with_no_errors(|this|
                            this.resolve_path(expr.id, path, TypeNS, false)) {
5693
                            Some((DefTy(struct_id, _), _))
5694 5695 5696 5697 5698
                              if self.structs.contains_key(&struct_id) => {
                                self.resolve_error(expr.span,
                                        format!("`{}` is a structure name, but \
                                                 this expression \
                                                 uses it like a function name",
5699
                                                path_name).as_slice());
5700

P
P1start 已提交
5701
                                self.session.span_help(expr.span,
5702 5703
                                    format!("Did you mean to write: \
                                            `{} {{ /* fields */ }}`?",
5704
                                            path_name).as_slice());
5705

5706
                            }
5707 5708
                            _ => {
                                let mut method_scope = false;
5709
                                self.value_ribs.iter().rev().all(|rib| {
5710 5711
                                    let res = match *rib {
                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5712
                                        Rib { bindings: _, kind: ItemRibKind } => false,
5713 5714 5715 5716 5717 5718 5719
                                        _ => return true, // Keep advancing
                                    };

                                    method_scope = res;
                                    false // Stop advancing
                                });

J
John Clements 已提交
5720
                                if method_scope && token::get_name(self.self_name).get()
5721
                                                                   == path_name {
5722 5723 5724 5725 5726
                                        self.resolve_error(
                                            expr.span,
                                            "`self` is not available \
                                             in a static method. Maybe a \
                                             `self` argument is missing?");
5727
                                } else {
5728 5729
                                    let last_name = path.segments.last().unwrap().identifier.name;
                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
5730 5731 5732
                                        NoSuggestion => {
                                            // limit search to 5 to reduce the number
                                            // of stupid suggestions
5733
                                            self.find_best_match_for_name(path_name.as_slice(), 5)
5734
                                                                .map_or("".to_string(),
5735 5736 5737
                                                                        |x| format!("`{}`", x))
                                        }
                                        Field =>
5738
                                            format!("`self.{}`", path_name),
5739
                                        Method
5740
                                        | TraitItem =>
5741
                                            format!("to call `self.{}`", path_name),
5742
                                        TraitMethod(path_str)
5743
                                        | StaticMethod(path_str) =>
5744
                                            format!("to call `{}::{}`", path_str, path_name)
5745 5746 5747
                                    };

                                    if msg.len() > 0 {
5748
                                        msg = format!(". Did you mean {}?", msg)
5749 5750
                                    }

5751 5752
                                    self.resolve_error(
                                        expr.span,
5753
                                        format!("unresolved name `{}`{}",
5754
                                                path_name,
5755
                                                msg).as_slice());
5756 5757
                                }
                            }
V
Vincent Belliard 已提交
5758
                        }
5759 5760 5761
                    }
                }

5762
                visit::walk_expr(self, expr);
5763 5764
            }

5765
            ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
B
Björn Steinbrink 已提交
5766
                self.capture_mode_map.insert(expr.id, capture_clause);
5767 5768 5769 5770
                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
                                      Some(&**fn_decl), NoTypeParameters,
                                      &**block);
            }
5771

5772
            ExprStruct(ref path, _, _) => {
5773 5774 5775
                // Resolve the path to the structure it goes to. We don't
                // check to ensure that the path is actually a structure; that
                // is checked later during typeck.
A
Alex Crichton 已提交
5776
                match self.resolve_path(expr.id, path, TypeNS, false) {
5777
                    Some(definition) => self.record_def(expr.id, definition),
S
Steven Fackler 已提交
5778
                    result => {
5779
                        debug!("(resolving expression) didn't find struct \
L
Luqman Aden 已提交
5780
                                def: {}", result);
A
Alex Crichton 已提交
5781
                        let msg = format!("`{}` does not name a structure",
5782
                                          self.path_names_to_string(path));
A
Alex Crichton 已提交
5783
                        self.resolve_error(path.span, msg[]);
5784 5785 5786
                    }
                }

5787
                visit::walk_expr(self, expr);
5788 5789
            }

P
Pythoner6 已提交
5790
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5791
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
5792
                    let def_like = DlDef(DefLabel(expr.id));
5793

5794
                    {
5795
                        let rib = this.label_ribs.last_mut().unwrap();
5796
                        let renamed = mtwt::resolve(label);
5797
                        rib.bindings.insert(renamed, def_like);
5798
                    }
5799

5800
                    visit::walk_expr(this, expr);
5801
                })
5802 5803
            }

5804 5805 5806
            ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
                self.resolve_expr(&**head);

5807
                self.value_ribs.push(Rib::new(NormalRibKind));
5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820

                self.resolve_pattern(&**pattern,
                                     LocalIrrefutableMode,
                                     &mut HashMap::new());

                match optional_label {
                    None => {}
                    Some(label) => {
                        self.label_ribs
                            .push(Rib::new(NormalRibKind));
                        let def_like = DlDef(DefLabel(expr.id));

                        {
5821
                            let rib = self.label_ribs.last_mut().unwrap();
5822
                            let renamed = mtwt::resolve(label);
5823
                            rib.bindings.insert(renamed, def_like);
5824 5825 5826 5827 5828 5829 5830
                        }
                    }
                }

                self.resolve_block(&**body);

                if optional_label.is_some() {
5831
                    drop(self.label_ribs.pop())
5832 5833
                }

5834
                self.value_ribs.pop();
5835
            }
5836

5837
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5838
                let renamed = mtwt::resolve(label);
A
Alex Crichton 已提交
5839
                match self.search_ribs(self.label_ribs[],
E
Eduard Burtescu 已提交
5840
                                       renamed, expr.span) {
5841 5842 5843 5844
                    None => {
                        self.resolve_error(
                            expr.span,
                            format!("use of undeclared label `{}`",
A
Alex Crichton 已提交
5845
                                    token::get_ident(label))[])
5846
                    }
5847
                    Some(DlDef(def @ DefLabel(_))) => {
5848 5849
                        // Since this def is a label, it is never read.
                        self.record_def(expr.id, (def, LastMod(AllPublic)))
5850 5851
                    }
                    Some(_) => {
5852
                        self.session.span_bug(expr.span,
5853 5854
                                              "label wasn't mapped to a \
                                               label def!")
5855 5856 5857 5858
                    }
                }
            }

B
Brian Anderson 已提交
5859
            _ => {
5860
                visit::walk_expr(self, expr);
5861 5862 5863 5864
            }
        }
    }

E
Eduard Burtescu 已提交
5865
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5866
        match expr.node {
5867
            ExprField(_, ident) => {
5868 5869 5870 5871
                // FIXME(#6890): Even though you can't treat a method like a
                // field, we need to add any trait methods we find that match
                // the field name so that we can do some nice error reporting
                // later on in typeck.
5872
                let traits = self.search_for_traits_containing_method(ident.node.name);
5873
                self.trait_map.insert(expr.id, traits);
5874
            }
5875
            ExprMethodCall(ident, _, _) => {
5876
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
5877
                        traits for {}",
5878
                       expr.id);
5879
                let traits = self.search_for_traits_containing_method(ident.node.name);
5880
                self.trait_map.insert(expr.id, traits);
5881
            }
5882
            _ => {
5883 5884 5885 5886 5887
                // Nothing to do.
            }
        }
    }

E
Eduard Burtescu 已提交
5888
    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5889
        debug!("(searching for traits containing method) looking for '{}'",
E
Eduard Burtescu 已提交
5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900
               token::get_name(name));

        fn add_trait_info(found_traits: &mut Vec<DefId>,
                          trait_def_id: DefId,
                          name: Name) {
            debug!("(adding trait info) found trait {}:{} for method '{}'",
                trait_def_id.krate,
                trait_def_id.node,
                token::get_name(name));
            found_traits.push(trait_def_id);
        }
5901

5902
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
5903
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
5904 5905
        loop {
            // Look for the current trait.
5906 5907
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
5908
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
5909
                        add_trait_info(&mut found_traits, trait_def_id, name);
5910 5911
                    }
                }
5912
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
5913
            }
5914

E
Eduard Burtescu 已提交
5915
            // Look for trait children.
E
Eduard Burtescu 已提交
5916
            self.populate_module_if_necessary(&search_module);
5917

E
Eduard Burtescu 已提交
5918
            {
E
Eduard Burtescu 已提交
5919
                for (_, child_names) in search_module.children.borrow().iter() {
5920 5921 5922 5923 5924 5925 5926 5927
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
                        None => continue
                    };
                    let trait_def_id = match def {
                        DefTrait(trait_def_id) => trait_def_id,
                        _ => continue,
                    };
5928
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
5929
                        add_trait_info(&mut found_traits, trait_def_id, name);
5930 5931
                    }
                }
E
Eduard Burtescu 已提交
5932
            }
5933

E
Eduard Burtescu 已提交
5934
            // Look for imports.
E
Eduard Burtescu 已提交
5935
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
5936 5937 5938 5939 5940 5941 5942 5943
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
                    Some(DefTrait(trait_def_id)) => trait_def_id,
                    Some(..) | None => continue,
                };
5944
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
5945
                    add_trait_info(&mut found_traits, did, name);
5946 5947 5948 5949
                    let id = import.type_id;
                    self.used_imports.insert((id, TypeNS));
                    let trait_name = self.get_trait_name(did);
                    self.record_import_use(id, trait_name);
5950 5951
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
5952
                    }
5953
                }
E
Eduard Burtescu 已提交
5954
            }
5955

E
Eduard Burtescu 已提交
5956
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
5957 5958
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
5959
                    search_module = parent_module.upgrade().unwrap();
5960
                }
E
Eduard Burtescu 已提交
5961
            }
5962 5963
        }

E
Eduard Burtescu 已提交
5964
        found_traits
5965 5966
    }

5967
    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
L
Luqman Aden 已提交
5968
        debug!("(recording def) recording {} for {}, last private {}",
5969
                def, node_id, lp);
5970 5971
        assert!(match lp {LastImport{..} => false, _ => true},
                "Import should only be used for `use` directives");
5972
        self.last_private.insert(node_id, lp);
5973 5974

        match self.def_map.borrow_mut().entry(node_id) {
5975 5976 5977
            // Resolve appears to "resolve" the same ID multiple
            // times, so here is a sanity check it at least comes to
            // the same conclusion! - nmatsakis
5978
            Occupied(entry) => if def != *entry.get() {
5979
                self.session
L
Luqman Aden 已提交
5980 5981
                    .bug(format!("node_id {} resolved first to {} and \
                                  then {}",
5982
                                 node_id,
5983
                                 *entry.get(),
A
Alex Crichton 已提交
5984
                                 def)[]);
5985 5986 5987
            },
            Vacant(entry) => { entry.set(def); },
        }
5988 5989
    }

F
Felix S. Klock II 已提交
5990
    fn enforce_default_binding_mode(&mut self,
5991
                                        pat: &Pat,
5992
                                        pat_binding_mode: BindingMode,
5993
                                        descr: &str) {
5994
        match pat_binding_mode {
5995
            BindByValue(_) => {}
A
Alex Crichton 已提交
5996
            BindByRef(..) => {
5997 5998 5999
                self.resolve_error(pat.span,
                                   format!("cannot use `ref` binding mode \
                                            with {}",
A
Alex Crichton 已提交
6000
                                           descr)[]);
6001 6002 6003 6004
            }
        }
    }

6005 6006 6007 6008 6009 6010 6011
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

6012
    /// A somewhat inefficient routine to obtain the name of a module.
6013
    fn module_to_string(&self, module: &Module) -> String {
6014
        let mut names = Vec::new();
E
Eduard Burtescu 已提交
6015

6016
        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
E
Eduard Burtescu 已提交
6017 6018 6019
            match module.parent_link {
                NoParentLink => {}
                ModuleParentLink(ref module, name) => {
6020 6021
                    names.push(name);
                    collect_mod(names, &*module.upgrade().unwrap());
6022
                }
E
Eduard Burtescu 已提交
6023
                BlockParentLink(ref module, _) => {
J
John Clements 已提交
6024
                    // danger, shouldn't be ident?
6025 6026
                    names.push(special_idents::opaque.name);
                    collect_mod(names, &*module.upgrade().unwrap());
6027 6028 6029
                }
            }
        }
6030
        collect_mod(&mut names, module);
6031

6032
        if names.len() == 0 {
6033
            return "???".to_string();
6034
        }
6035
        self.names_to_string(names.into_iter().rev()
A
Alex Crichton 已提交
6036
                                  .collect::<Vec<ast::Name>>()[])
6037 6038
    }

K
Kiet Tran 已提交
6039
    #[allow(dead_code)]   // useful for debugging
E
Eduard Burtescu 已提交
6040
    fn dump_module(&mut self, module_: Rc<Module>) {
6041
        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6042

6043
        debug!("Children:");
E
Eduard Burtescu 已提交
6044
        self.populate_module_if_necessary(&module_);
6045
        for (&name, _) in module_.children.borrow().iter() {
6046
            debug!("* {}", token::get_name(name));
6047 6048
        }

6049
        debug!("Import resolutions:");
6050
        let import_resolutions = module_.import_resolutions.borrow();
6051
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
6052
            let value_repr;
6053
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
6054
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
6055
                Some(_) => {
R
Richo Healey 已提交
6056
                    value_repr = " value:?".to_string();
6057
                    // FIXME #4954
6058 6059 6060
                }
            }

N
Niko Matsakis 已提交
6061
            let type_repr;
6062
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
6063
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
6064
                Some(_) => {
R
Richo Healey 已提交
6065
                    type_repr = " type:?".to_string();
6066
                    // FIXME #4954
6067 6068 6069
                }
            }

6070
            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6071 6072 6073 6074
        }
    }
}

6075
pub struct CrateMap {
6076
    pub def_map: DefMap,
6077 6078
    pub freevars: RefCell<FreevarMap>,
    pub capture_mode_map: RefCell<CaptureModeMap>,
6079
    pub export_map: ExportMap,
6080 6081 6082
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
    pub last_private_map: LastPrivateMap,
6083 6084 6085
    pub glob_map: Option<GlobMap>
}

N
Nick Cameron 已提交
6086
#[deriving(PartialEq,Copy)]
6087 6088 6089
pub enum MakeGlobMap {
    Yes,
    No
6090 6091
}

6092
/// Entry point to crate resolution.
6093 6094 6095 6096 6097 6098 6099
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                               ast_map: &'a ast_map::Map<'tcx>,
                               _: &LanguageItems,
                               krate: &Crate,
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
    let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
6100 6101 6102 6103 6104 6105 6106

    resolver.build_reduced_graph(krate);
    session.abort_if_errors();

    resolver.resolve_imports();
    session.abort_if_errors();

6107
    record_exports::record(&mut resolver);
6108 6109 6110 6111 6112 6113 6114
    session.abort_if_errors();

    resolver.resolve_crate(krate);
    session.abort_if_errors();

    check_unused::check_crate(&mut resolver, krate);

6115
    CrateMap {
6116 6117
        def_map: resolver.def_map,
        freevars: resolver.freevars,
6118
        capture_mode_map: RefCell::new(resolver.capture_mode_map),
6119
        export_map: resolver.export_map,
6120 6121 6122
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
        last_private_map: resolver.last_private,
6123 6124 6125 6126 6127
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
6128
    }
6129
}