lib.rs 195.6 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
#![crate_name = "rustc_resolve"]
12
#![unstable(feature = "rustc_private")]
B
Brian Anderson 已提交
13
#![staged_api]
14 15 16 17 18 19
#![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/")]

20 21 22
#![feature(alloc)]
#![feature(collections)]
#![feature(core)]
A
Alex Crichton 已提交
23 24 25
#![feature(hash)]
#![feature(int_uint)]
#![feature(rustc_diagnostic_macros)]
26
#![feature(rustc_private)]
A
Alex Crichton 已提交
27 28
#![feature(slicing_syntax)]
#![feature(staged_api)]
29
#![feature(std_misc)]
30

A
Alex Crichton 已提交
31 32
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
33
#[macro_use] #[no_link] extern crate rustc_bitflags;
34 35 36

extern crate rustc;

S
Steven Fackler 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::NamespaceResult::*;
use self::NameDefinition::*;
use self::ImportDirectiveSubclass::*;
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::ParentLink::*;
use self::ModuleKind::*;
use self::TraitReferenceType::*;
use self::FallbackChecks::*;

56 57 58 59 60 61 62 63 64
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};
65
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
66
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
A
Alex Crichton 已提交
67
use rustc::util::lev_distance::lev_distance;
68

69
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
70
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
J
Jorge Aparicio 已提交
71
use syntax::ast::{ExprClosure, ExprLoop, ExprWhile, ExprMethodCall};
72
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
73
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
74 75 76 77
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
78
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
79 80 81 82
use syntax::ast::{PatRange, PatStruct, Path};
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
use syntax::ast::{RegionTyParamBound, StructField};
use syntax::ast::{TraitRef, TraitTyParamBound};
J
Jorge Aparicio 已提交
83
use syntax::ast::{Ty, TyBool, TyChar, TyF32};
84
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
85
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
86
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
87
use syntax::ast::{TypeImplItem};
P
Patrick Walton 已提交
88
use syntax::ast;
89
use syntax::ast_map;
90
use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
91
use syntax::attr::AttrMetaMethods;
92
use syntax::ext::mtwt;
93
use syntax::parse::token::{self, special_names, special_idents};
94
use syntax::codemap::{Span, Pos};
95
use syntax::owned_slice::OwnedSlice;
96
use syntax::visit::{self, Visitor};
97

98
use std::collections::{HashMap, HashSet};
C
Corey Farwell 已提交
99
use std::collections::hash_map::Entry::{Occupied, Vacant};
100
use std::cell::{Cell, RefCell};
101
use std::fmt;
102
use std::mem::replace;
E
Eduard Burtescu 已提交
103
use std::rc::{Rc, Weak};
104
use std::uint;
105

106 107 108 109
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

A
Alex Crichton 已提交
110 111
mod check_unused;
mod record_exports;
112
mod build_reduced_graph;
113

114
#[derive(Copy)]
115
struct BindingInfo {
116
    span: Span,
117
    binding_mode: BindingMode,
118 119 120
}

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

123
#[derive(Copy, PartialEq)]
F
Felix S. Klock II 已提交
124
enum PatternBindingMode {
125
    RefutableMode,
126
    LocalIrrefutableMode,
127
    ArgumentIrrefutableMode,
128 129
}

J
Jorge Aparicio 已提交
130
#[derive(Copy, PartialEq, Eq, Hash, Debug)]
F
Felix S. Klock II 已提交
131
enum Namespace {
132
    TypeNS,
133
    ValueNS
134 135
}

B
Brian Anderson 已提交
136 137 138
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
139
#[derive(Clone)]
F
Felix S. Klock II 已提交
140
enum NamespaceResult {
T
Tim Chevalier 已提交
141 142 143
    /// 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.)
144
    UnknownResult,
B
Brian Anderson 已提交
145 146
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
147
    UnboundResult,
T
Tim Chevalier 已提交
148 149
    /// Means that resolve has determined that the name is bound in the Module
    /// argument, and specified by the NameBindings argument.
E
Eduard Burtescu 已提交
150
    BoundResult(Rc<Module>, Rc<NameBindings>)
151 152
}

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

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

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

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

202 203
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
204
enum ResolveResult<T> {
205 206 207
    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.
208 209
}

210
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
211
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
212
        match *self { Indeterminate => true, _ => false }
213 214 215
    }
}

216 217 218 219
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
220
    TraitItem,
221
    StaticMethod(String),
222
    TraitMethod(String),
223 224
}

225
#[derive(Copy)]
E
Erik Price 已提交
226
enum TypeParameters<'a> {
227 228 229 230 231 232 233 234 235 236 237 238 239 240
    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)
241 242
}

243 244
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
J
Jorge Aparicio 已提交
245
#[derive(Copy, Debug)]
F
Felix S. Klock II 已提交
246
enum RibKind {
247 248
    // No translation needs to be applied.
    NormalRibKind,
249

250 251
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
252
    ClosureRibKind(NodeId /* func id */),
253

254
    // We passed through an impl or trait and are now in one of its
255
    // methods. Allow references to ty params that impl or trait
256 257 258
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
              // parent;   method itself
259
    MethodRibKind(NodeId, MethodSort),
260

261 262
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
263 264 265

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

268
// Methods can be required or provided. RequiredMethod methods only occur in traits.
J
Jorge Aparicio 已提交
269
#[derive(Copy, Debug)]
F
Felix S. Klock II 已提交
270
enum MethodSort {
271 272
    RequiredMethod,
    ProvidedMethod(NodeId)
273 274
}

275
#[derive(Copy)]
F
Felix S. Klock II 已提交
276
enum UseLexicalScopeFlag {
277 278 279 280
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
281
enum ModulePrefixResult {
282
    NoPrefixFound,
E
Eduard Burtescu 已提交
283
    PrefixFound(Rc<Module>, uint)
284 285
}

286
#[derive(Copy, PartialEq)]
287
enum NameSearchType {
288 289 290 291
    /// 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
292 293
    /// expression, or a path pattern.
    PathSearch,
294 295
}

296
#[derive(Copy)]
F
Felix S. Klock II 已提交
297
enum BareIdentifierPatternResolution {
298 299
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
300
    BareIdentifierPatternUnresolved
301 302
}

303
/// One local scope.
J
Jorge Aparicio 已提交
304
#[derive(Debug)]
F
Felix S. Klock II 已提交
305
struct Rib {
306
    bindings: HashMap<Name, DefLike>,
307
    kind: RibKind,
B
Brian Anderson 已提交
308
}
309

310
impl Rib {
F
Felix S. Klock II 已提交
311
    fn new(kind: RibKind) -> Rib {
312
        Rib {
313
            bindings: HashMap::new(),
314 315
            kind: kind
        }
316 317 318
    }
}

319
/// Whether an import can be shadowed by another import.
J
Jorge Aparicio 已提交
320
#[derive(Debug,PartialEq,Clone,Copy)]
321 322 323 324 325
enum Shadowable {
    Always,
    Never
}

326
/// One import directive.
J
Jorge Aparicio 已提交
327
#[derive(Debug)]
F
Felix S. Klock II 已提交
328
struct ImportDirective {
329
    module_path: Vec<Name>,
E
Eduard Burtescu 已提交
330
    subclass: ImportDirectiveSubclass,
331
    span: Span,
332
    id: NodeId,
333
    is_public: bool, // see note in ImportResolution about how to use this
334
    shadowable: Shadowable,
B
Brian Anderson 已提交
335
}
336

337
impl ImportDirective {
338
    fn new(module_path: Vec<Name> ,
E
Eduard Burtescu 已提交
339
           subclass: ImportDirectiveSubclass,
340 341
           span: Span,
           id: NodeId,
342
           is_public: bool,
343
           shadowable: Shadowable)
344
           -> ImportDirective {
345 346 347 348
        ImportDirective {
            module_path: module_path,
            subclass: subclass,
            span: span,
349 350
            id: id,
            is_public: is_public,
351
            shadowable: shadowable,
352
        }
353 354 355
    }
}

356
/// The item that an import resolves to.
J
Jorge Aparicio 已提交
357
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
358
struct Target {
E
Eduard Burtescu 已提交
359 360
    target_module: Rc<Module>,
    bindings: Rc<NameBindings>,
361
    shadowable: Shadowable,
B
Brian Anderson 已提交
362
}
363

364
impl Target {
365 366
    fn new(target_module: Rc<Module>,
           bindings: Rc<NameBindings>,
367
           shadowable: Shadowable)
368
           -> Target {
369 370
        Target {
            target_module: target_module,
371 372
            bindings: bindings,
            shadowable: shadowable,
373
        }
374 375 376
    }
}

T
Tim Chevalier 已提交
377
/// An ImportResolution represents a particular `use` directive.
J
Jorge Aparicio 已提交
378
#[derive(Debug)]
F
Felix S. Klock II 已提交
379
struct ImportResolution {
380 381 382 383
    /// 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 已提交
384
    is_public: bool,
385

386 387 388
    // 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 已提交
389
    outstanding_references: uint,
390

T
Tim Chevalier 已提交
391
    /// The value that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
392
    value_target: Option<Target>,
393 394
    /// The source node of the `use` directive leading to the value target
    /// being non-none
E
Eduard Burtescu 已提交
395
    value_id: NodeId,
396

T
Tim Chevalier 已提交
397
    /// The type that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
398
    type_target: Option<Target>,
399 400
    /// The source node of the `use` directive leading to the type target
    /// being non-none
E
Eduard Burtescu 已提交
401
    type_id: NodeId,
E
Erick Tryzelaar 已提交
402 403
}

404
impl ImportResolution {
405
    fn new(id: NodeId, is_public: bool) -> ImportResolution {
406
        ImportResolution {
E
Eduard Burtescu 已提交
407 408 409 410 411 412
            type_id: id,
            value_id: id,
            outstanding_references: 0,
            value_target: None,
            type_target: None,
            is_public: is_public,
413
        }
B
Brian Anderson 已提交
414 415
    }

F
Felix S. Klock II 已提交
416
    fn target_for_namespace(&self, namespace: Namespace)
417
                                -> Option<Target> {
418
        match namespace {
E
Eduard Burtescu 已提交
419 420
            TypeNS  => self.type_target.clone(),
            ValueNS => self.value_target.clone(),
421 422
        }
    }
423

424
    fn id(&self, namespace: Namespace) -> NodeId {
425
        match namespace {
E
Eduard Burtescu 已提交
426 427
            TypeNS  => self.type_id,
            ValueNS => self.value_id,
428 429
        }
    }
430 431 432 433 434 435 436 437 438

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

        target.unwrap().shadowable
    }
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

    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;
            }
        }
    }
455 456
}

457
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
458
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
459
enum ParentLink {
460
    NoParentLink,
461
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
462
    BlockParentLink(Weak<Module>, NodeId)
463 464
}

465
/// The type of module this is.
J
Jorge Aparicio 已提交
466
#[derive(Copy, PartialEq, Debug)]
F
Felix S. Klock II 已提交
467
enum ModuleKind {
468 469
    NormalModuleKind,
    TraitModuleKind,
470
    ImplModuleKind,
471
    EnumModuleKind,
472
    TypeModuleKind,
473 474 475
    AnonymousModuleKind,
}

476
/// One node in the tree of modules.
F
Felix S. Klock II 已提交
477
struct Module {
478
    parent_link: ParentLink,
479
    def_id: Cell<Option<DefId>>,
480
    kind: Cell<ModuleKind>,
481
    is_public: bool,
482

E
Eduard Burtescu 已提交
483 484
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
485

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

490 491 492 493 494 495 496 497 498 499 500 501 502 503
    // 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 已提交
504
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
505 506

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

    // The number of unresolved globs that this module exports.
510
    glob_count: Cell<uint>,
511 512

    // The index of the import we're resolving.
513
    resolved_import_count: Cell<uint>,
514 515 516 517

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

521
impl Module {
F
Felix S. Klock II 已提交
522
    fn new(parent_link: ParentLink,
523 524 525 526
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
527
           -> Module {
528 529
        Module {
            parent_link: parent_link,
530
            def_id: Cell::new(def_id),
531
            kind: Cell::new(kind),
532
            is_public: is_public,
533
            children: RefCell::new(HashMap::new()),
534
            imports: RefCell::new(Vec::new()),
535
            external_module_children: RefCell::new(HashMap::new()),
536
            anonymous_children: RefCell::new(NodeMap()),
537
            import_resolutions: RefCell::new(HashMap::new()),
538
            glob_count: Cell::new(0),
539
            resolved_import_count: Cell::new(0),
540
            populated: Cell::new(!external),
541
        }
B
Brian Anderson 已提交
542 543
    }

F
Felix S. Klock II 已提交
544
    fn all_imports_resolved(&self) -> bool {
545
        self.imports.borrow().len() == self.resolved_import_count.get()
546 547 548
    }
}

549
impl fmt::Debug for Module {
550
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
551
        write!(f, "{:?}, kind: {:?}, {}",
552 553 554 555 556 557
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

558
bitflags! {
J
Jorge Aparicio 已提交
559
    #[derive(Debug)]
560 561 562 563 564 565
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

566
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
567
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
568
struct TypeNsDef {
569
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
570
    module_def: Option<Rc<Module>>,
571
    type_def: Option<Def>,
572
    type_span: Option<Span>
573 574 575
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
576
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
577
struct ValueNsDef {
578
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
579
    def: Def,
580
    value_span: Option<Span>,
581 582
}

583 584
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
585
#[derive(Debug)]
F
Felix S. Klock II 已提交
586
struct NameBindings {
587
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
588
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
589 590
}

591
/// Ways in which a trait can be referenced
592
#[derive(Copy)]
593 594 595 596
enum TraitReferenceType {
    TraitImplementation,             // impl SomeTrait for T { ... }
    TraitDerivation,                 // trait T : SomeTrait { ... }
    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
N
Niko Matsakis 已提交
597
    TraitObject,                     // Box<for<'a> SomeTrait>
598
    TraitQPath,                      // <T as SomeTrait>::
599 600
}

601
impl NameBindings {
K
Kevin Butler 已提交
602 603 604 605 606 607 608
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

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

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

690
    /// Records a type definition.
691
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
692
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
693
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
694 695
        let type_def = self.type_def.borrow().clone();
        match type_def {
696
            None => {
E
Erick Tryzelaar 已提交
697
                *self.type_def.borrow_mut() = Some(TypeNsDef {
698
                    module_def: None,
699
                    type_def: Some(def),
700
                    type_span: Some(sp),
701
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
702
                });
703
            }
704
            Some(type_def) => {
E
Erick Tryzelaar 已提交
705
                *self.type_def.borrow_mut() = Some(TypeNsDef {
706
                    module_def: type_def.module_def,
707
                    type_def: Some(def),
708
                    type_span: Some(sp),
709
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
710
                });
711 712
            }
        }
713 714
    }

715
    /// Records a value definition.
716
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
717
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
718
        *self.value_def.borrow_mut() = Some(ValueNsDef {
719 720
            def: def,
            value_span: Some(sp),
721
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
722
        });
723 724
    }

725
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
726
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
727
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
728
            Some(ref type_def) => type_def.module_def.clone(),
729
            None => None
730 731 732
        }
    }

S
Steve Klabnik 已提交
733 734
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
735
    fn get_module(&self) -> Rc<Module> {
736 737
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
738
                panic!("get_module called on a node with no module \
739
                       definition!")
740
            }
741
            Some(module_def) => module_def
742 743 744
        }
    }

F
Felix S. Klock II 已提交
745
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
746
        match namespace {
E
Erick Tryzelaar 已提交
747 748
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
749 750 751
        }
    }

F
Felix S. Klock II 已提交
752
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
753 754 755 756
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
757
        match namespace {
E
Erick Tryzelaar 已提交
758
            TypeNS => match *self.type_def.borrow() {
759
                Some(ref def) => def.modifiers.contains(modifiers), None => false
760
            },
E
Erick Tryzelaar 已提交
761
            ValueNS => match *self.value_def.borrow() {
762
                Some(ref def) => def.modifiers.contains(modifiers), None => false
763 764 765 766
            }
        }
    }

F
Felix S. Klock II 已提交
767
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
768
        match namespace {
769
            TypeNS => {
E
Erick Tryzelaar 已提交
770
                match *self.type_def.borrow() {
771
                    None => None,
E
Eduard Burtescu 已提交
772
                    Some(ref type_def) => {
773
                        match type_def.type_def {
774
                            Some(type_def) => Some(type_def),
775 776
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
777
                                    Some(ref module) => {
778
                                        match module.def_id.get() {
779
                                            Some(did) => Some(DefMod(did)),
780 781 782 783 784 785
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
786
                        }
787 788
                    }
                }
789 790
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
791
                match *self.value_def.borrow() {
792 793 794 795 796 797 798
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
799
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
800
        if self.defined_in_namespace(namespace) {
801
            match namespace {
802
                TypeNS  => {
E
Erick Tryzelaar 已提交
803
                    match *self.type_def.borrow() {
804
                        None => None,
E
Eduard Burtescu 已提交
805
                        Some(ref type_def) => type_def.type_span
806 807 808
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
809
                    match *self.value_def.borrow() {
810
                        None => None,
E
Eduard Burtescu 已提交
811
                        Some(ref value_def) => value_def.value_span
812 813
                    }
                }
814
            }
815 816
        } else {
            None
817 818
        }
    }
819 820
}

821
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
822
struct PrimitiveTypeTable {
823
    primitive_types: HashMap<Name, PrimTy>,
824
}
825

826
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
827 828 829 830 831 832 833 834 835
    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));
836 837
        table.intern("int",     TyInt(TyIs(true)));
        table.intern("isize",   TyInt(TyIs(false)));
K
Kevin Butler 已提交
838 839 840 841 842
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
843 844
        table.intern("uint",    TyUint(TyUs(true)));
        table.intern("usize",   TyUint(TyUs(false)));
K
Kevin Butler 已提交
845 846 847 848 849 850 851 852
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

853
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
854
        self.primitive_types.insert(token::intern(string), primitive_type);
855 856 857
    }
}

858
/// The main resolver class.
859
struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
860
    session: &'a Session,
861

862 863
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
864
    graph_root: NameBindings,
865

866
    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
867

868
    structs: FnvHashMap<DefId, Vec<Name>>,
869

870
    // The number of imports that are currently unresolved.
871
    unresolved_imports: uint,
872 873

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
874
    current_module: Rc<Module>,
875 876

    // The current set of local scopes, for values.
877
    // FIXME #4948: Reuse ribs to avoid allocation.
878
    value_ribs: Vec<Rib>,
879 880

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

883
    // The current set of local scopes, for labels.
884
    label_ribs: Vec<Rib>,
885

886
    // The trait that the current context can refer to.
887 888 889 890
    current_trait_ref: Option<(DefId, TraitRef)>,

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

892
    // The ident for the keyword "self".
J
John Clements 已提交
893
    self_name: Name,
894
    // The ident for the non-keyword "Self".
J
John Clements 已提交
895
    type_self_name: Name,
896

897
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
898
    primitive_type_table: PrimitiveTypeTable,
899

900
    def_map: DefMap,
901 902
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
903
    export_map: ExportMap,
904
    trait_map: TraitMap,
905 906
    external_exports: ExternalExports,
    last_private: LastPrivateMap,
907

908 909 910 911 912
    // 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,

913 914 915 916 917
    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,

918
    used_imports: HashSet<(NodeId, Namespace)>,
919
    used_crates: HashSet<CrateNum>,
920 921
}

922
#[derive(PartialEq)]
S
Steven Fackler 已提交
923 924 925 926 927 928
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}


929 930 931 932 933
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 已提交
934 935 936 937 938 939 940 941 942 943 944 945 946 947
        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,

948 949
            ast_map: ast_map,

K
Kevin Butler 已提交
950 951 952 953 954
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

955 956
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
957 958 959 960

            unresolved_imports: 0,

            current_module: current_module,
961 962 963
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
964 965 966 967

            current_trait_ref: None,
            current_self_type: None,

J
John Clements 已提交
968 969
            self_name: special_names::self_,
            type_self_name: special_names::type_self,
K
Kevin Butler 已提交
970 971 972

            primitive_type_table: PrimitiveTypeTable::new(),

973 974 975 976 977
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
978
            used_imports: HashSet::new(),
979
            used_crates: HashSet::new(),
980 981
            external_exports: DefIdSet(),
            last_private: NodeMap(),
K
Kevin Butler 已提交
982 983

            emit_errors: true,
984 985
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
986 987
        }
    }
988 989 990 991 992 993 994 995 996

    // 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.

997 998
    /// Resolves all imports for the crate. This method performs the fixed-
    /// point iteration.
F
Felix S. Klock II 已提交
999
    fn resolve_imports(&mut self) {
1000
        let mut i = 0u;
T
Tim Chevalier 已提交
1001
        let mut prev_unresolved_imports = 0;
1002
        loop {
1003
            debug!("(resolving imports) iteration {}, {} imports left",
P
Paul Stansifer 已提交
1004
                   i, self.unresolved_imports);
1005

1006
            let module_root = self.graph_root.get_module();
E
Eduard Burtescu 已提交
1007
            self.resolve_imports_for_module_subtree(module_root.clone());
1008

T
Tim Chevalier 已提交
1009
            if self.unresolved_imports == 0 {
1010
                debug!("(resolving imports) success");
1011 1012 1013 1014 1015 1016 1017 1018
                break;
            }

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

T
Tim Chevalier 已提交
1019
            i += 1;
1020 1021 1022 1023
            prev_unresolved_imports = self.unresolved_imports;
        }
    }

1024 1025
    /// Attempts to resolve imports for the given module and all of its
    /// submodules.
E
Eduard Burtescu 已提交
1026
    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
1027
        debug!("(resolving imports for module subtree) resolving {}",
1028
               self.module_to_string(&*module_));
1029
        let orig_module = replace(&mut self.current_module, module_.clone());
E
Eduard Burtescu 已提交
1030
        self.resolve_imports_for_module(module_.clone());
1031
        self.current_module = orig_module;
1032

1033
        build_reduced_graph::populate_module_if_necessary(self, &module_);
E
Eduard Burtescu 已提交
1034
        for (_, child_node) in module_.children.borrow().iter() {
1035 1036 1037 1038 1039 1040
            match child_node.get_module_if_available() {
                None => {
                    // Nothing to do.
                }
                Some(child_module) => {
                    self.resolve_imports_for_module_subtree(child_module);
1041 1042 1043 1044
                }
            }
        }

E
Eduard Burtescu 已提交
1045 1046
        for (_, child_module) in module_.anonymous_children.borrow().iter() {
            self.resolve_imports_for_module_subtree(child_module.clone());
1047 1048 1049
        }
    }

1050
    /// Attempts to resolve imports for the given module only.
E
Eduard Burtescu 已提交
1051
    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
1052
        if module.all_imports_resolved() {
1053
            debug!("(resolving imports for module) all imports resolved for \
A
Alex Crichton 已提交
1054
                   {}",
1055
                   self.module_to_string(&*module));
B
Brian Anderson 已提交
1056
            return;
1057 1058
        }

1059
        let imports = module.imports.borrow();
1060
        let import_count = imports.len();
1061 1062
        while module.resolved_import_count.get() < import_count {
            let import_index = module.resolved_import_count.get();
1063
            let import_directive = &(*imports)[import_index];
1064 1065
            match self.resolve_import_for_module(module.clone(),
                                                 import_directive) {
1066 1067 1068 1069 1070 1071
                Failed(err) => {
                    let (span, help) = match err {
                        Some((span, msg)) => (span, format!(". {}", msg)),
                        None => (import_directive.span, String::new())
                    };
                    let msg = format!("unresolved import `{}`{}",
1072
                                      self.import_path_to_string(
J
Jorge Aparicio 已提交
1073
                                          &import_directive.module_path[],
1074 1075
                                          import_directive.subclass),
                                      help);
J
Jorge Aparicio 已提交
1076
                    self.resolve_error(span, &msg[]);
1077
                }
1078 1079
                Indeterminate => break, // Bail out. We'll come around next time.
                Success(()) => () // Good. Continue.
1080 1081
            }

1082 1083
            module.resolved_import_count
                  .set(module.resolved_import_count.get() + 1);
1084 1085 1086
        }
    }

1087
    fn names_to_string(&self, names: &[Name]) -> String {
1088
        let mut first = true;
1089
        let mut result = String::new();
1090
        for name in names.iter() {
1091 1092 1093 1094 1095
            if first {
                first = false
            } else {
                result.push_str("::")
            }
1096
            result.push_str(token::get_name(*name).get());
1097
        };
1098
        result
P
Paul Stansifer 已提交
1099
    }
1100

1101 1102 1103 1104 1105
    fn path_names_to_string(&self, path: &Path) -> String {
        let names: Vec<ast::Name> = path.segments
                                        .iter()
                                        .map(|seg| seg.identifier.name)
                                        .collect();
J
Jorge Aparicio 已提交
1106
        self.names_to_string(&names[])
1107 1108
    }

1109
    fn import_directive_subclass_to_string(&mut self,
P
Patrick Walton 已提交
1110
                                        subclass: ImportDirectiveSubclass)
1111
                                        -> String {
1112
        match subclass {
1113
            SingleImport(_, source) => {
1114
                token::get_name(source).get().to_string()
P
Patrick Walton 已提交
1115
            }
1116
            GlobImport => "*".to_string()
1117 1118
        }
    }
1119

1120
    fn import_path_to_string(&mut self,
1121
                          names: &[Name],
P
Patrick Walton 已提交
1122
                          subclass: ImportDirectiveSubclass)
1123
                          -> String {
1124
        if names.is_empty() {
1125
            self.import_directive_subclass_to_string(subclass)
1126
        } else {
A
Alex Crichton 已提交
1127
            (format!("{}::{}",
1128
                     self.names_to_string(names),
1129
                     self.import_directive_subclass_to_string(
1130
                         subclass))).to_string()
1131 1132
        }
    }
1133

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149
    #[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 {
1150
        if did.krate == ast::LOCAL_CRATE {
1151 1152 1153 1154 1155 1156
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

1157 1158 1159 1160 1161
    /// 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 已提交
1162
    fn resolve_import_for_module(&mut self,
E
Eduard Burtescu 已提交
1163 1164
                                 module_: Rc<Module>,
                                 import_directive: &ImportDirective)
1165
                                 -> ResolveResult<()> {
1166
        let mut resolution_result = Failed(None);
A
Alex Crichton 已提交
1167
        let module_path = &import_directive.module_path;
1168

1169
        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
J
Jorge Aparicio 已提交
1170
               self.names_to_string(&module_path[]),
1171
               self.module_to_string(&*module_));
1172

1173
        // First, resolve the module path for the directive, if necessary.
1174
        let container = if module_path.len() == 0 {
1175
            // Use the crate root.
1176
            Some((self.graph_root.get_module(), LastMod(AllPublic)))
1177
        } else {
E
Eduard Burtescu 已提交
1178
            match self.resolve_module_path(module_.clone(),
J
Jorge Aparicio 已提交
1179
                                           &module_path[],
1180 1181 1182
                                           DontUseLexicalScope,
                                           import_directive.span,
                                           ImportSearch) {
1183 1184 1185 1186
                Failed(err) => {
                    resolution_result = Failed(err);
                    None
                },
B
Brian Anderson 已提交
1187
                Indeterminate => {
1188
                    resolution_result = Indeterminate;
1189
                    None
1190
                }
1191
                Success(container) => Some(container),
1192 1193 1194
            }
        };

1195
        match container {
1196
            None => {}
1197
            Some((containing_module, lp)) => {
1198 1199 1200
                // We found the module that the target is contained
                // within. Attempt to resolve the import within it.

E
Eduard Burtescu 已提交
1201
                match import_directive.subclass {
1202
                    SingleImport(target, source) => {
1203
                        resolution_result =
E
Eduard Burtescu 已提交
1204
                            self.resolve_single_import(&*module_,
1205 1206
                                                       containing_module,
                                                       target,
1207
                                                       source,
1208 1209
                                                       import_directive,
                                                       lp);
1210 1211 1212
                    }
                    GlobImport => {
                        resolution_result =
E
Eduard Burtescu 已提交
1213
                            self.resolve_glob_import(&*module_,
1214
                                                     containing_module,
1215
                                                     import_directive,
1216
                                                     lp);
1217 1218 1219 1220 1221 1222
                    }
                }
            }
        }

        // Decrement the count of unresolved imports.
1223
        match resolution_result {
B
Brian Anderson 已提交
1224
            Success(()) => {
P
Patrick Walton 已提交
1225
                assert!(self.unresolved_imports >= 1);
T
Tim Chevalier 已提交
1226
                self.unresolved_imports -= 1;
1227
            }
B
Brian Anderson 已提交
1228
            _ => {
1229 1230 1231 1232 1233 1234 1235 1236 1237
                // 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.)

1238
        if !resolution_result.indeterminate() {
E
Eduard Burtescu 已提交
1239
            match import_directive.subclass {
B
Brian Anderson 已提交
1240
                GlobImport => {
1241 1242
                    assert!(module_.glob_count.get() >= 1);
                    module_.glob_count.set(module_.glob_count.get() - 1);
1243
                }
A
Alex Crichton 已提交
1244
                SingleImport(..) => {
1245 1246 1247 1248 1249
                    // Ignore.
                }
            }
        }

B
Brian Anderson 已提交
1250
        return resolution_result;
1251 1252
    }

E
Eduard Burtescu 已提交
1253
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1254
        NameBindings {
1255
            type_def: RefCell::new(Some(TypeNsDef {
1256
                modifiers: IMPORTABLE,
1257 1258
                module_def: Some(module),
                type_def: None,
1259
                type_span: None
1260
            })),
1261
            value_def: RefCell::new(None),
1262 1263 1264
        }
    }

F
Felix S. Klock II 已提交
1265
    fn resolve_single_import(&mut self,
E
Eduard Burtescu 已提交
1266 1267
                             module_: &Module,
                             containing_module: Rc<Module>,
1268 1269
                             target: Name,
                             source: Name,
1270 1271
                             directive: &ImportDirective,
                             lp: LastPrivate)
1272
                                 -> ResolveResult<()> {
1273
        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
1274
                `{}` id {}, last private {:?}",
1275
               token::get_name(target),
1276
               self.module_to_string(&*containing_module),
1277
               token::get_name(source),
1278
               self.module_to_string(module_),
1279 1280
               directive.id,
               lp);
1281

1282 1283
        let lp = match lp {
            LastMod(lp) => lp,
1284 1285 1286 1287 1288
            LastImport {..} => {
                self.session
                    .span_bug(directive.span,
                              "not expecting Import here, must be LastMod")
            }
1289 1290
        };

1291
        // We need to resolve both namespaces for this to succeed.
1292 1293 1294 1295 1296 1297
        //

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

        // Search for direct children of the containing module.
1298
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
1299

1300
        match containing_module.children.borrow().get(&source) {
1301 1302 1303
            None => {
                // Continue.
            }
E
Eduard Burtescu 已提交
1304
            Some(ref child_name_bindings) => {
1305
                if child_name_bindings.defined_in_namespace(ValueNS) {
1306
                    debug!("(resolving single import) found value binding");
E
Eduard Burtescu 已提交
1307 1308
                    value_result = BoundResult(containing_module.clone(),
                                               (*child_name_bindings).clone());
1309
                }
1310
                if child_name_bindings.defined_in_namespace(TypeNS) {
1311
                    debug!("(resolving single import) found type binding");
E
Eduard Burtescu 已提交
1312 1313
                    type_result = BoundResult(containing_module.clone(),
                                              (*child_name_bindings).clone());
1314 1315 1316 1317
                }
            }
        }

1318 1319
        // Unless we managed to find a result in both namespaces (unlikely),
        // search imports as well.
1320 1321
        let mut value_used_reexport = false;
        let mut type_used_reexport = false;
E
Eduard Burtescu 已提交
1322
        match (value_result.clone(), type_result.clone()) {
A
Alex Crichton 已提交
1323
            (BoundResult(..), BoundResult(..)) => {} // Continue.
B
Brian Anderson 已提交
1324
            _ => {
1325 1326 1327 1328
                // 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.

1329
                if containing_module.glob_count.get() > 0 {
1330
                    debug!("(resolving single import) unresolved glob; \
P
Paul Stansifer 已提交
1331
                            bailing out");
B
Brian Anderson 已提交
1332
                    return Indeterminate;
1333 1334
                }

E
Eduard Burtescu 已提交
1335
                // Now search the exported imports within the containing module.
1336
                match containing_module.import_resolutions.borrow().get(&source) {
B
Brian Anderson 已提交
1337
                    None => {
1338
                        debug!("(resolving single import) no import");
1339 1340 1341 1342 1343
                        // 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.

1344
                        if value_result.is_unknown() {
1345 1346
                            value_result = UnboundResult;
                        }
1347
                        if type_result.is_unknown() {
1348 1349 1350
                            type_result = UnboundResult;
                        }
                    }
B
Brian Anderson 已提交
1351
                    Some(import_resolution)
E
Eduard Burtescu 已提交
1352
                            if import_resolution.outstanding_references == 0 => {
1353

A
Alex Crichton 已提交
1354
                        fn get_binding(this: &mut Resolver,
E
Eduard Burtescu 已提交
1355
                                       import_resolution: &ImportResolution,
1356 1357
                                       namespace: Namespace,
                                       source: &Name)
1358
                                    -> NamespaceResult {
T
Tim Chevalier 已提交
1359

1360 1361
                            // Import resolutions must be declared with "pub"
                            // in order to be exported.
E
Eduard Burtescu 已提交
1362
                            if !import_resolution.is_public {
1363 1364 1365
                                return UnboundResult;
                            }

E
Eduard Burtescu 已提交
1366
                            match import_resolution.
1367
                                    target_for_namespace(namespace) {
B
Brian Anderson 已提交
1368
                                None => {
B
Brian Anderson 已提交
1369
                                    return UnboundResult;
1370
                                }
1371 1372 1373 1374 1375
                                Some(Target {
                                    target_module,
                                    bindings,
                                    shadowable: _
                                }) => {
1376
                                    debug!("(resolving single import) found \
1377
                                            import in ns {:?}", namespace);
1378
                                    let id = import_resolution.id(namespace);
1379
                                    // track used imports and extern crates as well
1380
                                    this.used_imports.insert((id, namespace));
1381
                                    this.record_import_use(id, *source);
1382 1383 1384 1385 1386 1387
                                    match target_module.def_id.get() {
                                        Some(DefId{krate: kid, ..}) => {
                                            this.used_crates.insert(kid);
                                        },
                                        _ => {}
                                    }
E
Eduard Burtescu 已提交
1388
                                    return BoundResult(target_module, bindings);
1389 1390 1391 1392 1393 1394
                                }
                            }
                        }

                        // The name is an import which has been fully
                        // resolved. We can, therefore, just follow it.
1395
                        if value_result.is_unknown() {
1396 1397 1398 1399
                            value_result = get_binding(self,
                                                       import_resolution,
                                                       ValueNS,
                                                       &source);
E
Eduard Burtescu 已提交
1400
                            value_used_reexport = import_resolution.is_public;
1401
                        }
1402
                        if type_result.is_unknown() {
1403 1404 1405 1406
                            type_result = get_binding(self,
                                                      import_resolution,
                                                      TypeNS,
                                                      &source);
E
Eduard Burtescu 已提交
1407
                            type_used_reexport = import_resolution.is_public;
1408
                        }
1409

1410
                    }
B
Brian Anderson 已提交
1411
                    Some(_) => {
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
                        // 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;
                            }
                        }
1440 1441 1442 1443 1444
                    }
                }
            }
        }

1445 1446
        // If we didn't find a result in the type namespace, search the
        // external modules.
1447 1448
        let mut value_used_public = false;
        let mut type_used_public = false;
1449
        match type_result {
A
Alex Crichton 已提交
1450
            BoundResult(..) => {}
1451
            _ => {
1452
                match containing_module.external_module_children.borrow_mut()
1453
                                       .get(&source).cloned() {
1454 1455
                    None => {} // Continue.
                    Some(module) => {
1456 1457
                        debug!("(resolving single import) found external \
                                module");
1458 1459 1460 1461 1462
                        // track the module as used.
                        match module.def_id.get() {
                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
                            _ => {}
                        }
1463
                        let name_bindings =
E
Eduard Burtescu 已提交
1464 1465 1466
                            Rc::new(Resolver::create_name_bindings_from_module(
                                module));
                        type_result = BoundResult(containing_module.clone(),
1467
                                                  name_bindings);
1468
                        type_used_public = true;
1469 1470 1471 1472 1473
                    }
                }
            }
        }

1474
        // We've successfully resolved the import. Write the results in.
E
Eduard Burtescu 已提交
1475
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1476
        let import_resolution = &mut (*import_resolutions)[target];
1477
        {
1478
            let mut check_and_write_import = |&mut: namespace, result: &_, used_public: &mut bool| {
1479 1480 1481 1482
                let namespace_name = match namespace {
                    TypeNS => "type",
                    ValueNS => "value",
                };
1483

1484 1485
                match *result {
                    BoundResult(ref target_module, ref name_bindings) => {
1486
                        debug!("(resolving single import) found {:?} target: {:?}",
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509
                               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 => {
1510
                        panic!("{:?} result should be known at this point", namespace_name);
1511 1512 1513 1514 1515
                    }
                }
            };
            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
1516 1517
        }

1518 1519 1520 1521
        self.check_for_conflicts_between_imports_and_items(
            module_,
            import_resolution,
            directive.span,
1522
            target);
1523

1524
        if value_result.is_unbound() && type_result.is_unbound() {
1525
            let msg = format!("There is no `{}` in `{}`",
1526
                              token::get_name(source),
1527
                              self.module_to_string(&*containing_module));
1528
            return Failed(Some((directive.span, msg)));
1529
        }
1530 1531
        let value_used_public = value_used_reexport || value_used_public;
        let type_used_public = type_used_reexport || type_used_public;
1532

E
Eduard Burtescu 已提交
1533 1534
        assert!(import_resolution.outstanding_references >= 1);
        import_resolution.outstanding_references -= 1;
1535

A
Alex Crichton 已提交
1536 1537 1538
        // 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 已提交
1539 1540
        let value_private = match import_resolution.value_target {
            Some(ref target) => {
1541
                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
1542
                self.def_map.borrow_mut().insert(directive.id, def);
1543
                let did = def.def_id();
1544 1545 1546 1547 1548 1549
                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 已提交
1550 1551
        let type_private = match import_resolution.type_target {
            Some(ref target) => {
1552
                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
1553
                self.def_map.borrow_mut().insert(directive.id, def);
1554
                let did = def.def_id();
1555 1556 1557 1558 1559 1560 1561 1562 1563
                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 已提交
1564

1565
        debug!("(resolving single import) successfully resolved import");
B
Brian Anderson 已提交
1566
        return Success(());
1567 1568
    }

1569
    // Resolves a glob import. Note that this function cannot fail; it either
1570
    // succeeds or bails out (as importing * from an empty module or a module
1571 1572
    // 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 已提交
1573
    fn resolve_glob_import(&mut self,
E
Eduard Burtescu 已提交
1574 1575
                           module_: &Module,
                           containing_module: Rc<Module>,
1576
                           import_directive: &ImportDirective,
1577 1578
                           lp: LastPrivate)
                           -> ResolveResult<()> {
1579 1580 1581
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1582 1583 1584
        // This function works in a highly imperative manner; it eagerly adds
        // everything it can to the list of import resolutions of the module
        // node.
1585
        debug!("(resolving glob import) resolving glob import {}", id);
1586 1587 1588 1589

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

1595
        assert_eq!(containing_module.glob_count.get(), 0);
1596 1597

        // Add all resolved imports from the containing module.
1598
        let import_resolutions = containing_module.import_resolutions.borrow();
1599
        for (ident, target_import_resolution) in import_resolutions.iter() {
1600
            debug!("(resolving glob import) writing module resolution \
L
Luqman Aden 已提交
1601
                    {} into `{}`",
1602
                   token::get_name(*ident),
1603
                   self.module_to_string(module_));
1604

E
Eduard Burtescu 已提交
1605
            if !target_import_resolution.is_public {
1606
                debug!("(resolving glob import) nevermind, just kidding");
1607 1608 1609
                continue
            }

1610
            // Here we merge two import resolutions.
1611
            let mut import_resolutions = module_.import_resolutions.borrow_mut();
1612
            match import_resolutions.get_mut(ident) {
E
Eduard Burtescu 已提交
1613
                Some(dest_import_resolution) => {
1614 1615 1616
                    // Merge the two import resolutions at a finer-grained
                    // level.

E
Eduard Burtescu 已提交
1617
                    match target_import_resolution.value_target {
B
Brian Anderson 已提交
1618
                        None => {
1619 1620
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1621
                        Some(ref value_target) => {
1622 1623 1624 1625
                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
                                                              import_directive.span,
                                                              *ident,
                                                              ValueNS);
1626
                            dest_import_resolution.value_target = Some(value_target.clone());
1627 1628
                        }
                    }
E
Eduard Burtescu 已提交
1629
                    match target_import_resolution.type_target {
B
Brian Anderson 已提交
1630
                        None => {
1631 1632
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1633
                        Some(ref type_target) => {
1634 1635 1636 1637
                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
                                                              import_directive.span,
                                                              *ident,
                                                              TypeNS);
1638
                            dest_import_resolution.type_target = Some(type_target.clone());
1639 1640
                        }
                    }
E
Eduard Burtescu 已提交
1641 1642
                    dest_import_resolution.is_public = is_public;
                    continue;
1643
                }
E
Eduard Burtescu 已提交
1644
                None => {}
1645
            }
E
Eduard Burtescu 已提交
1646 1647 1648 1649 1650 1651 1652 1653 1654

            // 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);
1655 1656
        }

1657
        // Add all children from the containing module.
1658
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
1659

1660
        for (&name, name_bindings) in containing_module.children.borrow().iter() {
1661 1662 1663 1664 1665 1666
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings.clone());

1667 1668 1669
        }

        // Add external module children from the containing module.
1670
        for (&name, module) in containing_module.external_module_children.borrow().iter() {
1671
            let name_bindings =
E
Eduard Burtescu 已提交
1672
                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
1673 1674 1675 1676 1677
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings);
1678 1679
        }

A
Alex Crichton 已提交
1680
        // Record the destination of this import
1681
        match containing_module.def_id.get() {
A
Alex Crichton 已提交
1682
            Some(did) => {
1683
                self.def_map.borrow_mut().insert(id, DefMod(did));
1684
                self.last_private.insert(id, lp);
A
Alex Crichton 已提交
1685 1686 1687 1688
            }
            None => {}
        }

1689
        debug!("(resolving glob import) successfully resolved import");
B
Brian Anderson 已提交
1690
        return Success(());
1691 1692
    }

1693
    fn merge_import_resolution(&mut self,
E
Eduard Burtescu 已提交
1694 1695
                               module_: &Module,
                               containing_module: Rc<Module>,
1696
                               import_directive: &ImportDirective,
1697
                               name: Name,
E
Eduard Burtescu 已提交
1698
                               name_bindings: Rc<NameBindings>) {
1699 1700 1701
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1702
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1703
        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
1704
            |vacant_entry| {
1705
                // Create a new import resolution from this child.
1706 1707
                vacant_entry.insert(ImportResolution::new(id, is_public))
            });
1708 1709 1710

        debug!("(resolving glob import) writing resolution `{}` in `{}` \
               to `{}`",
1711
               token::get_name(name).get(),
1712 1713
               self.module_to_string(&*containing_module),
               self.module_to_string(module_));
1714 1715

        // Merge the child item into the import resolution.
1716
        {
1717
            let mut merge_child_item = |&mut : namespace| {
1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728
                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());
B
Brian Anderson 已提交
1729
                        span_err!(self.session, import_directive.span, E0251, "{}", msg.as_slice());
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
                    } 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);
1742
        }
1743

E
Eduard Burtescu 已提交
1744
        dest_import_resolution.is_public = is_public;
1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758

        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) {
1759 1760 1761 1762
        debug!("check_for_conflicting_import: {}; target exists: {}",
               token::get_name(name).get(),
               target.is_some());

1763
        match *target {
1764
            Some(ref target) if target.shadowable != Shadowable::Always => {
1765 1766 1767 1768 1769 1770 1771
                let msg = format!("a {} named `{}` has already been imported \
                                   in this module",
                                  match namespace {
                                    TypeNS => "type",
                                    ValueNS => "value",
                                  },
                                  token::get_name(name).get());
B
Brian Anderson 已提交
1772
                span_err!(self.session, import_span, E0252, "{}", &msg[]);
1773 1774 1775 1776 1777
            }
            Some(_) | None => {}
        }
    }

1778 1779 1780 1781 1782 1783 1784 1785 1786
    /// 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));
B
Brian Anderson 已提交
1787
            span_err!(self.session, import_span, E0253, "{}", &msg[]);
1788 1789 1790
        }
    }

1791 1792 1793 1794
    /// 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:
1795
                                                     &ImportResolution,
1796 1797 1798 1799 1800 1801 1802
                                                     import_span: Span,
                                                     name: Name) {
        // First, check for conflicts between imports and `extern crate`s.
        if module.external_module_children
                 .borrow()
                 .contains_key(&name) {
            match import_resolution.type_target {
1803
                Some(ref target) if target.shadowable != Shadowable::Always => {
1804 1805 1806
                    let msg = format!("import `{0}` conflicts with imported \
                                       crate in this module \
                                       (maybe you meant `use {0}::*`?)",
1807
                                      token::get_name(name).get());
B
Brian Anderson 已提交
1808
                    span_err!(self.session, import_span, E0254, "{}", &msg[]);
1809 1810 1811 1812 1813 1814 1815
                }
                Some(_) | None => {}
            }
        }

        // Check for item conflicts.
        let children = module.children.borrow();
1816
        let name_bindings = match children.get(&name) {
1817 1818 1819 1820 1821 1822 1823 1824
            None => {
                // There can't be any conflicts.
                return
            }
            Some(ref name_bindings) => (*name_bindings).clone(),
        };

        match import_resolution.value_target {
1825
            Some(ref target) if target.shadowable != Shadowable::Always => {
1826 1827 1828 1829
                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());
B
Brian Anderson 已提交
1830
                    span_err!(self.session, import_span, E0255, "{}", &msg[]);
1831 1832
                    if let Some(span) = value.value_span {
                        self.session.span_note(span,
C
Colin Davidson 已提交
1833
                                               "conflicting value here");
1834 1835 1836 1837 1838 1839 1840
                    }
                }
            }
            Some(_) | None => {}
        }

        match import_resolution.type_target {
1841
            Some(ref target) if target.shadowable != Shadowable::Always => {
1842 1843 1844 1845 1846 1847
                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());
B
Brian Anderson 已提交
1848
                            span_err!(self.session, import_span, E0256, "{}", &msg[]);
1849 1850
                            if let Some(span) = ty.type_span {
                                self.session.span_note(span,
1851 1852
                                                       "note conflicting type here")
                            }
1853 1854 1855 1856 1857 1858 1859 1860
                        }
                        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");
B
Brian Anderson 已提交
1861
                                        span_err!(self.session, span, E0257, "{}", &msg[]);
1862
                                        self.session.span_note(import_span,
1863 1864
                                                               "import from other module here")
                                    }
1865 1866 1867 1868 1869
                                }
                                _ => {
                                    let msg = format!("import `{}` conflicts with existing \
                                                       submodule",
                                                      token::get_name(name).get());
B
Brian Anderson 已提交
1870
                                    span_err!(self.session, import_span, E0258, "{}", &msg[]);
1871 1872
                                    if let Some(span) = ty.type_span {
                                        self.session.span_note(span,
1873 1874 1875
                                                               "note conflicting module here")
                                    }
                                }
1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891
                            }
                        }
                    }
                }
            }
            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) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1892 1893
                span_err!(self.session, span, E0259,
                          "an external crate named `{}` has already \
1894
                                   been imported into this module",
B
Brian Anderson 已提交
1895
                                  token::get_name(name).get());
1896 1897 1898 1899 1900 1901 1902 1903 1904
        }
    }

    /// 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) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1905 1906
                span_err!(self.session, span, E0260,
                          "the name `{}` conflicts with an external \
1907 1908
                                   crate that has been imported into this \
                                   module",
B
Brian Anderson 已提交
1909
                                  token::get_name(name).get());
1910
        }
1911 1912
    }

1913
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1914
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1915
                                     module_: Rc<Module>,
1916
                                     module_path: &[Name],
1917 1918 1919 1920
                                     index: uint,
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
1921
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
1922 1923 1924
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
            module.external_module_children.borrow()
1925
                                            .get(&needle).cloned()
1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937
                                            .map(|_| module.clone())
                                            .or_else(|| {
                match module.parent_link.clone() {
                    ModuleParentLink(parent, _) => {
                        search_parent_externals(needle,
                                                &parent.upgrade().unwrap())
                    }
                   _ => None
                }
            })
        }

1938
        let mut search_module = module_;
1939
        let mut index = index;
A
Alex Crichton 已提交
1940
        let module_path_len = module_path.len();
1941
        let mut closest_private = lp;
1942 1943 1944 1945 1946

        // 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 已提交
1947
            let name = module_path[index];
E
Eduard Burtescu 已提交
1948
            match self.resolve_name_in_module(search_module.clone(),
1949
                                              name,
1950
                                              TypeNS,
1951 1952
                                              name_search_type,
                                              false) {
1953
                Failed(None) => {
1954
                    let segment_name = token::get_name(name);
1955
                    let module_name = self.module_to_string(&*search_module);
1956
                    let mut span = span;
J
Jorge Aparicio 已提交
1957
                    let msg = if "???" == &module_name[] {
1958
                        span.hi = span.lo + Pos::from_usize(segment_name.get().len());
1959

1960
                        match search_parent_externals(name,
1961
                                                     &self.current_module) {
1962
                            Some(module) => {
1963
                                let path_str = self.names_to_string(module_path);
1964
                                let target_mod_str = self.module_to_string(&*module);
1965
                                let current_mod_str =
1966
                                    self.module_to_string(&*self.current_module);
1967 1968 1969 1970 1971 1972 1973

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

1974
                                format!("Did you mean `{}{}`?", prefix, path_str)
1975
                            },
1976 1977
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
1978
                        }
1979
                    } else {
1980
                        format!("Could not find `{}` in `{}`",
1981 1982 1983
                                segment_name,
                                module_name)
                    };
1984

1985
                    return Failed(Some((span, msg)));
1986
                }
1987
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1988
                Indeterminate => {
1989
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
1990
                            resolution is indeterminate: {}",
1991
                            token::get_name(name));
B
Brian Anderson 已提交
1992
                    return Indeterminate;
1993
                }
1994
                Success((target, used_proxy)) => {
1995 1996
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
1997
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1998
                        Some(ref type_def) => {
1999 2000
                            match type_def.module_def {
                                None => {
2001
                                    let msg = format!("Not a module `{}`",
2002
                                                        token::get_name(name));
2003 2004

                                    return Failed(Some((span, msg)));
2005
                                }
E
Eduard Burtescu 已提交
2006
                                Some(ref module_def) => {
2007 2008 2009
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
2010 2011
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
2012
                                    }
2013

2014 2015 2016
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
2017 2018 2019
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
2020
                                        }
2021
                                    }
2022 2023 2024 2025 2026
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
2027
                            let msg = format!("Not a module `{}`",
2028
                                              token::get_name(name));
2029
                            return Failed(Some((span, msg)));
2030 2031 2032 2033 2034
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
2035
            index += 1;
2036 2037
        }

2038
        return Success((search_module, closest_private));
2039 2040
    }

2041 2042
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
2043 2044 2045
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
2046
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
2047
                           module_: Rc<Module>,
2048
                           module_path: &[Name],
2049 2050 2051
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
2052
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
2053
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
2054
        assert!(module_path_len > 0);
2055

2056
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
2057
               self.names_to_string(module_path),
2058
               self.module_to_string(&*module_));
2059

2060
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
2061
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
2062
                                                              module_path);
2063

2064 2065
        let search_module;
        let start_index;
2066
        let last_private;
2067
        match module_prefix_result {
2068
            Failed(None) => {
2069
                let mpath = self.names_to_string(module_path);
J
Jorge Aparicio 已提交
2070
                let mpath = &mpath[];
2071
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
2072
                    Some(idx) => {
2073 2074 2075
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
2076 2077
                                            &mpath[idx + 1..],
                                            &mpath[..idx - 1]);
2078
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
2079
                    },
2080 2081 2082
                    None => {
                        return Failed(None)
                    }
2083
                }
2084
            }
2085
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
2086
            Indeterminate => {
2087
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
2088
                        bailing");
B
Brian Anderson 已提交
2089
                return Indeterminate;
2090
            }
2091 2092 2093 2094 2095 2096 2097 2098 2099 2100
            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;
2101
                        last_private = LastMod(AllPublic);
2102 2103 2104 2105 2106
                    }
                    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.
2107 2108
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
2109
                            Failed(err) => return Failed(err),
2110
                            Indeterminate => {
2111
                                debug!("(resolving module path for import) \
2112 2113 2114 2115 2116 2117
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
2118
                                last_private = LastMod(AllPublic);
2119 2120 2121 2122 2123
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
2124 2125
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
2126
                start_index = index;
2127 2128 2129
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
2130 2131 2132
            }
        }

2133 2134 2135 2136
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
2137 2138
                                           name_search_type,
                                           last_private)
2139 2140
    }

2141 2142
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2143
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
2144
                                     module_: Rc<Module>,
2145
                                     name: Name,
2146
                                     namespace: Namespace)
2147
                                    -> ResolveResult<(Target, bool)> {
2148
        debug!("(resolving item in lexical scope) resolving `{}` in \
2149
                namespace {:?} in `{}`",
2150
               token::get_name(name),
2151
               namespace,
2152
               self.module_to_string(&*module_));
2153 2154 2155

        // The current module node is handled specially. First, check for
        // its immediate children.
2156
        build_reduced_graph::populate_module_if_necessary(self, &module_);
2157

2158
        match module_.children.borrow().get(&name) {
2159 2160 2161
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
2162 2163
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
2164
                                            Shadowable::Never),
2165
                               false));
2166
            }
2167
            Some(_) | None => { /* Not found; continue. */ }
2168 2169 2170 2171 2172 2173
        }

        // 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.
2174 2175 2176 2177 2178
        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 \
2179
                            import resolution, but not in namespace {:?}",
2180 2181 2182 2183 2184 2185
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
2186 2187 2188
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
2189
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
2190
                         self.used_crates.insert(kid);
2191
                    }
2192
                    return Success((target, false));
2193 2194 2195 2196
                }
            }
        }

2197 2198
        // Search for external modules.
        if namespace == TypeNS {
2199 2200 2201 2202
            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");
2203 2204 2205
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2206
                                false));
2207 2208 2209
            }
        }

2210
        // Finally, proceed up the scope chain looking for parent modules.
2211
        let mut search_module = module_;
2212 2213
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
2214
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
2215
                NoParentLink => {
2216
                    // No more parents. This module was unresolved.
2217
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
2218
                            module");
2219
                    return Failed(None);
2220
                }
2221
                ModuleParentLink(parent_module_node, _) => {
2222 2223 2224 2225 2226 2227 2228
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
2229
                            return Failed(None);
2230
                        }
2231 2232
                        TraitModuleKind |
                        ImplModuleKind |
2233
                        EnumModuleKind |
2234
                        TypeModuleKind |
2235
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
2236
                            search_module = parent_module_node.upgrade().unwrap();
2237 2238 2239
                        }
                    }
                }
E
Eduard Burtescu 已提交
2240 2241
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
2242 2243 2244 2245
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
2246
            match self.resolve_name_in_module(search_module.clone(),
2247
                                              name,
2248
                                              namespace,
2249 2250
                                              PathSearch,
                                              true) {
2251
                Failed(Some((span, msg))) =>
J
Jorge Aparicio 已提交
2252 2253
                    self.resolve_error(span, &format!("failed to resolve. {}",
                                                     msg)[]),
2254
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
2255
                Indeterminate => {
2256 2257 2258
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

2259
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
2260
                            higher scope; bailing");
B
Brian Anderson 已提交
2261
                    return Indeterminate;
2262
                }
2263
                Success((target, used_reexport)) => {
2264
                    // We found the module.
2265
                    debug!("(resolving item in lexical scope) found name \
2266 2267
                            in module, done");
                    return Success((target, used_reexport));
2268 2269 2270 2271 2272
                }
            }
        }
    }

2273
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
2274
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
2275
                                       module_: Rc<Module>,
2276
                                       name: Name)
E
Eduard Burtescu 已提交
2277
                                -> ResolveResult<Rc<Module>> {
2278 2279
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
2280
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
2281
        match resolve_result {
2282
            Success((target, _)) => {
2283
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
2284
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
2285
                    Some(ref type_def) => {
2286
                        match type_def.module_def {
2287
                            None => {
2288
                                debug!("!!! (resolving module in lexical \
2289 2290
                                        scope) module wasn't actually a \
                                        module!");
2291
                                return Failed(None);
2292
                            }
E
Eduard Burtescu 已提交
2293 2294
                            Some(ref module_def) => {
                                return Success(module_def.clone());
2295 2296 2297 2298
                            }
                        }
                    }
                    None => {
2299
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
2300
                                wasn't actually a module!");
2301
                        return Failed(None);
2302 2303 2304
                    }
                }
            }
B
Brian Anderson 已提交
2305
            Indeterminate => {
2306
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
2307
                        bailing");
B
Brian Anderson 已提交
2308
                return Indeterminate;
2309
            }
2310 2311 2312
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
2313 2314 2315 2316
            }
        }
    }

2317
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
2318 2319
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
2320 2321
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
2322
            match module_.parent_link.clone() {
2323 2324 2325
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
2326
                    let new_module = new_module.upgrade().unwrap();
2327
                    match new_module.kind.get() {
2328 2329
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
2330
                        ImplModuleKind |
2331
                        EnumModuleKind |
2332
                        TypeModuleKind |
2333 2334 2335 2336 2337 2338 2339
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

2340 2341
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
2342 2343
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
2344
        match module_.kind.get() {
2345
            NormalModuleKind => return module_,
2346 2347
            TraitModuleKind |
            ImplModuleKind |
2348
            EnumModuleKind |
2349
            TypeModuleKind |
2350
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
2351
                match self.get_nearest_normal_module_parent(module_.clone()) {
2352 2353 2354 2355 2356 2357 2358
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

2359
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
2360
    /// (b) some chain of `super::`.
2361
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
2362
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
2363
                             module_: Rc<Module>,
2364
                             module_path: &[Name])
2365
                                 -> ResolveResult<ModulePrefixResult> {
2366 2367 2368 2369
        // 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;
2370
        let first_module_path_string = token::get_name(module_path[0]);
2371
        if "self" == first_module_path_string.get() {
2372 2373 2374
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 1;
2375
        } else if "super" == first_module_path_string.get() {
2376 2377 2378 2379 2380 2381 2382 2383
            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.
2384
        while i < module_path.len() {
2385
            let string = token::get_name(module_path[i]);
2386 2387 2388
            if "super" != string.get() {
                break
            }
2389
            debug!("(resolving module prefix) resolving `super` at {}",
2390
                   self.module_to_string(&*containing_module));
2391
            match self.get_nearest_normal_module_parent(containing_module) {
2392
                None => return Failed(None),
2393 2394 2395
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
2396 2397 2398 2399
                }
            }
        }

2400
        debug!("(resolving module prefix) finished resolving prefix at {}",
2401
               self.module_to_string(&*containing_module));
2402 2403

        return Success(PrefixFound(containing_module, i));
2404 2405
    }

2406 2407 2408
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
2409 2410 2411
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
2412
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
2413
                              module_: Rc<Module>,
2414
                              name: Name,
2415
                              namespace: Namespace,
2416 2417
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
2418
                              -> ResolveResult<(Target, bool)> {
2419
        debug!("(resolving name in module) resolving `{}` in `{}`",
2420
               token::get_name(name).get(),
2421
               self.module_to_string(&*module_));
2422 2423

        // First, check the direct children of the module.
2424
        build_reduced_graph::populate_module_if_necessary(self, &module_);
2425

2426
        match module_.children.borrow().get(&name) {
2427 2428 2429
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
2430 2431
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
2432
                                            Shadowable::Never),
2433 2434 2435 2436
                               false));
            }
            Some(_) | None => {
                // Continue.
2437 2438 2439
            }
        }

2440 2441 2442 2443
        // 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.
2444
        if name_search_type == PathSearch {
2445
            assert_eq!(module_.glob_count.get(), 0);
2446 2447
        }

2448
        // Check the list of resolved imports.
2449
        match module_.import_resolutions.borrow().get(&name) {
2450
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
2451
                                       import_resolution.is_public => {
2452

E
Eduard Burtescu 已提交
2453 2454
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
2455
                    debug!("(resolving name in module) import \
2456
                           unresolved; bailing out");
B
Brian Anderson 已提交
2457
                    return Indeterminate;
2458
                }
2459
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
2460
                    None => {
2461
                        debug!("(resolving name in module) name found, \
2462
                                but not in namespace {:?}",
P
Paul Stansifer 已提交
2463
                               namespace);
2464
                    }
2465
                    Some(target) => {
2466
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
2467
                                import");
2468
                        // track used imports and extern crates as well
2469 2470 2471
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
2472 2473
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
2474
                        }
2475
                        return Success((target, true));
2476
                    }
2477 2478
                }
            }
2479
            Some(..) | None => {} // Continue.
2480 2481 2482 2483
        }

        // Finally, search through external children.
        if namespace == TypeNS {
2484 2485 2486
            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
2487 2488 2489
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2490
                                false));
2491 2492 2493 2494
            }
        }

        // We're out of luck.
2495
        debug!("(resolving name in module) failed to resolve `{}`",
2496
               token::get_name(name).get());
2497
        return Failed(None);
2498 2499
    }

E
Eduard Burtescu 已提交
2500
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
2501
        let index = module_.resolved_import_count.get();
2502 2503
        let imports = module_.imports.borrow();
        let import_count = imports.len();
2504
        if index != import_count {
2505
            let sn = self.session
E
Eduard Burtescu 已提交
2506
                         .codemap()
2507
                         .span_to_snippet((*imports)[index].span)
2508
                         .unwrap();
2509
            if sn.contains("::") {
2510
                self.resolve_error((*imports)[index].span,
2511
                                   "unresolved import");
2512
            } else {
A
Alex Crichton 已提交
2513
                let err = format!("unresolved import (maybe you meant `{}::*`?)",
A
Alex Crichton 已提交
2514
                                  sn);
J
Jorge Aparicio 已提交
2515
                self.resolve_error((*imports)[index].span, &err[]);
2516
            }
2517 2518 2519
        }

        // Descend into children and anonymous children.
2520
        build_reduced_graph::populate_module_if_necessary(self, &module_);
2521

E
Eduard Burtescu 已提交
2522
        for (_, child_node) in module_.children.borrow().iter() {
2523 2524 2525 2526 2527 2528
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
2529 2530 2531 2532
                }
            }
        }

E
Eduard Burtescu 已提交
2533 2534
        for (_, module_) in module_.anonymous_children.borrow().iter() {
            self.report_unresolved_imports(module_.clone());
2535 2536 2537 2538 2539
        }
    }

    // AST resolution
    //
2540
    // We maintain a list of value ribs and type ribs.
2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555
    //
    // 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 已提交
2556 2557 2558
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
2559
        let orig_module = self.current_module.clone();
2560 2561

        // Move down in the graph.
2562
        match name {
B
Brian Anderson 已提交
2563
            None => {
2564 2565
                // Nothing to do.
            }
B
Brian Anderson 已提交
2566
            Some(name) => {
2567
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
2568

2569
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
2570
                    None => {
2571
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
2572
                               token::get_name(name),
2573
                               self.module_to_string(&*orig_module));
2574
                    }
B
Brian Anderson 已提交
2575
                    Some(name_bindings) => {
2576
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
2577
                            None => {
2578
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
2579
                                        for `{}` in `{}`",
2580
                                       token::get_name(name),
2581
                                       self.module_to_string(&*orig_module));
2582
                            }
B
Brian Anderson 已提交
2583
                            Some(module_) => {
2584
                                self.current_module = module_;
2585 2586 2587 2588 2589 2590 2591
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
2592
        f(self);
2593 2594 2595 2596

        self.current_module = orig_module;
    }

2597
    /// Wraps the given definition in the appropriate number of `DefUpvar`
2598
    /// wrappers.
E
Eduard Burtescu 已提交
2599
    fn upvarify(&self,
E
Eduard Burtescu 已提交
2600
                ribs: &[Rib],
E
Eduard Burtescu 已提交
2601 2602 2603
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
2604
        match def_like {
2605 2606
            DlDef(d @ DefUpvar(..)) => {
                self.session.span_bug(span,
J
Jorge Aparicio 已提交
2607
                    &format!("unexpected {:?} in bindings", d)[])
2608 2609 2610 2611 2612 2613 2614 2615 2616
            }
            DlDef(d @ DefLocal(_)) => {
                let node_id = d.def_id().node;
                let mut def = d;
                for rib in ribs.iter() {
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
2617
                        ClosureRibKind(function_id) => {
2618
                            let prev_def = def;
2619
                            def = DefUpvar(node_id, function_id);
2620

2621
                            let mut seen = self.freevars_seen.borrow_mut();
2622
                            let seen = match seen.entry(function_id) {
2623
                                Occupied(v) => v.into_mut(),
2624
                                Vacant(v) => v.insert(NodeSet()),
2625
                            };
2626 2627 2628
                            if seen.contains(&node_id) {
                                continue;
                            }
2629
                            match self.freevars.borrow_mut().entry(function_id) {
2630
                                Occupied(v) => v.into_mut(),
2631
                                Vacant(v) => v.insert(vec![]),
2632
                            }.push(Freevar { def: prev_def, span: span });
2633 2634 2635 2636 2637 2638
                            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 {
2639
                                DefTyParam(_, _, did, _) if {
2640
                                    self.def_map.borrow().get(&did.node).cloned()
2641 2642 2643 2644 2645 2646 2647
                                        == 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.
2648

2649 2650 2651 2652
                                    self.resolve_error(
                                        span,
                                        "can't capture dynamic environment in a fn item; \
                                        use the || { ... } closure form instead");
2653

2654 2655 2656 2657 2658 2659 2660 2661
                                    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.
2662

2663 2664 2665 2666
                            self.resolve_error(
                                span,
                                "can't capture dynamic environment in a fn item; \
                                use the || { ... } closure form instead");
2667

2668 2669 2670 2671 2672 2673 2674
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
                            self.resolve_error(span,
                                               "attempt to use a non-constant \
                                                value in a constant");
2675

2676
                        }
2677 2678
                    }
                }
2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691
                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 {
2692
                                DefTyParam(_, _, did, _) if {
2693
                                    self.def_map.borrow().get(&did.node).cloned()
2694 2695 2696
                                        == Some(DefTyParamBinder(item_id))
                                } => {} // ok
                                DefSelfTy(did) if did == item_id => {} // ok
2697

2698 2699 2700
                                _ => {
                                    // This was an attempt to use a type parameter outside
                                    // its scope.
2701

2702 2703 2704 2705
                                    self.resolve_error(span,
                                                        "can't use type parameters from \
                                                        outer function; try using a local \
                                                        type parameter instead");
2706

2707 2708 2709 2710 2711 2712 2713
                                    return None;
                                }
                            }
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
2714

2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729
                            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");

                        }
                    }
2730
                }
2731
                Some(DlDef(def))
2732
            }
2733
            _ => Some(def_like)
2734 2735 2736
        }
    }

S
Seo Sanghyeon 已提交
2737 2738
    /// Searches the current set of local scopes and
    /// applies translations for closures.
E
Eduard Burtescu 已提交
2739
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
2740
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
2741 2742 2743
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
2744
        // FIXME #4950: Try caching?
2745

2746
        for (i, rib) in ribs.iter().enumerate().rev() {
2747
            match rib.bindings.get(&name).cloned() {
2748
                Some(def_like) => {
2749
                    return self.upvarify(&ribs[i + 1..], def_like, span);
2750
                }
B
Brian Anderson 已提交
2751
                None => {
2752 2753 2754 2755 2756
                    // Continue.
                }
            }
        }

2757
        None
2758 2759
    }

S
Seo Sanghyeon 已提交
2760 2761
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773
    fn search_label(&self, name: Name) -> Option<DefLike> {
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
                    return None
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
2774 2775
            if result.is_some() {
                return result
2776 2777 2778 2779 2780
            }
        }
        None
    }

2781
    fn resolve_crate(&mut self, krate: &ast::Crate) {
2782
        debug!("(resolving crate) starting");
2783

2784
        visit::walk_crate(self, krate);
2785 2786
    }

2787
    fn resolve_item(&mut self, item: &Item) {
2788 2789
        let name = item.ident.name;

2790
        debug!("(resolving item) resolving {}",
2791
               token::get_name(name));
2792

2793
        match item.node {
2794 2795 2796

            // enum item: resolve all the variants' discrs,
            // then resolve the ty params
2797
            ItemEnum(ref enum_def, ref generics) => {
D
Daniel Micay 已提交
2798 2799
                for variant in (*enum_def).variants.iter() {
                    for dis_expr in variant.node.disr_expr.iter() {
2800 2801
                        // resolve the discriminator expr
                        // as a constant
A
Alex Crichton 已提交
2802
                        self.with_constant_rib(|this| {
2803
                            this.resolve_expr(&**dis_expr);
2804 2805 2806 2807
                        });
                    }
                }

J
Joseph Crail 已提交
2808
                // n.b. the discr expr gets visited twice.
2809 2810
                // but maybe it's okay since the first time will signal an
                // error if there is one? -- tjc
2811
                self.with_type_parameter_rib(HasTypeParameters(generics,
2812
                                                               TypeSpace,
2813
                                                               item.id,
2814
                                                               ItemRibKind),
2815
                                             |this| {
N
Nick Cameron 已提交
2816
                    this.resolve_type_parameters(&generics.ty_params);
2817
                    this.resolve_where_clause(&generics.where_clause);
2818
                    visit::walk_item(this, item);
2819
                });
2820
            }
T
Tim Chevalier 已提交
2821

2822
            ItemTy(_, ref generics) => {
2823
                self.with_type_parameter_rib(HasTypeParameters(generics,
2824
                                                               TypeSpace,
2825
                                                               item.id,
2826
                                                               ItemRibKind),
2827
                                             |this| {
N
Nick Cameron 已提交
2828
                    this.resolve_type_parameters(&generics.ty_params);
2829
                    visit::walk_item(this, item);
2830
                });
2831 2832
            }

2833
            ItemImpl(_, _,
2834
                     ref generics,
2835 2836
                     ref implemented_traits,
                     ref self_type,
2837
                     ref impl_items) => {
2838
                self.resolve_implementation(item.id,
2839
                                            generics,
2840
                                            implemented_traits,
2841
                                            &**self_type,
J
Jorge Aparicio 已提交
2842
                                            &impl_items[]);
2843 2844
            }

N
Nick Cameron 已提交
2845
            ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
2846
                // Create a new rib for the self type.
2847
                let mut self_type_rib = Rib::new(ItemRibKind);
2848

J
John Clements 已提交
2849 2850
                // plain insert (no renaming, types are not currently hygienic....)
                let name = self.type_self_name;
2851 2852
                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
                self.type_ribs.push(self_type_rib);
2853

2854
                // Create a new rib for the trait-wide type parameters.
2855
                self.with_type_parameter_rib(HasTypeParameters(generics,
2856
                                                               TypeSpace,
2857 2858 2859
                                                               item.id,
                                                               NormalRibKind),
                                             |this| {
A
Alex Crichton 已提交
2860
                    this.resolve_type_parameters(&generics.ty_params);
2861
                    this.resolve_where_clause(&generics.where_clause);
2862

2863 2864 2865
                    this.resolve_type_parameter_bounds(item.id, bounds,
                                                       TraitDerivation);

2866 2867
                    for trait_item in (*trait_items).iter() {
                        // Create a new rib for the trait_item-specific type
2868 2869
                        // parameters.
                        //
2870
                        // FIXME #4951: Do we need a node ID here?
2871

2872
                        match *trait_item {
2873
                          ast::RequiredMethod(ref ty_m) => {
2874
                            this.with_type_parameter_rib
2875
                                (HasTypeParameters(&ty_m.generics,
2876
                                                   FnSpace,
2877
                                                   item.id,
2878
                                        MethodRibKind(item.id, RequiredMethod)),
2879
                                 |this| {
2880

2881 2882
                                // Resolve the method-specific type
                                // parameters.
A
Alex Crichton 已提交
2883 2884
                                this.resolve_type_parameters(
                                    &ty_m.generics.ty_params);
2885 2886
                                this.resolve_where_clause(&ty_m.generics
                                                               .where_clause);
2887

D
Daniel Micay 已提交
2888
                                for argument in ty_m.decl.inputs.iter() {
2889
                                    this.resolve_type(&*argument.ty);
2890
                                }
2891

2892 2893
                                if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
                                    this.resolve_type(&**typ)
2894 2895
                                }

2896 2897 2898
                                if let ast::Return(ref ret_ty) = ty_m.decl.output {
                                    this.resolve_type(&**ret_ty);
                                }
2899
                            });
2900
                          }
2901
                          ast::ProvidedMethod(ref m) => {
A
Alex Crichton 已提交
2902
                              this.resolve_method(MethodRibKind(item.id,
2903
                                                                ProvidedMethod(m.id)),
2904
                                                  &**m)
2905
                          }
2906 2907 2908
                          ast::TypeTraitItem(ref data) => {
                              this.resolve_type_parameter(&data.ty_param);
                              visit::walk_trait_item(this, trait_item);
2909
                          }
2910 2911
                        }
                    }
2912
                });
2913

2914
                self.type_ribs.pop();
2915 2916
            }

2917
            ItemStruct(ref struct_def, ref generics) => {
2918
                self.resolve_struct(item.id,
2919
                                    generics,
J
Jorge Aparicio 已提交
2920
                                    &struct_def.fields[]);
2921 2922
            }

2923
            ItemMod(ref module_) => {
2924 2925
                self.with_scope(Some(name), |this| {
                    this.resolve_module(module_, item.span, name,
A
Alex Crichton 已提交
2926
                                        item.id);
2927
                });
2928 2929
            }

2930
            ItemForeignMod(ref foreign_module) => {
2931
                self.with_scope(Some(name), |this| {
D
Daniel Micay 已提交
2932
                    for foreign_item in foreign_module.items.iter() {
2933
                        match foreign_item.node {
2934
                            ForeignItemFn(_, ref generics) => {
A
Alex Crichton 已提交
2935
                                this.with_type_parameter_rib(
2936
                                    HasTypeParameters(
2937
                                        generics, FnSpace, foreign_item.id,
2938
                                        ItemRibKind),
2939 2940 2941 2942 2943
                                    |this| {
                                        this.resolve_type_parameters(&generics.ty_params);
                                        this.resolve_where_clause(&generics.where_clause);
                                        visit::walk_foreign_item(this, &**foreign_item)
                                    });
2944
                            }
2945
                            ForeignItemStatic(..) => {
A
Alex Crichton 已提交
2946
                                visit::walk_foreign_item(this,
2947
                                                         &**foreign_item);
2948
                            }
2949 2950
                        }
                    }
2951
                });
2952 2953
            }

2954
            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
2955
                self.resolve_function(ItemRibKind,
2956
                                      Some(&**fn_decl),
2957
                                      HasTypeParameters
2958
                                        (generics,
2959
                                         FnSpace,
2960
                                         item.id,
2961
                                         ItemRibKind),
2962
                                      &**block);
2963 2964
            }

2965
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2966
                self.with_constant_rib(|this| {
2967
                    visit::walk_item(this, item);
2968
                });
2969
            }
2970

2971
            ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
2972
                // do nothing, these are just around to be encoded
2973
            }
2974 2975 2976
        }
    }

J
Jorge Aparicio 已提交
2977 2978 2979
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
2980
        match type_parameters {
2981
            HasTypeParameters(generics, space, node_id, rib_kind) => {
2982
                let mut function_type_rib = Rib::new(rib_kind);
2983
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2984
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2985
                    let name = type_parameter.ident.name;
2986
                    debug!("with_type_parameter_rib: {} {}", node_id,
P
Paul Stansifer 已提交
2987
                           type_parameter.id);
2988

2989
                    if seen_bindings.contains(&name) {
2990
                        self.resolve_error(type_parameter.span,
J
Jorge Aparicio 已提交
2991
                                           &format!("the name `{}` is already \
2992 2993 2994
                                                    used for a type \
                                                    parameter in this type \
                                                    parameter list",
2995
                                                   token::get_name(
J
Jorge Aparicio 已提交
2996
                                                       name))[])
2997
                    }
2998
                    seen_bindings.insert(name);
2999

3000
                    let def_like = DlDef(DefTyParam(space,
3001
                                                    index as u32,
3002
                                                    local_def(type_parameter.id),
3003
                                                    name));
3004 3005 3006
                    // Associate this type parameter with
                    // the item that bound it
                    self.record_def(type_parameter.id,
3007
                                    (DefTyParamBinder(node_id), LastMod(AllPublic)));
3008
                    // plain insert (no renaming)
3009
                    function_type_rib.bindings.insert(name, def_like);
3010
                }
3011
                self.type_ribs.push(function_type_rib);
3012 3013
            }

B
Brian Anderson 已提交
3014
            NoTypeParameters => {
3015 3016 3017 3018
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
3019
        f(self);
3020

3021
        match type_parameters {
3022
            HasTypeParameters(..) => { self.type_ribs.pop(); }
3023
            NoTypeParameters => { }
3024 3025 3026
        }
    }

J
Jorge Aparicio 已提交
3027 3028 3029
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
3030
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
3031
        f(self);
3032
        self.label_ribs.pop();
3033
    }
3034

J
Jorge Aparicio 已提交
3035 3036 3037
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
3038 3039
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
3040
        f(self);
3041 3042
        self.type_ribs.pop();
        self.value_ribs.pop();
3043 3044
    }

F
Felix S. Klock II 已提交
3045
    fn resolve_function(&mut self,
3046
                        rib_kind: RibKind,
3047
                        optional_declaration: Option<&FnDecl>,
3048
                        type_parameters: TypeParameters,
3049
                        block: &Block) {
3050
        // Create a value rib for the function.
E
Eduard Burtescu 已提交
3051
        let function_value_rib = Rib::new(rib_kind);
3052
        self.value_ribs.push(function_value_rib);
3053

3054
        // Create a label rib for the function.
E
Eduard Burtescu 已提交
3055
        let function_label_rib = Rib::new(rib_kind);
3056
        self.label_ribs.push(function_label_rib);
3057

3058
        // If this function has type parameters, add them now.
3059
        self.with_type_parameter_rib(type_parameters, |this| {
3060
            // Resolve the type parameters.
3061
            match type_parameters {
B
Brian Anderson 已提交
3062
                NoTypeParameters => {
3063 3064
                    // Continue.
                }
3065
                HasTypeParameters(ref generics, _, _, _) => {
A
Alex Crichton 已提交
3066
                    this.resolve_type_parameters(&generics.ty_params);
3067
                    this.resolve_where_clause(&generics.where_clause);
3068 3069 3070 3071
                }
            }

            // Add each argument to the rib.
3072
            match optional_declaration {
B
Brian Anderson 已提交
3073
                None => {
3074 3075
                    // Nothing to do.
                }
B
Brian Anderson 已提交
3076
                Some(declaration) => {
3077
                    let mut bindings_list = HashMap::new();
D
Daniel Micay 已提交
3078
                    for argument in declaration.inputs.iter() {
3079
                        this.resolve_pattern(&*argument.pat,
3080
                                             ArgumentIrrefutableMode,
3081
                                             &mut bindings_list);
3082

3083
                        this.resolve_type(&*argument.ty);
3084

3085
                        debug!("(resolving function) recorded argument");
3086 3087
                    }

3088 3089 3090
                    if let ast::Return(ref ret_ty) = declaration.output {
                        this.resolve_type(&**ret_ty);
                    }
3091 3092 3093 3094
                }
            }

            // Resolve the function body.
3095
            this.resolve_block(&*block);
3096

3097
            debug!("(resolving function) leaving function");
3098
        });
3099

3100 3101
        self.label_ribs.pop();
        self.value_ribs.pop();
3102 3103
    }

F
Felix S. Klock II 已提交
3104
    fn resolve_type_parameters(&mut self,
N
Nick Cameron 已提交
3105
                               type_parameters: &OwnedSlice<TyParam>) {
D
Daniel Micay 已提交
3106
        for type_parameter in type_parameters.iter() {
3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119
            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.default {
            Some(ref ty) => self.resolve_type(&**ty),
            None => {}
3120 3121 3122
        }
    }

3123 3124 3125 3126 3127 3128 3129 3130 3131 3132
    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 已提交
3133
    fn resolve_type_parameter_bound(&mut self,
3134
                                    id: NodeId,
3135 3136
                                    type_parameter_bound: &TyParamBound,
                                    reference_type: TraitReferenceType) {
3137
        match *type_parameter_bound {
N
Nick Cameron 已提交
3138
            TraitTyParamBound(ref tref, _) => {
N
Niko Matsakis 已提交
3139
                self.resolve_poly_trait_reference(id, tref, reference_type)
3140
            }
3141
            RegionTyParamBound(..) => {}
3142 3143 3144
        }
    }

N
Niko Matsakis 已提交
3145 3146 3147 3148 3149 3150 3151
    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 已提交
3152
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
3153 3154 3155
                               id: NodeId,
                               trait_reference: &TraitRef,
                               reference_type: TraitReferenceType) {
A
Alex Crichton 已提交
3156
        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3157
            None => {
3158
                let path_str = self.path_names_to_string(&trait_reference.path);
3159
                let usage_str = match reference_type {
3160
                    TraitBoundingTypeParameter => "bound type parameter with",
3161
                    TraitImplementation        => "implement",
3162
                    TraitDerivation            => "derive",
N
Niko Matsakis 已提交
3163
                    TraitObject                => "reference",
3164
                    TraitQPath                 => "extract an associated item from",
3165 3166
                };

A
Alex Crichton 已提交
3167
                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
J
Jorge Aparicio 已提交
3168
                self.resolve_error(trait_reference.path.span, &msg[]);
3169 3170
            }
            Some(def) => {
3171 3172
                match def {
                    (DefTrait(_), _) => {
3173
                        debug!("(resolving trait) found trait def: {:?}", def);
3174 3175 3176 3177
                        self.record_def(trait_reference.ref_id, def);
                    }
                    (def, _) => {
                        self.resolve_error(trait_reference.path.span,
J
Jorge Aparicio 已提交
3178
                                           &format!("`{}` is not a trait",
3179
                                                   self.path_names_to_string(
J
Jorge Aparicio 已提交
3180
                                                       &trait_reference.path))[]);
3181 3182

                        // If it's a typedef, give a note
3183 3184 3185
                        if let DefTy(..) = def {
                            self.session.span_note(
                                trait_reference.path.span,
J
Jorge Aparicio 已提交
3186 3187
                                &format!("`type` aliases cannot be used for traits")
                                []);
3188 3189 3190
                        }
                    }
                }
3191 3192 3193 3194
            }
        }
    }

3195 3196
    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
        for predicate in where_clause.predicates.iter() {
3197
            match predicate {
N
Nick Cameron 已提交
3198
                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
3199
                    self.resolve_type(&*bound_pred.bounded_ty);
3200 3201

                    for bound in bound_pred.bounds.iter() {
3202
                        self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
3203 3204
                                                          TraitBoundingTypeParameter);
                    }
3205
                }
3206
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
3207
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
3208 3209 3210 3211 3212 3213 3214 3215 3216
                    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");
                        }
                    }
3217

3218 3219
                    self.resolve_type(&*eq_pred.ty);
                }
3220 3221 3222 3223
            }
        }
    }

F
Felix S. Klock II 已提交
3224
    fn resolve_struct(&mut self,
3225 3226 3227
                      id: NodeId,
                      generics: &Generics,
                      fields: &[StructField]) {
3228
        // If applicable, create a rib for the type parameters.
3229
        self.with_type_parameter_rib(HasTypeParameters(generics,
3230
                                                       TypeSpace,
3231
                                                       id,
3232
                                                       ItemRibKind),
3233
                                     |this| {
3234
            // Resolve the type parameters.
A
Alex Crichton 已提交
3235
            this.resolve_type_parameters(&generics.ty_params);
3236
            this.resolve_where_clause(&generics.where_clause);
3237

3238
            // Resolve fields.
D
Daniel Micay 已提交
3239
            for field in fields.iter() {
3240
                this.resolve_type(&*field.node.ty);
3241
            }
3242
        });
3243 3244
    }

3245 3246
    // Does this really need to take a RibKind or is it always going
    // to be NormalRibKind?
F
Felix S. Klock II 已提交
3247
    fn resolve_method(&mut self,
3248
                      rib_kind: RibKind,
3249
                      method: &ast::Method) {
3250
        let method_generics = method.pe_generics();
3251 3252 3253 3254
        let type_parameters = HasTypeParameters(method_generics,
                                                FnSpace,
                                                method.id,
                                                rib_kind);
3255

3256 3257
        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
            self.resolve_type(&**typ);
3258 3259 3260 3261 3262
        }

        self.resolve_function(rib_kind,
                              Some(method.pe_fn_decl()),
                              type_parameters,
3263
                              method.pe_body());
3264 3265
    }

J
Jorge Aparicio 已提交
3266 3267 3268
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3269 3270 3271 3272 3273 3274 3275
        // 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 已提交
3276 3277 3278 3279 3280
    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,
    {
3281 3282 3283 3284
        let new_val = match *opt_trait_ref {
            Some(ref trait_ref) => {
                self.resolve_trait_reference(id, trait_ref, TraitImplementation);

3285
                match self.def_map.borrow().get(&trait_ref.ref_id) {
3286
                    Some(def) => {
3287
                        let did = def.def_id();
3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300
                        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 已提交
3301
    fn resolve_implementation(&mut self,
3302 3303 3304 3305
                              id: NodeId,
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
3306
                              impl_items: &[ImplItem]) {
3307
        // If applicable, create a rib for the type parameters.
3308
        self.with_type_parameter_rib(HasTypeParameters(generics,
3309
                                                       TypeSpace,
3310 3311 3312
                                                       id,
                                                       NormalRibKind),
                                     |this| {
3313
            // Resolve the type parameters.
A
Alex Crichton 已提交
3314
            this.resolve_type_parameters(&generics.ty_params);
3315
            this.resolve_where_clause(&generics.where_clause);
3316

3317
            // Resolve the trait reference, if necessary.
3318 3319 3320 3321 3322
            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| {
3323 3324
                    for impl_item in impl_items.iter() {
                        match *impl_item {
3325
                            MethodImplItem(ref method) => {
3326 3327
                                // If this is a trait impl, ensure the method
                                // exists in trait
3328
                                this.check_trait_item(method.pe_ident().name,
3329 3330 3331 3332 3333
                                                      method.span);

                                // We also need a new scope for the method-
                                // specific type parameters.
                                this.resolve_method(
3334
                                    MethodRibKind(id, ProvidedMethod(method.id)),
3335
                                    &**method);
3336
                            }
3337 3338 3339
                            TypeImplItem(ref typedef) => {
                                // If this is a trait impl, ensure the method
                                // exists in trait
3340
                                this.check_trait_item(typedef.ident.name,
3341 3342 3343 3344
                                                      typedef.span);

                                this.resolve_type(&*typedef.typ);
                            }
3345
                        }
3346
                    }
3347 3348
                });
            });
3349
        });
3350 3351 3352 3353 3354 3355 3356 3357 3358 3359

        // 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.
3360
                TyPath(ref path, path_id) => {
3361
                    match self.def_map.borrow().get(&path_id) {
3362 3363 3364 3365
                        // 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 \
3366
                                                           the current module");
3367 3368 3369 3370 3371 3372 3373
                        }
                        _ => {}
                    }
                }
                _ => { }
            }
        }
3374 3375
    }

3376
    fn check_trait_item(&self, name: Name, span: Span) {
3377 3378
        // 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() {
3379
            if self.trait_item_map.get(&(name, did)).is_none() {
3380
                let path_str = self.path_names_to_string(&trait_ref.path);
3381
                self.resolve_error(span,
J
Jorge Aparicio 已提交
3382
                                    &format!("method `{}` is not a member of trait `{}`",
3383
                                            token::get_name(name),
J
Jorge Aparicio 已提交
3384
                                            path_str)[]);
3385 3386 3387 3388
            }
        }
    }

3389
    fn resolve_module(&mut self, module: &Mod, _span: Span,
3390
                      _name: Name, id: NodeId) {
3391
        // Write the implementations in scope into the module metadata.
3392
        debug!("(resolving module) resolving module ID {}", id);
3393
        visit::walk_mod(self, module);
3394 3395
    }

E
Eduard Burtescu 已提交
3396
    fn resolve_local(&mut self, local: &Local) {
3397
        // Resolve the type.
S
Seo Sanghyeon 已提交
3398 3399 3400
        if let Some(ref ty) = local.ty {
            self.resolve_type(&**ty);
        }
3401 3402

        // Resolve the initializer, if necessary.
3403
        match local.init {
B
Brian Anderson 已提交
3404
            None => {
3405 3406
                // Nothing to do.
            }
3407 3408
            Some(ref initializer) => {
                self.resolve_expr(&**initializer);
3409 3410 3411 3412
            }
        }

        // Resolve the pattern.
3413 3414 3415 3416
        let mut bindings_list = HashMap::new();
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
                             &mut bindings_list);
3417 3418
    }

J
John Clements 已提交
3419 3420 3421 3422
    // 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 已提交
3423
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
3424
        let mut result = HashMap::new();
3425 3426
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
3427 3428 3429 3430
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
3431
        });
3432
        return result;
3433 3434
    }

J
John Clements 已提交
3435 3436
    // 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 已提交
3437
    fn check_consistent_bindings(&mut self, arm: &Arm) {
3438 3439 3440
        if arm.pats.len() == 0 {
            return
        }
3441
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
3442
        for (i, p) in arm.pats.iter().enumerate() {
3443
            let map_i = self.binding_mode_map(&**p);
3444

D
Daniel Micay 已提交
3445
            for (&key, &binding_0) in map_0.iter() {
3446
                match map_i.get(&key) {
3447 3448 3449
                  None => {
                    self.resolve_error(
                        p.span,
J
Jorge Aparicio 已提交
3450
                        &format!("variable `{}` from pattern #1 is \
3451 3452
                                  not bound in pattern #{}",
                                token::get_name(key),
J
Jorge Aparicio 已提交
3453
                                i + 1)[]);
3454 3455 3456 3457 3458
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
                        self.resolve_error(
                            binding_i.span,
J
Jorge Aparicio 已提交
3459
                            &format!("variable `{}` is bound with different \
3460 3461
                                      mode in pattern #{} than in pattern #1",
                                    token::get_name(key),
J
Jorge Aparicio 已提交
3462
                                    i + 1)[]);
3463 3464
                    }
                  }
3465 3466 3467
                }
            }

D
Daniel Micay 已提交
3468
            for (&key, &binding) in map_i.iter() {
3469
                if !map_0.contains_key(&key) {
3470
                    self.resolve_error(
3471
                        binding.span,
J
Jorge Aparicio 已提交
3472
                        &format!("variable `{}` from pattern {}{} is \
3473
                                  not bound in pattern {}1",
3474
                                token::get_name(key),
J
Jorge Aparicio 已提交
3475
                                "#", i + 1, "#")[]);
3476 3477 3478
                }
            }
        }
3479 3480
    }

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

3484
        let mut bindings_list = HashMap::new();
D
Daniel Micay 已提交
3485
        for pattern in arm.pats.iter() {
3486
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
3487 3488
        }

3489 3490 3491 3492
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

3493
        visit::walk_expr_opt(self, &arm.guard);
3494
        self.resolve_expr(&*arm.body);
3495

3496
        self.value_ribs.pop();
3497 3498
    }

E
Eduard Burtescu 已提交
3499
    fn resolve_block(&mut self, block: &Block) {
3500
        debug!("(resolving block) entering block");
3501
        self.value_ribs.push(Rib::new(NormalRibKind));
3502 3503

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
3504
        let orig_module = self.current_module.clone();
3505
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
3506
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
3507
            Some(anonymous_module) => {
3508
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
3509
                        down");
E
Eduard Burtescu 已提交
3510
                self.current_module = anonymous_module.clone();
3511 3512 3513
            }
        }

3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
        for statement in block.stmts.iter() {
            if let ast::StmtDecl(ref declaration, _) = statement.node {
                if let ast::DeclItem(ref i) = declaration.node {
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
                            span_err!(self.session, i.span, E0154,
                                "imports are not allowed after non-item statements");
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

3534
        // Descend into the block.
3535
        visit::walk_block(self, block);
3536 3537 3538 3539

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

3540
        self.value_ribs.pop();
3541
        debug!("(resolving block) leaving block");
3542 3543
    }

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

3549
            TyPath(ref path, path_id) => {
3550
                // This is a path in the type namespace. Walk through scopes
3551
                // looking for it.
3552
                let mut result_def = None;
3553

3554
                // First, check to see whether the name is a primitive type.
3555
                if path.segments.len() == 1 {
3556
                    let id = path.segments.last().unwrap().identifier;
3557 3558 3559

                    match self.primitive_type_table
                            .primitive_types
3560
                            .get(&id.name) {
3561

3562
                        Some(&primitive_type) => {
3563
                            result_def =
3564
                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
3565

3566
                            if path.segments[0].parameters.has_lifetimes() {
J
Jakub Wieczorek 已提交
3567 3568
                                span_err!(self.session, path.span, E0157,
                                    "lifetime parameters are not allowed on this type");
3569
                            } else if !path.segments[0].parameters.is_empty() {
J
Jakub Wieczorek 已提交
3570 3571
                                span_err!(self.session, path.span, E0153,
                                    "type parameters are not allowed on this type");
3572
                            }
3573 3574 3575 3576
                        }
                        None => {
                            // Continue.
                        }
3577 3578 3579
                    }
                }

3580 3581
                if let None = result_def {
                    result_def = self.resolve_path(ty.id, path, TypeNS, true);
3582 3583
                }

3584
                match result_def {
B
Brian Anderson 已提交
3585
                    Some(def) => {
3586
                        // Write the result into the def map.
3587
                        debug!("(resolving type) writing resolution for `{}` \
3588
                                (id {}) = {:?}",
3589
                               self.path_names_to_string(path),
3590
                               path_id, def);
3591 3592
                        self.record_def(path_id, def);
                    }
B
Brian Anderson 已提交
3593
                    None => {
A
Alex Crichton 已提交
3594
                        let msg = format!("use of undeclared type name `{}`",
3595
                                          self.path_names_to_string(path));
J
Jorge Aparicio 已提交
3596
                        self.resolve_error(ty.span, &msg[]);
3597 3598
                    }
                }
3599
            }
3600

3601 3602 3603
            TyObjectSum(ref ty, ref bound_vec) => {
                self.resolve_type(&**ty);
                self.resolve_type_parameter_bounds(ty.id, bound_vec,
3604
                                                       TraitBoundingTypeParameter);
3605 3606
            }

3607
            TyQPath(ref qpath) => {
3608 3609
                self.resolve_type(&*qpath.self_type);
                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
3610 3611 3612 3613 3614 3615
                for ty in qpath.item_path.parameters.types().into_iter() {
                    self.resolve_type(&**ty);
                }
                for binding in qpath.item_path.parameters.bindings().into_iter() {
                    self.resolve_type(&*binding.ty);
                }
3616 3617
            }

3618 3619
            TyPolyTraitRef(ref bounds) => {
                self.resolve_type_parameter_bounds(
N
Niko Matsakis 已提交
3620
                    ty.id,
3621
                    bounds,
N
Niko Matsakis 已提交
3622 3623 3624
                    TraitObject);
                visit::walk_ty(self, ty);
            }
B
Brian Anderson 已提交
3625
            _ => {
3626
                // Just resolve embedded types.
3627
                visit::walk_ty(self, ty);
3628 3629 3630 3631
            }
        }
    }

F
Felix S. Klock II 已提交
3632
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
3633
                       pattern: &Pat,
3634 3635 3636
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
3637
                       bindings_list: &mut HashMap<Name, NodeId>) {
3638
        let pat_id = pattern.id;
3639
        walk_pat(pattern, |pattern| {
3640
            match pattern.node {
3641
                PatIdent(binding_mode, ref path1, _) => {
3642 3643

                    // The meaning of pat_ident with no type parameters
3644 3645 3646 3647 3648 3649 3650
                    // 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).
3651

3652
                    let ident = path1.node;
3653
                    let renamed = mtwt::resolve(ident);
3654

3655
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
3656
                        FoundStructOrEnumVariant(ref def, lp)
3657
                                if mode == RefutableMode => {
3658
                            debug!("(resolving pattern) resolving `{}` to \
3659
                                    struct or enum variant",
3660
                                   token::get_name(renamed));
3661

3662 3663 3664 3665
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
3666
                            self.record_def(pattern.id, (def.clone(), lp));
3667
                        }
A
Alex Crichton 已提交
3668
                        FoundStructOrEnumVariant(..) => {
3669 3670
                            self.resolve_error(
                                pattern.span,
J
Jorge Aparicio 已提交
3671
                                &format!("declaration of `{}` shadows an enum \
3672 3673
                                         variant or unit-like struct in \
                                         scope",
J
Jorge Aparicio 已提交
3674
                                        token::get_name(renamed))[]);
3675
                        }
3676
                        FoundConst(ref def, lp) if mode == RefutableMode => {
3677
                            debug!("(resolving pattern) resolving `{}` to \
3678
                                    constant",
3679
                                   token::get_name(renamed));
3680

3681 3682 3683 3684
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
3685
                            self.record_def(pattern.id, (def.clone(), lp));
3686
                        }
A
Alex Crichton 已提交
3687
                        FoundConst(..) => {
3688
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
3689
                                                  "only irrefutable patterns \
3690
                                                   allowed here");
3691
                        }
3692
                        BareIdentifierPatternUnresolved => {
3693
                            debug!("(resolving pattern) binding `{}`",
3694
                                   token::get_name(renamed));
3695

3696
                            let def = DefLocal(pattern.id);
3697 3698 3699 3700 3701

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

3702
                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
3703 3704 3705 3706 3707 3708

                            // 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.)
3709 3710
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
3711 3712
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
3713
                                bindings_list.insert(renamed, pat_id);
3714 3715 3716 3717 3718
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
                                self.resolve_error(pattern.span,
J
Jorge Aparicio 已提交
3719
                                                   &format!("identifier `{}` \
3720 3721 3722 3723 3724 3725
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
J
Jorge Aparicio 已提交
3726
                                                   [])
3727
                            } else if bindings_list.get(&renamed) ==
3728 3729 3730 3731
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
                                self.resolve_error(pattern.span,
J
Jorge Aparicio 已提交
3732
                                    &format!("identifier `{}` is bound \
3733 3734
                                             more than once in the same \
                                             pattern",
J
Jorge Aparicio 已提交
3735
                                            token::get_ident(ident))[]);
3736
                            }
3737 3738
                            // Else, not bound in the same pattern: do
                            // nothing.
3739 3740 3741 3742
                        }
                    }
                }

3743
                PatEnum(ref path, _) => {
3744
                    // This must be an enum variant, struct or const.
A
Alex Crichton 已提交
3745
                    match self.resolve_path(pat_id, path, ValueNS, false) {
A
Alex Crichton 已提交
3746 3747
                        Some(def @ (DefVariant(..), _)) |
                        Some(def @ (DefStruct(..), _))  |
3748
                        Some(def @ (DefConst(..), _)) => {
3749 3750
                            self.record_def(pattern.id, def);
                        }
3751 3752 3753 3754 3755 3756
                        Some((DefStatic(..), _)) => {
                            self.resolve_error(path.span,
                                               "static variables cannot be \
                                                referenced in a pattern, \
                                                use a `const` instead");
                        }
3757
                        Some(_) => {
3758
                            self.resolve_error(path.span,
A
Alex Crichton 已提交
3759
                                format!("`{}` is not an enum variant, struct or const",
3760
                                    token::get_ident(
N
fallout  
Nick Cameron 已提交
3761
                                        path.segments.last().unwrap().identifier)).as_slice());
3762 3763
                        }
                        None => {
3764
                            self.resolve_error(path.span,
3765
                                format!("unresolved enum variant, struct or const `{}`",
3766
                                    token::get_ident(
N
fallout  
Nick Cameron 已提交
3767
                                        path.segments.last().unwrap().identifier)).as_slice());
3768 3769 3770 3771
                        }
                    }

                    // Check the types in the path pattern.
3772
                    for ty in path.segments
3773
                                  .iter()
3774
                                  .flat_map(|s| s.parameters.types().into_iter()) {
3775
                        self.resolve_type(&**ty);
3776 3777 3778
                    }
                }

3779 3780
                PatLit(ref expr) => {
                    self.resolve_expr(&**expr);
3781 3782
                }

3783 3784 3785
                PatRange(ref first_expr, ref last_expr) => {
                    self.resolve_expr(&**first_expr);
                    self.resolve_expr(&**last_expr);
3786 3787
                }

3788
                PatStruct(ref path, _, _) => {
A
Alex Crichton 已提交
3789
                    match self.resolve_path(pat_id, path, TypeNS, false) {
3790
                        Some(definition) => {
3791 3792
                            self.record_def(pattern.id, definition);
                        }
3793
                        result => {
3794
                            debug!("(resolving pattern) didn't find struct \
3795
                                    def: {:?}", result);
A
Alex Crichton 已提交
3796
                            let msg = format!("`{}` does not name a structure",
3797
                                              self.path_names_to_string(path));
J
Jorge Aparicio 已提交
3798
                            self.resolve_error(path.span, &msg[]);
3799 3800 3801 3802
                        }
                    }
                }

3803
                _ => {
3804 3805 3806
                    // Nothing to do.
                }
            }
3807
            true
3808
        });
3809 3810
    }

3811
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
3812 3813 3814
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3815
                                                 name,
3816
                                                 ValueNS) {
3817
            Success((target, _)) => {
3818
                debug!("(resolve bare identifier pattern) succeeded in \
3819
                         finding {} at {:?}",
3820
                        token::get_name(name),
E
Erick Tryzelaar 已提交
3821 3822
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
3823
                    None => {
S
Steve Klabnik 已提交
3824
                        panic!("resolved name in the value namespace to a \
3825
                              set of name bindings with no def?!");
3826
                    }
B
Brian Anderson 已提交
3827
                    Some(def) => {
3828 3829 3830
                        // 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.
3831
                        match def.def {
A
Alex Crichton 已提交
3832
                            def @ DefVariant(..) | def @ DefStruct(..) => {
3833
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
3834
                            }
3835
                            def @ DefConst(..) => {
3836
                                return FoundConst(def, LastMod(AllPublic));
3837
                            }
3838
                            DefStatic(..) => {
3839
                                self.resolve_error(span,
3840 3841 3842
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
3843 3844
                                return BareIdentifierPatternUnresolved;
                            }
3845
                            _ => {
3846
                                return BareIdentifierPatternUnresolved;
3847 3848
                            }
                        }
3849 3850 3851 3852
                    }
                }
            }

B
Brian Anderson 已提交
3853
            Indeterminate => {
S
Steve Klabnik 已提交
3854
                panic!("unexpected indeterminate result");
3855
            }
3856 3857 3858
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
J
Jorge Aparicio 已提交
3859 3860
                        self.resolve_error(span, &format!("failed to resolve: {}",
                                                         msg)[]);
3861 3862 3863
                    }
                    None => ()
                }
3864

3865
                debug!("(resolve bare identifier pattern) failed to find {}",
3866
                        token::get_name(name));
3867
                return BareIdentifierPatternUnresolved;
3868 3869 3870 3871
            }
        }
    }

3872 3873
    /// 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 已提交
3874
    fn resolve_path(&mut self,
3875 3876 3877 3878
                    id: NodeId,
                    path: &Path,
                    namespace: Namespace,
                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
3879
        // First, resolve the types and associated type bindings.
3880
        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
3881
            self.resolve_type(&**ty);
3882
        }
3883 3884 3885
        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
            self.resolve_type(&*binding.ty);
        }
3886

3887 3888 3889 3890 3891 3892 3893 3894 3895
        // 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 {
3896
                        DefTyParam(_, _, did, _) => {
3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914
                            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));
                        }
                        _ => {}
                    }
                }
                _ => {}
            }
        }

3915
        if path.global {
3916
            return self.resolve_crate_relative_path(path, namespace);
3917 3918
        }

3919
        // Try to find a path to an item in a module.
3920
        let unqualified_def =
A
Aaron Turon 已提交
3921
                self.resolve_identifier(path.segments.last().unwrap().identifier,
3922 3923 3924
                                        namespace,
                                        check_ribs,
                                        path.span);
3925

3926
        if path.segments.len() > 1 {
3927
            let def = self.resolve_module_relative_path(path, namespace);
3928
            match (def, unqualified_def) {
3929
                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
3930
                    self.session
A
Aaron Turon 已提交
3931
                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
3932 3933
                                  id,
                                  path.span,
3934
                                  "unnecessary qualification".to_string());
3935 3936 3937
                }
                _ => ()
            }
3938

3939
            return def;
3940 3941
        }

3942
        return unqualified_def;
3943 3944
    }

J
John Clements 已提交
3945
    // resolve a single identifier (used as a varref)
F
Felix S. Klock II 已提交
3946
    fn resolve_identifier(&mut self,
3947 3948 3949 3950 3951
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3952
        if check_ribs {
3953
            match self.resolve_identifier_in_local_ribs(identifier,
3954 3955
                                                        namespace,
                                                        span) {
B
Brian Anderson 已提交
3956
                Some(def) => {
3957
                    return Some((def, LastMod(AllPublic)));
3958
                }
B
Brian Anderson 已提交
3959
                None => {
3960 3961 3962 3963 3964
                    // Continue.
                }
            }
        }

3965
        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
3966 3967
    }

3968
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3969
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3970
                                            containing_module: Rc<Module>,
3971
                                            name: Name,
3972
                                            namespace: Namespace)
3973
                                            -> NameDefinition {
3974
        // First, search children.
3975
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3976

3977
        match containing_module.children.borrow().get(&name) {
3978 3979 3980 3981 3982 3983 3984
            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 {
3985
                            LastMod(DependsOn(def.def_id()))
3986 3987
                        };
                        return ChildNameDefinition(def, lp);
3988
                    }
3989
                    None => {}
3990 3991
                }
            }
3992
            None => {}
3993 3994 3995
        }

        // Next, search import resolutions.
3996
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3997
            Some(import_resolution) if import_resolution.is_public => {
3998 3999 4000 4001 4002 4003 4004
                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));
4005
                            self.record_import_use(id, name);
4006 4007 4008 4009 4010
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
4011
                            }
4012 4013 4014 4015 4016
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
4017 4018 4019 4020
                        }
                    }
                }
            }
A
Alex Crichton 已提交
4021
            Some(..) | None => {} // Continue.
4022 4023 4024 4025
        }

        // Finally, search through external children.
        if namespace == TypeNS {
4026 4027 4028 4029 4030 4031 4032 4033 4034
            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);
4035
                }
4036 4037
            }
        }
4038 4039

        return NoNameDefinition;
4040 4041
    }

4042
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
4043
    fn resolve_module_relative_path(&mut self,
4044 4045 4046
                                    path: &Path,
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
4047 4048 4049
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4050

4051
        let containing_module;
4052
        let last_private;
E
Eduard Burtescu 已提交
4053 4054
        let module = self.current_module.clone();
        match self.resolve_module_path(module,
J
Jorge Aparicio 已提交
4055
                                       &module_path[],
4056 4057
                                       UseLexicalScope,
                                       path.span,
4058
                                       PathSearch) {
4059 4060 4061 4062
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
4063 4064
                        let msg = format!("Use of undeclared type or module `{}`",
                                          self.names_to_string(module_path.as_slice()));
4065 4066 4067
                        (path.span, msg)
                    }
                };
4068

J
Jorge Aparicio 已提交
4069 4070
                self.resolve_error(span, &format!("failed to resolve. {}",
                                                 msg)[]);
4071
                return None;
4072
            }
S
Steve Klabnik 已提交
4073
            Indeterminate => panic!("indeterminate unexpected"),
4074
            Success((resulting_module, resulting_last_private)) => {
4075
                containing_module = resulting_module;
4076
                last_private = resulting_last_private;
4077 4078 4079
            }
        }

4080
        let name = path.segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
4081
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
4082
                                                                  name,
4083
                                                                  namespace) {
B
Brian Anderson 已提交
4084
            NoNameDefinition => {
4085
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4086
                return None;
4087
            }
4088 4089
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
4090
            }
4091
        };
4092 4093
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
4094
        }
4095
        return Some(def);
4096 4097
    }

4098 4099
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
4100
    fn resolve_crate_relative_path(&mut self,
4101 4102 4103
                                   path: &Path,
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
4104 4105 4106
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4107

4108
        let root_module = self.graph_root.get_module();
4109

4110
        let containing_module;
4111
        let last_private;
4112
        match self.resolve_module_path_from_root(root_module,
J
Jorge Aparicio 已提交
4113
                                                 &module_path[],
4114
                                                 0,
4115
                                                 path.span,
4116
                                                 PathSearch,
4117
                                                 LastMod(AllPublic)) {
4118 4119 4120 4121 4122
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
J
Jorge Aparicio 已提交
4123
                                          self.names_to_string(&module_path[]));
4124 4125 4126 4127
                        (path.span, msg)
                    }
                };

J
Jorge Aparicio 已提交
4128 4129
                self.resolve_error(span, &format!("failed to resolve. {}",
                                                 msg)[]);
B
Brian Anderson 已提交
4130
                return None;
4131 4132
            }

B
Brian Anderson 已提交
4133
            Indeterminate => {
S
Steve Klabnik 已提交
4134
                panic!("indeterminate unexpected");
4135 4136
            }

4137
            Success((resulting_module, resulting_last_private)) => {
4138
                containing_module = resulting_module;
4139
                last_private = resulting_last_private;
4140 4141 4142
            }
        }

4143
        let name = path.segments.last().unwrap().identifier.name;
4144
        match self.resolve_definition_of_name_in_module(containing_module,
4145
                                                        name,
4146
                                                        namespace) {
B
Brian Anderson 已提交
4147
            NoNameDefinition => {
4148
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4149
                return None;
4150
            }
4151 4152
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
4153 4154 4155 4156
            }
        }
    }

F
Felix S. Klock II 已提交
4157
    fn resolve_identifier_in_local_ribs(&mut self,
4158 4159 4160 4161
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
4162
        // Check the local set of ribs.
4163
        let search_result = match namespace {
B
Brian Anderson 已提交
4164
            ValueNS => {
4165
                let renamed = mtwt::resolve(ident);
4166
                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
4167
            }
B
Brian Anderson 已提交
4168
            TypeNS => {
4169
                let name = ident.name;
J
Jorge Aparicio 已提交
4170
                self.search_ribs(&self.type_ribs[], name, span)
4171
            }
4172
        };
4173

4174
        match search_result {
4175
            Some(DlDef(def)) => {
4176
                debug!("(resolving path in local ribs) resolved `{}` to \
4177
                        local: {:?}",
4178
                       token::get_ident(ident),
P
Paul Stansifer 已提交
4179
                       def);
B
Brian Anderson 已提交
4180
                return Some(def);
4181
            }
4182
            Some(DlField) | Some(DlImpl(_)) | None => {
B
Brian Anderson 已提交
4183
                return None;
4184 4185 4186 4187
            }
        }
    }

4188 4189 4190 4191
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
4192
        // Check the items.
E
Eduard Burtescu 已提交
4193 4194
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
4195
                                                 name,
4196
                                                 namespace) {
4197
            Success((target, _)) => {
4198
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
4199
                    None => {
4200 4201
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
4202
                        debug!("(resolving item path by identifier in lexical \
4203
                                 scope) failed to resolve {} after success...",
4204
                                 token::get_name(name));
4205
                        return None;
4206
                    }
B
Brian Anderson 已提交
4207
                    Some(def) => {
4208
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
4209
                                resolved `{}` to item",
4210
                               token::get_name(name));
4211 4212 4213
                        // 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.
4214
                        return Some((def, LastMod(AllPublic)));
4215 4216 4217
                    }
                }
            }
B
Brian Anderson 已提交
4218
            Indeterminate => {
S
Steve Klabnik 已提交
4219
                panic!("unexpected indeterminate result");
4220
            }
4221 4222 4223
            Failed(err) => {
                match err {
                    Some((span, msg)) =>
J
Jorge Aparicio 已提交
4224 4225
                        self.resolve_error(span, &format!("failed to resolve. {}",
                                                         msg)[]),
4226 4227 4228
                    None => ()
                }

4229
                debug!("(resolving item path by identifier in lexical scope) \
4230
                         failed to resolve {}", token::get_name(name));
B
Brian Anderson 已提交
4231
                return None;
4232 4233 4234 4235
            }
        }
    }

J
Jorge Aparicio 已提交
4236 4237 4238
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
4239
        self.emit_errors = false;
A
Alex Crichton 已提交
4240
        let rs = f(self);
4241 4242 4243 4244
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
4245
    fn resolve_error(&self, span: Span, s: &str) {
4246
        if self.emit_errors {
A
Alex Crichton 已提交
4247
            self.session.span_err(span, s);
4248 4249 4250
        }
    }

4251
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
4252 4253 4254
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
4255
                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
4256 4257
                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),
4258 4259 4260 4261 4262 4263 4264
                // 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,
            }
        }

4265
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
4266 4267
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
4268
            let last_name = name_path.last().unwrap();
4269

4270
            if name_path.len() == 1 {
4271
                match this.primitive_type_table.primitive_types.get(last_name) {
4272 4273
                    Some(_) => None,
                    None => {
4274
                        match this.current_module.children.borrow().get(last_name) {
4275 4276 4277 4278 4279 4280 4281
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
J
Jorge Aparicio 已提交
4282
                                                &name_path[],
4283 4284 4285 4286 4287 4288 4289 4290 4291
                                                UseLexicalScope,
                                                span,
                                                PathSearch) {
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

4292 4293 4294 4295
        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,
4296 4297 4298 4299
            },
            None => return NoSuggestion,
        };

4300 4301
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
4302
            match self.def_map.borrow().get(&node_id) {
4303
                 Some(&DefTy(did, _))
4304
                | Some(&DefStruct(did))
4305
                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
4306 4307 4308 4309 4310
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
4311
                    }
4312 4313 4314
                },
                _ => {} // Self type didn't resolve properly
            }
4315 4316
        }

4317
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
4318 4319

        // Look for a method in the current self type's impl module.
J
Jorge Aparicio 已提交
4320
        match get_module(self, path.span, &name_path[]) {
4321
            Some(module) => match module.children.borrow().get(&name) {
4322
                Some(binding) => {
4323
                    let p_str = self.path_names_to_string(&path);
4324
                    match binding.def_for_namespace(ValueNS) {
4325
                        Some(DefStaticMethod(_, provenance)) => {
4326 4327 4328 4329 4330
                            match provenance {
                                FromImpl(_) => return StaticMethod(p_str),
                                FromTrait(_) => unreachable!()
                            }
                        }
4331 4332
                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343
                        _ => ()
                    }
                }
                None => {}
            },
            None => {}
        }

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

4346
                match self.trait_item_map.get(&(name, did)) {
4347 4348 4349
                    Some(&StaticMethodTraitItemKind) => {
                        return TraitMethod(path_str)
                    }
4350
                    Some(_) => return TraitItem,
4351 4352 4353 4354 4355 4356 4357 4358 4359
                    None => {}
                }
            }
            None => {}
        }

        NoSuggestion
    }

4360
    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4361
                                -> Option<String> {
4362 4363
        let this = &mut *self;

4364 4365
        let mut maybes: Vec<token::InternedString> = Vec::new();
        let mut values: Vec<uint> = Vec::new();
4366

4367 4368
        for rib in this.value_ribs.iter().rev() {
            for (&k, _) in rib.bindings.iter() {
4369
                maybes.push(token::get_name(k));
C
Chris Wong 已提交
4370
                values.push(uint::MAX);
4371 4372 4373 4374
            }
        }

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

4378
            if values[i] <= values[smallest] {
4379 4380 4381 4382
                smallest = i;
            }
        }

Y
Youngmin Yoo 已提交
4383
        if values.len() > 0 &&
4384 4385 4386 4387
            values[smallest] != uint::MAX &&
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
            name != maybes[smallest].get() {
4388

4389
            Some(maybes[smallest].get().to_string())
4390 4391 4392 4393 4394 4395

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
4396
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
4397 4398
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
4399 4400 4401

        self.record_candidate_traits_for_expr_if_necessary(expr);

4402
        // Next, resolve the node.
4403
        match expr.node {
4404 4405 4406
            // The interpretation of paths depends on whether the path has
            // multiple elements in it or not.

4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419
            ExprPath(_) | ExprQPath(_) => {
                let mut path_from_qpath;
                let path = match expr.node {
                    ExprPath(ref path) => path,
                    ExprQPath(ref qpath) => {
                        self.resolve_type(&*qpath.self_type);
                        self.resolve_trait_reference(expr.id, &*qpath.trait_ref, TraitQPath);
                        path_from_qpath = qpath.trait_ref.path.clone();
                        path_from_qpath.segments.push(qpath.item_path.clone());
                        &path_from_qpath
                    }
                    _ => unreachable!()
                };
4420 4421
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
A
Alex Crichton 已提交
4422
                match self.resolve_path(expr.id, path, ValueNS, true) {
4423 4424
                    // Check if struct variant
                    Some((DefVariant(_, _, true), _)) => {
4425
                        let path_name = self.path_names_to_string(path);
4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436
                        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 已提交
4437
                    Some(def) => {
4438
                        // Write the result into the def map.
4439
                        debug!("(resolving expr) resolved `{}`",
4440
                               self.path_names_to_string(path));
4441

4442 4443
                        self.record_def(expr.id, def);
                    }
B
Brian Anderson 已提交
4444
                    None => {
A
Alex Crichton 已提交
4445 4446 4447 4448
                        // 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.)
4449
                        let path_name = self.path_names_to_string(path);
A
Alex Crichton 已提交
4450 4451
                        match self.with_no_errors(|this|
                            this.resolve_path(expr.id, path, TypeNS, false)) {
4452
                            Some((DefTy(struct_id, _), _))
4453 4454 4455 4456 4457
                              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",
4458
                                                path_name).as_slice());
4459

P
P1start 已提交
4460
                                self.session.span_help(expr.span,
4461 4462
                                    format!("Did you mean to write: \
                                            `{} {{ /* fields */ }}`?",
4463
                                            path_name).as_slice());
4464

4465
                            }
4466 4467
                            _ => {
                                let mut method_scope = false;
4468
                                self.value_ribs.iter().rev().all(|rib| {
4469 4470
                                    let res = match *rib {
                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
4471
                                        Rib { bindings: _, kind: ItemRibKind } => false,
4472 4473 4474 4475 4476 4477 4478
                                        _ => return true, // Keep advancing
                                    };

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

J
John Clements 已提交
4479
                                if method_scope && token::get_name(self.self_name).get()
4480
                                                                   == path_name {
4481 4482 4483 4484 4485
                                        self.resolve_error(
                                            expr.span,
                                            "`self` is not available \
                                             in a static method. Maybe a \
                                             `self` argument is missing?");
4486
                                } else {
4487 4488
                                    let last_name = path.segments.last().unwrap().identifier.name;
                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
4489 4490 4491
                                        NoSuggestion => {
                                            // limit search to 5 to reduce the number
                                            // of stupid suggestions
4492
                                            self.find_best_match_for_name(path_name.as_slice(), 5)
4493
                                                                .map_or("".to_string(),
4494 4495 4496
                                                                        |x| format!("`{}`", x))
                                        }
                                        Field =>
4497
                                            format!("`self.{}`", path_name),
4498
                                        Method
4499
                                        | TraitItem =>
4500
                                            format!("to call `self.{}`", path_name),
4501
                                        TraitMethod(path_str)
4502
                                        | StaticMethod(path_str) =>
4503
                                            format!("to call `{}::{}`", path_str, path_name)
4504 4505 4506
                                    };

                                    if msg.len() > 0 {
4507
                                        msg = format!(". Did you mean {}?", msg)
4508 4509
                                    }

4510 4511
                                    self.resolve_error(
                                        expr.span,
4512
                                        format!("unresolved name `{}`{}",
4513
                                                path_name,
4514
                                                msg).as_slice());
4515 4516
                                }
                            }
V
Vincent Belliard 已提交
4517
                        }
4518 4519 4520
                    }
                }

4521
                visit::walk_expr(self, expr);
4522 4523
            }

4524
            ExprClosure(_, _, ref fn_decl, ref block) => {
4525
                self.resolve_function(ClosureRibKind(expr.id),
4526 4527 4528
                                      Some(&**fn_decl), NoTypeParameters,
                                      &**block);
            }
4529

4530
            ExprStruct(ref path, _, _) => {
4531 4532 4533
                // 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 已提交
4534
                match self.resolve_path(expr.id, path, TypeNS, false) {
4535
                    Some(definition) => self.record_def(expr.id, definition),
S
Steven Fackler 已提交
4536
                    result => {
4537
                        debug!("(resolving expression) didn't find struct \
4538
                                def: {:?}", result);
A
Alex Crichton 已提交
4539
                        let msg = format!("`{}` does not name a structure",
4540
                                          self.path_names_to_string(path));
J
Jorge Aparicio 已提交
4541
                        self.resolve_error(path.span, &msg[]);
4542 4543 4544
                    }
                }

4545
                visit::walk_expr(self, expr);
4546 4547
            }

P
Pythoner6 已提交
4548
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
4549
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
4550
                    let def_like = DlDef(DefLabel(expr.id));
4551

4552
                    {
4553
                        let rib = this.label_ribs.last_mut().unwrap();
4554
                        let renamed = mtwt::resolve(label);
4555
                        rib.bindings.insert(renamed, def_like);
4556
                    }
4557

4558
                    visit::walk_expr(this, expr);
4559
                })
4560 4561
            }

4562
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
4563
                let renamed = mtwt::resolve(label);
4564
                match self.search_label(renamed) {
4565 4566 4567
                    None => {
                        self.resolve_error(
                            expr.span,
J
Jorge Aparicio 已提交
4568 4569
                            &format!("use of undeclared label `{}`",
                                    token::get_ident(label))[])
4570
                    }
4571
                    Some(DlDef(def @ DefLabel(_))) => {
4572 4573
                        // Since this def is a label, it is never read.
                        self.record_def(expr.id, (def, LastMod(AllPublic)))
4574 4575
                    }
                    Some(_) => {
4576
                        self.session.span_bug(expr.span,
4577 4578
                                              "label wasn't mapped to a \
                                               label def!")
4579 4580 4581 4582
                    }
                }
            }

B
Brian Anderson 已提交
4583
            _ => {
4584
                visit::walk_expr(self, expr);
4585 4586 4587 4588
            }
        }
    }

E
Eduard Burtescu 已提交
4589
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
4590
        match expr.node {
4591
            ExprField(_, ident) => {
4592 4593 4594 4595
                // 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.
4596
                let traits = self.search_for_traits_containing_method(ident.node.name);
4597
                self.trait_map.insert(expr.id, traits);
4598
            }
4599
            ExprMethodCall(ident, _, _) => {
4600
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
4601
                        traits for {}",
4602
                       expr.id);
4603
                let traits = self.search_for_traits_containing_method(ident.node.name);
4604
                self.trait_map.insert(expr.id, traits);
4605
            }
4606
            _ => {
4607 4608 4609 4610 4611
                // Nothing to do.
            }
        }
    }

E
Eduard Burtescu 已提交
4612
    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
4613
        debug!("(searching for traits containing method) looking for '{}'",
E
Eduard Burtescu 已提交
4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624
               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);
        }
4625

4626
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
4627
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
4628 4629
        loop {
            // Look for the current trait.
4630 4631
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
4632
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
4633
                        add_trait_info(&mut found_traits, trait_def_id, name);
4634 4635
                    }
                }
4636
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
4637
            }
4638

E
Eduard Burtescu 已提交
4639
            // Look for trait children.
4640
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
4641

E
Eduard Burtescu 已提交
4642
            {
E
Eduard Burtescu 已提交
4643
                for (_, child_names) in search_module.children.borrow().iter() {
4644 4645 4646 4647 4648 4649 4650 4651
                    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,
                    };
4652
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
4653
                        add_trait_info(&mut found_traits, trait_def_id, name);
4654 4655
                    }
                }
E
Eduard Burtescu 已提交
4656
            }
4657

E
Eduard Burtescu 已提交
4658
            // Look for imports.
E
Eduard Burtescu 已提交
4659
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
4660 4661 4662 4663 4664 4665 4666 4667
                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,
                };
4668
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
4669
                    add_trait_info(&mut found_traits, did, name);
4670 4671 4672 4673
                    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);
4674 4675
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
4676
                    }
4677
                }
E
Eduard Burtescu 已提交
4678
            }
4679

E
Eduard Burtescu 已提交
4680
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
4681 4682
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
4683
                    search_module = parent_module.upgrade().unwrap();
4684
                }
E
Eduard Burtescu 已提交
4685
            }
4686 4687
        }

E
Eduard Burtescu 已提交
4688
        found_traits
4689 4690
    }

4691
    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
4692
        debug!("(recording def) recording {:?} for {}, last private {:?}",
4693
                def, node_id, lp);
4694 4695
        assert!(match lp {LastImport{..} => false, _ => true},
                "Import should only be used for `use` directives");
4696
        self.last_private.insert(node_id, lp);
4697

4698
        match self.def_map.borrow_mut().entry(node_id) {
4699 4700 4701
            // Resolve appears to "resolve" the same ID multiple
            // times, so here is a sanity check it at least comes to
            // the same conclusion! - nmatsakis
4702
            Occupied(entry) => if def != *entry.get() {
4703
                self.session
J
Jorge Aparicio 已提交
4704
                    .bug(&format!("node_id {} resolved first to {:?} and \
4705
                                  then {:?}",
4706
                                 node_id,
4707
                                 *entry.get(),
J
Jorge Aparicio 已提交
4708
                                 def)[]);
4709
            },
4710
            Vacant(entry) => { entry.insert(def); },
4711
        }
4712 4713
    }

F
Felix S. Klock II 已提交
4714
    fn enforce_default_binding_mode(&mut self,
4715
                                        pat: &Pat,
4716
                                        pat_binding_mode: BindingMode,
4717
                                        descr: &str) {
4718
        match pat_binding_mode {
4719
            BindByValue(_) => {}
A
Alex Crichton 已提交
4720
            BindByRef(..) => {
4721
                self.resolve_error(pat.span,
J
Jorge Aparicio 已提交
4722
                                   &format!("cannot use `ref` binding mode \
4723
                                            with {}",
J
Jorge Aparicio 已提交
4724
                                           descr)[]);
4725 4726 4727 4728
            }
        }
    }

4729 4730 4731 4732 4733 4734 4735
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

4740
        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
E
Eduard Burtescu 已提交
4741 4742 4743
            match module.parent_link {
                NoParentLink => {}
                ModuleParentLink(ref module, name) => {
4744 4745
                    names.push(name);
                    collect_mod(names, &*module.upgrade().unwrap());
4746
                }
E
Eduard Burtescu 已提交
4747
                BlockParentLink(ref module, _) => {
J
John Clements 已提交
4748
                    // danger, shouldn't be ident?
4749 4750
                    names.push(special_idents::opaque.name);
                    collect_mod(names, &*module.upgrade().unwrap());
4751 4752 4753
                }
            }
        }
4754
        collect_mod(&mut names, module);
4755

4756
        if names.len() == 0 {
4757
            return "???".to_string();
4758
        }
J
Jorge Aparicio 已提交
4759 4760
        self.names_to_string(&names.into_iter().rev()
                                  .collect::<Vec<ast::Name>>()[])
4761 4762
    }

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

4767
        debug!("Children:");
4768
        build_reduced_graph::populate_module_if_necessary(self, &module_);
4769
        for (&name, _) in module_.children.borrow().iter() {
4770
            debug!("* {}", token::get_name(name));
4771 4772
        }

4773
        debug!("Import resolutions:");
4774
        let import_resolutions = module_.import_resolutions.borrow();
4775
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
4776
            let value_repr;
4777
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
4778
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4779
                Some(_) => {
R
Richo Healey 已提交
4780
                    value_repr = " value:?".to_string();
4781
                    // FIXME #4954
4782 4783 4784
                }
            }

N
Niko Matsakis 已提交
4785
            let type_repr;
4786
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
4787
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4788
                Some(_) => {
R
Richo Healey 已提交
4789
                    type_repr = " type:?".to_string();
4790
                    // FIXME #4954
4791 4792 4793
                }
            }

4794
            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
4795 4796 4797 4798
        }
    }
}

4799
pub struct CrateMap {
4800
    pub def_map: DefMap,
4801
    pub freevars: RefCell<FreevarMap>,
4802
    pub export_map: ExportMap,
4803 4804 4805
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
    pub last_private_map: LastPrivateMap,
4806 4807 4808
    pub glob_map: Option<GlobMap>
}

4809
#[derive(PartialEq,Copy)]
4810 4811 4812
pub enum MakeGlobMap {
    Yes,
    No
4813 4814
}

4815
/// Entry point to crate resolution.
4816 4817 4818 4819 4820 4821 4822
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);
4823

4824
    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
4825 4826 4827 4828 4829
    session.abort_if_errors();

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

4830
    record_exports::record(&mut resolver);
4831 4832 4833 4834 4835 4836 4837
    session.abort_if_errors();

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

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

4838
    CrateMap {
4839 4840
        def_map: resolver.def_map,
        freevars: resolver.freevars,
4841
        export_map: resolver.export_map,
4842 4843 4844
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
        last_private_map: resolver.last_private,
4845 4846 4847 4848 4849
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
4850
    }
4851
}