“5686a91914ac678ccb78220367daefe585a0d66a”上不存在“src/librustc_resolve/lib.rs”
lib.rs 196.2 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"]
B
Brian Anderson 已提交
12
#![unstable]
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/")]

A
Alex Crichton 已提交
20
#![feature(slicing_syntax)]
21
#![feature(rustc_diagnostic_macros)]
H
Huon Wilson 已提交
22
#![allow(unknown_features)] #![feature(int_uint)]
23
#![allow(unstable)]
24

A
Alex Crichton 已提交
25 26
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
27
#[macro_use] #[no_link] extern crate rustc_bitflags;
28 29 30

extern crate rustc;

S
Steven Fackler 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
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::*;

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

63
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
64
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
65
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
66
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
67
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
68 69 70 71
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};
72
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
73 74 75 76
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 已提交
77
use syntax::ast::{Ty, TyBool, TyChar, TyF32};
78
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
79
use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
80
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
81
use syntax::ast::{TypeImplItem};
P
Patrick Walton 已提交
82
use syntax::ast;
83
use syntax::ast_map;
84
use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
85
use syntax::attr::AttrMetaMethods;
86
use syntax::ext::mtwt;
87
use syntax::parse::token::{self, special_names, special_idents};
88
use syntax::codemap::{Span, Pos};
89
use syntax::owned_slice::OwnedSlice;
90
use syntax::visit::{self, Visitor};
91

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

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

104
#[derive(Copy)]
105
struct BindingInfo {
106
    span: Span,
107
    binding_mode: BindingMode,
108 109 110
}

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

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

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

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

143
impl NamespaceResult {
F
Felix S. Klock II 已提交
144
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
145
        match *self {
146 147 148 149
            UnknownResult => true,
            _ => false
        }
    }
150 151 152 153 154 155
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
            _ => false
        }
    }
156 157
}

F
Felix S. Klock II 已提交
158
enum NameDefinition {
159
    NoNameDefinition,           //< The name was unbound.
160 161
    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
162 163
}

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

185
/// Contains data for specific types of import directives.
186
#[derive(Copy,Show)]
F
Felix S. Klock II 已提交
187
enum ImportDirectiveSubclass {
188
    SingleImport(Name /* target */, Name /* source */),
189 190 191
    GlobImport
}

192 193
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
194
enum ResolveResult<T> {
195 196 197
    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.
198 199
}

200
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
201
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
202
        match *self { Indeterminate => true, _ => false }
203 204 205
    }
}

206 207 208 209
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
210
    TraitItem,
211
    StaticMethod(String),
212
    TraitMethod(String),
213 214
}

215
#[derive(Copy)]
E
Erik Price 已提交
216
enum TypeParameters<'a> {
217 218 219 220 221 222 223 224 225 226 227 228 229 230
    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)
231 232
}

233 234
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
235
#[derive(Copy, Show)]
F
Felix S. Klock II 已提交
236
enum RibKind {
237 238
    // No translation needs to be applied.
    NormalRibKind,
239

240 241
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
242
    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
243

244
    // We passed through an impl or trait and are now in one of its
245
    // methods. Allow references to ty params that impl or trait
246 247 248
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
              // parent;   method itself
249
    MethodRibKind(NodeId, MethodSort),
250

251 252
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
253 254 255

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

258
// Methods can be required or provided. RequiredMethod methods only occur in traits.
259
#[derive(Copy, Show)]
F
Felix S. Klock II 已提交
260
enum MethodSort {
261 262
    RequiredMethod,
    ProvidedMethod(NodeId)
263 264
}

265
#[derive(Copy)]
F
Felix S. Klock II 已提交
266
enum UseLexicalScopeFlag {
267 268 269 270
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
271
enum ModulePrefixResult {
272
    NoPrefixFound,
E
Eduard Burtescu 已提交
273
    PrefixFound(Rc<Module>, uint)
274 275
}

276
#[derive(Copy, PartialEq)]
277
enum NameSearchType {
278 279 280 281
    /// 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
282 283
    /// expression, or a path pattern.
    PathSearch,
284 285
}

286
#[derive(Copy)]
F
Felix S. Klock II 已提交
287
enum BareIdentifierPatternResolution {
288 289
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
290
    BareIdentifierPatternUnresolved
291 292
}

293
/// One local scope.
294
#[derive(Show)]
F
Felix S. Klock II 已提交
295
struct Rib {
296
    bindings: HashMap<Name, DefLike>,
297
    kind: RibKind,
B
Brian Anderson 已提交
298
}
299

300
impl Rib {
F
Felix S. Klock II 已提交
301
    fn new(kind: RibKind) -> Rib {
302
        Rib {
303
            bindings: HashMap::new(),
304 305
            kind: kind
        }
306 307 308
    }
}

309
/// Whether an import can be shadowed by another import.
310
#[derive(Show,PartialEq,Clone,Copy)]
311 312 313 314 315
enum Shadowable {
    Always,
    Never
}

316
/// One import directive.
317
#[derive(Show)]
F
Felix S. Klock II 已提交
318
struct ImportDirective {
319
    module_path: Vec<Name>,
E
Eduard Burtescu 已提交
320
    subclass: ImportDirectiveSubclass,
321
    span: Span,
322
    id: NodeId,
323
    is_public: bool, // see note in ImportResolution about how to use this
324
    shadowable: Shadowable,
B
Brian Anderson 已提交
325
}
326

327
impl ImportDirective {
328
    fn new(module_path: Vec<Name> ,
E
Eduard Burtescu 已提交
329
           subclass: ImportDirectiveSubclass,
330 331
           span: Span,
           id: NodeId,
332
           is_public: bool,
333
           shadowable: Shadowable)
334
           -> ImportDirective {
335 336 337 338
        ImportDirective {
            module_path: module_path,
            subclass: subclass,
            span: span,
339 340
            id: id,
            is_public: is_public,
341
            shadowable: shadowable,
342
        }
343 344 345
    }
}

346
/// The item that an import resolves to.
347
#[derive(Clone,Show)]
F
Felix S. Klock II 已提交
348
struct Target {
E
Eduard Burtescu 已提交
349 350
    target_module: Rc<Module>,
    bindings: Rc<NameBindings>,
351
    shadowable: Shadowable,
B
Brian Anderson 已提交
352
}
353

354
impl Target {
355 356
    fn new(target_module: Rc<Module>,
           bindings: Rc<NameBindings>,
357
           shadowable: Shadowable)
358
           -> Target {
359 360
        Target {
            target_module: target_module,
361 362
            bindings: bindings,
            shadowable: shadowable,
363
        }
364 365 366
    }
}

T
Tim Chevalier 已提交
367
/// An ImportResolution represents a particular `use` directive.
368
#[derive(Show)]
F
Felix S. Klock II 已提交
369
struct ImportResolution {
370 371 372 373
    /// 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 已提交
374
    is_public: bool,
375

376 377 378
    // 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 已提交
379
    outstanding_references: uint,
380

T
Tim Chevalier 已提交
381
    /// The value that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
382
    value_target: Option<Target>,
383 384
    /// The source node of the `use` directive leading to the value target
    /// being non-none
E
Eduard Burtescu 已提交
385
    value_id: NodeId,
386

T
Tim Chevalier 已提交
387
    /// The type that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
388
    type_target: Option<Target>,
389 390
    /// The source node of the `use` directive leading to the type target
    /// being non-none
E
Eduard Burtescu 已提交
391
    type_id: NodeId,
E
Erick Tryzelaar 已提交
392 393
}

394
impl ImportResolution {
395
    fn new(id: NodeId, is_public: bool) -> ImportResolution {
396
        ImportResolution {
E
Eduard Burtescu 已提交
397 398 399 400 401 402
            type_id: id,
            value_id: id,
            outstanding_references: 0,
            value_target: None,
            type_target: None,
            is_public: is_public,
403
        }
B
Brian Anderson 已提交
404 405
    }

F
Felix S. Klock II 已提交
406
    fn target_for_namespace(&self, namespace: Namespace)
407
                                -> Option<Target> {
408
        match namespace {
E
Eduard Burtescu 已提交
409 410
            TypeNS  => self.type_target.clone(),
            ValueNS => self.value_target.clone(),
411 412
        }
    }
413

414
    fn id(&self, namespace: Namespace) -> NodeId {
415
        match namespace {
E
Eduard Burtescu 已提交
416 417
            TypeNS  => self.type_id,
            ValueNS => self.value_id,
418 419
        }
    }
420 421 422 423 424 425 426 427 428

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

        target.unwrap().shadowable
    }
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444

    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;
            }
        }
    }
445 446
}

447
/// The link from a module up to its nearest parent node.
448
#[derive(Clone,Show)]
F
Felix S. Klock II 已提交
449
enum ParentLink {
450
    NoParentLink,
451
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
452
    BlockParentLink(Weak<Module>, NodeId)
453 454
}

455
/// The type of module this is.
456
#[derive(Copy, PartialEq, Show)]
F
Felix S. Klock II 已提交
457
enum ModuleKind {
458 459
    NormalModuleKind,
    TraitModuleKind,
460
    ImplModuleKind,
461
    EnumModuleKind,
462
    TypeModuleKind,
463 464 465
    AnonymousModuleKind,
}

466
/// One node in the tree of modules.
F
Felix S. Klock II 已提交
467
struct Module {
468
    parent_link: ParentLink,
469
    def_id: Cell<Option<DefId>>,
470
    kind: Cell<ModuleKind>,
471
    is_public: bool,
472

E
Eduard Burtescu 已提交
473 474
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
475

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

480 481 482 483 484 485 486 487 488 489 490 491 492 493
    // 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 已提交
494
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
495 496

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

    // The number of unresolved globs that this module exports.
500
    glob_count: Cell<uint>,
501 502

    // The index of the import we're resolving.
503
    resolved_import_count: Cell<uint>,
504 505 506 507

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

511
impl Module {
F
Felix S. Klock II 已提交
512
    fn new(parent_link: ParentLink,
513 514 515 516
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
517
           -> Module {
518 519
        Module {
            parent_link: parent_link,
520
            def_id: Cell::new(def_id),
521
            kind: Cell::new(kind),
522
            is_public: is_public,
523
            children: RefCell::new(HashMap::new()),
524
            imports: RefCell::new(Vec::new()),
525
            external_module_children: RefCell::new(HashMap::new()),
526
            anonymous_children: RefCell::new(NodeMap()),
527
            import_resolutions: RefCell::new(HashMap::new()),
528
            glob_count: Cell::new(0),
529
            resolved_import_count: Cell::new(0),
530
            populated: Cell::new(!external),
531
        }
B
Brian Anderson 已提交
532 533
    }

F
Felix S. Klock II 已提交
534
    fn all_imports_resolved(&self) -> bool {
535
        self.imports.borrow().len() == self.resolved_import_count.get()
536 537 538
    }
}

539 540
impl fmt::Show for Module {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
541
        write!(f, "{:?}, kind: {:?}, {}",
542 543 544 545 546 547
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

548
bitflags! {
549
    #[derive(Show)]
550 551 552 553 554 555
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

556
// Records a possibly-private type definition.
557
#[derive(Clone,Show)]
F
Felix S. Klock II 已提交
558
struct TypeNsDef {
559
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
560
    module_def: Option<Rc<Module>>,
561
    type_def: Option<Def>,
562
    type_span: Option<Span>
563 564 565
}

// Records a possibly-private value definition.
566
#[derive(Clone, Copy, Show)]
F
Felix S. Klock II 已提交
567
struct ValueNsDef {
568
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
569
    def: Def,
570
    value_span: Option<Span>,
571 572
}

573 574
// Records the definitions (at most one for each namespace) that a name is
// bound to.
575
#[derive(Show)]
F
Felix S. Klock II 已提交
576
struct NameBindings {
577
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
578
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
579 580
}

581
/// Ways in which a trait can be referenced
582
#[derive(Copy)]
583 584 585 586
enum TraitReferenceType {
    TraitImplementation,             // impl SomeTrait for T { ... }
    TraitDerivation,                 // trait T : SomeTrait { ... }
    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
N
Niko Matsakis 已提交
587
    TraitObject,                     // Box<for<'a> SomeTrait>
588
    TraitQPath,                      // <T as SomeTrait>::
589 590
}

591
impl NameBindings {
K
Kevin Butler 已提交
592 593 594 595 596 597 598
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

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

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

680
    /// Records a type definition.
681
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
682
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
683
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
684 685
        let type_def = self.type_def.borrow().clone();
        match type_def {
686
            None => {
E
Erick Tryzelaar 已提交
687
                *self.type_def.borrow_mut() = Some(TypeNsDef {
688
                    module_def: None,
689
                    type_def: Some(def),
690
                    type_span: Some(sp),
691
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
692
                });
693
            }
694
            Some(type_def) => {
E
Erick Tryzelaar 已提交
695
                *self.type_def.borrow_mut() = Some(TypeNsDef {
696
                    module_def: type_def.module_def,
697
                    type_def: Some(def),
698
                    type_span: Some(sp),
699
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
700
                });
701 702
            }
        }
703 704
    }

705
    /// Records a value definition.
706
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
707
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
708
        *self.value_def.borrow_mut() = Some(ValueNsDef {
709 710
            def: def,
            value_span: Some(sp),
711
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
712
        });
713 714
    }

715
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
716
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
717
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
718
            Some(ref type_def) => type_def.module_def.clone(),
719
            None => None
720 721 722
        }
    }

S
Steve Klabnik 已提交
723 724
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
725
    fn get_module(&self) -> Rc<Module> {
726 727
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
728
                panic!("get_module called on a node with no module \
729
                       definition!")
730
            }
731
            Some(module_def) => module_def
732 733 734
        }
    }

F
Felix S. Klock II 已提交
735
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
736
        match namespace {
E
Erick Tryzelaar 已提交
737 738
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
739 740 741
        }
    }

F
Felix S. Klock II 已提交
742
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
743 744 745 746
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
747
        match namespace {
E
Erick Tryzelaar 已提交
748
            TypeNS => match *self.type_def.borrow() {
749
                Some(ref def) => def.modifiers.contains(modifiers), None => false
750
            },
E
Erick Tryzelaar 已提交
751
            ValueNS => match *self.value_def.borrow() {
752
                Some(ref def) => def.modifiers.contains(modifiers), None => false
753 754 755 756
            }
        }
    }

F
Felix S. Klock II 已提交
757
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
758
        match namespace {
759
            TypeNS => {
E
Erick Tryzelaar 已提交
760
                match *self.type_def.borrow() {
761
                    None => None,
E
Eduard Burtescu 已提交
762
                    Some(ref type_def) => {
763
                        match type_def.type_def {
764
                            Some(type_def) => Some(type_def),
765 766
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
767
                                    Some(ref module) => {
768
                                        match module.def_id.get() {
769
                                            Some(did) => Some(DefMod(did)),
770 771 772 773 774 775
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
776
                        }
777 778
                    }
                }
779 780
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
781
                match *self.value_def.borrow() {
782 783 784 785 786 787 788
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
789
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
790
        if self.defined_in_namespace(namespace) {
791
            match namespace {
792
                TypeNS  => {
E
Erick Tryzelaar 已提交
793
                    match *self.type_def.borrow() {
794
                        None => None,
E
Eduard Burtescu 已提交
795
                        Some(ref type_def) => type_def.type_span
796 797 798
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
799
                    match *self.value_def.borrow() {
800
                        None => None,
E
Eduard Burtescu 已提交
801
                        Some(ref value_def) => value_def.value_span
802 803
                    }
                }
804
            }
805 806
        } else {
            None
807 808
        }
    }
809 810
}

811
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
812
struct PrimitiveTypeTable {
813
    primitive_types: HashMap<Name, PrimTy>,
814
}
815

816
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
817 818 819 820 821 822 823 824 825
    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));
826 827
        table.intern("int",     TyInt(TyIs(true)));
        table.intern("isize",   TyInt(TyIs(false)));
K
Kevin Butler 已提交
828 829 830 831 832
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
833 834
        table.intern("uint",    TyUint(TyUs(true)));
        table.intern("usize",   TyUint(TyUs(false)));
K
Kevin Butler 已提交
835 836 837 838 839 840 841 842
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

843
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
844
        self.primitive_types.insert(token::intern(string), primitive_type);
845 846 847
    }
}

848
/// The main resolver class.
849
struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
850
    session: &'a Session,
851

852 853
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
854
    graph_root: NameBindings,
855

856
    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
857

858
    structs: FnvHashMap<DefId, Vec<Name>>,
859

860
    // The number of imports that are currently unresolved.
861
    unresolved_imports: uint,
862 863

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
864
    current_module: Rc<Module>,
865 866

    // The current set of local scopes, for values.
867
    // FIXME #4948: Reuse ribs to avoid allocation.
868
    value_ribs: Vec<Rib>,
869 870

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

873
    // The current set of local scopes, for labels.
874
    label_ribs: Vec<Rib>,
875

876
    // The trait that the current context can refer to.
877 878 879 880
    current_trait_ref: Option<(DefId, TraitRef)>,

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

882
    // The ident for the keyword "self".
J
John Clements 已提交
883
    self_name: Name,
884
    // The ident for the non-keyword "Self".
J
John Clements 已提交
885
    type_self_name: Name,
886

887
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
888
    primitive_type_table: PrimitiveTypeTable,
889

890
    def_map: DefMap,
891 892
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
893
    capture_mode_map: CaptureModeMap,
894
    export_map: ExportMap,
895
    trait_map: TraitMap,
896 897
    external_exports: ExternalExports,
    last_private: LastPrivateMap,
898

899 900 901 902 903
    // 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,

904 905 906 907 908
    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,

909
    used_imports: HashSet<(NodeId, Namespace)>,
910
    used_crates: HashSet<CrateNum>,
911 912
}

913
#[derive(PartialEq)]
S
Steven Fackler 已提交
914 915 916 917 918 919
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}


920 921 922 923 924
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 已提交
925 926 927 928 929 930 931 932 933 934 935 936 937 938
        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,

939 940
            ast_map: ast_map,

K
Kevin Butler 已提交
941 942 943 944 945
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

946 947
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
948 949 950 951

            unresolved_imports: 0,

            current_module: current_module,
952 953 954
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
955 956 957 958

            current_trait_ref: None,
            current_self_type: None,

J
John Clements 已提交
959 960
            self_name: special_names::self_,
            type_self_name: special_names::type_self,
K
Kevin Butler 已提交
961 962 963

            primitive_type_table: PrimitiveTypeTable::new(),

964 965 966 967 968 969
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            capture_mode_map: NodeMap(),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
970
            used_imports: HashSet::new(),
971
            used_crates: HashSet::new(),
972 973
            external_exports: DefIdSet(),
            last_private: NodeMap(),
K
Kevin Butler 已提交
974 975

            emit_errors: true,
976 977
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
978 979
        }
    }
980 981 982 983 984 985 986 987 988

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

989 990
    /// Resolves all imports for the crate. This method performs the fixed-
    /// point iteration.
F
Felix S. Klock II 已提交
991
    fn resolve_imports(&mut self) {
992
        let mut i = 0u;
T
Tim Chevalier 已提交
993
        let mut prev_unresolved_imports = 0;
994
        loop {
995
            debug!("(resolving imports) iteration {}, {} imports left",
P
Paul Stansifer 已提交
996
                   i, self.unresolved_imports);
997

998
            let module_root = self.graph_root.get_module();
E
Eduard Burtescu 已提交
999
            self.resolve_imports_for_module_subtree(module_root.clone());
1000

T
Tim Chevalier 已提交
1001
            if self.unresolved_imports == 0 {
1002
                debug!("(resolving imports) success");
1003 1004 1005 1006 1007 1008 1009 1010
                break;
            }

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

T
Tim Chevalier 已提交
1011
            i += 1;
1012 1013 1014 1015
            prev_unresolved_imports = self.unresolved_imports;
        }
    }

1016 1017
    /// Attempts to resolve imports for the given module and all of its
    /// submodules.
E
Eduard Burtescu 已提交
1018
    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
1019
        debug!("(resolving imports for module subtree) resolving {}",
1020
               self.module_to_string(&*module_));
1021
        let orig_module = replace(&mut self.current_module, module_.clone());
E
Eduard Burtescu 已提交
1022
        self.resolve_imports_for_module(module_.clone());
1023
        self.current_module = orig_module;
1024

1025
        build_reduced_graph::populate_module_if_necessary(self, &module_);
E
Eduard Burtescu 已提交
1026
        for (_, child_node) in module_.children.borrow().iter() {
1027 1028 1029 1030 1031 1032
            match child_node.get_module_if_available() {
                None => {
                    // Nothing to do.
                }
                Some(child_module) => {
                    self.resolve_imports_for_module_subtree(child_module);
1033 1034 1035 1036
                }
            }
        }

E
Eduard Burtescu 已提交
1037 1038
        for (_, child_module) in module_.anonymous_children.borrow().iter() {
            self.resolve_imports_for_module_subtree(child_module.clone());
1039 1040 1041
        }
    }

1042
    /// Attempts to resolve imports for the given module only.
E
Eduard Burtescu 已提交
1043
    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
1044
        if module.all_imports_resolved() {
1045
            debug!("(resolving imports for module) all imports resolved for \
A
Alex Crichton 已提交
1046
                   {}",
1047
                   self.module_to_string(&*module));
B
Brian Anderson 已提交
1048
            return;
1049 1050
        }

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

1074 1075
            module.resolved_import_count
                  .set(module.resolved_import_count.get() + 1);
1076 1077 1078
        }
    }

1079
    fn names_to_string(&self, names: &[Name]) -> String {
1080
        let mut first = true;
1081
        let mut result = String::new();
1082
        for name in names.iter() {
1083 1084 1085 1086 1087
            if first {
                first = false
            } else {
                result.push_str("::")
            }
1088
            result.push_str(token::get_name(*name).get());
1089
        };
1090
        result
P
Paul Stansifer 已提交
1091
    }
1092

1093 1094 1095 1096 1097
    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 已提交
1098
        self.names_to_string(&names[])
1099 1100
    }

1101
    fn import_directive_subclass_to_string(&mut self,
P
Patrick Walton 已提交
1102
                                        subclass: ImportDirectiveSubclass)
1103
                                        -> String {
1104
        match subclass {
1105
            SingleImport(_, source) => {
1106
                token::get_name(source).get().to_string()
P
Patrick Walton 已提交
1107
            }
1108
            GlobImport => "*".to_string()
1109 1110
        }
    }
1111

1112
    fn import_path_to_string(&mut self,
1113
                          names: &[Name],
P
Patrick Walton 已提交
1114
                          subclass: ImportDirectiveSubclass)
1115
                          -> String {
1116
        if names.is_empty() {
1117
            self.import_directive_subclass_to_string(subclass)
1118
        } else {
A
Alex Crichton 已提交
1119
            (format!("{}::{}",
1120
                     self.names_to_string(names),
1121
                     self.import_directive_subclass_to_string(
1122
                         subclass))).to_string()
1123 1124
        }
    }
1125

1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141
    #[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 {
1142
        if did.krate == ast::LOCAL_CRATE {
1143 1144 1145 1146 1147 1148
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

1149 1150 1151 1152 1153
    /// 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 已提交
1154
    fn resolve_import_for_module(&mut self,
E
Eduard Burtescu 已提交
1155 1156
                                 module_: Rc<Module>,
                                 import_directive: &ImportDirective)
1157
                                 -> ResolveResult<()> {
1158
        let mut resolution_result = Failed(None);
A
Alex Crichton 已提交
1159
        let module_path = &import_directive.module_path;
1160

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

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

1187
        match container {
1188
            None => {}
1189
            Some((containing_module, lp)) => {
1190 1191 1192
                // We found the module that the target is contained
                // within. Attempt to resolve the import within it.

E
Eduard Burtescu 已提交
1193
                match import_directive.subclass {
1194
                    SingleImport(target, source) => {
1195
                        resolution_result =
E
Eduard Burtescu 已提交
1196
                            self.resolve_single_import(&*module_,
1197 1198
                                                       containing_module,
                                                       target,
1199
                                                       source,
1200 1201
                                                       import_directive,
                                                       lp);
1202 1203 1204
                    }
                    GlobImport => {
                        resolution_result =
E
Eduard Burtescu 已提交
1205
                            self.resolve_glob_import(&*module_,
1206
                                                     containing_module,
1207
                                                     import_directive,
1208
                                                     lp);
1209 1210 1211 1212 1213 1214
                    }
                }
            }
        }

        // Decrement the count of unresolved imports.
1215
        match resolution_result {
B
Brian Anderson 已提交
1216
            Success(()) => {
P
Patrick Walton 已提交
1217
                assert!(self.unresolved_imports >= 1);
T
Tim Chevalier 已提交
1218
                self.unresolved_imports -= 1;
1219
            }
B
Brian Anderson 已提交
1220
            _ => {
1221 1222 1223 1224 1225 1226 1227 1228 1229
                // 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.)

1230
        if !resolution_result.indeterminate() {
E
Eduard Burtescu 已提交
1231
            match import_directive.subclass {
B
Brian Anderson 已提交
1232
                GlobImport => {
1233 1234
                    assert!(module_.glob_count.get() >= 1);
                    module_.glob_count.set(module_.glob_count.get() - 1);
1235
                }
A
Alex Crichton 已提交
1236
                SingleImport(..) => {
1237 1238 1239 1240 1241
                    // Ignore.
                }
            }
        }

B
Brian Anderson 已提交
1242
        return resolution_result;
1243 1244
    }

E
Eduard Burtescu 已提交
1245
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1246
        NameBindings {
1247
            type_def: RefCell::new(Some(TypeNsDef {
1248
                modifiers: IMPORTABLE,
1249 1250
                module_def: Some(module),
                type_def: None,
1251
                type_span: None
1252
            })),
1253
            value_def: RefCell::new(None),
1254 1255 1256
        }
    }

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

1274 1275
        let lp = match lp {
            LastMod(lp) => lp,
1276 1277 1278 1279 1280
            LastImport {..} => {
                self.session
                    .span_bug(directive.span,
                              "not expecting Import here, must be LastMod")
            }
1281 1282
        };

1283
        // We need to resolve both namespaces for this to succeed.
1284 1285 1286 1287 1288 1289
        //

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

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

1292
        match containing_module.children.borrow().get(&source) {
1293 1294 1295
            None => {
                // Continue.
            }
E
Eduard Burtescu 已提交
1296
            Some(ref child_name_bindings) => {
1297
                if child_name_bindings.defined_in_namespace(ValueNS) {
1298
                    debug!("(resolving single import) found value binding");
E
Eduard Burtescu 已提交
1299 1300
                    value_result = BoundResult(containing_module.clone(),
                                               (*child_name_bindings).clone());
1301
                }
1302
                if child_name_bindings.defined_in_namespace(TypeNS) {
1303
                    debug!("(resolving single import) found type binding");
E
Eduard Burtescu 已提交
1304 1305
                    type_result = BoundResult(containing_module.clone(),
                                              (*child_name_bindings).clone());
1306 1307 1308 1309
                }
            }
        }

1310 1311
        // Unless we managed to find a result in both namespaces (unlikely),
        // search imports as well.
1312 1313
        let mut value_used_reexport = false;
        let mut type_used_reexport = false;
E
Eduard Burtescu 已提交
1314
        match (value_result.clone(), type_result.clone()) {
A
Alex Crichton 已提交
1315
            (BoundResult(..), BoundResult(..)) => {} // Continue.
B
Brian Anderson 已提交
1316
            _ => {
1317 1318 1319 1320
                // 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.

1321
                if containing_module.glob_count.get() > 0 {
1322
                    debug!("(resolving single import) unresolved glob; \
P
Paul Stansifer 已提交
1323
                            bailing out");
B
Brian Anderson 已提交
1324
                    return Indeterminate;
1325 1326
                }

E
Eduard Burtescu 已提交
1327
                // Now search the exported imports within the containing module.
1328
                match containing_module.import_resolutions.borrow().get(&source) {
B
Brian Anderson 已提交
1329
                    None => {
1330
                        debug!("(resolving single import) no import");
1331 1332 1333 1334 1335
                        // 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.

1336
                        if value_result.is_unknown() {
1337 1338
                            value_result = UnboundResult;
                        }
1339
                        if type_result.is_unknown() {
1340 1341 1342
                            type_result = UnboundResult;
                        }
                    }
B
Brian Anderson 已提交
1343
                    Some(import_resolution)
E
Eduard Burtescu 已提交
1344
                            if import_resolution.outstanding_references == 0 => {
1345

A
Alex Crichton 已提交
1346
                        fn get_binding(this: &mut Resolver,
E
Eduard Burtescu 已提交
1347
                                       import_resolution: &ImportResolution,
1348 1349
                                       namespace: Namespace,
                                       source: &Name)
1350
                                    -> NamespaceResult {
T
Tim Chevalier 已提交
1351

1352 1353
                            // Import resolutions must be declared with "pub"
                            // in order to be exported.
E
Eduard Burtescu 已提交
1354
                            if !import_resolution.is_public {
1355 1356 1357
                                return UnboundResult;
                            }

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

                        // The name is an import which has been fully
                        // resolved. We can, therefore, just follow it.
1387
                        if value_result.is_unknown() {
1388 1389 1390 1391
                            value_result = get_binding(self,
                                                       import_resolution,
                                                       ValueNS,
                                                       &source);
E
Eduard Burtescu 已提交
1392
                            value_used_reexport = import_resolution.is_public;
1393
                        }
1394
                        if type_result.is_unknown() {
1395 1396 1397 1398
                            type_result = get_binding(self,
                                                      import_resolution,
                                                      TypeNS,
                                                      &source);
E
Eduard Burtescu 已提交
1399
                            type_used_reexport = import_resolution.is_public;
1400
                        }
1401

1402
                    }
B
Brian Anderson 已提交
1403
                    Some(_) => {
1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
                        // 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;
                            }
                        }
1432 1433 1434 1435 1436
                    }
                }
            }
        }

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

1466
        // We've successfully resolved the import. Write the results in.
E
Eduard Burtescu 已提交
1467
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1468
        let import_resolution = &mut (*import_resolutions)[target];
1469
        {
1470
            let mut check_and_write_import = |&mut: namespace, result: &_, used_public: &mut bool| {
1471 1472 1473 1474
                let namespace_name = match namespace {
                    TypeNS => "type",
                    ValueNS => "value",
                };
1475

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

1510 1511 1512 1513
        self.check_for_conflicts_between_imports_and_items(
            module_,
            import_resolution,
            directive.span,
1514
            target);
1515

1516
        if value_result.is_unbound() && type_result.is_unbound() {
1517
            let msg = format!("There is no `{}` in `{}`",
1518
                              token::get_name(source),
1519
                              self.module_to_string(&*containing_module));
1520
            return Failed(Some((directive.span, msg)));
1521
        }
1522 1523
        let value_used_public = value_used_reexport || value_used_public;
        let type_used_public = type_used_reexport || type_used_public;
1524

E
Eduard Burtescu 已提交
1525 1526
        assert!(import_resolution.outstanding_references >= 1);
        import_resolution.outstanding_references -= 1;
1527

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

1557
        debug!("(resolving single import) successfully resolved import");
B
Brian Anderson 已提交
1558
        return Success(());
1559 1560
    }

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

1574 1575 1576
        // This function works in a highly imperative manner; it eagerly adds
        // everything it can to the list of import resolutions of the module
        // node.
1577
        debug!("(resolving glob import) resolving glob import {}", id);
1578 1579 1580 1581

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

1587
        assert_eq!(containing_module.glob_count.get(), 0);
1588 1589

        // Add all resolved imports from the containing module.
1590
        let import_resolutions = containing_module.import_resolutions.borrow();
1591
        for (ident, target_import_resolution) in import_resolutions.iter() {
1592
            debug!("(resolving glob import) writing module resolution \
L
Luqman Aden 已提交
1593
                    {} into `{}`",
1594
                   token::get_name(*ident),
1595
                   self.module_to_string(module_));
1596

E
Eduard Burtescu 已提交
1597
            if !target_import_resolution.is_public {
1598
                debug!("(resolving glob import) nevermind, just kidding");
1599 1600 1601
                continue
            }

1602
            // Here we merge two import resolutions.
1603
            let mut import_resolutions = module_.import_resolutions.borrow_mut();
1604
            match import_resolutions.get_mut(ident) {
E
Eduard Burtescu 已提交
1605
                Some(dest_import_resolution) => {
1606 1607 1608
                    // Merge the two import resolutions at a finer-grained
                    // level.

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

            // 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);
1647 1648
        }

1649
        // Add all children from the containing module.
1650
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
1651

1652
        for (&name, name_bindings) in containing_module.children.borrow().iter() {
1653 1654 1655 1656 1657 1658
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings.clone());

1659 1660 1661
        }

        // Add external module children from the containing module.
1662
        for (&name, module) in containing_module.external_module_children.borrow().iter() {
1663
            let name_bindings =
E
Eduard Burtescu 已提交
1664
                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
1665 1666 1667 1668 1669
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings);
1670 1671
        }

A
Alex Crichton 已提交
1672
        // Record the destination of this import
1673
        match containing_module.def_id.get() {
A
Alex Crichton 已提交
1674
            Some(did) => {
1675
                self.def_map.borrow_mut().insert(id, DefMod(did));
1676
                self.last_private.insert(id, lp);
A
Alex Crichton 已提交
1677 1678 1679 1680
            }
            None => {}
        }

1681
        debug!("(resolving glob import) successfully resolved import");
B
Brian Anderson 已提交
1682
        return Success(());
1683 1684
    }

1685
    fn merge_import_resolution(&mut self,
E
Eduard Burtescu 已提交
1686 1687
                               module_: &Module,
                               containing_module: Rc<Module>,
1688
                               import_directive: &ImportDirective,
1689
                               name: Name,
E
Eduard Burtescu 已提交
1690
                               name_bindings: Rc<NameBindings>) {
1691 1692 1693
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1694
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1695
        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
1696
            |vacant_entry| {
1697
                // Create a new import resolution from this child.
1698 1699
                vacant_entry.insert(ImportResolution::new(id, is_public))
            });
1700 1701 1702

        debug!("(resolving glob import) writing resolution `{}` in `{}` \
               to `{}`",
1703
               token::get_name(name).get(),
1704 1705
               self.module_to_string(&*containing_module),
               self.module_to_string(module_));
1706 1707

        // Merge the child item into the import resolution.
1708
        {
1709
            let mut merge_child_item = |&mut : namespace| {
1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733
                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
                    let namespace_name = match namespace {
                        TypeNS => "type",
                        ValueNS => "value",
                    };
                    debug!("(resolving glob import) ... for {} target", namespace_name);
                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
                        let msg = format!("a {} named `{}` has already been imported \
                                           in this module",
                                          namespace_name,
                                          token::get_name(name).get());
                        self.session.span_err(import_directive.span, msg.as_slice());
                    } else {
                        let target = Target::new(containing_module.clone(),
                                                 name_bindings.clone(),
                                                 import_directive.shadowable);
                        dest_import_resolution.set_target_and_id(namespace,
                                                                 Some(target),
                                                                 id);
                    }
                }
            };
            merge_child_item(ValueNS);
            merge_child_item(TypeNS);
1734
        }
1735

E
Eduard Burtescu 已提交
1736
        dest_import_resolution.is_public = is_public;
1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750

        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) {
1751 1752 1753 1754
        debug!("check_for_conflicting_import: {}; target exists: {}",
               token::get_name(name).get(),
               target.is_some());

1755
        match *target {
1756
            Some(ref target) if target.shadowable != Shadowable::Always => {
1757 1758 1759 1760 1761 1762 1763
                let msg = format!("a {} named `{}` has already been imported \
                                   in this module",
                                  match namespace {
                                    TypeNS => "type",
                                    ValueNS => "value",
                                  },
                                  token::get_name(name).get());
J
Jorge Aparicio 已提交
1764
                self.session.span_err(import_span, &msg[]);
1765 1766 1767 1768 1769
            }
            Some(_) | None => {}
        }
    }

1770 1771 1772 1773 1774 1775 1776 1777 1778
    /// 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));
J
Jorge Aparicio 已提交
1779
            self.session.span_err(import_span, &msg[]);
1780 1781 1782
        }
    }

1783 1784 1785 1786
    /// 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:
1787
                                                     &ImportResolution,
1788 1789 1790 1791 1792 1793 1794
                                                     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 {
1795
                Some(ref target) if target.shadowable != Shadowable::Always => {
1796 1797 1798
                    let msg = format!("import `{0}` conflicts with imported \
                                       crate in this module \
                                       (maybe you meant `use {0}::*`?)",
1799
                                      token::get_name(name).get());
J
Jorge Aparicio 已提交
1800
                    self.session.span_err(import_span, &msg[]);
1801 1802 1803 1804 1805 1806 1807
                }
                Some(_) | None => {}
            }
        }

        // Check for item conflicts.
        let children = module.children.borrow();
1808
        let name_bindings = match children.get(&name) {
1809 1810 1811 1812 1813 1814 1815 1816
            None => {
                // There can't be any conflicts.
                return
            }
            Some(ref name_bindings) => (*name_bindings).clone(),
        };

        match import_resolution.value_target {
1817
            Some(ref target) if target.shadowable != Shadowable::Always => {
1818 1819 1820 1821
                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());
J
Jorge Aparicio 已提交
1822
                    self.session.span_err(import_span, &msg[]);
1823 1824
                    if let Some(span) = value.value_span {
                        self.session.span_note(span,
C
Colin Davidson 已提交
1825
                                               "conflicting value here");
1826 1827 1828 1829 1830 1831 1832
                    }
                }
            }
            Some(_) | None => {}
        }

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

    /// 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) {
            self.session
                .span_err(span,
J
Jorge Aparicio 已提交
1900
                          &format!("the name `{}` conflicts with an external \
1901 1902
                                   crate that has been imported into this \
                                   module",
J
Jorge Aparicio 已提交
1903
                                  token::get_name(name).get())[]);
1904
        }
1905 1906
    }

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

1932
        let mut search_module = module_;
1933
        let mut index = index;
A
Alex Crichton 已提交
1934
        let module_path_len = module_path.len();
1935
        let mut closest_private = lp;
1936 1937 1938 1939 1940

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

1954
                        match search_parent_externals(name,
1955
                                                     &self.current_module) {
1956
                            Some(module) => {
1957
                                let path_str = self.names_to_string(module_path);
1958
                                let target_mod_str = self.module_to_string(&*module);
1959
                                let current_mod_str =
1960
                                    self.module_to_string(&*self.current_module);
1961 1962 1963 1964 1965 1966 1967

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

1968
                                format!("Did you mean `{}{}`?", prefix, path_str)
1969
                            },
1970 1971
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
1972
                        }
1973
                    } else {
1974
                        format!("Could not find `{}` in `{}`",
1975 1976 1977
                                segment_name,
                                module_name)
                    };
1978

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

                                    return Failed(Some((span, msg)));
1999
                                }
E
Eduard Burtescu 已提交
2000
                                Some(ref module_def) => {
2001 2002 2003
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
2004 2005
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
2006
                                    }
2007

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

T
Tim Chevalier 已提交
2029
            index += 1;
2030 2031
        }

2032
        return Success((search_module, closest_private));
2033 2034
    }

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

2050
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
2051
               self.names_to_string(module_path),
2052
               self.module_to_string(&*module_));
2053

2054
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
2055
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
2056
                                                              module_path);
2057

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

2127 2128 2129 2130
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
2131 2132
                                           name_search_type,
                                           last_private)
2133 2134
    }

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

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

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

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

2191 2192
        // Search for external modules.
        if namespace == TypeNS {
2193 2194 2195 2196
            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");
2197 2198 2199
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2200
                                false));
2201 2202 2203
            }
        }

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

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

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

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

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

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

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

2394
        debug!("(resolving module prefix) finished resolving prefix at {}",
2395
               self.module_to_string(&*containing_module));
2396 2397

        return Success(PrefixFound(containing_module, i));
2398 2399
    }

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

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

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

2434 2435 2436 2437
        // 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.
2438
        if name_search_type == PathSearch {
2439
            assert_eq!(module_.glob_count.get(), 0);
2440 2441
        }

2442
        // Check the list of resolved imports.
2443
        match module_.import_resolutions.borrow().get(&name) {
2444
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
2445
                                       import_resolution.is_public => {
2446

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

        // Finally, search through external children.
        if namespace == TypeNS {
2478 2479 2480
            if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
2481 2482 2483
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2484
                                false));
2485 2486 2487 2488
            }
        }

        // We're out of luck.
2489
        debug!("(resolving name in module) failed to resolve `{}`",
2490
               token::get_name(name).get());
2491
        return Failed(None);
2492 2493
    }

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

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

E
Eduard Burtescu 已提交
2516
        for (_, child_node) in module_.children.borrow().iter() {
2517 2518 2519 2520 2521 2522
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
2523 2524 2525 2526
                }
            }
        }

E
Eduard Burtescu 已提交
2527 2528
        for (_, module_) in module_.anonymous_children.borrow().iter() {
            self.report_unresolved_imports(module_.clone());
2529 2530 2531 2532 2533
        }
    }

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

        // Move down in the graph.
2556
        match name {
B
Brian Anderson 已提交
2557
            None => {
2558 2559
                // Nothing to do.
            }
B
Brian Anderson 已提交
2560
            Some(name) => {
2561
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
2562

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

A
Alex Crichton 已提交
2586
        f(self);
2587 2588 2589 2590

        self.current_module = orig_module;
    }

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

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

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

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

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

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

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

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

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

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

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

                        }
                    }
2728
                }
2729
                Some(DlDef(def))
2730
            }
2731
            _ => Some(def_like)
2732 2733 2734
        }
    }

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

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

2755
        None
2756 2757
    }

S
Seo Sanghyeon 已提交
2758 2759
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771
    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 已提交
2772 2773
            if result.is_some() {
                return result
2774 2775 2776 2777 2778
            }
        }
        None
    }

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

2782
        visit::walk_crate(self, krate);
2783 2784
    }

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

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

2791
        match item.node {
2792 2793 2794

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

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

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

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

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

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

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

2861 2862 2863
                    this.resolve_type_parameter_bounds(item.id, bounds,
                                                       TraitDerivation);

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

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

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

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

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

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

2912
                self.type_ribs.pop();
2913 2914
            }

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

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

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

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

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

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

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

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

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

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

A
Alex Crichton 已提交
3017
        f(self);
3018

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

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

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

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

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

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

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

3081
                        this.resolve_type(&*argument.ty);
3082

3083
                        debug!("(resolving function) recorded argument");
3084 3085
                    }

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

            // Resolve the function body.
3093
            this.resolve_block(&*block);
3094

3095
            debug!("(resolving function) leaving function");
3096
        });
3097

3098 3099
        self.label_ribs.pop();
        self.value_ribs.pop();
3100 3101
    }

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

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

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

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

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

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

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

3216 3217
                    self.resolve_type(&*eq_pred.ty);
                }
3218 3219 3220 3221
            }
        }
    }

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

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

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

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

        self.resolve_function(rib_kind,
                              Some(method.pe_fn_decl()),
                              type_parameters,
3261
                              method.pe_body());
3262 3263
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3494
        self.value_ribs.pop();
3495 3496
    }

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

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

        // Descend into the block.
3513
        visit::walk_block(self, block);
3514 3515 3516 3517

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

3518
        self.value_ribs.pop();
3519
        debug!("(resolving block) leaving block");
3520 3521
    }

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

3527
            TyPath(ref path, path_id) => {
3528
                // This is a path in the type namespace. Walk through scopes
3529
                // looking for it.
3530
                let mut result_def = None;
3531

3532
                // First, check to see whether the name is a primitive type.
3533
                if path.segments.len() == 1 {
3534
                    let id = path.segments.last().unwrap().identifier;
3535 3536 3537

                    match self.primitive_type_table
                            .primitive_types
3538
                            .get(&id.name) {
3539

3540
                        Some(&primitive_type) => {
3541
                            result_def =
3542
                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
3543

3544
                            if path.segments[0].parameters.has_lifetimes() {
J
Jakub Wieczorek 已提交
3545 3546
                                span_err!(self.session, path.span, E0157,
                                    "lifetime parameters are not allowed on this type");
3547
                            } else if !path.segments[0].parameters.is_empty() {
J
Jakub Wieczorek 已提交
3548 3549
                                span_err!(self.session, path.span, E0153,
                                    "type parameters are not allowed on this type");
3550
                            }
3551 3552 3553 3554
                        }
                        None => {
                            // Continue.
                        }
3555 3556 3557
                    }
                }

3558 3559
                if let None = result_def {
                    result_def = self.resolve_path(ty.id, path, TypeNS, true);
3560 3561
                }

3562
                match result_def {
B
Brian Anderson 已提交
3563
                    Some(def) => {
3564
                        // Write the result into the def map.
3565
                        debug!("(resolving type) writing resolution for `{}` \
3566
                                (id {}) = {:?}",
3567
                               self.path_names_to_string(path),
3568
                               path_id, def);
3569 3570
                        self.record_def(path_id, def);
                    }
B
Brian Anderson 已提交
3571
                    None => {
A
Alex Crichton 已提交
3572
                        let msg = format!("use of undeclared type name `{}`",
3573
                                          self.path_names_to_string(path));
J
Jorge Aparicio 已提交
3574
                        self.resolve_error(ty.span, &msg[]);
3575 3576
                    }
                }
3577
            }
3578

3579 3580 3581
            TyObjectSum(ref ty, ref bound_vec) => {
                self.resolve_type(&**ty);
                self.resolve_type_parameter_bounds(ty.id, bound_vec,
3582
                                                       TraitBoundingTypeParameter);
3583 3584
            }

3585
            TyQPath(ref qpath) => {
3586 3587
                self.resolve_type(&*qpath.self_type);
                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
3588 3589 3590 3591 3592 3593
                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);
                }
3594 3595
            }

3596 3597
            TyPolyTraitRef(ref bounds) => {
                self.resolve_type_parameter_bounds(
N
Niko Matsakis 已提交
3598
                    ty.id,
3599
                    bounds,
N
Niko Matsakis 已提交
3600 3601 3602
                    TraitObject);
                visit::walk_ty(self, ty);
            }
B
Brian Anderson 已提交
3603
            _ => {
3604
                // Just resolve embedded types.
3605
                visit::walk_ty(self, ty);
3606 3607 3608 3609
            }
        }
    }

F
Felix S. Klock II 已提交
3610
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
3611
                       pattern: &Pat,
3612 3613 3614
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
3615
                       bindings_list: &mut HashMap<Name, NodeId>) {
3616
        let pat_id = pattern.id;
3617
        walk_pat(pattern, |pattern| {
3618
            match pattern.node {
3619
                PatIdent(binding_mode, ref path1, _) => {
3620 3621

                    // The meaning of pat_ident with no type parameters
3622 3623 3624 3625 3626 3627 3628
                    // 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).
3629

3630
                    let ident = path1.node;
3631
                    let renamed = mtwt::resolve(ident);
3632

3633
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
3634
                        FoundStructOrEnumVariant(ref def, lp)
3635
                                if mode == RefutableMode => {
3636
                            debug!("(resolving pattern) resolving `{}` to \
3637
                                    struct or enum variant",
3638
                                   token::get_name(renamed));
3639

3640 3641 3642 3643
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
3644
                            self.record_def(pattern.id, (def.clone(), lp));
3645
                        }
A
Alex Crichton 已提交
3646
                        FoundStructOrEnumVariant(..) => {
3647 3648
                            self.resolve_error(
                                pattern.span,
J
Jorge Aparicio 已提交
3649
                                &format!("declaration of `{}` shadows an enum \
3650 3651
                                         variant or unit-like struct in \
                                         scope",
J
Jorge Aparicio 已提交
3652
                                        token::get_name(renamed))[]);
3653
                        }
3654
                        FoundConst(ref def, lp) if mode == RefutableMode => {
3655
                            debug!("(resolving pattern) resolving `{}` to \
3656
                                    constant",
3657
                                   token::get_name(renamed));
3658

3659 3660 3661 3662
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
3663
                            self.record_def(pattern.id, (def.clone(), lp));
3664
                        }
A
Alex Crichton 已提交
3665
                        FoundConst(..) => {
3666
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
3667
                                                  "only irrefutable patterns \
3668
                                                   allowed here");
3669
                        }
3670
                        BareIdentifierPatternUnresolved => {
3671
                            debug!("(resolving pattern) binding `{}`",
3672
                                   token::get_name(renamed));
3673

3674
                            let def = DefLocal(pattern.id);
3675 3676 3677 3678 3679

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

3680
                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
3681 3682 3683 3684 3685 3686

                            // 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.)
3687 3688
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
3689 3690
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
3691
                                bindings_list.insert(renamed, pat_id);
3692 3693 3694 3695 3696
                            } 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 已提交
3697
                                                   &format!("identifier `{}` \
3698 3699 3700 3701 3702 3703
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
J
Jorge Aparicio 已提交
3704
                                                   [])
3705
                            } else if bindings_list.get(&renamed) ==
3706 3707 3708 3709
                                    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 已提交
3710
                                    &format!("identifier `{}` is bound \
3711 3712
                                             more than once in the same \
                                             pattern",
J
Jorge Aparicio 已提交
3713
                                            token::get_ident(ident))[]);
3714
                            }
3715 3716
                            // Else, not bound in the same pattern: do
                            // nothing.
3717 3718 3719 3720
                        }
                    }
                }

3721
                PatEnum(ref path, _) => {
3722
                    // This must be an enum variant, struct or const.
A
Alex Crichton 已提交
3723
                    match self.resolve_path(pat_id, path, ValueNS, false) {
A
Alex Crichton 已提交
3724 3725
                        Some(def @ (DefVariant(..), _)) |
                        Some(def @ (DefStruct(..), _))  |
3726
                        Some(def @ (DefConst(..), _)) => {
3727 3728
                            self.record_def(pattern.id, def);
                        }
3729 3730 3731 3732 3733 3734
                        Some((DefStatic(..), _)) => {
                            self.resolve_error(path.span,
                                               "static variables cannot be \
                                                referenced in a pattern, \
                                                use a `const` instead");
                        }
3735
                        Some(_) => {
3736
                            self.resolve_error(path.span,
A
Alex Crichton 已提交
3737
                                format!("`{}` is not an enum variant, struct or const",
3738
                                    token::get_ident(
N
fallout  
Nick Cameron 已提交
3739
                                        path.segments.last().unwrap().identifier)).as_slice());
3740 3741
                        }
                        None => {
3742
                            self.resolve_error(path.span,
3743
                                format!("unresolved enum variant, struct or const `{}`",
3744
                                    token::get_ident(
N
fallout  
Nick Cameron 已提交
3745
                                        path.segments.last().unwrap().identifier)).as_slice());
3746 3747 3748 3749
                        }
                    }

                    // Check the types in the path pattern.
3750
                    for ty in path.segments
3751
                                  .iter()
3752
                                  .flat_map(|s| s.parameters.types().into_iter()) {
3753
                        self.resolve_type(&**ty);
3754 3755 3756
                    }
                }

3757 3758
                PatLit(ref expr) => {
                    self.resolve_expr(&**expr);
3759 3760
                }

3761 3762 3763
                PatRange(ref first_expr, ref last_expr) => {
                    self.resolve_expr(&**first_expr);
                    self.resolve_expr(&**last_expr);
3764 3765
                }

3766
                PatStruct(ref path, _, _) => {
A
Alex Crichton 已提交
3767
                    match self.resolve_path(pat_id, path, TypeNS, false) {
3768
                        Some(definition) => {
3769 3770
                            self.record_def(pattern.id, definition);
                        }
3771
                        result => {
3772
                            debug!("(resolving pattern) didn't find struct \
3773
                                    def: {:?}", result);
A
Alex Crichton 已提交
3774
                            let msg = format!("`{}` does not name a structure",
3775
                                              self.path_names_to_string(path));
J
Jorge Aparicio 已提交
3776
                            self.resolve_error(path.span, &msg[]);
3777 3778 3779 3780
                        }
                    }
                }

3781
                _ => {
3782 3783 3784
                    // Nothing to do.
                }
            }
3785
            true
3786
        });
3787 3788
    }

3789
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
3790 3791 3792
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3793
                                                 name,
3794
                                                 ValueNS) {
3795
            Success((target, _)) => {
3796
                debug!("(resolve bare identifier pattern) succeeded in \
3797
                         finding {} at {:?}",
3798
                        token::get_name(name),
E
Erick Tryzelaar 已提交
3799 3800
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
3801
                    None => {
S
Steve Klabnik 已提交
3802
                        panic!("resolved name in the value namespace to a \
3803
                              set of name bindings with no def?!");
3804
                    }
B
Brian Anderson 已提交
3805
                    Some(def) => {
3806 3807 3808
                        // 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.
3809
                        match def.def {
A
Alex Crichton 已提交
3810
                            def @ DefVariant(..) | def @ DefStruct(..) => {
3811
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
3812
                            }
3813
                            def @ DefConst(..) => {
3814
                                return FoundConst(def, LastMod(AllPublic));
3815
                            }
3816
                            DefStatic(..) => {
3817
                                self.resolve_error(span,
3818 3819 3820
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
3821 3822
                                return BareIdentifierPatternUnresolved;
                            }
3823
                            _ => {
3824
                                return BareIdentifierPatternUnresolved;
3825 3826
                            }
                        }
3827 3828 3829 3830
                    }
                }
            }

B
Brian Anderson 已提交
3831
            Indeterminate => {
S
Steve Klabnik 已提交
3832
                panic!("unexpected indeterminate result");
3833
            }
3834 3835 3836
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
J
Jorge Aparicio 已提交
3837 3838
                        self.resolve_error(span, &format!("failed to resolve: {}",
                                                         msg)[]);
3839 3840 3841
                    }
                    None => ()
                }
3842

3843
                debug!("(resolve bare identifier pattern) failed to find {}",
3844
                        token::get_name(name));
3845
                return BareIdentifierPatternUnresolved;
3846 3847 3848 3849
            }
        }
    }

3850 3851
    /// 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 已提交
3852
    fn resolve_path(&mut self,
3853 3854 3855 3856
                    id: NodeId,
                    path: &Path,
                    namespace: Namespace,
                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
3857
        // First, resolve the types and associated type bindings.
3858
        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
3859
            self.resolve_type(&**ty);
3860
        }
3861 3862 3863
        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
            self.resolve_type(&*binding.ty);
        }
3864

3865 3866 3867 3868 3869 3870 3871 3872 3873
        // 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 {
3874
                        DefTyParam(_, _, did, _) => {
3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892
                            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));
                        }
                        _ => {}
                    }
                }
                _ => {}
            }
        }

3893
        if path.global {
3894
            return self.resolve_crate_relative_path(path, namespace);
3895 3896
        }

3897
        // Try to find a path to an item in a module.
3898
        let unqualified_def =
A
Aaron Turon 已提交
3899
                self.resolve_identifier(path.segments.last().unwrap().identifier,
3900 3901 3902
                                        namespace,
                                        check_ribs,
                                        path.span);
3903

3904
        if path.segments.len() > 1 {
3905
            let def = self.resolve_module_relative_path(path, namespace);
3906
            match (def, unqualified_def) {
3907
                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
3908
                    self.session
A
Aaron Turon 已提交
3909
                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
3910 3911
                                  id,
                                  path.span,
3912
                                  "unnecessary qualification".to_string());
3913 3914 3915
                }
                _ => ()
            }
3916

3917
            return def;
3918 3919
        }

3920
        return unqualified_def;
3921 3922
    }

J
John Clements 已提交
3923
    // resolve a single identifier (used as a varref)
F
Felix S. Klock II 已提交
3924
    fn resolve_identifier(&mut self,
3925 3926 3927 3928 3929
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3930
        if check_ribs {
3931
            match self.resolve_identifier_in_local_ribs(identifier,
3932 3933
                                                        namespace,
                                                        span) {
B
Brian Anderson 已提交
3934
                Some(def) => {
3935
                    return Some((def, LastMod(AllPublic)));
3936
                }
B
Brian Anderson 已提交
3937
                None => {
3938 3939 3940 3941 3942
                    // Continue.
                }
            }
        }

3943
        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
3944 3945
    }

3946
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3947
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3948
                                            containing_module: Rc<Module>,
3949
                                            name: Name,
3950
                                            namespace: Namespace)
3951
                                            -> NameDefinition {
3952
        // First, search children.
3953
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3954

3955
        match containing_module.children.borrow().get(&name) {
3956 3957 3958 3959 3960 3961 3962
            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 {
3963
                            LastMod(DependsOn(def.def_id()))
3964 3965
                        };
                        return ChildNameDefinition(def, lp);
3966
                    }
3967
                    None => {}
3968 3969
                }
            }
3970
            None => {}
3971 3972 3973
        }

        // Next, search import resolutions.
3974
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3975
            Some(import_resolution) if import_resolution.is_public => {
3976 3977 3978 3979 3980 3981 3982
                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));
3983
                            self.record_import_use(id, name);
3984 3985 3986 3987 3988
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
3989
                            }
3990 3991 3992 3993 3994
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
3995 3996 3997 3998
                        }
                    }
                }
            }
A
Alex Crichton 已提交
3999
            Some(..) | None => {} // Continue.
4000 4001 4002 4003
        }

        // Finally, search through external children.
        if namespace == TypeNS {
4004 4005 4006 4007 4008 4009 4010 4011 4012
            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);
4013
                }
4014 4015
            }
        }
4016 4017

        return NoNameDefinition;
4018 4019
    }

4020
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
4021
    fn resolve_module_relative_path(&mut self,
4022 4023 4024
                                    path: &Path,
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
4025 4026 4027
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4028

4029
        let containing_module;
4030
        let last_private;
E
Eduard Burtescu 已提交
4031 4032
        let module = self.current_module.clone();
        match self.resolve_module_path(module,
J
Jorge Aparicio 已提交
4033
                                       &module_path[],
4034 4035
                                       UseLexicalScope,
                                       path.span,
4036
                                       PathSearch) {
4037 4038 4039 4040
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
4041 4042
                        let msg = format!("Use of undeclared type or module `{}`",
                                          self.names_to_string(module_path.as_slice()));
4043 4044 4045
                        (path.span, msg)
                    }
                };
4046

J
Jorge Aparicio 已提交
4047 4048
                self.resolve_error(span, &format!("failed to resolve. {}",
                                                 msg)[]);
4049
                return None;
4050
            }
S
Steve Klabnik 已提交
4051
            Indeterminate => panic!("indeterminate unexpected"),
4052
            Success((resulting_module, resulting_last_private)) => {
4053
                containing_module = resulting_module;
4054
                last_private = resulting_last_private;
4055 4056 4057
            }
        }

4058
        let name = path.segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
4059
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
4060
                                                                  name,
4061
                                                                  namespace) {
B
Brian Anderson 已提交
4062
            NoNameDefinition => {
4063
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4064
                return None;
4065
            }
4066 4067
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
4068
            }
4069
        };
4070 4071
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
4072
        }
4073
        return Some(def);
4074 4075
    }

4076 4077
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
4078
    fn resolve_crate_relative_path(&mut self,
4079 4080 4081
                                   path: &Path,
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
4082 4083 4084
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4085

4086
        let root_module = self.graph_root.get_module();
4087

4088
        let containing_module;
4089
        let last_private;
4090
        match self.resolve_module_path_from_root(root_module,
J
Jorge Aparicio 已提交
4091
                                                 &module_path[],
4092
                                                 0,
4093
                                                 path.span,
4094
                                                 PathSearch,
4095
                                                 LastMod(AllPublic)) {
4096 4097 4098 4099 4100
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
J
Jorge Aparicio 已提交
4101
                                          self.names_to_string(&module_path[]));
4102 4103 4104 4105
                        (path.span, msg)
                    }
                };

J
Jorge Aparicio 已提交
4106 4107
                self.resolve_error(span, &format!("failed to resolve. {}",
                                                 msg)[]);
B
Brian Anderson 已提交
4108
                return None;
4109 4110
            }

B
Brian Anderson 已提交
4111
            Indeterminate => {
S
Steve Klabnik 已提交
4112
                panic!("indeterminate unexpected");
4113 4114
            }

4115
            Success((resulting_module, resulting_last_private)) => {
4116
                containing_module = resulting_module;
4117
                last_private = resulting_last_private;
4118 4119 4120
            }
        }

4121
        let name = path.segments.last().unwrap().identifier.name;
4122
        match self.resolve_definition_of_name_in_module(containing_module,
4123
                                                        name,
4124
                                                        namespace) {
B
Brian Anderson 已提交
4125
            NoNameDefinition => {
4126
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4127
                return None;
4128
            }
4129 4130
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
4131 4132 4133 4134
            }
        }
    }

F
Felix S. Klock II 已提交
4135
    fn resolve_identifier_in_local_ribs(&mut self,
4136 4137 4138 4139
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
4140
        // Check the local set of ribs.
4141
        let search_result = match namespace {
B
Brian Anderson 已提交
4142
            ValueNS => {
4143
                let renamed = mtwt::resolve(ident);
4144
                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
4145
            }
B
Brian Anderson 已提交
4146
            TypeNS => {
4147
                let name = ident.name;
J
Jorge Aparicio 已提交
4148
                self.search_ribs(&self.type_ribs[], name, span)
4149
            }
4150
        };
4151

4152
        match search_result {
4153
            Some(DlDef(def)) => {
4154
                debug!("(resolving path in local ribs) resolved `{}` to \
4155
                        local: {:?}",
4156
                       token::get_ident(ident),
P
Paul Stansifer 已提交
4157
                       def);
B
Brian Anderson 已提交
4158
                return Some(def);
4159
            }
4160
            Some(DlField) | Some(DlImpl(_)) | None => {
B
Brian Anderson 已提交
4161
                return None;
4162 4163 4164 4165
            }
        }
    }

4166 4167 4168 4169
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
4170
        // Check the items.
E
Eduard Burtescu 已提交
4171 4172
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
4173
                                                 name,
4174
                                                 namespace) {
4175
            Success((target, _)) => {
4176
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
4177
                    None => {
4178 4179
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
4180
                        debug!("(resolving item path by identifier in lexical \
4181
                                 scope) failed to resolve {} after success...",
4182
                                 token::get_name(name));
4183
                        return None;
4184
                    }
B
Brian Anderson 已提交
4185
                    Some(def) => {
4186
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
4187
                                resolved `{}` to item",
4188
                               token::get_name(name));
4189 4190 4191
                        // 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.
4192
                        return Some((def, LastMod(AllPublic)));
4193 4194 4195
                    }
                }
            }
B
Brian Anderson 已提交
4196
            Indeterminate => {
S
Steve Klabnik 已提交
4197
                panic!("unexpected indeterminate result");
4198
            }
4199 4200 4201
            Failed(err) => {
                match err {
                    Some((span, msg)) =>
J
Jorge Aparicio 已提交
4202 4203
                        self.resolve_error(span, &format!("failed to resolve. {}",
                                                         msg)[]),
4204 4205 4206
                    None => ()
                }

4207
                debug!("(resolving item path by identifier in lexical scope) \
4208
                         failed to resolve {}", token::get_name(name));
B
Brian Anderson 已提交
4209
                return None;
4210 4211 4212 4213
            }
        }
    }

J
Jorge Aparicio 已提交
4214 4215 4216
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
4217
        self.emit_errors = false;
A
Alex Crichton 已提交
4218
        let rs = f(self);
4219 4220 4221 4222
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
4223
    fn resolve_error(&self, span: Span, s: &str) {
4224
        if self.emit_errors {
A
Alex Crichton 已提交
4225
            self.session.span_err(span, s);
4226 4227 4228
        }
    }

4229
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
4230 4231 4232
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
4233
                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
4234 4235
                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),
4236 4237 4238 4239 4240 4241 4242
                // 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,
            }
        }

4243
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
4244 4245
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
4246
            let last_name = name_path.last().unwrap();
4247

4248
            if name_path.len() == 1 {
4249
                match this.primitive_type_table.primitive_types.get(last_name) {
4250 4251
                    Some(_) => None,
                    None => {
4252
                        match this.current_module.children.borrow().get(last_name) {
4253 4254 4255 4256 4257 4258 4259
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
J
Jorge Aparicio 已提交
4260
                                                &name_path[],
4261 4262 4263 4264 4265 4266 4267 4268 4269
                                                UseLexicalScope,
                                                span,
                                                PathSearch) {
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

4270 4271 4272 4273
        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,
4274 4275 4276 4277
            },
            None => return NoSuggestion,
        };

4278 4279
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
4280
            match self.def_map.borrow().get(&node_id) {
4281
                 Some(&DefTy(did, _))
4282
                | Some(&DefStruct(did))
4283
                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
4284 4285 4286 4287 4288
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
4289
                    }
4290 4291 4292
                },
                _ => {} // Self type didn't resolve properly
            }
4293 4294
        }

4295
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
4296 4297

        // Look for a method in the current self type's impl module.
J
Jorge Aparicio 已提交
4298
        match get_module(self, path.span, &name_path[]) {
4299
            Some(module) => match module.children.borrow().get(&name) {
4300
                Some(binding) => {
4301
                    let p_str = self.path_names_to_string(&path);
4302
                    match binding.def_for_namespace(ValueNS) {
4303
                        Some(DefStaticMethod(_, provenance)) => {
4304 4305 4306 4307 4308
                            match provenance {
                                FromImpl(_) => return StaticMethod(p_str),
                                FromTrait(_) => unreachable!()
                            }
                        }
4309 4310
                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321
                        _ => ()
                    }
                }
                None => {}
            },
            None => {}
        }

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

4324
                match self.trait_item_map.get(&(name, did)) {
4325 4326 4327
                    Some(&StaticMethodTraitItemKind) => {
                        return TraitMethod(path_str)
                    }
4328
                    Some(_) => return TraitItem,
4329 4330 4331 4332 4333 4334 4335 4336 4337
                    None => {}
                }
            }
            None => {}
        }

        NoSuggestion
    }

4338
    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4339
                                -> Option<String> {
4340 4341
        let this = &mut *self;

4342 4343
        let mut maybes: Vec<token::InternedString> = Vec::new();
        let mut values: Vec<uint> = Vec::new();
4344

4345 4346
        for rib in this.value_ribs.iter().rev() {
            for (&k, _) in rib.bindings.iter() {
4347
                maybes.push(token::get_name(k));
C
Chris Wong 已提交
4348
                values.push(uint::MAX);
4349 4350 4351 4352
            }
        }

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

4356
            if values[i] <= values[smallest] {
4357 4358 4359 4360
                smallest = i;
            }
        }

Y
Youngmin Yoo 已提交
4361
        if values.len() > 0 &&
4362 4363 4364 4365
            values[smallest] != uint::MAX &&
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
            name != maybes[smallest].get() {
4366

4367
            Some(maybes[smallest].get().to_string())
4368 4369 4370 4371 4372 4373

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
4374
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
4375 4376
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
4377 4378 4379

        self.record_candidate_traits_for_expr_if_necessary(expr);

4380
        // Next, resolve the node.
4381
        match expr.node {
4382 4383 4384
            // The interpretation of paths depends on whether the path has
            // multiple elements in it or not.

4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397
            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!()
                };
4398 4399
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
A
Alex Crichton 已提交
4400
                match self.resolve_path(expr.id, path, ValueNS, true) {
4401 4402
                    // Check if struct variant
                    Some((DefVariant(_, _, true), _)) => {
4403
                        let path_name = self.path_names_to_string(path);
4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414
                        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 已提交
4415
                    Some(def) => {
4416
                        // Write the result into the def map.
4417
                        debug!("(resolving expr) resolved `{}`",
4418
                               self.path_names_to_string(path));
4419

4420 4421
                        self.record_def(expr.id, def);
                    }
B
Brian Anderson 已提交
4422
                    None => {
A
Alex Crichton 已提交
4423 4424 4425 4426
                        // 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.)
4427
                        let path_name = self.path_names_to_string(path);
A
Alex Crichton 已提交
4428 4429
                        match self.with_no_errors(|this|
                            this.resolve_path(expr.id, path, TypeNS, false)) {
4430
                            Some((DefTy(struct_id, _), _))
4431 4432 4433 4434 4435
                              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",
4436
                                                path_name).as_slice());
4437

P
P1start 已提交
4438
                                self.session.span_help(expr.span,
4439 4440
                                    format!("Did you mean to write: \
                                            `{} {{ /* fields */ }}`?",
4441
                                            path_name).as_slice());
4442

4443
                            }
4444 4445
                            _ => {
                                let mut method_scope = false;
4446
                                self.value_ribs.iter().rev().all(|rib| {
4447 4448
                                    let res = match *rib {
                                        Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
4449
                                        Rib { bindings: _, kind: ItemRibKind } => false,
4450 4451 4452 4453 4454 4455 4456
                                        _ => return true, // Keep advancing
                                    };

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

J
John Clements 已提交
4457
                                if method_scope && token::get_name(self.self_name).get()
4458
                                                                   == path_name {
4459 4460 4461 4462 4463
                                        self.resolve_error(
                                            expr.span,
                                            "`self` is not available \
                                             in a static method. Maybe a \
                                             `self` argument is missing?");
4464
                                } else {
4465 4466
                                    let last_name = path.segments.last().unwrap().identifier.name;
                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
4467 4468 4469
                                        NoSuggestion => {
                                            // limit search to 5 to reduce the number
                                            // of stupid suggestions
4470
                                            self.find_best_match_for_name(path_name.as_slice(), 5)
4471
                                                                .map_or("".to_string(),
4472 4473 4474
                                                                        |x| format!("`{}`", x))
                                        }
                                        Field =>
4475
                                            format!("`self.{}`", path_name),
4476
                                        Method
4477
                                        | TraitItem =>
4478
                                            format!("to call `self.{}`", path_name),
4479
                                        TraitMethod(path_str)
4480
                                        | StaticMethod(path_str) =>
4481
                                            format!("to call `{}::{}`", path_str, path_name)
4482 4483 4484
                                    };

                                    if msg.len() > 0 {
4485
                                        msg = format!(". Did you mean {}?", msg)
4486 4487
                                    }

4488 4489
                                    self.resolve_error(
                                        expr.span,
4490
                                        format!("unresolved name `{}`{}",
4491
                                                path_name,
4492
                                                msg).as_slice());
4493 4494
                                }
                            }
V
Vincent Belliard 已提交
4495
                        }
4496 4497 4498
                    }
                }

4499
                visit::walk_expr(self, expr);
4500 4501
            }

4502
            ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
B
Björn Steinbrink 已提交
4503
                self.capture_mode_map.insert(expr.id, capture_clause);
4504 4505 4506 4507
                self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
                                      Some(&**fn_decl), NoTypeParameters,
                                      &**block);
            }
4508

4509
            ExprStruct(ref path, _, _) => {
4510 4511 4512
                // 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 已提交
4513
                match self.resolve_path(expr.id, path, TypeNS, false) {
4514
                    Some(definition) => self.record_def(expr.id, definition),
S
Steven Fackler 已提交
4515
                    result => {
4516
                        debug!("(resolving expression) didn't find struct \
4517
                                def: {:?}", result);
A
Alex Crichton 已提交
4518
                        let msg = format!("`{}` does not name a structure",
4519
                                          self.path_names_to_string(path));
J
Jorge Aparicio 已提交
4520
                        self.resolve_error(path.span, &msg[]);
4521 4522 4523
                    }
                }

4524
                visit::walk_expr(self, expr);
4525 4526
            }

P
Pythoner6 已提交
4527
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
4528
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
4529
                    let def_like = DlDef(DefLabel(expr.id));
4530

4531
                    {
4532
                        let rib = this.label_ribs.last_mut().unwrap();
4533
                        let renamed = mtwt::resolve(label);
4534
                        rib.bindings.insert(renamed, def_like);
4535
                    }
4536

4537
                    visit::walk_expr(this, expr);
4538
                })
4539 4540
            }

4541 4542 4543
            ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
                self.resolve_expr(&**head);

4544
                self.value_ribs.push(Rib::new(NormalRibKind));
4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557

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

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

                        {
4558
                            let rib = self.label_ribs.last_mut().unwrap();
4559
                            let renamed = mtwt::resolve(label);
4560
                            rib.bindings.insert(renamed, def_like);
4561 4562 4563 4564 4565 4566 4567
                        }
                    }
                }

                self.resolve_block(&**body);

                if optional_label.is_some() {
4568
                    drop(self.label_ribs.pop())
4569 4570
                }

4571
                self.value_ribs.pop();
4572
            }
4573

4574
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
4575
                let renamed = mtwt::resolve(label);
4576
                match self.search_label(renamed) {
4577 4578 4579
                    None => {
                        self.resolve_error(
                            expr.span,
J
Jorge Aparicio 已提交
4580 4581
                            &format!("use of undeclared label `{}`",
                                    token::get_ident(label))[])
4582
                    }
4583
                    Some(DlDef(def @ DefLabel(_))) => {
4584 4585
                        // Since this def is a label, it is never read.
                        self.record_def(expr.id, (def, LastMod(AllPublic)))
4586 4587
                    }
                    Some(_) => {
4588
                        self.session.span_bug(expr.span,
4589 4590
                                              "label wasn't mapped to a \
                                               label def!")
4591 4592 4593 4594
                    }
                }
            }

B
Brian Anderson 已提交
4595
            _ => {
4596
                visit::walk_expr(self, expr);
4597 4598 4599 4600
            }
        }
    }

E
Eduard Burtescu 已提交
4601
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
4602
        match expr.node {
4603
            ExprField(_, ident) => {
4604 4605 4606 4607
                // 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.
4608
                let traits = self.search_for_traits_containing_method(ident.node.name);
4609
                self.trait_map.insert(expr.id, traits);
4610
            }
4611
            ExprMethodCall(ident, _, _) => {
4612
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
4613
                        traits for {}",
4614
                       expr.id);
4615
                let traits = self.search_for_traits_containing_method(ident.node.name);
4616
                self.trait_map.insert(expr.id, traits);
4617
            }
4618
            _ => {
4619 4620 4621 4622 4623
                // Nothing to do.
            }
        }
    }

E
Eduard Burtescu 已提交
4624
    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
4625
        debug!("(searching for traits containing method) looking for '{}'",
E
Eduard Burtescu 已提交
4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636
               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);
        }
4637

4638
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
4639
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
4640 4641
        loop {
            // Look for the current trait.
4642 4643
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
4644
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
4645
                        add_trait_info(&mut found_traits, trait_def_id, name);
4646 4647
                    }
                }
4648
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
4649
            }
4650

E
Eduard Burtescu 已提交
4651
            // Look for trait children.
4652
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
4653

E
Eduard Burtescu 已提交
4654
            {
E
Eduard Burtescu 已提交
4655
                for (_, child_names) in search_module.children.borrow().iter() {
4656 4657 4658 4659 4660 4661 4662 4663
                    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,
                    };
4664
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
4665
                        add_trait_info(&mut found_traits, trait_def_id, name);
4666 4667
                    }
                }
E
Eduard Burtescu 已提交
4668
            }
4669

E
Eduard Burtescu 已提交
4670
            // Look for imports.
E
Eduard Burtescu 已提交
4671
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
4672 4673 4674 4675 4676 4677 4678 4679
                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,
                };
4680
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
4681
                    add_trait_info(&mut found_traits, did, name);
4682 4683 4684 4685
                    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);
4686 4687
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
4688
                    }
4689
                }
E
Eduard Burtescu 已提交
4690
            }
4691

E
Eduard Burtescu 已提交
4692
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
4693 4694
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
4695
                    search_module = parent_module.upgrade().unwrap();
4696
                }
E
Eduard Burtescu 已提交
4697
            }
4698 4699
        }

E
Eduard Burtescu 已提交
4700
        found_traits
4701 4702
    }

4703
    fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
4704
        debug!("(recording def) recording {:?} for {}, last private {:?}",
4705
                def, node_id, lp);
4706 4707
        assert!(match lp {LastImport{..} => false, _ => true},
                "Import should only be used for `use` directives");
4708
        self.last_private.insert(node_id, lp);
4709

4710
        match self.def_map.borrow_mut().entry(node_id) {
4711 4712 4713
            // Resolve appears to "resolve" the same ID multiple
            // times, so here is a sanity check it at least comes to
            // the same conclusion! - nmatsakis
4714
            Occupied(entry) => if def != *entry.get() {
4715
                self.session
J
Jorge Aparicio 已提交
4716
                    .bug(&format!("node_id {} resolved first to {:?} and \
4717
                                  then {:?}",
4718
                                 node_id,
4719
                                 *entry.get(),
J
Jorge Aparicio 已提交
4720
                                 def)[]);
4721
            },
4722
            Vacant(entry) => { entry.insert(def); },
4723
        }
4724 4725
    }

F
Felix S. Klock II 已提交
4726
    fn enforce_default_binding_mode(&mut self,
4727
                                        pat: &Pat,
4728
                                        pat_binding_mode: BindingMode,
4729
                                        descr: &str) {
4730
        match pat_binding_mode {
4731
            BindByValue(_) => {}
A
Alex Crichton 已提交
4732
            BindByRef(..) => {
4733
                self.resolve_error(pat.span,
J
Jorge Aparicio 已提交
4734
                                   &format!("cannot use `ref` binding mode \
4735
                                            with {}",
J
Jorge Aparicio 已提交
4736
                                           descr)[]);
4737 4738 4739 4740
            }
        }
    }

4741 4742 4743 4744 4745 4746 4747
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

4752
        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
E
Eduard Burtescu 已提交
4753 4754 4755
            match module.parent_link {
                NoParentLink => {}
                ModuleParentLink(ref module, name) => {
4756 4757
                    names.push(name);
                    collect_mod(names, &*module.upgrade().unwrap());
4758
                }
E
Eduard Burtescu 已提交
4759
                BlockParentLink(ref module, _) => {
J
John Clements 已提交
4760
                    // danger, shouldn't be ident?
4761 4762
                    names.push(special_idents::opaque.name);
                    collect_mod(names, &*module.upgrade().unwrap());
4763 4764 4765
                }
            }
        }
4766
        collect_mod(&mut names, module);
4767

4768
        if names.len() == 0 {
4769
            return "???".to_string();
4770
        }
J
Jorge Aparicio 已提交
4771 4772
        self.names_to_string(&names.into_iter().rev()
                                  .collect::<Vec<ast::Name>>()[])
4773 4774
    }

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

4779
        debug!("Children:");
4780
        build_reduced_graph::populate_module_if_necessary(self, &module_);
4781
        for (&name, _) in module_.children.borrow().iter() {
4782
            debug!("* {}", token::get_name(name));
4783 4784
        }

4785
        debug!("Import resolutions:");
4786
        let import_resolutions = module_.import_resolutions.borrow();
4787
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
4788
            let value_repr;
4789
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
4790
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4791
                Some(_) => {
R
Richo Healey 已提交
4792
                    value_repr = " value:?".to_string();
4793
                    // FIXME #4954
4794 4795 4796
                }
            }

N
Niko Matsakis 已提交
4797
            let type_repr;
4798
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
4799
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4800
                Some(_) => {
R
Richo Healey 已提交
4801
                    type_repr = " type:?".to_string();
4802
                    // FIXME #4954
4803 4804 4805
                }
            }

4806
            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
4807 4808 4809 4810
        }
    }
}

4811
pub struct CrateMap {
4812
    pub def_map: DefMap,
4813 4814
    pub freevars: RefCell<FreevarMap>,
    pub capture_mode_map: RefCell<CaptureModeMap>,
4815
    pub export_map: ExportMap,
4816 4817 4818
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
    pub last_private_map: LastPrivateMap,
4819 4820 4821
    pub glob_map: Option<GlobMap>
}

4822
#[derive(PartialEq,Copy)]
4823 4824 4825
pub enum MakeGlobMap {
    Yes,
    No
4826 4827
}

4828
/// Entry point to crate resolution.
4829 4830 4831 4832 4833 4834 4835
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);
4836

4837
    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
4838 4839 4840 4841 4842
    session.abort_if_errors();

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

4843
    record_exports::record(&mut resolver);
4844 4845 4846 4847 4848 4849 4850
    session.abort_if_errors();

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

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

4851
    CrateMap {
4852 4853
        def_map: resolver.def_map,
        freevars: resolver.freevars,
4854
        capture_mode_map: RefCell::new(resolver.capture_mode_map),
4855
        export_map: resolver.export_map,
4856 4857 4858
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
        last_private_map: resolver.last_private,
4859 4860 4861 4862 4863
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
4864
    }
4865
}