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

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

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

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

extern crate rustc;

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

46 47 48 49 50 51 52 53 54
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 已提交
55
use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap, GlobMap};
56
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
A
Alex Crichton 已提交
57
use rustc::util::lev_distance::lev_distance;
58

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

88
use std::collections::{HashMap, HashSet};
C
Corey Farwell 已提交
89
use std::collections::hash_map::Entry::{Occupied, Vacant};
90
use std::cell::{Cell, RefCell};
91
use std::mem::replace;
E
Eduard Burtescu 已提交
92
use std::rc::{Rc, Weak};
93
use std::uint;
94

A
Alex Crichton 已提交
95 96
mod check_unused;
mod record_exports;
97
mod build_reduced_graph;
98

J
Jorge Aparicio 已提交
99
#[deriving(Copy)]
100
struct BindingInfo {
101
    span: Span,
102
    binding_mode: BindingMode,
103 104 105
}

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

J
Jorge Aparicio 已提交
108
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
109
enum PatternBindingMode {
110
    RefutableMode,
111
    LocalIrrefutableMode,
112
    ArgumentIrrefutableMode,
113 114
}

J
Jorge Aparicio 已提交
115
#[deriving(Copy, PartialEq, Eq, Hash, Show)]
F
Felix S. Klock II 已提交
116
enum Namespace {
117
    TypeNS,
118
    ValueNS
119 120
}

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

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

F
Felix S. Klock II 已提交
153
enum NameDefinition {
154
    NoNameDefinition,           //< The name was unbound.
155 156
    ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
    ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
157 158
}

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

180
/// Contains data for specific types of import directives.
J
Jorge Aparicio 已提交
181
#[deriving(Copy)]
F
Felix S. Klock II 已提交
182
enum ImportDirectiveSubclass {
183
    SingleImport(Name /* target */, Name /* source */),
184 185 186
    GlobImport
}

187 188
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
189
enum ResolveResult<T> {
190 191 192
    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.
193 194
}

195
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
196
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
197
        match *self { Indeterminate => true, _ => false }
198 199 200
    }
}

201 202 203 204
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
205
    TraitItem,
206
    StaticMethod(String),
207
    TraitMethod(String),
208 209
}

J
Jorge Aparicio 已提交
210
#[deriving(Copy)]
E
Erik Price 已提交
211
enum TypeParameters<'a> {
212 213 214 215 216 217 218 219 220 221 222 223 224 225
    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)
226 227
}

228 229
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
J
Jorge Aparicio 已提交
230
#[deriving(Copy, Show)]
F
Felix S. Klock II 已提交
231
enum RibKind {
232 233
    // No translation needs to be applied.
    NormalRibKind,
234

235 236
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
237
    ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
238

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

246 247
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
248 249 250

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

253
// Methods can be required or provided. RequiredMethod methods only occur in traits.
J
Jorge Aparicio 已提交
254
#[deriving(Copy, Show)]
F
Felix S. Klock II 已提交
255
enum MethodSort {
256 257
    RequiredMethod,
    ProvidedMethod(NodeId)
258 259
}

J
Jorge Aparicio 已提交
260
#[deriving(Copy)]
F
Felix S. Klock II 已提交
261
enum UseLexicalScopeFlag {
262 263 264 265
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
266
enum ModulePrefixResult {
267
    NoPrefixFound,
E
Eduard Burtescu 已提交
268
    PrefixFound(Rc<Module>, uint)
269 270
}

J
Jorge Aparicio 已提交
271
#[deriving(Copy, PartialEq)]
272
enum NameSearchType {
273 274 275 276
    /// 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
277 278
    /// expression, or a path pattern.
    PathSearch,
279 280
}

J
Jorge Aparicio 已提交
281
#[deriving(Copy)]
F
Felix S. Klock II 已提交
282
enum BareIdentifierPatternResolution {
283 284
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
285
    BareIdentifierPatternUnresolved
286 287
}

288
/// One local scope.
289
#[deriving(Show)]
F
Felix S. Klock II 已提交
290
struct Rib {
291
    bindings: HashMap<Name, DefLike>,
292
    kind: RibKind,
B
Brian Anderson 已提交
293
}
294

295
impl Rib {
F
Felix S. Klock II 已提交
296
    fn new(kind: RibKind) -> Rib {
297
        Rib {
298
            bindings: HashMap::new(),
299 300
            kind: kind
        }
301 302 303
    }
}

304
/// Whether an import can be shadowed by another import.
N
Nick Cameron 已提交
305
#[deriving(Show,PartialEq,Clone,Copy)]
306 307 308 309 310
enum Shadowable {
    Always,
    Never
}

311
/// One import directive.
F
Felix S. Klock II 已提交
312
struct ImportDirective {
313
    module_path: Vec<Name>,
E
Eduard Burtescu 已提交
314
    subclass: ImportDirectiveSubclass,
315
    span: Span,
316
    id: NodeId,
317
    is_public: bool, // see note in ImportResolution about how to use this
318
    shadowable: Shadowable,
B
Brian Anderson 已提交
319
}
320

321
impl ImportDirective {
322
    fn new(module_path: Vec<Name> ,
E
Eduard Burtescu 已提交
323
           subclass: ImportDirectiveSubclass,
324 325
           span: Span,
           id: NodeId,
326
           is_public: bool,
327
           shadowable: Shadowable)
328
           -> ImportDirective {
329 330 331 332
        ImportDirective {
            module_path: module_path,
            subclass: subclass,
            span: span,
333 334
            id: id,
            is_public: is_public,
335
            shadowable: shadowable,
336
        }
337 338 339
    }
}

340
/// The item that an import resolves to.
341
#[deriving(Clone)]
F
Felix S. Klock II 已提交
342
struct Target {
E
Eduard Burtescu 已提交
343 344
    target_module: Rc<Module>,
    bindings: Rc<NameBindings>,
345
    shadowable: Shadowable,
B
Brian Anderson 已提交
346
}
347

348
impl Target {
349 350
    fn new(target_module: Rc<Module>,
           bindings: Rc<NameBindings>,
351
           shadowable: Shadowable)
352
           -> Target {
353 354
        Target {
            target_module: target_module,
355 356
            bindings: bindings,
            shadowable: shadowable,
357
        }
358 359 360
    }
}

T
Tim Chevalier 已提交
361
/// An ImportResolution represents a particular `use` directive.
F
Felix S. Klock II 已提交
362
struct ImportResolution {
363 364 365 366
    /// 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 已提交
367
    is_public: bool,
368

369 370 371
    // 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 已提交
372
    outstanding_references: uint,
373

T
Tim Chevalier 已提交
374
    /// The value that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
375
    value_target: Option<Target>,
376 377
    /// The source node of the `use` directive leading to the value target
    /// being non-none
E
Eduard Burtescu 已提交
378
    value_id: NodeId,
379

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

387
impl ImportResolution {
388
    fn new(id: NodeId, is_public: bool) -> ImportResolution {
389
        ImportResolution {
E
Eduard Burtescu 已提交
390 391 392 393 394 395
            type_id: id,
            value_id: id,
            outstanding_references: 0,
            value_target: None,
            type_target: None,
            is_public: is_public,
396
        }
B
Brian Anderson 已提交
397 398
    }

F
Felix S. Klock II 已提交
399
    fn target_for_namespace(&self, namespace: Namespace)
400
                                -> Option<Target> {
401
        match namespace {
E
Eduard Burtescu 已提交
402 403
            TypeNS  => self.type_target.clone(),
            ValueNS => self.value_target.clone(),
404 405
        }
    }
406

407
    fn id(&self, namespace: Namespace) -> NodeId {
408
        match namespace {
E
Eduard Burtescu 已提交
409 410
            TypeNS  => self.type_id,
            ValueNS => self.value_id,
411 412
        }
    }
413 414 415 416 417 418 419 420 421

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

        target.unwrap().shadowable
    }
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437

    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;
            }
        }
    }
438 439
}

440
/// The link from a module up to its nearest parent node.
E
Eduard Burtescu 已提交
441
#[deriving(Clone)]
F
Felix S. Klock II 已提交
442
enum ParentLink {
443
    NoParentLink,
444
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
445
    BlockParentLink(Weak<Module>, NodeId)
446 447
}

448
/// The type of module this is.
J
Jorge Aparicio 已提交
449
#[deriving(Copy, PartialEq)]
F
Felix S. Klock II 已提交
450
enum ModuleKind {
451 452
    NormalModuleKind,
    TraitModuleKind,
453
    ImplModuleKind,
454
    EnumModuleKind,
455 456 457
    AnonymousModuleKind,
}

458
/// One node in the tree of modules.
F
Felix S. Klock II 已提交
459
struct Module {
460
    parent_link: ParentLink,
461
    def_id: Cell<Option<DefId>>,
462
    kind: Cell<ModuleKind>,
463
    is_public: bool,
464

E
Eduard Burtescu 已提交
465 466
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
467

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

472 473 474 475 476 477 478 479 480 481 482 483 484 485
    // 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 已提交
486
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
487 488

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

    // The number of unresolved globs that this module exports.
492
    glob_count: Cell<uint>,
493 494

    // The index of the import we're resolving.
495
    resolved_import_count: Cell<uint>,
496 497 498 499

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

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

F
Felix S. Klock II 已提交
526
    fn all_imports_resolved(&self) -> bool {
527
        self.imports.borrow().len() == self.resolved_import_count.get()
528 529 530
    }
}

531 532 533 534 535 536 537 538
bitflags! {
    #[deriving(Show)]
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

539
// Records a possibly-private type definition.
540
#[deriving(Clone)]
F
Felix S. Klock II 已提交
541
struct TypeNsDef {
542
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
543
    module_def: Option<Rc<Module>>,
544
    type_def: Option<Def>,
545
    type_span: Option<Span>
546 547 548
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
549
#[deriving(Clone, Copy, Show)]
F
Felix S. Klock II 已提交
550
struct ValueNsDef {
551
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
552
    def: Def,
553
    value_span: Option<Span>,
554 555
}

556 557
// Records the definitions (at most one for each namespace) that a name is
// bound to.
F
Felix S. Klock II 已提交
558
struct NameBindings {
559
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
560
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
561 562
}

563
/// Ways in which a trait can be referenced
J
Jorge Aparicio 已提交
564
#[deriving(Copy)]
565 566 567 568
enum TraitReferenceType {
    TraitImplementation,             // impl SomeTrait for T { ... }
    TraitDerivation,                 // trait T : SomeTrait { ... }
    TraitBoundingTypeParameter,      // fn f<T:SomeTrait>() { ... }
N
Niko Matsakis 已提交
569
    TraitObject,                     // Box<for<'a> SomeTrait>
570
    TraitQPath,                      // <T as SomeTrait>::
571 572
}

573
impl NameBindings {
K
Kevin Butler 已提交
574 575 576 577 578 579 580
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

581
    /// Creates a new module in this set of name bindings.
582
    fn define_module(&self,
583 584 585 586 587 588
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
589
        // Merges the module with the existing type def or creates a new one.
590
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
591 592 593 594
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
595
                                          is_public));
E
Erick Tryzelaar 已提交
596 597
        let type_def = self.type_def.borrow().clone();
        match type_def {
598
            None => {
E
Erick Tryzelaar 已提交
599
                *self.type_def.borrow_mut() = Some(TypeNsDef {
600
                    modifiers: modifiers,
601
                    module_def: Some(module_),
602 603
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
604
                });
605
            }
606
            Some(type_def) => {
E
Erick Tryzelaar 已提交
607
                *self.type_def.borrow_mut() = Some(TypeNsDef {
608
                    modifiers: modifiers,
609
                    module_def: Some(module_),
610
                    type_span: Some(sp),
611
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
612
                });
613
            }
614 615 616
        }
    }

617
    /// Sets the kind of the module, creating a new one if necessary.
618
    fn set_module_kind(&self,
619 620 621 622 623 624
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
625
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
E
Erick Tryzelaar 已提交
626 627
        let type_def = self.type_def.borrow().clone();
        match type_def {
628
            None => {
629 630 631 632 633
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
634
                *self.type_def.borrow_mut() = Some(TypeNsDef {
635
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
636
                    module_def: Some(Rc::new(module)),
637 638
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
639
                });
640 641 642 643
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
644 645 646 647 648
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
649
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
650
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
651
                            module_def: Some(Rc::new(module)),
652 653
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
654
                        });
655
                    }
656
                    Some(module_def) => module_def.kind.set(kind),
657 658 659 660 661
                }
            }
        }
    }

662
    /// Records a type definition.
663 664
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
        debug!("defining type for def {} with modifiers {}", def, modifiers);
665
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
666 667
        let type_def = self.type_def.borrow().clone();
        match type_def {
668
            None => {
E
Erick Tryzelaar 已提交
669
                *self.type_def.borrow_mut() = Some(TypeNsDef {
670
                    module_def: None,
671
                    type_def: Some(def),
672
                    type_span: Some(sp),
673
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
674
                });
675
            }
676
            Some(type_def) => {
E
Erick Tryzelaar 已提交
677
                *self.type_def.borrow_mut() = Some(TypeNsDef {
678
                    module_def: type_def.module_def,
679
                    type_def: Some(def),
680
                    type_span: Some(sp),
681
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
682
                });
683 684
            }
        }
685 686
    }

687
    /// Records a value definition.
688 689
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
        debug!("defining value for def {} with modifiers {}", def, modifiers);
E
Erick Tryzelaar 已提交
690
        *self.value_def.borrow_mut() = Some(ValueNsDef {
691 692
            def: def,
            value_span: Some(sp),
693
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
694
        });
695 696
    }

697
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
698
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
699
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
700
            Some(ref type_def) => type_def.module_def.clone(),
701
            None => None
702 703 704
        }
    }

S
Steve Klabnik 已提交
705 706
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
707
    fn get_module(&self) -> Rc<Module> {
708 709
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
710
                panic!("get_module called on a node with no module \
711
                       definition!")
712
            }
713
            Some(module_def) => module_def
714 715 716
        }
    }

F
Felix S. Klock II 已提交
717
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
718
        match namespace {
E
Erick Tryzelaar 已提交
719 720
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
721 722 723
        }
    }

F
Felix S. Klock II 已提交
724
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
725 726 727 728
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
729
        match namespace {
E
Erick Tryzelaar 已提交
730
            TypeNS => match *self.type_def.borrow() {
731
                Some(ref def) => def.modifiers.contains(modifiers), None => false
732
            },
E
Erick Tryzelaar 已提交
733
            ValueNS => match *self.value_def.borrow() {
734
                Some(ref def) => def.modifiers.contains(modifiers), None => false
735 736 737 738
            }
        }
    }

F
Felix S. Klock II 已提交
739
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
740
        match namespace {
741
            TypeNS => {
E
Erick Tryzelaar 已提交
742
                match *self.type_def.borrow() {
743
                    None => None,
E
Eduard Burtescu 已提交
744
                    Some(ref type_def) => {
745
                        match type_def.type_def {
746
                            Some(type_def) => Some(type_def),
747 748
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
749
                                    Some(ref module) => {
750
                                        match module.def_id.get() {
751
                                            Some(did) => Some(DefMod(did)),
752 753 754 755 756 757
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
758
                        }
759 760
                    }
                }
761 762
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
763
                match *self.value_def.borrow() {
764 765 766 767 768 769 770
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
771
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
772
        if self.defined_in_namespace(namespace) {
773
            match namespace {
774
                TypeNS  => {
E
Erick Tryzelaar 已提交
775
                    match *self.type_def.borrow() {
776
                        None => None,
E
Eduard Burtescu 已提交
777
                        Some(ref type_def) => type_def.type_span
778 779 780
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
781
                    match *self.value_def.borrow() {
782
                        None => None,
E
Eduard Burtescu 已提交
783
                        Some(ref value_def) => value_def.value_span
784 785
                    }
                }
786
            }
787 788
        } else {
            None
789 790
        }
    }
791 792
}

793
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
794
struct PrimitiveTypeTable {
795
    primitive_types: HashMap<Name, PrimTy>,
796
}
797

798
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
    fn new() -> PrimitiveTypeTable {
        let mut table = PrimitiveTypeTable {
            primitive_types: HashMap::new()
        };

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

        table
    }

823
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
824
        self.primitive_types.insert(token::intern(string), primitive_type);
825 826 827
    }
}

828
/// The main resolver class.
829
struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
830
    session: &'a Session,
831

832 833
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
834
    graph_root: NameBindings,
835

836
    trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
837

838
    structs: FnvHashMap<DefId, Vec<Name>>,
839

840
    // The number of imports that are currently unresolved.
841
    unresolved_imports: uint,
842 843

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
844
    current_module: Rc<Module>,
845 846

    // The current set of local scopes, for values.
847
    // FIXME #4948: Reuse ribs to avoid allocation.
848
    value_ribs: Vec<Rib>,
849 850

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

853
    // The current set of local scopes, for labels.
854
    label_ribs: Vec<Rib>,
855

856
    // The trait that the current context can refer to.
857 858 859 860
    current_trait_ref: Option<(DefId, TraitRef)>,

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

862
    // The ident for the keyword "self".
J
John Clements 已提交
863
    self_name: Name,
864
    // The ident for the non-keyword "Self".
J
John Clements 已提交
865
    type_self_name: Name,
866

867
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
868
    primitive_type_table: PrimitiveTypeTable,
869

870
    def_map: DefMap,
871 872
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
873
    capture_mode_map: CaptureModeMap,
874
    export_map: ExportMap,
875
    trait_map: TraitMap,
876 877
    external_exports: ExternalExports,
    last_private: LastPrivateMap,
878

879 880 881 882 883
    // 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,

884 885 886 887 888
    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,

889
    used_imports: HashSet<(NodeId, Namespace)>,
890
    used_crates: HashSet<CrateNum>,
891 892
}

S
Steven Fackler 已提交
893 894 895 896 897 898 899
#[deriving(PartialEq)]
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}


900 901 902 903 904
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 已提交
905 906 907 908 909 910 911 912 913 914 915 916 917 918
        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,

919 920
            ast_map: ast_map,

K
Kevin Butler 已提交
921 922 923 924 925
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

926
            trait_item_map: FnvHashMap::new(),
K
Kevin Butler 已提交
927 928 929 930 931
            structs: FnvHashMap::new(),

            unresolved_imports: 0,

            current_module: current_module,
932 933 934
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
935 936 937 938

            current_trait_ref: None,
            current_self_type: None,

J
John Clements 已提交
939 940
            self_name: special_names::self_,
            type_self_name: special_names::type_self,
K
Kevin Butler 已提交
941 942 943 944

            primitive_type_table: PrimitiveTypeTable::new(),

            def_map: RefCell::new(NodeMap::new()),
945 946
            freevars: RefCell::new(NodeMap::new()),
            freevars_seen: RefCell::new(NodeMap::new()),
947
            capture_mode_map: NodeMap::new(),
948
            export_map: NodeMap::new(),
K
Kevin Butler 已提交
949 950
            trait_map: NodeMap::new(),
            used_imports: HashSet::new(),
951
            used_crates: HashSet::new(),
K
Kevin Butler 已提交
952 953 954 955
            external_exports: DefIdSet::new(),
            last_private: NodeMap::new(),

            emit_errors: true,
956 957
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
958 959
        }
    }
960 961 962 963 964 965 966 967 968

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

969 970
    /// Resolves all imports for the crate. This method performs the fixed-
    /// point iteration.
F
Felix S. Klock II 已提交
971
    fn resolve_imports(&mut self) {
972
        let mut i = 0u;
T
Tim Chevalier 已提交
973
        let mut prev_unresolved_imports = 0;
974
        loop {
975
            debug!("(resolving imports) iteration {}, {} imports left",
P
Paul Stansifer 已提交
976
                   i, self.unresolved_imports);
977

978
            let module_root = self.graph_root.get_module();
E
Eduard Burtescu 已提交
979
            self.resolve_imports_for_module_subtree(module_root.clone());
980

T
Tim Chevalier 已提交
981
            if self.unresolved_imports == 0 {
982
                debug!("(resolving imports) success");
983 984 985 986 987 988 989 990
                break;
            }

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

T
Tim Chevalier 已提交
991
            i += 1;
992 993 994 995
            prev_unresolved_imports = self.unresolved_imports;
        }
    }

996 997
    /// Attempts to resolve imports for the given module and all of its
    /// submodules.
E
Eduard Burtescu 已提交
998
    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
999
        debug!("(resolving imports for module subtree) resolving {}",
1000
               self.module_to_string(&*module_));
1001
        let orig_module = replace(&mut self.current_module, module_.clone());
E
Eduard Burtescu 已提交
1002
        self.resolve_imports_for_module(module_.clone());
1003
        self.current_module = orig_module;
1004

1005
        build_reduced_graph::populate_module_if_necessary(self, &module_);
E
Eduard Burtescu 已提交
1006
        for (_, child_node) in module_.children.borrow().iter() {
1007 1008 1009 1010 1011 1012
            match child_node.get_module_if_available() {
                None => {
                    // Nothing to do.
                }
                Some(child_module) => {
                    self.resolve_imports_for_module_subtree(child_module);
1013 1014 1015 1016
                }
            }
        }

E
Eduard Burtescu 已提交
1017 1018
        for (_, child_module) in module_.anonymous_children.borrow().iter() {
            self.resolve_imports_for_module_subtree(child_module.clone());
1019 1020 1021
        }
    }

1022
    /// Attempts to resolve imports for the given module only.
E
Eduard Burtescu 已提交
1023
    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
1024
        if module.all_imports_resolved() {
1025
            debug!("(resolving imports for module) all imports resolved for \
A
Alex Crichton 已提交
1026
                   {}",
1027
                   self.module_to_string(&*module));
B
Brian Anderson 已提交
1028
            return;
1029 1030
        }

1031
        let imports = module.imports.borrow();
1032
        let import_count = imports.len();
1033 1034
        while module.resolved_import_count.get() < import_count {
            let import_index = module.resolved_import_count.get();
1035
            let import_directive = &(*imports)[import_index];
1036 1037
            match self.resolve_import_for_module(module.clone(),
                                                 import_directive) {
1038 1039 1040 1041 1042 1043
                Failed(err) => {
                    let (span, help) = match err {
                        Some((span, msg)) => (span, format!(". {}", msg)),
                        None => (import_directive.span, String::new())
                    };
                    let msg = format!("unresolved import `{}`{}",
1044
                                      self.import_path_to_string(
1045
                                          import_directive.module_path
A
Alex Crichton 已提交
1046
                                                          [],
1047 1048
                                          import_directive.subclass),
                                      help);
A
Alex Crichton 已提交
1049
                    self.resolve_error(span, msg[]);
1050
                }
1051 1052
                Indeterminate => break, // Bail out. We'll come around next time.
                Success(()) => () // Good. Continue.
1053 1054
            }

1055 1056
            module.resolved_import_count
                  .set(module.resolved_import_count.get() + 1);
1057 1058 1059
        }
    }

1060
    fn names_to_string(&self, names: &[Name]) -> String {
1061
        let mut first = true;
1062
        let mut result = String::new();
1063
        for name in names.iter() {
1064 1065 1066 1067 1068
            if first {
                first = false
            } else {
                result.push_str("::")
            }
1069
            result.push_str(token::get_name(*name).get());
1070
        };
1071
        result
P
Paul Stansifer 已提交
1072
    }
1073

1074 1075 1076 1077 1078
    fn path_names_to_string(&self, path: &Path) -> String {
        let names: Vec<ast::Name> = path.segments
                                        .iter()
                                        .map(|seg| seg.identifier.name)
                                        .collect();
A
Alex Crichton 已提交
1079
        self.names_to_string(names[])
1080 1081
    }

1082
    fn import_directive_subclass_to_string(&mut self,
P
Patrick Walton 已提交
1083
                                        subclass: ImportDirectiveSubclass)
1084
                                        -> String {
1085
        match subclass {
1086
            SingleImport(_, source) => {
1087
                token::get_name(source).get().to_string()
P
Patrick Walton 已提交
1088
            }
1089
            GlobImport => "*".to_string()
1090 1091
        }
    }
1092

1093
    fn import_path_to_string(&mut self,
1094
                          names: &[Name],
P
Patrick Walton 已提交
1095
                          subclass: ImportDirectiveSubclass)
1096
                          -> String {
1097
        if names.is_empty() {
1098
            self.import_directive_subclass_to_string(subclass)
1099
        } else {
A
Alex Crichton 已提交
1100
            (format!("{}::{}",
1101
                     self.names_to_string(names),
1102
                     self.import_directive_subclass_to_string(
1103
                         subclass))).to_string()
1104 1105
        }
    }
1106

1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
    #[inline]
    fn record_import_use(&mut self, import_id: NodeId, name: Name) {
        if !self.make_glob_map {
            return;
        }
        if self.glob_map.contains_key(&import_id) {
            self.glob_map[import_id].insert(name);
            return;
        }

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

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

1130 1131 1132 1133 1134
    /// 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 已提交
1135
    fn resolve_import_for_module(&mut self,
E
Eduard Burtescu 已提交
1136 1137
                                 module_: Rc<Module>,
                                 import_directive: &ImportDirective)
1138
                                 -> ResolveResult<()> {
1139
        let mut resolution_result = Failed(None);
A
Alex Crichton 已提交
1140
        let module_path = &import_directive.module_path;
1141

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

1146
        // First, resolve the module path for the directive, if necessary.
1147
        let container = if module_path.len() == 0 {
1148
            // Use the crate root.
1149
            Some((self.graph_root.get_module(), LastMod(AllPublic)))
1150
        } else {
E
Eduard Burtescu 已提交
1151
            match self.resolve_module_path(module_.clone(),
A
Alex Crichton 已提交
1152
                                           module_path[],
1153 1154 1155
                                           DontUseLexicalScope,
                                           import_directive.span,
                                           ImportSearch) {
1156 1157 1158 1159
                Failed(err) => {
                    resolution_result = Failed(err);
                    None
                },
B
Brian Anderson 已提交
1160
                Indeterminate => {
1161
                    resolution_result = Indeterminate;
1162
                    None
1163
                }
1164
                Success(container) => Some(container),
1165 1166 1167
            }
        };

1168
        match container {
1169
            None => {}
1170
            Some((containing_module, lp)) => {
1171 1172 1173
                // We found the module that the target is contained
                // within. Attempt to resolve the import within it.

E
Eduard Burtescu 已提交
1174
                match import_directive.subclass {
1175
                    SingleImport(target, source) => {
1176
                        resolution_result =
E
Eduard Burtescu 已提交
1177
                            self.resolve_single_import(&*module_,
1178 1179
                                                       containing_module,
                                                       target,
1180
                                                       source,
1181 1182
                                                       import_directive,
                                                       lp);
1183 1184 1185
                    }
                    GlobImport => {
                        resolution_result =
E
Eduard Burtescu 已提交
1186
                            self.resolve_glob_import(&*module_,
1187
                                                     containing_module,
1188
                                                     import_directive,
1189
                                                     lp);
1190 1191 1192 1193 1194 1195
                    }
                }
            }
        }

        // Decrement the count of unresolved imports.
1196
        match resolution_result {
B
Brian Anderson 已提交
1197
            Success(()) => {
P
Patrick Walton 已提交
1198
                assert!(self.unresolved_imports >= 1);
T
Tim Chevalier 已提交
1199
                self.unresolved_imports -= 1;
1200
            }
B
Brian Anderson 已提交
1201
            _ => {
1202 1203 1204 1205 1206 1207 1208 1209 1210
                // 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.)

1211
        if !resolution_result.indeterminate() {
E
Eduard Burtescu 已提交
1212
            match import_directive.subclass {
B
Brian Anderson 已提交
1213
                GlobImport => {
1214 1215
                    assert!(module_.glob_count.get() >= 1);
                    module_.glob_count.set(module_.glob_count.get() - 1);
1216
                }
A
Alex Crichton 已提交
1217
                SingleImport(..) => {
1218 1219 1220 1221 1222
                    // Ignore.
                }
            }
        }

B
Brian Anderson 已提交
1223
        return resolution_result;
1224 1225
    }

E
Eduard Burtescu 已提交
1226
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1227
        NameBindings {
1228
            type_def: RefCell::new(Some(TypeNsDef {
1229
                modifiers: IMPORTABLE,
1230 1231
                module_def: Some(module),
                type_def: None,
1232
                type_span: None
1233
            })),
1234
            value_def: RefCell::new(None),
1235 1236 1237
        }
    }

F
Felix S. Klock II 已提交
1238
    fn resolve_single_import(&mut self,
E
Eduard Burtescu 已提交
1239 1240
                             module_: &Module,
                             containing_module: Rc<Module>,
1241 1242
                             target: Name,
                             source: Name,
1243 1244
                             directive: &ImportDirective,
                             lp: LastPrivate)
1245
                                 -> ResolveResult<()> {
1246
        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
L
Luqman Aden 已提交
1247
                `{}` id {}, last private {}",
1248
               token::get_name(target),
1249
               self.module_to_string(&*containing_module),
1250
               token::get_name(source),
1251
               self.module_to_string(module_),
1252 1253
               directive.id,
               lp);
1254

1255 1256
        let lp = match lp {
            LastMod(lp) => lp,
1257 1258 1259 1260 1261
            LastImport {..} => {
                self.session
                    .span_bug(directive.span,
                              "not expecting Import here, must be LastMod")
            }
1262 1263
        };

1264
        // We need to resolve both namespaces for this to succeed.
1265 1266 1267 1268 1269 1270
        //

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

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

1273
        match containing_module.children.borrow().get(&source) {
1274 1275 1276
            None => {
                // Continue.
            }
E
Eduard Burtescu 已提交
1277
            Some(ref child_name_bindings) => {
1278
                if child_name_bindings.defined_in_namespace(ValueNS) {
1279
                    debug!("(resolving single import) found value binding");
E
Eduard Burtescu 已提交
1280 1281
                    value_result = BoundResult(containing_module.clone(),
                                               (*child_name_bindings).clone());
1282
                }
1283
                if child_name_bindings.defined_in_namespace(TypeNS) {
1284
                    debug!("(resolving single import) found type binding");
E
Eduard Burtescu 已提交
1285 1286
                    type_result = BoundResult(containing_module.clone(),
                                              (*child_name_bindings).clone());
1287 1288 1289 1290
                }
            }
        }

1291 1292
        // Unless we managed to find a result in both namespaces (unlikely),
        // search imports as well.
1293 1294
        let mut value_used_reexport = false;
        let mut type_used_reexport = false;
E
Eduard Burtescu 已提交
1295
        match (value_result.clone(), type_result.clone()) {
A
Alex Crichton 已提交
1296
            (BoundResult(..), BoundResult(..)) => {} // Continue.
B
Brian Anderson 已提交
1297
            _ => {
1298 1299 1300 1301
                // 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.

1302
                if containing_module.glob_count.get() > 0 {
1303
                    debug!("(resolving single import) unresolved glob; \
P
Paul Stansifer 已提交
1304
                            bailing out");
B
Brian Anderson 已提交
1305
                    return Indeterminate;
1306 1307
                }

E
Eduard Burtescu 已提交
1308
                // Now search the exported imports within the containing module.
1309
                match containing_module.import_resolutions.borrow().get(&source) {
B
Brian Anderson 已提交
1310
                    None => {
1311
                        debug!("(resolving single import) no import");
1312 1313 1314 1315 1316
                        // 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.

1317
                        if value_result.is_unknown() {
1318 1319
                            value_result = UnboundResult;
                        }
1320
                        if type_result.is_unknown() {
1321 1322 1323
                            type_result = UnboundResult;
                        }
                    }
B
Brian Anderson 已提交
1324
                    Some(import_resolution)
E
Eduard Burtescu 已提交
1325
                            if import_resolution.outstanding_references == 0 => {
1326

A
Alex Crichton 已提交
1327
                        fn get_binding(this: &mut Resolver,
E
Eduard Burtescu 已提交
1328
                                       import_resolution: &ImportResolution,
1329 1330
                                       namespace: Namespace,
                                       source: &Name)
1331
                                    -> NamespaceResult {
T
Tim Chevalier 已提交
1332

1333 1334
                            // Import resolutions must be declared with "pub"
                            // in order to be exported.
E
Eduard Burtescu 已提交
1335
                            if !import_resolution.is_public {
1336 1337 1338
                                return UnboundResult;
                            }

E
Eduard Burtescu 已提交
1339
                            match import_resolution.
1340
                                    target_for_namespace(namespace) {
B
Brian Anderson 已提交
1341
                                None => {
B
Brian Anderson 已提交
1342
                                    return UnboundResult;
1343
                                }
1344 1345 1346 1347 1348
                                Some(Target {
                                    target_module,
                                    bindings,
                                    shadowable: _
                                }) => {
1349
                                    debug!("(resolving single import) found \
L
Luqman Aden 已提交
1350
                                            import in ns {}", namespace);
1351
                                    let id = import_resolution.id(namespace);
1352
                                    // track used imports and extern crates as well
1353
                                    this.used_imports.insert((id, namespace));
1354
                                    this.record_import_use(id, *source);
1355 1356 1357 1358 1359 1360
                                    match target_module.def_id.get() {
                                        Some(DefId{krate: kid, ..}) => {
                                            this.used_crates.insert(kid);
                                        },
                                        _ => {}
                                    }
E
Eduard Burtescu 已提交
1361
                                    return BoundResult(target_module, bindings);
1362 1363 1364 1365 1366 1367
                                }
                            }
                        }

                        // The name is an import which has been fully
                        // resolved. We can, therefore, just follow it.
1368
                        if value_result.is_unknown() {
1369 1370 1371 1372
                            value_result = get_binding(self,
                                                       import_resolution,
                                                       ValueNS,
                                                       &source);
E
Eduard Burtescu 已提交
1373
                            value_used_reexport = import_resolution.is_public;
1374
                        }
1375
                        if type_result.is_unknown() {
1376 1377 1378 1379
                            type_result = get_binding(self,
                                                      import_resolution,
                                                      TypeNS,
                                                      &source);
E
Eduard Burtescu 已提交
1380
                            type_used_reexport = import_resolution.is_public;
1381
                        }
1382

1383
                    }
B
Brian Anderson 已提交
1384
                    Some(_) => {
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
                        // 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;
                            }
                        }
1413 1414 1415 1416 1417
                    }
                }
            }
        }

1418 1419
        // If we didn't find a result in the type namespace, search the
        // external modules.
1420 1421
        let mut value_used_public = false;
        let mut type_used_public = false;
1422
        match type_result {
A
Alex Crichton 已提交
1423
            BoundResult(..) => {}
1424
            _ => {
1425
                match containing_module.external_module_children.borrow_mut()
1426
                                       .get(&source).cloned() {
1427 1428
                    None => {} // Continue.
                    Some(module) => {
1429 1430
                        debug!("(resolving single import) found external \
                                module");
1431 1432 1433 1434 1435
                        // track the module as used.
                        match module.def_id.get() {
                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
                            _ => {}
                        }
1436
                        let name_bindings =
E
Eduard Burtescu 已提交
1437 1438 1439
                            Rc::new(Resolver::create_name_bindings_from_module(
                                module));
                        type_result = BoundResult(containing_module.clone(),
1440
                                                  name_bindings);
1441
                        type_used_public = true;
1442 1443 1444 1445 1446
                    }
                }
            }
        }

1447
        // We've successfully resolved the import. Write the results in.
E
Eduard Burtescu 已提交
1448
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1449
        let import_resolution = &mut (*import_resolutions)[target];
1450 1451 1452 1453 1454 1455
        {
            let check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
                let namespace_name = match namespace {
                    TypeNS => "type",
                    ValueNS => "value",
                };
1456

1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488
                match *result {
                    BoundResult(ref target_module, ref name_bindings) => {
                        debug!("(resolving single import) found {} target: {}",
                               namespace_name,
                               name_bindings.def_for_namespace(namespace));
                        self.check_for_conflicting_import(
                            &import_resolution.target_for_namespace(namespace),
                            directive.span,
                            target,
                            namespace);

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

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

1491 1492 1493 1494
        self.check_for_conflicts_between_imports_and_items(
            module_,
            import_resolution,
            directive.span,
1495
            target);
1496

1497
        if value_result.is_unbound() && type_result.is_unbound() {
1498
            let msg = format!("There is no `{}` in `{}`",
1499
                              token::get_name(source),
1500
                              self.module_to_string(&*containing_module));
1501
            return Failed(Some((directive.span, msg)));
1502
        }
1503 1504
        let value_used_public = value_used_reexport || value_used_public;
        let type_used_public = type_used_reexport || type_used_public;
1505

E
Eduard Burtescu 已提交
1506 1507
        assert!(import_resolution.outstanding_references >= 1);
        import_resolution.outstanding_references -= 1;
1508

A
Alex Crichton 已提交
1509 1510 1511
        // 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 已提交
1512 1513
        let value_private = match import_resolution.value_target {
            Some(ref target) => {
1514
                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
1515
                self.def_map.borrow_mut().insert(directive.id, def);
1516
                let did = def.def_id();
1517 1518 1519 1520 1521 1522
                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 已提交
1523 1524
        let type_private = match import_resolution.type_target {
            Some(ref target) => {
1525
                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
1526
                self.def_map.borrow_mut().insert(directive.id, def);
1527
                let did = def.def_id();
1528 1529 1530 1531 1532 1533 1534 1535 1536
                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 已提交
1537

1538
        debug!("(resolving single import) successfully resolved import");
B
Brian Anderson 已提交
1539
        return Success(());
1540 1541
    }

1542
    // Resolves a glob import. Note that this function cannot fail; it either
1543
    // succeeds or bails out (as importing * from an empty module or a module
1544 1545
    // 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 已提交
1546
    fn resolve_glob_import(&mut self,
E
Eduard Burtescu 已提交
1547 1548
                           module_: &Module,
                           containing_module: Rc<Module>,
1549
                           import_directive: &ImportDirective,
1550 1551
                           lp: LastPrivate)
                           -> ResolveResult<()> {
1552 1553 1554
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1555 1556 1557
        // This function works in a highly imperative manner; it eagerly adds
        // everything it can to the list of import resolutions of the module
        // node.
1558
        debug!("(resolving glob import) resolving glob import {}", id);
1559 1560 1561 1562

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

1568
        assert_eq!(containing_module.glob_count.get(), 0);
1569 1570

        // Add all resolved imports from the containing module.
1571
        let import_resolutions = containing_module.import_resolutions.borrow();
1572
        for (ident, target_import_resolution) in import_resolutions.iter() {
1573
            debug!("(resolving glob import) writing module resolution \
L
Luqman Aden 已提交
1574
                    {} into `{}`",
1575
                   token::get_name(*ident),
1576
                   self.module_to_string(module_));
1577

E
Eduard Burtescu 已提交
1578
            if !target_import_resolution.is_public {
1579
                debug!("(resolving glob import) nevermind, just kidding");
1580 1581 1582
                continue
            }

1583
            // Here we merge two import resolutions.
1584
            let mut import_resolutions = module_.import_resolutions.borrow_mut();
1585
            match import_resolutions.get_mut(ident) {
E
Eduard Burtescu 已提交
1586
                Some(dest_import_resolution) => {
1587 1588 1589
                    // Merge the two import resolutions at a finer-grained
                    // level.

E
Eduard Burtescu 已提交
1590
                    match target_import_resolution.value_target {
B
Brian Anderson 已提交
1591
                        None => {
1592 1593
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1594
                        Some(ref value_target) => {
1595 1596 1597 1598
                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
                                                              import_directive.span,
                                                              *ident,
                                                              ValueNS);
1599
                            dest_import_resolution.value_target = Some(value_target.clone());
1600 1601
                        }
                    }
E
Eduard Burtescu 已提交
1602
                    match target_import_resolution.type_target {
B
Brian Anderson 已提交
1603
                        None => {
1604 1605
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1606
                        Some(ref type_target) => {
1607 1608 1609 1610
                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
                                                              import_directive.span,
                                                              *ident,
                                                              TypeNS);
1611
                            dest_import_resolution.type_target = Some(type_target.clone());
1612 1613
                        }
                    }
E
Eduard Burtescu 已提交
1614 1615
                    dest_import_resolution.is_public = is_public;
                    continue;
1616
                }
E
Eduard Burtescu 已提交
1617
                None => {}
1618
            }
E
Eduard Burtescu 已提交
1619 1620 1621 1622 1623 1624 1625 1626 1627

            // 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);
1628 1629
        }

1630
        // Add all children from the containing module.
1631
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
1632

1633
        for (&name, name_bindings) in containing_module.children.borrow().iter() {
1634 1635 1636 1637 1638 1639
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings.clone());

1640 1641 1642
        }

        // Add external module children from the containing module.
1643
        for (&name, module) in containing_module.external_module_children.borrow().iter() {
1644
            let name_bindings =
E
Eduard Burtescu 已提交
1645
                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
1646 1647 1648 1649 1650
            self.merge_import_resolution(module_,
                                         containing_module.clone(),
                                         import_directive,
                                         name,
                                         name_bindings);
1651 1652
        }

A
Alex Crichton 已提交
1653
        // Record the destination of this import
1654
        match containing_module.def_id.get() {
A
Alex Crichton 已提交
1655
            Some(did) => {
1656
                self.def_map.borrow_mut().insert(id, DefMod(did));
1657
                self.last_private.insert(id, lp);
A
Alex Crichton 已提交
1658 1659 1660 1661
            }
            None => {}
        }

1662
        debug!("(resolving glob import) successfully resolved import");
B
Brian Anderson 已提交
1663
        return Success(());
1664 1665
    }

1666
    fn merge_import_resolution(&mut self,
E
Eduard Burtescu 已提交
1667 1668
                               module_: &Module,
                               containing_module: Rc<Module>,
1669
                               import_directive: &ImportDirective,
1670
                               name: Name,
E
Eduard Burtescu 已提交
1671
                               name_bindings: Rc<NameBindings>) {
1672 1673 1674
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1675
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1676
        let dest_import_resolution = match import_resolutions.entry(name) {
1677 1678 1679
            Occupied(entry) => {
                entry.into_mut()
            }
1680 1681 1682 1683 1684
            Vacant(entry) => {
                // Create a new import resolution from this child.
                entry.set(ImportResolution::new(id, is_public))
            }
        };
1685 1686 1687

        debug!("(resolving glob import) writing resolution `{}` in `{}` \
               to `{}`",
1688
               token::get_name(name).get(),
1689 1690
               self.module_to_string(&*containing_module),
               self.module_to_string(module_));
1691 1692

        // Merge the child item into the import resolution.
1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718
        {
            let merge_child_item = |namespace| {
                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
                    let namespace_name = match namespace {
                        TypeNS => "type",
                        ValueNS => "value",
                    };
                    debug!("(resolving glob import) ... for {} target", namespace_name);
                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
                        let msg = format!("a {} named `{}` has already been imported \
                                           in this module",
                                          namespace_name,
                                          token::get_name(name).get());
                        self.session.span_err(import_directive.span, msg.as_slice());
                    } else {
                        let target = Target::new(containing_module.clone(),
                                                 name_bindings.clone(),
                                                 import_directive.shadowable);
                        dest_import_resolution.set_target_and_id(namespace,
                                                                 Some(target),
                                                                 id);
                    }
                }
            };
            merge_child_item(ValueNS);
            merge_child_item(TypeNS);
1719
        }
1720

E
Eduard Burtescu 已提交
1721
        dest_import_resolution.is_public = is_public;
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735

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

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

1740 1741 1742 1743
        debug!("check_for_conflicting_import: {}; target exists: {}",
               token::get_name(name).get(),
               target.is_some());

1744
        match *target {
1745
            Some(ref target) if target.shadowable != Shadowable::Always => {
1746 1747 1748 1749 1750 1751 1752
                let msg = format!("a {} named `{}` has already been imported \
                                   in this module",
                                  match namespace {
                                    TypeNS => "type",
                                    ValueNS => "value",
                                  },
                                  token::get_name(name).get());
A
Alex Crichton 已提交
1753
                self.session.span_err(import_span, msg[]);
1754 1755 1756 1757 1758
            }
            Some(_) | None => {}
        }
    }

1759 1760 1761 1762 1763 1764 1765 1766 1767
    /// Checks that an import is actually importable
    fn check_that_import_is_importable(&mut self,
                                       name_bindings: &NameBindings,
                                       import_span: Span,
                                       name: Name,
                                       namespace: Namespace) {
        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
            let msg = format!("`{}` is not directly importable",
                              token::get_name(name));
A
Alex Crichton 已提交
1768
            self.session.span_err(import_span, msg[]);
1769 1770 1771
        }
    }

1772 1773 1774 1775
    /// 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:
1776
                                                     &ImportResolution,
1777 1778
                                                     import_span: Span,
                                                     name: Name) {
N
Nick Cameron 已提交
1779
        if self.session.features.borrow().import_shadowing {
1780 1781 1782 1783 1784 1785 1786 1787
            return
        }

        // First, check for conflicts between imports and `extern crate`s.
        if module.external_module_children
                 .borrow()
                 .contains_key(&name) {
            match import_resolution.type_target {
1788
                Some(ref target) if target.shadowable != Shadowable::Always => {
1789 1790 1791
                    let msg = format!("import `{0}` conflicts with imported \
                                       crate in this module \
                                       (maybe you meant `use {0}::*`?)",
1792
                                      token::get_name(name).get());
A
Alex Crichton 已提交
1793
                    self.session.span_err(import_span, msg[]);
1794 1795 1796 1797 1798 1799 1800
                }
                Some(_) | None => {}
            }
        }

        // Check for item conflicts.
        let children = module.children.borrow();
1801
        let name_bindings = match children.get(&name) {
1802 1803 1804 1805 1806 1807 1808 1809
            None => {
                // There can't be any conflicts.
                return
            }
            Some(ref name_bindings) => (*name_bindings).clone(),
        };

        match import_resolution.value_target {
1810
            Some(ref target) if target.shadowable != Shadowable::Always => {
1811 1812 1813 1814
                if let Some(ref value) = *name_bindings.value_def.borrow() {
                    let msg = format!("import `{}` conflicts with value \
                                       in this module",
                                      token::get_name(name).get());
A
Alex Crichton 已提交
1815
                    self.session.span_err(import_span, msg[]);
1816 1817
                    if let Some(span) = value.value_span {
                        self.session.span_note(span,
C
Colin Davidson 已提交
1818
                                               "conflicting value here");
1819 1820 1821 1822 1823 1824 1825
                    }
                }
            }
            Some(_) | None => {}
        }

        match import_resolution.type_target {
1826
            Some(ref target) if target.shadowable != Shadowable::Always => {
1827 1828 1829 1830 1831 1832
                if let Some(ref ty) = *name_bindings.type_def.borrow() {
                    match ty.module_def {
                        None => {
                            let msg = format!("import `{}` conflicts with type in \
                                               this module",
                                              token::get_name(name).get());
A
Alex Crichton 已提交
1833
                            self.session.span_err(import_span, msg[]);
1834 1835
                            if let Some(span) = ty.type_span {
                                self.session.span_note(span,
1836 1837
                                                       "note conflicting type here")
                            }
1838 1839 1840 1841 1842 1843 1844 1845
                        }
                        Some(ref module_def) => {
                            match module_def.kind.get() {
                                ImplModuleKind => {
                                    if let Some(span) = ty.type_span {
                                        let msg = format!("inherent implementations \
                                                           are only allowed on types \
                                                           defined in the current module");
A
Alex Crichton 已提交
1846
                                        self.session.span_err(span, msg[]);
1847
                                        self.session.span_note(import_span,
1848 1849
                                                               "import from other module here")
                                    }
1850 1851 1852 1853 1854
                                }
                                _ => {
                                    let msg = format!("import `{}` conflicts with existing \
                                                       submodule",
                                                      token::get_name(name).get());
A
Alex Crichton 已提交
1855
                                    self.session.span_err(import_span, msg[]);
1856 1857
                                    if let Some(span) = ty.type_span {
                                        self.session.span_note(span,
1858 1859 1860
                                                               "note conflicting module here")
                                    }
                                }
1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875
                            }
                        }
                    }
                }
            }
            Some(_) | None => {}
        }
    }

    /// Checks that the names of external crates don't collide with other
    /// external crates.
    fn check_for_conflicts_between_external_crates(&self,
                                                   module: &Module,
                                                   name: Name,
                                                   span: Span) {
N
Nick Cameron 已提交
1876
        if self.session.features.borrow().import_shadowing {
1877 1878 1879 1880 1881 1882 1883 1884
            return
        }

        if module.external_module_children.borrow().contains_key(&name) {
            self.session
                .span_err(span,
                          format!("an external crate named `{}` has already \
                                   been imported into this module",
A
Alex Crichton 已提交
1885
                                  token::get_name(name).get())[]);
1886 1887 1888 1889 1890 1891 1892 1893
        }
    }

    /// Checks that the names of items don't collide with external crates.
    fn check_for_conflicts_between_external_crates_and_items(&self,
                                                             module: &Module,
                                                             name: Name,
                                                             span: Span) {
N
Nick Cameron 已提交
1894
        if self.session.features.borrow().import_shadowing {
1895 1896 1897 1898 1899 1900 1901 1902 1903
            return
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2205
        // Finally, proceed up the scope chain looking for parent modules.
2206
        let mut search_module = module_;
2207 2208
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
2209
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
2210
                NoParentLink => {
2211
                    // No more parents. This module was unresolved.
2212
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
2213
                            module");
2214
                    return Failed(None);
2215
                }
2216
                ModuleParentLink(parent_module_node, _) => {
2217 2218 2219 2220 2221 2222 2223
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
2224
                            return Failed(None);
2225
                        }
2226 2227
                        TraitModuleKind |
                        ImplModuleKind |
2228
                        EnumModuleKind |
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 2246
                Failed(Some((span, msg))) =>
                    self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
2247
                                                     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 2327 2328 2329 2330 2331 2332
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

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

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

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

        return Success(PrefixFound(containing_module, i));
2396 2397
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

A
Alex Crichton 已提交
2584
        f(self);
2585 2586 2587 2588

        self.current_module = orig_module;
    }

2589
    /// Wraps the given definition in the appropriate number of `DefUpvar`
2590
    /// wrappers.
E
Eduard Burtescu 已提交
2591
    fn upvarify(&self,
E
Eduard Burtescu 已提交
2592
                ribs: &[Rib],
E
Eduard Burtescu 已提交
2593 2594 2595
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
2596
        match def_like {
2597 2598
            DlDef(d @ DefUpvar(..)) => {
                self.session.span_bug(span,
A
Alex Crichton 已提交
2599
                    format!("unexpected {} in bindings", d)[])
2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
            }
            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;
                            }
2615
                            def = DefUpvar(node_id, function_id, last_proc_body_id);
2616

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

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

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

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

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

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

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

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

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

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

                        }
                    }
2726
                }
2727
                Some(DlDef(def))
2728
            }
2729
            _ => Some(def_like)
2730 2731 2732
        }
    }

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

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

2753
        None
2754 2755
    }

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

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

2780
        visit::walk_crate(self, krate);
2781 2782
    }

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

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

2789
        match item.node {
2790 2791 2792

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

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

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

2829 2830
            ItemImpl(_,
                     ref generics,
2831 2832
                     ref implemented_traits,
                     ref self_type,
2833
                     ref impl_items) => {
2834
                self.resolve_implementation(item.id,
2835
                                            generics,
2836
                                            implemented_traits,
2837
                                            &**self_type,
A
Alex Crichton 已提交
2838
                                            impl_items[]);
2839 2840
            }

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

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

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

2859 2860 2861
                    this.resolve_type_parameter_bounds(item.id, bounds,
                                                       TraitDerivation);

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

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

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

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

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

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

2910
                self.type_ribs.pop();
2911 2912
            }

2913
            ItemStruct(ref struct_def, ref generics) => {
2914
                self.resolve_struct(item.id,
2915
                                    generics,
A
Alex Crichton 已提交
2916
                                    struct_def.fields[]);
2917 2918
            }

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

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

2947
            ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
2948
                self.resolve_function(ItemRibKind,
2949
                                      Some(&**fn_decl),
2950
                                      HasTypeParameters
2951
                                        (generics,
2952
                                         FnSpace,
2953
                                         item.id,
2954
                                         ItemRibKind),
2955
                                      &**block);
2956 2957
            }

2958
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2959
                self.with_constant_rib(|this| {
2960
                    visit::walk_item(this, item);
2961
                });
2962
            }
2963

2964 2965 2966
           ItemMac(..) => {
                // do nothing, these are just around to be encoded
           }
2967 2968 2969
        }
    }

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

2982
                    if seen_bindings.contains(&name) {
2983 2984 2985 2986 2987
                        self.resolve_error(type_parameter.span,
                                           format!("the name `{}` is already \
                                                    used for a type \
                                                    parameter in this type \
                                                    parameter list",
2988
                                                   token::get_name(
A
Alex Crichton 已提交
2989
                                                       name))[])
2990
                    }
2991
                    seen_bindings.insert(name);
2992

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

B
Brian Anderson 已提交
3007
            NoTypeParameters => {
3008 3009 3010 3011
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
3012
        f(self);
3013

3014
        match type_parameters {
3015
            HasTypeParameters(..) => { self.type_ribs.pop(); }
3016
            NoTypeParameters => { }
3017 3018 3019
        }
    }

J
Jorge Aparicio 已提交
3020 3021 3022
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
3023
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
3024
        f(self);
3025
        self.label_ribs.pop();
3026
    }
3027

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

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

3047
        // Create a label rib for the function.
E
Eduard Burtescu 已提交
3048
        let function_label_rib = Rib::new(rib_kind);
3049
        self.label_ribs.push(function_label_rib);
3050

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

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

3076
                        this.resolve_type(&*argument.ty);
3077

3078
                        debug!("(resolving function) recorded argument");
3079 3080
                    }

3081 3082 3083
                    if let ast::Return(ref ret_ty) = declaration.output {
                        this.resolve_type(&**ret_ty);
                    }
3084 3085 3086 3087
                }
            }

            // Resolve the function body.
3088
            this.resolve_block(&*block);
3089

3090
            debug!("(resolving function) leaving function");
3091
        });
3092

3093 3094
        self.label_ribs.pop();
        self.value_ribs.pop();
3095 3096
    }

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

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

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

A
Alex Crichton 已提交
3160
                let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
A
Alex Crichton 已提交
3161
                self.resolve_error(trait_reference.path.span, msg[]);
3162 3163
            }
            Some(def) => {
3164 3165
                match def {
                    (DefTrait(_), _) => {
L
Luqman Aden 已提交
3166
                        debug!("(resolving trait) found trait def: {}", def);
3167 3168 3169 3170 3171
                        self.record_def(trait_reference.ref_id, def);
                    }
                    (def, _) => {
                        self.resolve_error(trait_reference.path.span,
                                           format!("`{}` is not a trait",
3172
                                                   self.path_names_to_string(
A
Alex Crichton 已提交
3173
                                                       &trait_reference.path))[]);
3174 3175

                        // If it's a typedef, give a note
3176 3177 3178 3179
                        if let DefTy(..) = def {
                            self.session.span_note(
                                trait_reference.path.span,
                                format!("`type` aliases cannot be used for traits")
A
Alex Crichton 已提交
3180
                                    []);
3181 3182 3183
                        }
                    }
                }
3184 3185 3186 3187
            }
        }
    }

3188 3189
    fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
        for predicate in where_clause.predicates.iter() {
3190
            match predicate {
N
Nick Cameron 已提交
3191
                &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
3192
                    self.resolve_type(&*bound_pred.bounded_ty);
3193 3194

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

3211 3212
                    self.resolve_type(&*eq_pred.ty);
                }
3213 3214 3215 3216
            }
        }
    }

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

3231
            // Resolve fields.
D
Daniel Micay 已提交
3232
            for field in fields.iter() {
3233
                this.resolve_type(&*field.node.ty);
3234
            }
3235
        });
3236 3237
    }

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

3249 3250
        if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
            self.resolve_type(&**typ);
3251 3252 3253 3254 3255
        }

        self.resolve_function(rib_kind,
                              Some(method.pe_fn_decl()),
                              type_parameters,
3256
                              method.pe_body());
3257 3258
    }

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

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

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

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

                                this.resolve_type(&*typedef.typ);
                            }
3338
                        }
3339
                    }
3340 3341
                });
            });
3342
        });
3343 3344 3345 3346 3347 3348 3349 3350 3351 3352

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

3369
    fn check_trait_item(&self, name: Name, span: Span) {
3370 3371
        // 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() {
3372
            if self.trait_item_map.get(&(name, did)).is_none() {
3373
                let path_str = self.path_names_to_string(&trait_ref.path);
3374
                self.resolve_error(span,
3375
                                    format!("method `{}` is not a member of trait `{}`",
3376
                                            token::get_name(name),
A
Alex Crichton 已提交
3377
                                            path_str)[]);
3378 3379 3380 3381
            }
        }
    }

3382
    fn resolve_module(&mut self, module: &Mod, _span: Span,
3383
                      _name: Name, id: NodeId) {
3384
        // Write the implementations in scope into the module metadata.
3385
        debug!("(resolving module) resolving module ID {}", id);
3386
        visit::walk_mod(self, module);
3387 3388
    }

E
Eduard Burtescu 已提交
3389
    fn resolve_local(&mut self, local: &Local) {
3390
        // Resolve the type.
3391
        self.resolve_type(&*local.ty);
3392 3393

        // Resolve the initializer, if necessary.
3394
        match local.init {
B
Brian Anderson 已提交
3395
            None => {
3396 3397
                // Nothing to do.
            }
3398 3399
            Some(ref initializer) => {
                self.resolve_expr(&**initializer);
3400 3401 3402 3403
            }
        }

        // Resolve the pattern.
3404 3405 3406 3407
        let mut bindings_list = HashMap::new();
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
                             &mut bindings_list);
3408 3409
    }

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

J
John Clements 已提交
3426 3427
    // 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 已提交
3428
    fn check_consistent_bindings(&mut self, arm: &Arm) {
3429 3430 3431
        if arm.pats.len() == 0 {
            return
        }
3432
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
3433
        for (i, p) in arm.pats.iter().enumerate() {
3434
            let map_i = self.binding_mode_map(&**p);
3435

D
Daniel Micay 已提交
3436
            for (&key, &binding_0) in map_0.iter() {
3437
                match map_i.get(&key) {
3438 3439 3440 3441 3442 3443
                  None => {
                    self.resolve_error(
                        p.span,
                        format!("variable `{}` from pattern #1 is \
                                  not bound in pattern #{}",
                                token::get_name(key),
A
Alex Crichton 已提交
3444
                                i + 1)[]);
3445 3446 3447 3448 3449 3450 3451 3452
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
                        self.resolve_error(
                            binding_i.span,
                            format!("variable `{}` is bound with different \
                                      mode in pattern #{} than in pattern #1",
                                    token::get_name(key),
A
Alex Crichton 已提交
3453
                                    i + 1)[]);
3454 3455
                    }
                  }
3456 3457 3458
                }
            }

D
Daniel Micay 已提交
3459
            for (&key, &binding) in map_i.iter() {
3460
                if !map_0.contains_key(&key) {
3461
                    self.resolve_error(
3462
                        binding.span,
3463 3464
                        format!("variable `{}` from pattern {}{} is \
                                  not bound in pattern {}1",
3465
                                token::get_name(key),
A
Alex Crichton 已提交
3466
                                "#", i + 1, "#")[]);
3467 3468 3469
                }
            }
        }
3470 3471
    }

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

3475
        let mut bindings_list = HashMap::new();
D
Daniel Micay 已提交
3476
        for pattern in arm.pats.iter() {
3477
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
3478 3479
        }

3480 3481 3482 3483
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

3484
        visit::walk_expr_opt(self, &arm.guard);
3485
        self.resolve_expr(&*arm.body);
3486

3487
        self.value_ribs.pop();
3488 3489
    }

E
Eduard Burtescu 已提交
3490
    fn resolve_block(&mut self, block: &Block) {
3491
        debug!("(resolving block) entering block");
3492
        self.value_ribs.push(Rib::new(NormalRibKind));
3493 3494

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

        // Descend into the block.
3506
        visit::walk_block(self, block);
3507 3508 3509 3510

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

3511
        self.value_ribs.pop();
3512
        debug!("(resolving block) leaving block");
3513 3514
    }

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

3520
            TyPath(ref path, path_id) => {
3521
                // This is a path in the type namespace. Walk through scopes
3522
                // looking for it.
3523
                let mut result_def = None;
3524

3525
                // First, check to see whether the name is a primitive type.
3526
                if path.segments.len() == 1 {
3527
                    let id = path.segments.last().unwrap().identifier;
3528 3529 3530

                    match self.primitive_type_table
                            .primitive_types
3531
                            .get(&id.name) {
3532

3533
                        Some(&primitive_type) => {
3534
                            result_def =
3535
                                Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
3536

3537
                            if path.segments[0].parameters.has_lifetimes() {
J
Jakub Wieczorek 已提交
3538 3539
                                span_err!(self.session, path.span, E0157,
                                    "lifetime parameters are not allowed on this type");
3540
                            } else if !path.segments[0].parameters.is_empty() {
J
Jakub Wieczorek 已提交
3541 3542
                                span_err!(self.session, path.span, E0153,
                                    "type parameters are not allowed on this type");
3543
                            }
3544 3545 3546 3547
                        }
                        None => {
                            // Continue.
                        }
3548 3549 3550
                    }
                }

3551
                match result_def {
B
Brian Anderson 已提交
3552
                    None => {
3553
                        match self.resolve_path(ty.id, path, TypeNS, true) {
3554
                            Some(def) => {
3555
                                debug!("(resolving type) resolved `{}` to \
L
Luqman Aden 已提交
3556
                                        type {}",
A
Aaron Turon 已提交
3557
                                       token::get_ident(path.segments.last().unwrap() .identifier),
3558
                                       def);
3559 3560 3561 3562
                                result_def = Some(def);
                            }
                            None => {
                                result_def = None;
3563 3564 3565
                            }
                        }
                    }
3566
                    Some(_) => {}   // Continue.
3567 3568
                }

3569
                match result_def {
B
Brian Anderson 已提交
3570
                    Some(def) => {
3571
                        // Write the result into the def map.
3572
                        debug!("(resolving type) writing resolution for `{}` \
A
Alex Crichton 已提交
3573
                                (id {})",
3574
                               self.path_names_to_string(path),
P
Paul Stansifer 已提交
3575
                               path_id);
3576 3577
                        self.record_def(path_id, def);
                    }
B
Brian Anderson 已提交
3578
                    None => {
A
Alex Crichton 已提交
3579
                        let msg = format!("use of undeclared type name `{}`",
3580
                                          self.path_names_to_string(path));
A
Alex Crichton 已提交
3581
                        self.resolve_error(ty.span, msg[]);
3582 3583
                    }
                }
3584
            }
3585

3586 3587 3588
            TyObjectSum(ref ty, ref bound_vec) => {
                self.resolve_type(&**ty);
                self.resolve_type_parameter_bounds(ty.id, bound_vec,
3589
                                                       TraitBoundingTypeParameter);
3590 3591
            }

3592
            TyQPath(ref qpath) => {
3593 3594
                self.resolve_type(&*qpath.self_type);
                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
3595 3596
            }

3597
            TyClosure(ref c) => {
3598 3599 3600 3601
                self.resolve_type_parameter_bounds(
                    ty.id,
                    &c.bounds,
                    TraitBoundingTypeParameter);
3602
                visit::walk_ty(self, ty);
3603 3604
            }

3605 3606
            TyPolyTraitRef(ref bounds) => {
                self.resolve_type_parameter_bounds(
N
Niko Matsakis 已提交
3607
                    ty.id,
3608
                    bounds,
N
Niko Matsakis 已提交
3609 3610 3611
                    TraitObject);
                visit::walk_ty(self, ty);
            }
B
Brian Anderson 已提交
3612
            _ => {
3613
                // Just resolve embedded types.
3614
                visit::walk_ty(self, ty);
3615 3616 3617 3618
            }
        }
    }

F
Felix S. Klock II 已提交
3619
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
3620
                       pattern: &Pat,
3621 3622 3623
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
3624
                       bindings_list: &mut HashMap<Name, NodeId>) {
3625
        let pat_id = pattern.id;
3626
        walk_pat(pattern, |pattern| {
3627
            match pattern.node {
3628
                PatIdent(binding_mode, ref path1, _) => {
3629 3630

                    // The meaning of pat_ident with no type parameters
3631 3632 3633 3634 3635 3636 3637
                    // 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).
3638

3639
                    let ident = path1.node;
3640
                    let renamed = mtwt::resolve(ident);
3641

3642
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
3643
                        FoundStructOrEnumVariant(ref def, lp)
3644
                                if mode == RefutableMode => {
3645
                            debug!("(resolving pattern) resolving `{}` to \
3646
                                    struct or enum variant",
3647
                                   token::get_name(renamed));
3648

3649 3650 3651 3652
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
3653
                            self.record_def(pattern.id, (def.clone(), lp));
3654
                        }
A
Alex Crichton 已提交
3655
                        FoundStructOrEnumVariant(..) => {
3656 3657 3658 3659 3660
                            self.resolve_error(
                                pattern.span,
                                format!("declaration of `{}` shadows an enum \
                                         variant or unit-like struct in \
                                         scope",
A
Alex Crichton 已提交
3661
                                        token::get_name(renamed))[]);
3662
                        }
3663
                        FoundConst(ref def, lp) if mode == RefutableMode => {
3664
                            debug!("(resolving pattern) resolving `{}` to \
3665
                                    constant",
3666
                                   token::get_name(renamed));
3667

3668 3669 3670 3671
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
3672
                            self.record_def(pattern.id, (def.clone(), lp));
3673
                        }
A
Alex Crichton 已提交
3674
                        FoundConst(..) => {
3675
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
3676
                                                  "only irrefutable patterns \
3677
                                                   allowed here");
3678
                        }
3679
                        BareIdentifierPatternUnresolved => {
3680
                            debug!("(resolving pattern) binding `{}`",
3681
                                   token::get_name(renamed));
3682

3683
                            let def = DefLocal(pattern.id);
3684 3685 3686 3687 3688

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

3689
                            self.record_def(pattern.id, (def, LastMod(AllPublic)));
3690 3691 3692 3693 3694 3695

                            // 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.)
3696 3697
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
3698 3699
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
3700
                                bindings_list.insert(renamed, pat_id);
3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
                                self.resolve_error(pattern.span,
                                                   format!("identifier `{}` \
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
A
Alex Crichton 已提交
3713
                                                   [])
3714
                            } else if bindings_list.get(&renamed) ==
3715 3716 3717 3718 3719 3720 3721
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
                                self.resolve_error(pattern.span,
                                    format!("identifier `{}` is bound \
                                             more than once in the same \
                                             pattern",
A
Alex Crichton 已提交
3722
                                            token::get_ident(ident))[]);
3723
                            }
3724 3725
                            // Else, not bound in the same pattern: do
                            // nothing.
3726 3727 3728 3729
                        }
                    }
                }

3730
                PatEnum(ref path, _) => {
3731
                    // This must be an enum variant, struct or const.
A
Alex Crichton 已提交
3732
                    match self.resolve_path(pat_id, path, ValueNS, false) {
A
Alex Crichton 已提交
3733 3734
                        Some(def @ (DefVariant(..), _)) |
                        Some(def @ (DefStruct(..), _))  |
3735
                        Some(def @ (DefConst(..), _)) => {
3736 3737
                            self.record_def(pattern.id, def);
                        }
3738 3739 3740 3741 3742 3743
                        Some((DefStatic(..), _)) => {
                            self.resolve_error(path.span,
                                               "static variables cannot be \
                                                referenced in a pattern, \
                                                use a `const` instead");
                        }
3744
                        Some(_) => {
3745
                            self.resolve_error(path.span,
A
Alex Crichton 已提交
3746
                                format!("`{}` is not an enum variant, struct or const",
3747
                                    token::get_ident(
A
Aaron Turon 已提交
3748
                                        path.segments.last().unwrap().identifier))[]);
3749 3750
                        }
                        None => {
3751
                            self.resolve_error(path.span,
3752
                                format!("unresolved enum variant, struct or const `{}`",
3753
                                    token::get_ident(
A
Aaron Turon 已提交
3754
                                        path.segments.last().unwrap().identifier))[]);
3755 3756 3757 3758
                        }
                    }

                    // Check the types in the path pattern.
3759
                    for ty in path.segments
3760
                                  .iter()
3761
                                  .flat_map(|s| s.parameters.types().into_iter()) {
3762
                        self.resolve_type(&**ty);
3763 3764 3765
                    }
                }

3766 3767
                PatLit(ref expr) => {
                    self.resolve_expr(&**expr);
3768 3769
                }

3770 3771 3772
                PatRange(ref first_expr, ref last_expr) => {
                    self.resolve_expr(&**first_expr);
                    self.resolve_expr(&**last_expr);
3773 3774
                }

3775
                PatStruct(ref path, _, _) => {
A
Alex Crichton 已提交
3776
                    match self.resolve_path(pat_id, path, TypeNS, false) {
3777
                        Some(definition) => {
3778 3779
                            self.record_def(pattern.id, definition);
                        }
3780
                        result => {
3781
                            debug!("(resolving pattern) didn't find struct \
L
Luqman Aden 已提交
3782
                                    def: {}", result);
A
Alex Crichton 已提交
3783
                            let msg = format!("`{}` does not name a structure",
3784
                                              self.path_names_to_string(path));
A
Alex Crichton 已提交
3785
                            self.resolve_error(path.span, msg[]);
3786 3787 3788 3789
                        }
                    }
                }

3790
                _ => {
3791 3792 3793
                    // Nothing to do.
                }
            }
3794
            true
3795
        });
3796 3797
    }

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

B
Brian Anderson 已提交
3840
            Indeterminate => {
S
Steve Klabnik 已提交
3841
                panic!("unexpected indeterminate result");
3842
            }
3843 3844 3845 3846
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
                        self.resolve_error(span, format!("failed to resolve: {}",
A
Alex Crichton 已提交
3847
                                                         msg)[]);
3848 3849 3850
                    }
                    None => ()
                }
3851

3852
                debug!("(resolve bare identifier pattern) failed to find {}",
3853
                        token::get_name(name));
3854
                return BareIdentifierPatternUnresolved;
3855 3856 3857 3858
            }
        }
    }

3859 3860
    /// 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 已提交
3861
    fn resolve_path(&mut self,
3862 3863 3864 3865
                    id: NodeId,
                    path: &Path,
                    namespace: Namespace,
                    check_ribs: bool) -> Option<(Def, LastPrivate)> {
3866
        // First, resolve the types and associated type bindings.
3867
        for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
3868
            self.resolve_type(&**ty);
3869
        }
3870 3871 3872
        for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
            self.resolve_type(&*binding.ty);
        }
3873

3874 3875 3876 3877 3878 3879 3880 3881 3882
        // 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 {
3883
                        DefTyParam(_, _, did, _) => {
3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901
                            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));
                        }
                        _ => {}
                    }
                }
                _ => {}
            }
        }

3902
        if path.global {
3903
            return self.resolve_crate_relative_path(path, namespace);
3904 3905
        }

3906
        // Try to find a path to an item in a module.
3907
        let unqualified_def =
A
Aaron Turon 已提交
3908
                self.resolve_identifier(path.segments.last().unwrap().identifier,
3909 3910 3911
                                        namespace,
                                        check_ribs,
                                        path.span);
3912

3913
        if path.segments.len() > 1 {
3914
            let def = self.resolve_module_relative_path(path, namespace);
3915
            match (def, unqualified_def) {
3916
                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
3917
                    self.session
A
Aaron Turon 已提交
3918
                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
3919 3920
                                  id,
                                  path.span,
3921
                                  "unnecessary qualification".to_string());
3922 3923 3924
                }
                _ => ()
            }
3925

3926
            return def;
3927 3928
        }

3929
        return unqualified_def;
3930 3931
    }

J
John Clements 已提交
3932
    // resolve a single identifier (used as a varref)
F
Felix S. Klock II 已提交
3933
    fn resolve_identifier(&mut self,
3934 3935 3936 3937 3938
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3939
        if check_ribs {
3940
            match self.resolve_identifier_in_local_ribs(identifier,
3941 3942
                                                        namespace,
                                                        span) {
B
Brian Anderson 已提交
3943
                Some(def) => {
3944
                    return Some((def, LastMod(AllPublic)));
3945
                }
B
Brian Anderson 已提交
3946
                None => {
3947 3948 3949 3950 3951
                    // Continue.
                }
            }
        }

3952
        return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
3953 3954
    }

3955
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3956
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3957
                                            containing_module: Rc<Module>,
3958
                                            name: Name,
3959
                                            namespace: Namespace)
3960
                                            -> NameDefinition {
3961
        // First, search children.
3962
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3963

3964
        match containing_module.children.borrow().get(&name) {
3965 3966 3967 3968 3969 3970 3971
            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 {
3972
                            LastMod(DependsOn(def.def_id()))
3973 3974
                        };
                        return ChildNameDefinition(def, lp);
3975
                    }
3976
                    None => {}
3977 3978
                }
            }
3979
            None => {}
3980 3981 3982
        }

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

        // Finally, search through external children.
        if namespace == TypeNS {
4013 4014 4015 4016 4017 4018 4019 4020 4021
            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);
4022
                }
4023 4024
            }
        }
4025 4026

        return NoNameDefinition;
4027 4028
    }

4029
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
4030
    fn resolve_module_relative_path(&mut self,
4031 4032 4033
                                    path: &Path,
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
4034 4035 4036
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4037

4038
        let containing_module;
4039
        let last_private;
E
Eduard Burtescu 已提交
4040 4041
        let module = self.current_module.clone();
        match self.resolve_module_path(module,
A
Alex Crichton 已提交
4042
                                       module_path[],
4043 4044
                                       UseLexicalScope,
                                       path.span,
4045
                                       PathSearch) {
4046 4047 4048 4049
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
4050 4051
                        let msg = format!("Use of undeclared type or module `{}`",
                                          self.names_to_string(module_path.as_slice()));
4052 4053 4054
                        (path.span, msg)
                    }
                };
4055

4056
                self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
4057
                                                 msg)[]);
4058
                return None;
4059
            }
S
Steve Klabnik 已提交
4060
            Indeterminate => panic!("indeterminate unexpected"),
4061
            Success((resulting_module, resulting_last_private)) => {
4062
                containing_module = resulting_module;
4063
                last_private = resulting_last_private;
4064 4065 4066
            }
        }

4067
        let name = path.segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
4068
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
4069
                                                                  name,
4070
                                                                  namespace) {
B
Brian Anderson 已提交
4071
            NoNameDefinition => {
4072
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4073
                return None;
4074
            }
4075 4076
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
4077
            }
4078
        };
4079 4080
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
4081
        }
4082
        return Some(def);
4083 4084
    }

4085 4086
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
4087
    fn resolve_crate_relative_path(&mut self,
4088 4089 4090
                                   path: &Path,
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
4091 4092 4093
        let module_path = path.segments.init().iter()
                                              .map(|ps| ps.identifier.name)
                                              .collect::<Vec<_>>();
4094

4095
        let root_module = self.graph_root.get_module();
4096

4097
        let containing_module;
4098
        let last_private;
4099
        match self.resolve_module_path_from_root(root_module,
A
Alex Crichton 已提交
4100
                                                 module_path[],
4101
                                                 0,
4102
                                                 path.span,
4103
                                                 PathSearch,
4104
                                                 LastMod(AllPublic)) {
4105 4106 4107 4108 4109
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
A
Alex Crichton 已提交
4110
                                          self.names_to_string(module_path[]));
4111 4112 4113 4114 4115
                        (path.span, msg)
                    }
                };

                self.resolve_error(span, format!("failed to resolve. {}",
A
Alex Crichton 已提交
4116
                                                 msg)[]);
B
Brian Anderson 已提交
4117
                return None;
4118 4119
            }

B
Brian Anderson 已提交
4120
            Indeterminate => {
S
Steve Klabnik 已提交
4121
                panic!("indeterminate unexpected");
4122 4123
            }

4124
            Success((resulting_module, resulting_last_private)) => {
4125
                containing_module = resulting_module;
4126
                last_private = resulting_last_private;
4127 4128 4129
            }
        }

4130
        let name = path.segments.last().unwrap().identifier.name;
4131
        match self.resolve_definition_of_name_in_module(containing_module,
4132
                                                        name,
4133
                                                        namespace) {
B
Brian Anderson 已提交
4134
            NoNameDefinition => {
4135
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
4136
                return None;
4137
            }
4138 4139
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
4140 4141 4142 4143
            }
        }
    }

F
Felix S. Klock II 已提交
4144
    fn resolve_identifier_in_local_ribs(&mut self,
4145 4146 4147 4148
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
4149
        // Check the local set of ribs.
4150
        let search_result = match namespace {
B
Brian Anderson 已提交
4151
            ValueNS => {
4152
                let renamed = mtwt::resolve(ident);
4153
                self.search_ribs(self.value_ribs.as_slice(), renamed, span)
4154
            }
B
Brian Anderson 已提交
4155
            TypeNS => {
4156
                let name = ident.name;
A
Alex Crichton 已提交
4157
                self.search_ribs(self.type_ribs[], name, span)
4158
            }
4159
        };
4160

4161
        match search_result {
4162
            Some(DlDef(def)) => {
4163
                debug!("(resolving path in local ribs) resolved `{}` to \
L
Luqman Aden 已提交
4164
                        local: {}",
4165
                       token::get_ident(ident),
P
Paul Stansifer 已提交
4166
                       def);
B
Brian Anderson 已提交
4167
                return Some(def);
4168
            }
4169
            Some(DlField) | Some(DlImpl(_)) | None => {
B
Brian Anderson 已提交
4170
                return None;
4171 4172 4173 4174
            }
        }
    }

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

4216
                debug!("(resolving item path by identifier in lexical scope) \
4217
                         failed to resolve {}", token::get_name(name));
B
Brian Anderson 已提交
4218
                return None;
4219 4220 4221 4222
            }
        }
    }

J
Jorge Aparicio 已提交
4223 4224 4225
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
4226
        self.emit_errors = false;
A
Alex Crichton 已提交
4227
        let rs = f(self);
4228 4229 4230 4231
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
4232
    fn resolve_error(&self, span: Span, s: &str) {
4233
        if self.emit_errors {
A
Alex Crichton 已提交
4234
            self.session.span_err(span, s);
4235 4236 4237
        }
    }

4238
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
4239 4240 4241
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
4242
                TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
4243 4244
                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),
4245 4246 4247 4248 4249 4250 4251
                // 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,
            }
        }

4252
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
4253 4254
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
4255
            let last_name = name_path.last().unwrap();
4256

4257
            if name_path.len() == 1 {
4258
                match this.primitive_type_table.primitive_types.get(last_name) {
4259 4260
                    Some(_) => None,
                    None => {
4261
                        match this.current_module.children.borrow().get(last_name) {
4262 4263 4264 4265 4266 4267 4268
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
A
Alex Crichton 已提交
4269
                                                name_path[],
4270 4271 4272 4273 4274 4275 4276 4277 4278
                                                UseLexicalScope,
                                                span,
                                                PathSearch) {
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

4279 4280 4281 4282
        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,
4283 4284 4285 4286
            },
            None => return NoSuggestion,
        };

4287 4288
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
4289
            match self.def_map.borrow().get(&node_id) {
4290
                 Some(&DefTy(did, _))
4291
                | Some(&DefStruct(did))
4292
                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
4293 4294 4295 4296 4297
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
4298
                    }
4299 4300 4301
                },
                _ => {} // Self type didn't resolve properly
            }
4302 4303
        }

4304
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
4305 4306

        // Look for a method in the current self type's impl module.
A
Alex Crichton 已提交
4307
        match get_module(self, path.span, name_path[]) {
4308
            Some(module) => match module.children.borrow().get(&name) {
4309
                Some(binding) => {
4310
                    let p_str = self.path_names_to_string(&path);
4311
                    match binding.def_for_namespace(ValueNS) {
4312
                        Some(DefStaticMethod(_, provenance)) => {
4313 4314 4315 4316 4317
                            match provenance {
                                FromImpl(_) => return StaticMethod(p_str),
                                FromTrait(_) => unreachable!()
                            }
                        }
4318 4319
                        Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
                        Some(DefMethod(_, Some(_), _)) => return TraitItem,
4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330
                        _ => ()
                    }
                }
                None => {}
            },
            None => {}
        }

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

4333
                match self.trait_item_map.get(&(name, did)) {
4334 4335 4336
                    Some(&StaticMethodTraitItemKind) => {
                        return TraitMethod(path_str)
                    }
4337
                    Some(_) => return TraitItem,
4338 4339 4340 4341 4342 4343 4344 4345 4346
                    None => {}
                }
            }
            None => {}
        }

        NoSuggestion
    }

4347
    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4348
                                -> Option<String> {
4349 4350
        let this = &mut *self;

4351 4352
        let mut maybes: Vec<token::InternedString> = Vec::new();
        let mut values: Vec<uint> = Vec::new();
4353

4354 4355
        for rib in this.value_ribs.iter().rev() {
            for (&k, _) in rib.bindings.iter() {
4356
                maybes.push(token::get_name(k));
C
Chris Wong 已提交
4357
                values.push(uint::MAX);
4358 4359 4360 4361
            }
        }

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

4365
            if values[i] <= values[smallest] {
4366 4367 4368 4369
                smallest = i;
            }
        }

Y
Youngmin Yoo 已提交
4370
        if values.len() > 0 &&
4371 4372 4373 4374
            values[smallest] != uint::MAX &&
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
            name != maybes[smallest].get() {
4375

4376
            Some(maybes[smallest].get().to_string())
4377 4378 4379 4380 4381 4382

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
4383
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
4384 4385
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
4386 4387 4388

        self.record_candidate_traits_for_expr_if_necessary(expr);

4389
        // Next, resolve the node.
4390
        match expr.node {
4391 4392 4393
            // The interpretation of paths depends on whether the path has
            // multiple elements in it or not.

4394
            ExprPath(ref path) => {
4395 4396 4397
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.

4398 4399
                let path_name = self.path_names_to_string(path);

A
Alex Crichton 已提交
4400
                match self.resolve_path(expr.id, path, ValueNS, true) {
4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413
                    // Check if struct variant
                    Some((DefVariant(_, _, true), _)) => {
                        self.resolve_error(expr.span,
                                format!("`{}` is a struct variant name, but \
                                         this expression \
                                         uses it like a function name",
                                        path_name).as_slice());

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

4419 4420
                        self.record_def(expr.id, def);
                    }
B
Brian Anderson 已提交
4421
                    None => {
A
Alex Crichton 已提交
4422 4423 4424 4425 4426 4427
                        // Be helpful if the name refers to a struct
                        // (The pattern matching def_tys where the id is in self.structs
                        // matches on regular structs while excluding tuple- and enum-like
                        // structs, which wouldn't result in this error.)
                        match self.with_no_errors(|this|
                            this.resolve_path(expr.id, path, TypeNS, false)) {
4428
                            Some((DefTy(struct_id, _), _))
4429 4430 4431 4432 4433
                              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",
4434
                                                path_name).as_slice());
4435

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

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

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

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

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

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

4497
                visit::walk_expr(self, expr);
4498 4499
            }

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

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

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

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

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

4535
                    visit::walk_expr(this, expr);
4536
                })
4537 4538
            }

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

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

                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));

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

                self.resolve_block(&**body);

                if optional_label.is_some() {
4566
                    drop(self.label_ribs.pop())
4567 4568
                }

4569
                self.value_ribs.pop();
4570
            }
4571

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

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

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

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

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

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

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

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

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

E
Eduard Burtescu 已提交
4698
        found_traits
4699 4700
    }

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

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

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

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

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

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

4766
        if names.len() == 0 {
4767
            return "???".to_string();
4768
        }
4769
        self.names_to_string(names.into_iter().rev()
A
Alex Crichton 已提交
4770
                                  .collect::<Vec<ast::Name>>()[])
4771 4772
    }

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

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

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

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

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

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

N
Nick Cameron 已提交
4820
#[deriving(PartialEq,Copy)]
4821 4822 4823
pub enum MakeGlobMap {
    Yes,
    No
4824 4825
}

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

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

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

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

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

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

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