lib.rs 181.7 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
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
13
#![crate_name = "rustc_resolve"]
14
#![unstable(feature = "rustc_private")]
B
Brian Anderson 已提交
15
#![staged_api]
16 17 18 19 20 21
#![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/")]

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

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

extern crate rustc;

S
Steven Fackler 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
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::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;
use self::ModuleKind::*;
use self::FallbackChecks::*;

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

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

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

101 102 103 104
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

A
Alex Crichton 已提交
105 106
mod check_unused;
mod record_exports;
107
mod build_reduced_graph;
108

109
#[derive(Copy)]
110
struct BindingInfo {
111
    span: Span,
112
    binding_mode: BindingMode,
113 114 115
}

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

118
#[derive(Copy, PartialEq)]
F
Felix S. Klock II 已提交
119
enum PatternBindingMode {
120
    RefutableMode,
121
    LocalIrrefutableMode,
122
    ArgumentIrrefutableMode,
123 124
}

J
Jorge Aparicio 已提交
125
#[derive(Copy, PartialEq, Eq, Hash, Debug)]
F
Felix S. Klock II 已提交
126
enum Namespace {
127
    TypeNS,
128
    ValueNS
129 130
}

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

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

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

169
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
170
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
171
        self.resolve_item(item);
172
    }
173
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
174
        self.resolve_arm(arm);
175
    }
176
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
177
        self.resolve_block(block);
178
    }
179
    fn visit_expr(&mut self, expr: &Expr) {
A
Alex Crichton 已提交
180
        self.resolve_expr(expr);
181
    }
182
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
183
        self.resolve_local(local);
184
    }
185
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
186
        self.resolve_type(ty);
187
    }
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
    fn visit_generics(&mut self, generics: &Generics) {
        self.resolve_generics(generics);
    }
    fn visit_poly_trait_ref(&mut self,
                            tref: &ast::PolyTraitRef,
                            m: &ast::TraitBoundModifier) {
        match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) {
            Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
            Err(_) => { /* error already reported */ }
        }
        visit::walk_poly_trait_ref(self, tref, m);
    }
    fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) {
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
                this.visit_expr(&**dis_expr);
            });
        }

        // `visit::walk_variant` without the discriminant expression.
        match variant.node.kind {
            ast::TupleVariantKind(ref variant_arguments) => {
                for variant_argument in variant_arguments.iter() {
                    self.visit_ty(&*variant_argument.ty);
                }
            }
            ast::StructVariantKind(ref struct_definition) => {
                self.visit_struct_def(&**struct_definition,
                                      variant.node.name,
                                      generics,
                                      variant.node.id);
            }
        }
    }
    fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) {
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
            ForeignItemStatic(..) => NoTypeParameters
        };
        self.with_type_parameter_rib(type_parameters, |this| {
            visit::walk_foreign_item(this, foreign_item);
        });
    }
    fn visit_fn(&mut self,
                function_kind: visit::FnKind<'v>,
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
            visit::FkItemFn(_, generics, _, _) => {
                self.visit_generics(generics);
                ItemRibKind
            }
245 246 247
            visit::FkMethod(_, sig) => {
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
248 249 250 251 252 253
                MethodRibKind
            }
            visit::FkFnBlock(..) => ClosureRibKind(node_id)
        };
        self.resolve_function(rib_kind, declaration, block);
    }
254
}
255

256
/// Contains data for specific types of import directives.
J
Jorge Aparicio 已提交
257
#[derive(Copy,Debug)]
F
Felix S. Klock II 已提交
258
enum ImportDirectiveSubclass {
259
    SingleImport(Name /* target */, Name /* source */),
260 261 262
    GlobImport
}

263 264
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
265
enum ResolveResult<T> {
266 267 268
    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.
269 270
}

271
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
272
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
273
        match *self { Indeterminate => true, _ => false }
274 275 276
    }
}

277 278 279 280
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
281
    TraitItem,
282
    StaticMethod(String),
283
    TraitMethod(String),
284 285
}

286
#[derive(Copy)]
E
Erik Price 已提交
287
enum TypeParameters<'a> {
288 289 290 291 292 293 294 295 296 297 298
    NoTypeParameters,
    HasTypeParameters(
        // Type parameters.
        &'a Generics,

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

        // The kind of the rib used for type parameters.
        RibKind)
299 300
}

301 302
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
J
Jorge Aparicio 已提交
303
#[derive(Copy, Debug)]
F
Felix S. Klock II 已提交
304
enum RibKind {
305 306
    // No translation needs to be applied.
    NormalRibKind,
307

308 309
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
310
    ClosureRibKind(NodeId /* func id */),
311

312
    // We passed through an impl or trait and are now in one of its
313
    // methods. Allow references to ty params that impl or trait
314 315
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
316
    MethodRibKind,
317

318 319
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
320 321 322

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

325
#[derive(Copy)]
F
Felix S. Klock II 已提交
326
enum UseLexicalScopeFlag {
327 328 329 330
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
331
enum ModulePrefixResult {
332
    NoPrefixFound,
E
Eduard Burtescu 已提交
333
    PrefixFound(Rc<Module>, uint)
334 335
}

336
#[derive(Copy, PartialEq)]
337
enum NameSearchType {
338 339 340 341
    /// 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
342 343
    /// expression, or a path pattern.
    PathSearch,
344 345
}

346
#[derive(Copy)]
F
Felix S. Klock II 已提交
347
enum BareIdentifierPatternResolution {
348 349
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
350
    BareIdentifierPatternUnresolved
351 352
}

353
/// One local scope.
J
Jorge Aparicio 已提交
354
#[derive(Debug)]
F
Felix S. Klock II 已提交
355
struct Rib {
356
    bindings: HashMap<Name, DefLike>,
357
    kind: RibKind,
B
Brian Anderson 已提交
358
}
359

360
impl Rib {
F
Felix S. Klock II 已提交
361
    fn new(kind: RibKind) -> Rib {
362
        Rib {
363
            bindings: HashMap::new(),
364 365
            kind: kind
        }
366 367 368
    }
}

369
/// Whether an import can be shadowed by another import.
J
Jorge Aparicio 已提交
370
#[derive(Debug,PartialEq,Clone,Copy)]
371 372 373 374 375
enum Shadowable {
    Always,
    Never
}

376
/// One import directive.
J
Jorge Aparicio 已提交
377
#[derive(Debug)]
F
Felix S. Klock II 已提交
378
struct ImportDirective {
379
    module_path: Vec<Name>,
E
Eduard Burtescu 已提交
380
    subclass: ImportDirectiveSubclass,
381
    span: Span,
382
    id: NodeId,
383
    is_public: bool, // see note in ImportResolution about how to use this
384
    shadowable: Shadowable,
B
Brian Anderson 已提交
385
}
386

387
impl ImportDirective {
388
    fn new(module_path: Vec<Name> ,
E
Eduard Burtescu 已提交
389
           subclass: ImportDirectiveSubclass,
390 391
           span: Span,
           id: NodeId,
392
           is_public: bool,
393
           shadowable: Shadowable)
394
           -> ImportDirective {
395 396 397 398
        ImportDirective {
            module_path: module_path,
            subclass: subclass,
            span: span,
399 400
            id: id,
            is_public: is_public,
401
            shadowable: shadowable,
402
        }
403 404 405
    }
}

406
/// The item that an import resolves to.
J
Jorge Aparicio 已提交
407
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
408
struct Target {
E
Eduard Burtescu 已提交
409 410
    target_module: Rc<Module>,
    bindings: Rc<NameBindings>,
411
    shadowable: Shadowable,
B
Brian Anderson 已提交
412
}
413

414
impl Target {
415 416
    fn new(target_module: Rc<Module>,
           bindings: Rc<NameBindings>,
417
           shadowable: Shadowable)
418
           -> Target {
419 420
        Target {
            target_module: target_module,
421 422
            bindings: bindings,
            shadowable: shadowable,
423
        }
424 425 426
    }
}

T
Tim Chevalier 已提交
427
/// An ImportResolution represents a particular `use` directive.
J
Jorge Aparicio 已提交
428
#[derive(Debug)]
F
Felix S. Klock II 已提交
429
struct ImportResolution {
430
    /// Whether this resolution came from a `use` or a `pub use`. Note that this
N
Nick Cameron 已提交
431 432
    /// should *not* be used whenever resolution is being performed. Privacy
    /// testing occurs during a later phase of compilation.
E
Eduard Burtescu 已提交
433
    is_public: bool,
434

435 436 437
    // 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.
N
Nick Cameron 已提交
438 439 440
    // Note that this is usually either 0 or 1 - shadowing is forbidden the only
    // way outstanding_references is > 1 in a legal program is if the name is
    // used in both namespaces.
E
Eduard Burtescu 已提交
441
    outstanding_references: uint,
442

T
Tim Chevalier 已提交
443
    /// The value that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
444
    value_target: Option<Target>,
445 446
    /// The source node of the `use` directive leading to the value target
    /// being non-none
E
Eduard Burtescu 已提交
447
    value_id: NodeId,
448

T
Tim Chevalier 已提交
449
    /// The type that this `use` directive names, if there is one.
E
Eduard Burtescu 已提交
450
    type_target: Option<Target>,
451 452
    /// The source node of the `use` directive leading to the type target
    /// being non-none
E
Eduard Burtescu 已提交
453
    type_id: NodeId,
E
Erick Tryzelaar 已提交
454 455
}

456
impl ImportResolution {
457
    fn new(id: NodeId, is_public: bool) -> ImportResolution {
458
        ImportResolution {
E
Eduard Burtescu 已提交
459 460 461 462 463 464
            type_id: id,
            value_id: id,
            outstanding_references: 0,
            value_target: None,
            type_target: None,
            is_public: is_public,
465
        }
B
Brian Anderson 已提交
466 467
    }

F
Felix S. Klock II 已提交
468
    fn target_for_namespace(&self, namespace: Namespace)
469
                                -> Option<Target> {
470
        match namespace {
E
Eduard Burtescu 已提交
471 472
            TypeNS  => self.type_target.clone(),
            ValueNS => self.value_target.clone(),
473 474
        }
    }
475

476
    fn id(&self, namespace: Namespace) -> NodeId {
477
        match namespace {
E
Eduard Burtescu 已提交
478 479
            TypeNS  => self.type_id,
            ValueNS => self.value_id,
480 481
        }
    }
482 483 484 485 486 487 488 489 490

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

        target.unwrap().shadowable
    }
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506

    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;
            }
        }
    }
507 508
}

509
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
510
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
511
enum ParentLink {
512
    NoParentLink,
513
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
514
    BlockParentLink(Weak<Module>, NodeId)
515 516
}

517
/// The type of module this is.
J
Jorge Aparicio 已提交
518
#[derive(Copy, PartialEq, Debug)]
F
Felix S. Klock II 已提交
519
enum ModuleKind {
520 521
    NormalModuleKind,
    TraitModuleKind,
522
    EnumModuleKind,
523
    TypeModuleKind,
524 525 526
    AnonymousModuleKind,
}

527
/// One node in the tree of modules.
F
Felix S. Klock II 已提交
528
struct Module {
529
    parent_link: ParentLink,
530
    def_id: Cell<Option<DefId>>,
531
    kind: Cell<ModuleKind>,
532
    is_public: bool,
533

E
Eduard Burtescu 已提交
534 535
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
536

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

541 542 543 544 545 546 547 548 549 550 551 552 553 554
    // 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 已提交
555
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
556 557

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

    // The number of unresolved globs that this module exports.
561
    glob_count: Cell<uint>,
562 563

    // The index of the import we're resolving.
564
    resolved_import_count: Cell<uint>,
565 566 567 568

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

572
impl Module {
F
Felix S. Klock II 已提交
573
    fn new(parent_link: ParentLink,
574 575 576 577
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
578
           -> Module {
579 580
        Module {
            parent_link: parent_link,
581
            def_id: Cell::new(def_id),
582
            kind: Cell::new(kind),
583
            is_public: is_public,
584
            children: RefCell::new(HashMap::new()),
585
            imports: RefCell::new(Vec::new()),
586
            external_module_children: RefCell::new(HashMap::new()),
587
            anonymous_children: RefCell::new(NodeMap()),
588
            import_resolutions: RefCell::new(HashMap::new()),
589
            glob_count: Cell::new(0),
590
            resolved_import_count: Cell::new(0),
591
            populated: Cell::new(!external),
592
        }
B
Brian Anderson 已提交
593 594
    }

F
Felix S. Klock II 已提交
595
    fn all_imports_resolved(&self) -> bool {
596
        self.imports.borrow().len() == self.resolved_import_count.get()
597 598 599
    }
}

600
impl fmt::Debug for Module {
601
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
602
        write!(f, "{:?}, kind: {:?}, {}",
603 604 605 606 607 608
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

609
bitflags! {
J
Jorge Aparicio 已提交
610
    #[derive(Debug)]
611 612 613 614 615 616
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

617
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
618
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
619
struct TypeNsDef {
620
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
621
    module_def: Option<Rc<Module>>,
622
    type_def: Option<Def>,
623
    type_span: Option<Span>
624 625 626
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
627
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
628
struct ValueNsDef {
629
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
630
    def: Def,
631
    value_span: Option<Span>,
632 633
}

634 635
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
636
#[derive(Debug)]
F
Felix S. Klock II 已提交
637
struct NameBindings {
638
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
639
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
640 641
}

642
impl NameBindings {
K
Kevin Butler 已提交
643 644 645 646 647 648 649
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

650
    /// Creates a new module in this set of name bindings.
651
    fn define_module(&self,
652 653 654 655 656 657
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
658
        // Merges the module with the existing type def or creates a new one.
659
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
660 661 662 663
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
664
                                          is_public));
E
Erick Tryzelaar 已提交
665 666
        let type_def = self.type_def.borrow().clone();
        match type_def {
667
            None => {
E
Erick Tryzelaar 已提交
668
                *self.type_def.borrow_mut() = Some(TypeNsDef {
669
                    modifiers: modifiers,
670
                    module_def: Some(module_),
671 672
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
673
                });
674
            }
675
            Some(type_def) => {
E
Erick Tryzelaar 已提交
676
                *self.type_def.borrow_mut() = Some(TypeNsDef {
677
                    modifiers: modifiers,
678
                    module_def: Some(module_),
679
                    type_span: Some(sp),
680
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
681
                });
682
            }
683 684 685
        }
    }

686
    /// Sets the kind of the module, creating a new one if necessary.
687
    fn set_module_kind(&self,
688 689 690 691 692 693
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
694
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
E
Erick Tryzelaar 已提交
695 696
        let type_def = self.type_def.borrow().clone();
        match type_def {
697
            None => {
698 699 700 701 702
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
703
                *self.type_def.borrow_mut() = Some(TypeNsDef {
704
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
705
                    module_def: Some(Rc::new(module)),
706 707
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
708
                });
709 710 711 712
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
713 714 715 716 717
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
718
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
719
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
720
                            module_def: Some(Rc::new(module)),
721 722
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
723
                        });
724
                    }
725
                    Some(module_def) => module_def.kind.set(kind),
726 727 728 729 730
                }
            }
        }
    }

731
    /// Records a type definition.
732
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
733
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
734
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
735 736
        let type_def = self.type_def.borrow().clone();
        match type_def {
737
            None => {
E
Erick Tryzelaar 已提交
738
                *self.type_def.borrow_mut() = Some(TypeNsDef {
739
                    module_def: None,
740
                    type_def: Some(def),
741
                    type_span: Some(sp),
742
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
743
                });
744
            }
745
            Some(type_def) => {
E
Erick Tryzelaar 已提交
746
                *self.type_def.borrow_mut() = Some(TypeNsDef {
747
                    module_def: type_def.module_def,
748
                    type_def: Some(def),
749
                    type_span: Some(sp),
750
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
751
                });
752 753
            }
        }
754 755
    }

756
    /// Records a value definition.
757
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
758
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
759
        *self.value_def.borrow_mut() = Some(ValueNsDef {
760 761
            def: def,
            value_span: Some(sp),
762
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
763
        });
764 765
    }

766
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
767
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
768
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
769
            Some(ref type_def) => type_def.module_def.clone(),
770
            None => None
771 772 773
        }
    }

S
Steve Klabnik 已提交
774 775
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
776
    fn get_module(&self) -> Rc<Module> {
777 778
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
779
                panic!("get_module called on a node with no module \
780
                       definition!")
781
            }
782
            Some(module_def) => module_def
783 784 785
        }
    }

F
Felix S. Klock II 已提交
786
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
787
        match namespace {
E
Erick Tryzelaar 已提交
788 789
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
790 791 792
        }
    }

F
Felix S. Klock II 已提交
793
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
794 795 796 797
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
798
        match namespace {
E
Erick Tryzelaar 已提交
799
            TypeNS => match *self.type_def.borrow() {
800
                Some(ref def) => def.modifiers.contains(modifiers), None => false
801
            },
E
Erick Tryzelaar 已提交
802
            ValueNS => match *self.value_def.borrow() {
803
                Some(ref def) => def.modifiers.contains(modifiers), None => false
804 805 806 807
            }
        }
    }

F
Felix S. Klock II 已提交
808
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
809
        match namespace {
810
            TypeNS => {
E
Erick Tryzelaar 已提交
811
                match *self.type_def.borrow() {
812
                    None => None,
E
Eduard Burtescu 已提交
813
                    Some(ref type_def) => {
814
                        match type_def.type_def {
815
                            Some(type_def) => Some(type_def),
816 817
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
818
                                    Some(ref module) => {
819
                                        match module.def_id.get() {
820
                                            Some(did) => Some(DefMod(did)),
821 822 823 824 825 826
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
827
                        }
828 829
                    }
                }
830 831
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
832
                match *self.value_def.borrow() {
833 834 835 836 837 838 839
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
840
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
841
        if self.defined_in_namespace(namespace) {
842
            match namespace {
843
                TypeNS  => {
E
Erick Tryzelaar 已提交
844
                    match *self.type_def.borrow() {
845
                        None => None,
E
Eduard Burtescu 已提交
846
                        Some(ref type_def) => type_def.type_span
847 848 849
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
850
                    match *self.value_def.borrow() {
851
                        None => None,
E
Eduard Burtescu 已提交
852
                        Some(ref value_def) => value_def.value_span
853 854
                    }
                }
855
            }
856 857
        } else {
            None
858 859
        }
    }
860 861 862 863 864 865 866 867 868 869 870 871 872

    fn is_public(&self, namespace: Namespace) -> bool {
        match namespace {
            TypeNS  => {
                let type_def = self.type_def.borrow();
                type_def.as_ref().unwrap().modifiers.contains(PUBLIC)
            }
            ValueNS => {
                let value_def = self.value_def.borrow();
                value_def.as_ref().unwrap().modifiers.contains(PUBLIC)
            }
        }
    }
873 874
}

875
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
876
struct PrimitiveTypeTable {
877
    primitive_types: HashMap<Name, PrimTy>,
878
}
879

880
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
881 882 883 884 885 886 887 888 889
    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));
890 891
        table.intern("int",     TyInt(TyIs(true)));
        table.intern("isize",   TyInt(TyIs(false)));
K
Kevin Butler 已提交
892 893 894 895 896
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
897 898
        table.intern("uint",    TyUint(TyUs(true)));
        table.intern("usize",   TyUint(TyUs(false)));
K
Kevin Butler 已提交
899 900 901 902 903 904 905 906
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

907
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
908
        self.primitive_types.insert(token::intern(string), primitive_type);
909 910 911
    }
}

912
/// The main resolver class.
913
struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
914
    session: &'a Session,
915

916 917
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
918
    graph_root: NameBindings,
919

920
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
921

922
    structs: FnvHashMap<DefId, Vec<Name>>,
923

924
    // The number of imports that are currently unresolved.
925
    unresolved_imports: uint,
926 927

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
928
    current_module: Rc<Module>,
929 930

    // The current set of local scopes, for values.
931
    // FIXME #4948: Reuse ribs to avoid allocation.
932
    value_ribs: Vec<Rib>,
933 934

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

937
    // The current set of local scopes, for labels.
938
    label_ribs: Vec<Rib>,
939

940
    // The trait that the current context can refer to.
941 942 943 944
    current_trait_ref: Option<(DefId, TraitRef)>,

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

946
    // The ident for the keyword "self".
J
John Clements 已提交
947
    self_name: Name,
948
    // The ident for the non-keyword "Self".
J
John Clements 已提交
949
    type_self_name: Name,
950

951
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
952
    primitive_type_table: PrimitiveTypeTable,
953

954
    def_map: DefMap,
955 956
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
957
    export_map: ExportMap,
958
    trait_map: TraitMap,
959
    external_exports: ExternalExports,
960

961 962 963 964 965
    // 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,

966 967 968 969 970
    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,

971
    used_imports: HashSet<(NodeId, Namespace)>,
972
    used_crates: HashSet<CrateNum>,
973 974
}

975
#[derive(PartialEq)]
S
Steven Fackler 已提交
976 977 978 979 980 981
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}


982 983 984 985 986
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 已提交
987 988 989 990 991 992 993 994 995 996 997 998 999 1000
        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,

1001 1002
            ast_map: ast_map,

K
Kevin Butler 已提交
1003 1004 1005 1006 1007
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

1008 1009
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1010 1011 1012 1013

            unresolved_imports: 0,

            current_module: current_module,
1014 1015 1016
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1017 1018 1019 1020

            current_trait_ref: None,
            current_self_type: None,

J
John Clements 已提交
1021 1022
            self_name: special_names::self_,
            type_self_name: special_names::type_self,
K
Kevin Butler 已提交
1023 1024 1025

            primitive_type_table: PrimitiveTypeTable::new(),

1026 1027 1028 1029 1030
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1031
            used_imports: HashSet::new(),
1032
            used_crates: HashSet::new(),
1033
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1034 1035

            emit_errors: true,
1036 1037
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
1038 1039
        }
    }
1040 1041 1042 1043 1044 1045 1046 1047 1048

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

1049 1050
    /// Resolves all imports for the crate. This method performs the fixed-
    /// point iteration.
F
Felix S. Klock II 已提交
1051
    fn resolve_imports(&mut self) {
A
Alfie John 已提交
1052
        let mut i = 0;
T
Tim Chevalier 已提交
1053
        let mut prev_unresolved_imports = 0;
1054
        loop {
1055
            debug!("(resolving imports) iteration {}, {} imports left",
P
Paul Stansifer 已提交
1056
                   i, self.unresolved_imports);
1057

1058
            let module_root = self.graph_root.get_module();
E
Eduard Burtescu 已提交
1059
            self.resolve_imports_for_module_subtree(module_root.clone());
1060

T
Tim Chevalier 已提交
1061
            if self.unresolved_imports == 0 {
1062
                debug!("(resolving imports) success");
1063 1064 1065 1066 1067 1068 1069 1070
                break;
            }

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

T
Tim Chevalier 已提交
1071
            i += 1;
1072 1073 1074 1075
            prev_unresolved_imports = self.unresolved_imports;
        }
    }

1076 1077
    /// Attempts to resolve imports for the given module and all of its
    /// submodules.
E
Eduard Burtescu 已提交
1078
    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
1079
        debug!("(resolving imports for module subtree) resolving {}",
1080
               self.module_to_string(&*module_));
1081
        let orig_module = replace(&mut self.current_module, module_.clone());
E
Eduard Burtescu 已提交
1082
        self.resolve_imports_for_module(module_.clone());
1083
        self.current_module = orig_module;
1084

1085
        build_reduced_graph::populate_module_if_necessary(self, &module_);
1086
        for (_, child_node) in &*module_.children.borrow() {
1087 1088 1089 1090 1091 1092
            match child_node.get_module_if_available() {
                None => {
                    // Nothing to do.
                }
                Some(child_module) => {
                    self.resolve_imports_for_module_subtree(child_module);
1093 1094 1095 1096
                }
            }
        }

1097
        for (_, child_module) in &*module_.anonymous_children.borrow() {
E
Eduard Burtescu 已提交
1098
            self.resolve_imports_for_module_subtree(child_module.clone());
1099 1100 1101
        }
    }

1102
    /// Attempts to resolve imports for the given module only.
E
Eduard Burtescu 已提交
1103
    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
1104
        if module.all_imports_resolved() {
1105
            debug!("(resolving imports for module) all imports resolved for \
A
Alex Crichton 已提交
1106
                   {}",
1107
                   self.module_to_string(&*module));
B
Brian Anderson 已提交
1108
            return;
1109 1110
        }

1111
        let imports = module.imports.borrow();
1112
        let import_count = imports.len();
1113 1114
        while module.resolved_import_count.get() < import_count {
            let import_index = module.resolved_import_count.get();
1115
            let import_directive = &(*imports)[import_index];
1116 1117
            match self.resolve_import_for_module(module.clone(),
                                                 import_directive) {
1118 1119 1120 1121 1122 1123
                Failed(err) => {
                    let (span, help) = match err {
                        Some((span, msg)) => (span, format!(". {}", msg)),
                        None => (import_directive.span, String::new())
                    };
                    let msg = format!("unresolved import `{}`{}",
1124
                                      self.import_path_to_string(
1125
                                          &import_directive.module_path,
1126 1127
                                          import_directive.subclass),
                                      help);
1128
                    self.resolve_error(span, &msg[..]);
1129
                }
1130 1131
                Indeterminate => break, // Bail out. We'll come around next time.
                Success(()) => () // Good. Continue.
1132 1133
            }

1134 1135
            module.resolved_import_count
                  .set(module.resolved_import_count.get() + 1);
1136 1137 1138
        }
    }

1139
    fn names_to_string(&self, names: &[Name]) -> String {
1140
        let mut first = true;
1141
        let mut result = String::new();
1142
        for name in names {
1143 1144 1145 1146 1147
            if first {
                first = false
            } else {
                result.push_str("::")
            }
1148
            result.push_str(&token::get_name(*name));
1149
        };
1150
        result
P
Paul Stansifer 已提交
1151
    }
1152

1153 1154
    fn path_names_to_string(&self, path: &Path, depth: usize) -> String {
        let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth]
1155 1156 1157
                                        .iter()
                                        .map(|seg| seg.identifier.name)
                                        .collect();
1158
        self.names_to_string(&names[..])
1159 1160
    }

1161
    fn import_directive_subclass_to_string(&mut self,
N
Nick Cameron 已提交
1162 1163
                                           subclass: ImportDirectiveSubclass)
                                           -> String {
1164
        match subclass {
1165
            SingleImport(_, source) => {
1166
                token::get_name(source).to_string()
P
Patrick Walton 已提交
1167
            }
1168
            GlobImport => "*".to_string()
1169 1170
        }
    }
1171

1172
    fn import_path_to_string(&mut self,
N
Nick Cameron 已提交
1173 1174 1175
                             names: &[Name],
                             subclass: ImportDirectiveSubclass)
                             -> String {
1176
        if names.is_empty() {
1177
            self.import_directive_subclass_to_string(subclass)
1178
        } else {
A
Alex Crichton 已提交
1179
            (format!("{}::{}",
1180
                     self.names_to_string(names),
1181
                     self.import_directive_subclass_to_string(
1182
                         subclass))).to_string()
1183 1184
        }
    }
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
    #[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 {
1202
        if did.krate == ast::LOCAL_CRATE {
1203 1204 1205 1206 1207 1208
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

1209 1210 1211 1212 1213
    /// 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 已提交
1214
    fn resolve_import_for_module(&mut self,
E
Eduard Burtescu 已提交
1215 1216
                                 module_: Rc<Module>,
                                 import_directive: &ImportDirective)
1217
                                 -> ResolveResult<()> {
1218
        let mut resolution_result = Failed(None);
A
Alex Crichton 已提交
1219
        let module_path = &import_directive.module_path;
1220

1221
        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
1222
               self.names_to_string(&module_path[..]),
1223
               self.module_to_string(&*module_));
1224

1225
        // First, resolve the module path for the directive, if necessary.
1226
        let container = if module_path.len() == 0 {
1227
            // Use the crate root.
1228
            Some((self.graph_root.get_module(), LastMod(AllPublic)))
1229
        } else {
E
Eduard Burtescu 已提交
1230
            match self.resolve_module_path(module_.clone(),
1231
                                           &module_path[..],
1232 1233 1234
                                           DontUseLexicalScope,
                                           import_directive.span,
                                           ImportSearch) {
1235 1236 1237 1238
                Failed(err) => {
                    resolution_result = Failed(err);
                    None
                },
B
Brian Anderson 已提交
1239
                Indeterminate => {
1240
                    resolution_result = Indeterminate;
1241
                    None
1242
                }
1243
                Success(container) => Some(container),
1244 1245 1246
            }
        };

1247
        match container {
1248
            None => {}
1249
            Some((containing_module, lp)) => {
1250 1251 1252
                // We found the module that the target is contained
                // within. Attempt to resolve the import within it.

E
Eduard Burtescu 已提交
1253
                match import_directive.subclass {
1254
                    SingleImport(target, source) => {
1255
                        resolution_result =
N
Nick Cameron 已提交
1256
                            self.resolve_single_import(&module_,
1257 1258
                                                       containing_module,
                                                       target,
1259
                                                       source,
1260 1261
                                                       import_directive,
                                                       lp);
1262 1263 1264
                    }
                    GlobImport => {
                        resolution_result =
N
Nick Cameron 已提交
1265
                            self.resolve_glob_import(&module_,
1266
                                                     containing_module,
1267
                                                     import_directive,
1268
                                                     lp);
1269 1270 1271 1272 1273 1274
                    }
                }
            }
        }

        // Decrement the count of unresolved imports.
1275
        match resolution_result {
B
Brian Anderson 已提交
1276
            Success(()) => {
P
Patrick Walton 已提交
1277
                assert!(self.unresolved_imports >= 1);
T
Tim Chevalier 已提交
1278
                self.unresolved_imports -= 1;
1279
            }
B
Brian Anderson 已提交
1280
            _ => {
1281 1282 1283 1284 1285 1286 1287
                // 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
N
Nick Cameron 已提交
1288
        // resolve_imports_for_module).
1289

1290
        if !resolution_result.indeterminate() {
E
Eduard Burtescu 已提交
1291
            match import_directive.subclass {
B
Brian Anderson 已提交
1292
                GlobImport => {
1293 1294
                    assert!(module_.glob_count.get() >= 1);
                    module_.glob_count.set(module_.glob_count.get() - 1);
1295
                }
A
Alex Crichton 已提交
1296
                SingleImport(..) => {
1297 1298 1299 1300 1301
                    // Ignore.
                }
            }
        }

B
Brian Anderson 已提交
1302
        return resolution_result;
1303 1304
    }

E
Eduard Burtescu 已提交
1305
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1306
        NameBindings {
1307
            type_def: RefCell::new(Some(TypeNsDef {
1308
                modifiers: IMPORTABLE,
1309 1310
                module_def: Some(module),
                type_def: None,
1311
                type_span: None
1312
            })),
1313
            value_def: RefCell::new(None),
1314 1315 1316
        }
    }

F
Felix S. Klock II 已提交
1317
    fn resolve_single_import(&mut self,
E
Eduard Burtescu 已提交
1318
                             module_: &Module,
N
Nick Cameron 已提交
1319
                             target_module: Rc<Module>,
1320 1321
                             target: Name,
                             source: Name,
1322 1323
                             directive: &ImportDirective,
                             lp: LastPrivate)
N
Nick Cameron 已提交
1324
                             -> ResolveResult<()> {
1325
        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
1326
                `{}` id {}, last private {:?}",
1327
               token::get_name(target),
N
Nick Cameron 已提交
1328
               self.module_to_string(&*target_module),
1329
               token::get_name(source),
1330
               self.module_to_string(module_),
1331 1332
               directive.id,
               lp);
1333

1334 1335
        let lp = match lp {
            LastMod(lp) => lp,
1336 1337 1338 1339 1340
            LastImport {..} => {
                self.session
                    .span_bug(directive.span,
                              "not expecting Import here, must be LastMod")
            }
1341 1342
        };

1343
        // We need to resolve both namespaces for this to succeed.
1344 1345 1346 1347 1348 1349
        //

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

        // Search for direct children of the containing module.
1350
        build_reduced_graph::populate_module_if_necessary(self, &target_module);
1351

1352
        match target_module.children.borrow().get(&source) {
1353 1354 1355
            None => {
                // Continue.
            }
E
Eduard Burtescu 已提交
1356
            Some(ref child_name_bindings) => {
1357 1358
                // pub_err makes sure we don't give the same error twice.
                let mut pub_err = false;
1359
                if child_name_bindings.defined_in_namespace(ValueNS) {
1360
                    debug!("(resolving single import) found value binding");
1361
                    value_result = BoundResult(target_module.clone(),
E
Eduard Burtescu 已提交
1362
                                               (*child_name_bindings).clone());
1363 1364 1365 1366 1367
                    if directive.is_public && !child_name_bindings.is_public(ValueNS) {
                        let msg = format!("`{}` is private", token::get_name(source));
                        span_err!(self.session, directive.span, E0364, "{}", &msg);
                        pub_err = true;
                    }
1368
                }
1369
                if child_name_bindings.defined_in_namespace(TypeNS) {
1370
                    debug!("(resolving single import) found type binding");
1371
                    type_result = BoundResult(target_module.clone(),
E
Eduard Burtescu 已提交
1372
                                              (*child_name_bindings).clone());
1373 1374 1375 1376
                    if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
                        let msg = format!("`{}` is private", token::get_name(source));
                        span_err!(self.session, directive.span, E0365, "{}", &msg);
                    }
1377 1378 1379 1380
                }
            }
        }

1381 1382
        // Unless we managed to find a result in both namespaces (unlikely),
        // search imports as well.
1383 1384
        let mut value_used_reexport = false;
        let mut type_used_reexport = false;
E
Eduard Burtescu 已提交
1385
        match (value_result.clone(), type_result.clone()) {
A
Alex Crichton 已提交
1386
            (BoundResult(..), BoundResult(..)) => {} // Continue.
B
Brian Anderson 已提交
1387
            _ => {
1388 1389 1390 1391
                // 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.

N
Nick Cameron 已提交
1392
                if target_module.glob_count.get() > 0 {
1393
                    debug!("(resolving single import) unresolved glob; \
P
Paul Stansifer 已提交
1394
                            bailing out");
B
Brian Anderson 已提交
1395
                    return Indeterminate;
1396 1397
                }

E
Eduard Burtescu 已提交
1398
                // Now search the exported imports within the containing module.
N
Nick Cameron 已提交
1399
                match target_module.import_resolutions.borrow().get(&source) {
B
Brian Anderson 已提交
1400
                    None => {
1401
                        debug!("(resolving single import) no import");
1402 1403 1404 1405 1406
                        // 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.

1407
                        if value_result.is_unknown() {
1408 1409
                            value_result = UnboundResult;
                        }
1410
                        if type_result.is_unknown() {
1411 1412 1413
                            type_result = UnboundResult;
                        }
                    }
B
Brian Anderson 已提交
1414
                    Some(import_resolution)
E
Eduard Burtescu 已提交
1415
                            if import_resolution.outstanding_references == 0 => {
1416

A
Alex Crichton 已提交
1417
                        fn get_binding(this: &mut Resolver,
E
Eduard Burtescu 已提交
1418
                                       import_resolution: &ImportResolution,
1419 1420
                                       namespace: Namespace,
                                       source: &Name)
1421
                                    -> NamespaceResult {
T
Tim Chevalier 已提交
1422

1423 1424
                            // Import resolutions must be declared with "pub"
                            // in order to be exported.
E
Eduard Burtescu 已提交
1425
                            if !import_resolution.is_public {
1426 1427 1428
                                return UnboundResult;
                            }

N
Nick Cameron 已提交
1429
                            match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1430
                                None => {
B
Brian Anderson 已提交
1431
                                    return UnboundResult;
1432
                                }
1433 1434 1435 1436 1437
                                Some(Target {
                                    target_module,
                                    bindings,
                                    shadowable: _
                                }) => {
1438
                                    debug!("(resolving single import) found \
1439
                                            import in ns {:?}", namespace);
1440
                                    let id = import_resolution.id(namespace);
1441
                                    // track used imports and extern crates as well
1442
                                    this.used_imports.insert((id, namespace));
1443
                                    this.record_import_use(id, *source);
1444 1445 1446 1447 1448 1449
                                    match target_module.def_id.get() {
                                        Some(DefId{krate: kid, ..}) => {
                                            this.used_crates.insert(kid);
                                        },
                                        _ => {}
                                    }
E
Eduard Burtescu 已提交
1450
                                    return BoundResult(target_module, bindings);
1451 1452 1453 1454 1455 1456
                                }
                            }
                        }

                        // The name is an import which has been fully
                        // resolved. We can, therefore, just follow it.
1457
                        if value_result.is_unknown() {
1458 1459 1460 1461
                            value_result = get_binding(self,
                                                       import_resolution,
                                                       ValueNS,
                                                       &source);
E
Eduard Burtescu 已提交
1462
                            value_used_reexport = import_resolution.is_public;
1463
                        }
1464
                        if type_result.is_unknown() {
1465 1466 1467 1468
                            type_result = get_binding(self,
                                                      import_resolution,
                                                      TypeNS,
                                                      &source);
E
Eduard Burtescu 已提交
1469
                            type_used_reexport = import_resolution.is_public;
1470
                        }
1471

1472
                    }
B
Brian Anderson 已提交
1473
                    Some(_) => {
N
Nick Cameron 已提交
1474
                        // If target_module is the same module whose import we are resolving
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485
                        // 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
N
Nick Cameron 已提交
1486
                        match (module_.def_id.get(),  target_module.def_id.get()) {
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501
                            (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;
                            }
                        }
1502 1503 1504 1505 1506
                    }
                }
            }
        }

1507 1508
        let mut value_used_public = false;
        let mut type_used_public = false;
N
Nick Cameron 已提交
1509 1510 1511

        // If we didn't find a result in the type namespace, search the
        // external modules.
1512
        match type_result {
A
Alex Crichton 已提交
1513
            BoundResult(..) => {}
1514
            _ => {
N
Nick Cameron 已提交
1515
                match target_module.external_module_children.borrow_mut().get(&source).cloned() {
1516 1517
                    None => {} // Continue.
                    Some(module) => {
N
Nick Cameron 已提交
1518
                        debug!("(resolving single import) found external module");
1519 1520 1521 1522 1523
                        // track the module as used.
                        match module.def_id.get() {
                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
                            _ => {}
                        }
1524
                        let name_bindings =
N
Nick Cameron 已提交
1525 1526
                            Rc::new(Resolver::create_name_bindings_from_module(module));
                        type_result = BoundResult(target_module.clone(), name_bindings);
1527
                        type_used_public = true;
1528 1529 1530 1531 1532
                    }
                }
            }
        }

1533
        // We've successfully resolved the import. Write the results in.
E
Eduard Burtescu 已提交
1534
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1535
        let import_resolution = &mut (*import_resolutions)[target];
N
Nick Cameron 已提交
1536

1537
        {
1538
            let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
1539 1540 1541 1542
                let namespace_name = match namespace {
                    TypeNS => "type",
                    ValueNS => "value",
                };
1543

1544 1545
                match *result {
                    BoundResult(ref target_module, ref name_bindings) => {
1546
                        debug!("(resolving single import) found {:?} target: {:?}",
1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569
                               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 => {
1570
                        panic!("{:?} result should be known at this point", namespace_name);
1571 1572 1573 1574 1575
                    }
                }
            };
            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
1576 1577
        }

1578 1579 1580 1581
        self.check_for_conflicts_between_imports_and_items(
            module_,
            import_resolution,
            directive.span,
1582
            target);
1583

1584
        if value_result.is_unbound() && type_result.is_unbound() {
1585
            let msg = format!("There is no `{}` in `{}`",
1586
                              token::get_name(source),
N
Nick Cameron 已提交
1587
                              self.module_to_string(&target_module));
1588
            return Failed(Some((directive.span, msg)));
1589
        }
1590 1591
        let value_used_public = value_used_reexport || value_used_public;
        let type_used_public = type_used_reexport || type_used_public;
1592

E
Eduard Burtescu 已提交
1593 1594
        assert!(import_resolution.outstanding_references >= 1);
        import_resolution.outstanding_references -= 1;
1595

N
Nick Cameron 已提交
1596
        // Record what this import resolves to for later uses in documentation,
A
Alex Crichton 已提交
1597 1598
        // 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.
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
        let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
            let def = target.bindings.def_for_namespace(ValueNS).unwrap();
            (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
        });
        let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
            let def = target.bindings.def_for_namespace(TypeNS).unwrap();
            (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
        });

        let import_lp = LastImport {
            value_priv: value_def_and_priv.map(|(_, p)| p),
            value_used: Used,
            type_priv: type_def_and_priv.map(|(_, p)| p),
            type_used: Used
1613 1614
        };

1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628
        if let Some((def, _)) = value_def_and_priv {
            self.def_map.borrow_mut().insert(directive.id, PathResolution {
                base_def: def,
                last_private: import_lp,
                depth: 0
            });
        }
        if let Some((def, _)) = type_def_and_priv {
            self.def_map.borrow_mut().insert(directive.id, PathResolution {
                base_def: def,
                last_private: import_lp,
                depth: 0
            });
        }
A
Alex Crichton 已提交
1629

1630
        debug!("(resolving single import) successfully resolved import");
B
Brian Anderson 已提交
1631
        return Success(());
1632 1633
    }

1634
    // Resolves a glob import. Note that this function cannot fail; it either
1635
    // succeeds or bails out (as importing * from an empty module or a module
N
Nick Cameron 已提交
1636
    // that exports nothing is valid). target_module is the module we are
1637
    // actually importing, i.e., `foo` in `use foo::*`.
F
Felix S. Klock II 已提交
1638
    fn resolve_glob_import(&mut self,
E
Eduard Burtescu 已提交
1639
                           module_: &Module,
N
Nick Cameron 已提交
1640
                           target_module: Rc<Module>,
1641
                           import_directive: &ImportDirective,
1642 1643
                           lp: LastPrivate)
                           -> ResolveResult<()> {
1644 1645 1646
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1647 1648 1649
        // This function works in a highly imperative manner; it eagerly adds
        // everything it can to the list of import resolutions of the module
        // node.
1650
        debug!("(resolving glob import) resolving glob import {}", id);
1651 1652 1653

        // We must bail out if the node has unresolved imports of any kind
        // (including globs).
N
Nick Cameron 已提交
1654
        if !(*target_module).all_imports_resolved() {
1655
            debug!("(resolving glob import) target module has unresolved \
P
Paul Stansifer 已提交
1656
                    imports; bailing out");
B
Brian Anderson 已提交
1657
            return Indeterminate;
1658 1659
        }

N
Nick Cameron 已提交
1660
        assert_eq!(target_module.glob_count.get(), 0);
1661 1662

        // Add all resolved imports from the containing module.
N
Nick Cameron 已提交
1663
        let import_resolutions = target_module.import_resolutions.borrow();
1664
        for (ident, target_import_resolution) in &*import_resolutions {
1665
            debug!("(resolving glob import) writing module resolution \
L
Luqman Aden 已提交
1666
                    {} into `{}`",
1667
                   token::get_name(*ident),
1668
                   self.module_to_string(module_));
1669

E
Eduard Burtescu 已提交
1670
            if !target_import_resolution.is_public {
1671
                debug!("(resolving glob import) nevermind, just kidding");
1672 1673 1674
                continue
            }

1675
            // Here we merge two import resolutions.
1676
            let mut import_resolutions = module_.import_resolutions.borrow_mut();
1677
            match import_resolutions.get_mut(ident) {
E
Eduard Burtescu 已提交
1678
                Some(dest_import_resolution) => {
1679 1680 1681
                    // Merge the two import resolutions at a finer-grained
                    // level.

E
Eduard Burtescu 已提交
1682
                    match target_import_resolution.value_target {
B
Brian Anderson 已提交
1683
                        None => {
1684 1685
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1686
                        Some(ref value_target) => {
1687 1688 1689 1690
                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
                                                              import_directive.span,
                                                              *ident,
                                                              ValueNS);
1691
                            dest_import_resolution.value_target = Some(value_target.clone());
1692 1693
                        }
                    }
E
Eduard Burtescu 已提交
1694
                    match target_import_resolution.type_target {
B
Brian Anderson 已提交
1695
                        None => {
1696 1697
                            // Continue.
                        }
E
Eduard Burtescu 已提交
1698
                        Some(ref type_target) => {
1699 1700 1701 1702
                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
                                                              import_directive.span,
                                                              *ident,
                                                              TypeNS);
1703
                            dest_import_resolution.type_target = Some(type_target.clone());
1704 1705
                        }
                    }
E
Eduard Burtescu 已提交
1706 1707
                    dest_import_resolution.is_public = is_public;
                    continue;
1708
                }
E
Eduard Burtescu 已提交
1709
                None => {}
1710
            }
E
Eduard Burtescu 已提交
1711 1712 1713 1714 1715 1716 1717 1718 1719

            // 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);
1720 1721
        }

1722
        // Add all children from the containing module.
N
Nick Cameron 已提交
1723
        build_reduced_graph::populate_module_if_necessary(self, &target_module);
1724

N
Nick Cameron 已提交
1725
        for (&name, name_bindings) in &*target_module.children.borrow() {
1726
            self.merge_import_resolution(module_,
N
Nick Cameron 已提交
1727
                                         target_module.clone(),
1728 1729 1730 1731
                                         import_directive,
                                         name,
                                         name_bindings.clone());

1732 1733 1734
        }

        // Add external module children from the containing module.
N
Nick Cameron 已提交
1735
        for (&name, module) in &*target_module.external_module_children.borrow() {
1736
            let name_bindings =
E
Eduard Burtescu 已提交
1737
                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
1738
            self.merge_import_resolution(module_,
N
Nick Cameron 已提交
1739
                                         target_module.clone(),
1740 1741 1742
                                         import_directive,
                                         name,
                                         name_bindings);
1743 1744
        }

A
Alex Crichton 已提交
1745
        // Record the destination of this import
N
Nick Cameron 已提交
1746
        if let Some(did) = target_module.def_id.get() {
1747 1748 1749 1750 1751
            self.def_map.borrow_mut().insert(id, PathResolution {
                base_def: DefMod(did),
                last_private: lp,
                depth: 0
            });
A
Alex Crichton 已提交
1752 1753
        }

1754
        debug!("(resolving glob import) successfully resolved import");
B
Brian Anderson 已提交
1755
        return Success(());
1756 1757
    }

1758
    fn merge_import_resolution(&mut self,
E
Eduard Burtescu 已提交
1759 1760
                               module_: &Module,
                               containing_module: Rc<Module>,
1761
                               import_directive: &ImportDirective,
1762
                               name: Name,
E
Eduard Burtescu 已提交
1763
                               name_bindings: Rc<NameBindings>) {
1764 1765 1766
        let id = import_directive.id;
        let is_public = import_directive.is_public;

1767
        let mut import_resolutions = module_.import_resolutions.borrow_mut();
1768
        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
1769
            |vacant_entry| {
1770
                // Create a new import resolution from this child.
1771 1772
                vacant_entry.insert(ImportResolution::new(id, is_public))
            });
1773 1774 1775

        debug!("(resolving glob import) writing resolution `{}` in `{}` \
               to `{}`",
1776
               &token::get_name(name),
1777 1778
               self.module_to_string(&*containing_module),
               self.module_to_string(module_));
1779 1780

        // Merge the child item into the import resolution.
1781
        {
1782
            let mut merge_child_item = |namespace| {
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792
                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,
1793
                                          &token::get_name(name));
1794
                        span_err!(self.session, import_directive.span, E0251, "{}", msg);
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806
                    } 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);
1807
        }
1808

E
Eduard Burtescu 已提交
1809
        dest_import_resolution.is_public = is_public;
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823

        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) {
1824
        debug!("check_for_conflicting_import: {}; target exists: {}",
1825
               &token::get_name(name),
1826 1827
               target.is_some());

1828
        match *target {
1829
            Some(ref target) if target.shadowable != Shadowable::Always => {
1830 1831 1832 1833 1834 1835
                let msg = format!("a {} named `{}` has already been imported \
                                   in this module",
                                  match namespace {
                                    TypeNS => "type",
                                    ValueNS => "value",
                                  },
1836
                                  &token::get_name(name));
1837
                span_err!(self.session, import_span, E0252, "{}", &msg[..]);
1838 1839 1840 1841 1842
            }
            Some(_) | None => {}
        }
    }

1843 1844 1845 1846 1847 1848 1849 1850 1851
    /// 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));
1852
            span_err!(self.session, import_span, E0253, "{}", &msg[..]);
1853 1854 1855
        }
    }

1856 1857 1858 1859
    /// 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:
1860
                                                     &ImportResolution,
1861 1862 1863 1864 1865 1866 1867
                                                     import_span: Span,
                                                     name: Name) {
        // First, check for conflicts between imports and `extern crate`s.
        if module.external_module_children
                 .borrow()
                 .contains_key(&name) {
            match import_resolution.type_target {
1868
                Some(ref target) if target.shadowable != Shadowable::Always => {
1869 1870 1871
                    let msg = format!("import `{0}` conflicts with imported \
                                       crate in this module \
                                       (maybe you meant `use {0}::*`?)",
1872
                                      &token::get_name(name));
1873
                    span_err!(self.session, import_span, E0254, "{}", &msg[..]);
1874 1875 1876 1877 1878 1879 1880
                }
                Some(_) | None => {}
            }
        }

        // Check for item conflicts.
        let children = module.children.borrow();
1881
        let name_bindings = match children.get(&name) {
1882 1883 1884 1885 1886 1887 1888 1889
            None => {
                // There can't be any conflicts.
                return
            }
            Some(ref name_bindings) => (*name_bindings).clone(),
        };

        match import_resolution.value_target {
1890
            Some(ref target) if target.shadowable != Shadowable::Always => {
1891
                if let Some(ref value) = *name_bindings.value_def.borrow() {
1892 1893 1894
                    span_err!(self.session, import_span, E0255,
                              "import `{}` conflicts with value in this module",
                              &token::get_name(name));
1895
                    if let Some(span) = value.value_span {
1896
                        self.session.span_note(span, "conflicting value here");
1897 1898 1899 1900 1901 1902 1903
                    }
                }
            }
            Some(_) | None => {}
        }

        match import_resolution.type_target {
1904
            Some(ref target) if target.shadowable != Shadowable::Always => {
1905
                if let Some(ref ty) = *name_bindings.type_def.borrow() {
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915
                    let (what, note) = if ty.module_def.is_some() {
                        ("existing submodule", "note conflicting module here")
                    } else {
                        ("type in this module", "note conflicting type here")
                    };
                    span_err!(self.session, import_span, E0256,
                              "import `{}` conflicts with {}",
                              &token::get_name(name), what);
                    if let Some(span) = ty.type_span {
                        self.session.span_note(span, note);
1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929
                    }
                }
            }
            Some(_) | None => {}
        }
    }

    /// Checks that the names of external crates don't collide with other
    /// external crates.
    fn check_for_conflicts_between_external_crates(&self,
                                                   module: &Module,
                                                   name: Name,
                                                   span: Span) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1930 1931
                span_err!(self.session, span, E0259,
                          "an external crate named `{}` has already \
1932
                                   been imported into this module",
1933
                                  &token::get_name(name));
1934 1935 1936 1937 1938 1939 1940 1941 1942
        }
    }

    /// Checks that the names of items don't collide with external crates.
    fn check_for_conflicts_between_external_crates_and_items(&self,
                                                             module: &Module,
                                                             name: Name,
                                                             span: Span) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1943 1944
                span_err!(self.session, span, E0260,
                          "the name `{}` conflicts with an external \
1945 1946
                                   crate that has been imported into this \
                                   module",
1947
                                  &token::get_name(name));
1948
        }
1949 1950
    }

1951
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1952
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1953
                                     module_: Rc<Module>,
1954
                                     module_path: &[Name],
1955 1956 1957 1958
                                     index: uint,
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
1959
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
1960 1961
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
1962 1963 1964 1965 1966
            match module.external_module_children.borrow().get(&needle) {
                Some(_) => Some(module.clone()),
                None => match module.parent_link {
                    ModuleParentLink(ref parent, _) => {
                        search_parent_externals(needle, &parent.upgrade().unwrap())
1967 1968 1969
                    }
                   _ => None
                }
1970
            }
1971 1972
        }

1973
        let mut search_module = module_;
1974
        let mut index = index;
A
Alex Crichton 已提交
1975
        let module_path_len = module_path.len();
1976
        let mut closest_private = lp;
1977 1978 1979 1980 1981

        // 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 已提交
1982
            let name = module_path[index];
E
Eduard Burtescu 已提交
1983
            match self.resolve_name_in_module(search_module.clone(),
1984
                                              name,
1985
                                              TypeNS,
1986 1987
                                              name_search_type,
                                              false) {
1988
                Failed(None) => {
1989
                    let segment_name = token::get_name(name);
1990
                    let module_name = self.module_to_string(&*search_module);
1991
                    let mut span = span;
1992
                    let msg = if "???" == &module_name[..] {
1993
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1994

1995
                        match search_parent_externals(name,
1996
                                                     &self.current_module) {
1997
                            Some(module) => {
1998
                                let path_str = self.names_to_string(module_path);
1999
                                let target_mod_str = self.module_to_string(&*module);
2000
                                let current_mod_str =
2001
                                    self.module_to_string(&*self.current_module);
2002 2003 2004 2005 2006 2007 2008

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

2009
                                format!("Did you mean `{}{}`?", prefix, path_str)
2010
                            },
2011 2012
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
2013
                        }
2014
                    } else {
2015
                        format!("Could not find `{}` in `{}`",
2016 2017 2018
                                segment_name,
                                module_name)
                    };
2019

2020
                    return Failed(Some((span, msg)));
2021
                }
2022
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
2023
                Indeterminate => {
2024
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
2025
                            resolution is indeterminate: {}",
2026
                            token::get_name(name));
B
Brian Anderson 已提交
2027
                    return Indeterminate;
2028
                }
2029
                Success((target, used_proxy)) => {
2030 2031
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
2032
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
2033
                        Some(ref type_def) => {
2034 2035
                            match type_def.module_def {
                                None => {
2036
                                    let msg = format!("Not a module `{}`",
2037
                                                        token::get_name(name));
2038 2039

                                    return Failed(Some((span, msg)));
2040
                                }
E
Eduard Burtescu 已提交
2041
                                Some(ref module_def) => {
2042 2043 2044
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
2045 2046
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
2047
                                    }
2048

2049 2050 2051
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
2052 2053 2054
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
2055
                                        }
2056
                                    }
2057 2058 2059 2060 2061
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
2062
                            let msg = format!("Not a module `{}`",
2063
                                              token::get_name(name));
2064
                            return Failed(Some((span, msg)));
2065 2066 2067 2068 2069
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
2070
            index += 1;
2071 2072
        }

2073
        return Success((search_module, closest_private));
2074 2075
    }

2076 2077
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
2078 2079 2080
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
2081
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
2082
                           module_: Rc<Module>,
2083
                           module_path: &[Name],
2084 2085 2086
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
2087
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
2088
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
2089
        assert!(module_path_len > 0);
2090

2091
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
2092
               self.names_to_string(module_path),
2093
               self.module_to_string(&*module_));
2094

2095
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
2096
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
2097
                                                              module_path);
2098

2099 2100
        let search_module;
        let start_index;
2101
        let last_private;
2102
        match module_prefix_result {
2103
            Failed(None) => {
2104
                let mpath = self.names_to_string(module_path);
2105
                let mpath = &mpath[..];
2106
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
2107
                    Some(idx) => {
2108 2109 2110
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
2111 2112
                                            &mpath[idx + 1..],
                                            &mpath[..idx - 1]);
2113
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
2114
                    },
2115 2116 2117
                    None => {
                        return Failed(None)
                    }
2118
                }
2119
            }
2120
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
2121
            Indeterminate => {
2122
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
2123
                        bailing");
B
Brian Anderson 已提交
2124
                return Indeterminate;
2125
            }
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135
            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;
2136
                        last_private = LastMod(AllPublic);
2137 2138 2139 2140 2141
                    }
                    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.
2142 2143
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
2144
                            Failed(err) => return Failed(err),
2145
                            Indeterminate => {
2146
                                debug!("(resolving module path for import) \
2147 2148 2149 2150 2151 2152
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
2153
                                last_private = LastMod(AllPublic);
2154 2155 2156 2157 2158
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
2159 2160
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
2161
                start_index = index;
2162 2163 2164
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
2165 2166 2167
            }
        }

2168 2169 2170 2171
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
2172 2173
                                           name_search_type,
                                           last_private)
2174 2175
    }

2176 2177
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2178
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
2179
                                     module_: Rc<Module>,
2180
                                     name: Name,
2181
                                     namespace: Namespace)
2182
                                    -> ResolveResult<(Target, bool)> {
2183
        debug!("(resolving item in lexical scope) resolving `{}` in \
2184
                namespace {:?} in `{}`",
2185
               token::get_name(name),
2186
               namespace,
2187
               self.module_to_string(&*module_));
2188 2189 2190

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

2193
        match module_.children.borrow().get(&name) {
2194 2195 2196
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
2197 2198
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
2199
                                            Shadowable::Never),
2200
                               false));
2201
            }
2202
            Some(_) | None => { /* Not found; continue. */ }
2203 2204 2205 2206 2207 2208
        }

        // 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.
2209 2210 2211 2212 2213
        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 \
2214
                            import resolution, but not in namespace {:?}",
2215 2216 2217 2218 2219 2220
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
2221 2222 2223
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
2224
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
2225
                         self.used_crates.insert(kid);
2226
                    }
2227
                    return Success((target, false));
2228 2229 2230 2231
                }
            }
        }

2232 2233
        // Search for external modules.
        if namespace == TypeNS {
2234 2235 2236
            // FIXME (21114): In principle unclear `child` *has* to be lifted.
            let child = module_.external_module_children.borrow().get(&name).cloned();
            if let Some(module) = child {
2237 2238 2239
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
                debug!("lower name bindings succeeded");
2240 2241 2242
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2243
                                false));
2244 2245 2246
            }
        }

2247
        // Finally, proceed up the scope chain looking for parent modules.
2248
        let mut search_module = module_;
2249 2250
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
2251
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
2252
                NoParentLink => {
2253
                    // No more parents. This module was unresolved.
2254
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
2255
                            module");
2256
                    return Failed(None);
2257
                }
2258
                ModuleParentLink(parent_module_node, _) => {
2259 2260 2261 2262 2263 2264 2265
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
2266
                            return Failed(None);
2267
                        }
2268
                        TraitModuleKind |
2269
                        EnumModuleKind |
2270
                        TypeModuleKind |
2271
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
2272
                            search_module = parent_module_node.upgrade().unwrap();
2273 2274 2275
                        }
                    }
                }
E
Eduard Burtescu 已提交
2276 2277
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
2278 2279 2280 2281
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
2282
            match self.resolve_name_in_module(search_module.clone(),
2283
                                              name,
2284
                                              namespace,
2285 2286
                                              PathSearch,
                                              true) {
2287
                Failed(Some((span, msg))) =>
J
Jorge Aparicio 已提交
2288
                    self.resolve_error(span, &format!("failed to resolve. {}",
2289
                                                     msg)),
2290
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
2291
                Indeterminate => {
2292 2293 2294
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

2295
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
2296
                            higher scope; bailing");
B
Brian Anderson 已提交
2297
                    return Indeterminate;
2298
                }
2299
                Success((target, used_reexport)) => {
2300
                    // We found the module.
2301
                    debug!("(resolving item in lexical scope) found name \
2302 2303
                            in module, done");
                    return Success((target, used_reexport));
2304 2305 2306 2307 2308
                }
            }
        }
    }

2309
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
2310
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
2311
                                       module_: Rc<Module>,
2312
                                       name: Name)
E
Eduard Burtescu 已提交
2313
                                -> ResolveResult<Rc<Module>> {
2314 2315
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
2316
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
2317
        match resolve_result {
2318
            Success((target, _)) => {
2319
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
2320
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
2321
                    Some(ref type_def) => {
2322
                        match type_def.module_def {
2323
                            None => {
2324
                                debug!("!!! (resolving module in lexical \
2325 2326
                                        scope) module wasn't actually a \
                                        module!");
2327
                                return Failed(None);
2328
                            }
E
Eduard Burtescu 已提交
2329 2330
                            Some(ref module_def) => {
                                return Success(module_def.clone());
2331 2332 2333 2334
                            }
                        }
                    }
                    None => {
2335
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
2336
                                wasn't actually a module!");
2337
                        return Failed(None);
2338 2339 2340
                    }
                }
            }
B
Brian Anderson 已提交
2341
            Indeterminate => {
2342
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
2343
                        bailing");
B
Brian Anderson 已提交
2344
                return Indeterminate;
2345
            }
2346 2347 2348
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
2349 2350 2351 2352
            }
        }
    }

2353
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
2354 2355
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
2356 2357
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
2358
            match module_.parent_link.clone() {
2359 2360 2361
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
2362
                    let new_module = new_module.upgrade().unwrap();
2363
                    match new_module.kind.get() {
2364 2365
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
2366
                        EnumModuleKind |
2367
                        TypeModuleKind |
2368 2369 2370 2371 2372 2373 2374
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

2375 2376
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
2377 2378
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
2379
        match module_.kind.get() {
2380
            NormalModuleKind => return module_,
2381
            TraitModuleKind |
2382
            EnumModuleKind |
2383
            TypeModuleKind |
2384
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
2385
                match self.get_nearest_normal_module_parent(module_.clone()) {
2386 2387 2388 2389 2390 2391 2392
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

2393
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
2394
    /// (b) some chain of `super::`.
2395
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
2396
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
2397
                             module_: Rc<Module>,
2398
                             module_path: &[Name])
2399
                                 -> ResolveResult<ModulePrefixResult> {
2400 2401 2402 2403
        // 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;
2404
        let first_module_path_string = token::get_name(module_path[0]);
2405
        if "self" == &first_module_path_string[..] {
2406 2407 2408
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 1;
2409
        } else if "super" == &first_module_path_string[..] {
2410 2411 2412 2413 2414 2415 2416 2417
            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.
2418
        while i < module_path.len() {
2419
            let string = token::get_name(module_path[i]);
2420
            if "super" != &string[..] {
2421 2422
                break
            }
2423
            debug!("(resolving module prefix) resolving `super` at {}",
2424
                   self.module_to_string(&*containing_module));
2425
            match self.get_nearest_normal_module_parent(containing_module) {
2426
                None => return Failed(None),
2427 2428 2429
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
2430 2431 2432 2433
                }
            }
        }

2434
        debug!("(resolving module prefix) finished resolving prefix at {}",
2435
               self.module_to_string(&*containing_module));
2436 2437

        return Success(PrefixFound(containing_module, i));
2438 2439
    }

2440 2441 2442
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
2443 2444 2445
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
2446
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
2447
                              module_: Rc<Module>,
2448
                              name: Name,
2449
                              namespace: Namespace,
2450 2451
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
2452
                              -> ResolveResult<(Target, bool)> {
2453
        debug!("(resolving name in module) resolving `{}` in `{}`",
2454
               &token::get_name(name),
2455
               self.module_to_string(&*module_));
2456 2457

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

2460
        match module_.children.borrow().get(&name) {
2461 2462 2463
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
2464 2465
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
2466
                                            Shadowable::Never),
2467 2468 2469 2470
                               false));
            }
            Some(_) | None => {
                // Continue.
2471 2472 2473
            }
        }

2474 2475 2476 2477
        // 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.
2478
        if name_search_type == PathSearch {
2479
            assert_eq!(module_.glob_count.get(), 0);
2480 2481
        }

2482
        // Check the list of resolved imports.
2483
        match module_.import_resolutions.borrow().get(&name) {
2484
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
2485
                                       import_resolution.is_public => {
2486

E
Eduard Burtescu 已提交
2487 2488
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
2489
                    debug!("(resolving name in module) import \
2490
                           unresolved; bailing out");
B
Brian Anderson 已提交
2491
                    return Indeterminate;
2492
                }
2493
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
2494
                    None => {
2495
                        debug!("(resolving name in module) name found, \
2496
                                but not in namespace {:?}",
P
Paul Stansifer 已提交
2497
                               namespace);
2498
                    }
2499
                    Some(target) => {
2500
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
2501
                                import");
2502
                        // track used imports and extern crates as well
2503 2504 2505
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
2506 2507
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
2508
                        }
2509
                        return Success((target, true));
2510
                    }
2511 2512
                }
            }
2513
            Some(..) | None => {} // Continue.
2514 2515 2516 2517
        }

        // Finally, search through external children.
        if namespace == TypeNS {
2518 2519 2520
            // FIXME (21114): In principle unclear `child` *has* to be lifted.
            let child = module_.external_module_children.borrow().get(&name).cloned();
            if let Some(module) = child {
2521 2522
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
2523 2524 2525
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
2526
                                false));
2527 2528 2529 2530
            }
        }

        // We're out of luck.
2531
        debug!("(resolving name in module) failed to resolve `{}`",
2532
               &token::get_name(name));
2533
        return Failed(None);
2534 2535
    }

E
Eduard Burtescu 已提交
2536
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
2537
        let index = module_.resolved_import_count.get();
2538 2539
        let imports = module_.imports.borrow();
        let import_count = imports.len();
2540
        if index != import_count {
2541
            let sn = self.session
E
Eduard Burtescu 已提交
2542
                         .codemap()
2543
                         .span_to_snippet((*imports)[index].span)
2544
                         .unwrap();
2545
            if sn.contains("::") {
2546
                self.resolve_error((*imports)[index].span,
2547
                                   "unresolved import");
2548
            } else {
A
Alex Crichton 已提交
2549
                let err = format!("unresolved import (maybe you meant `{}::*`?)",
A
Alex Crichton 已提交
2550
                                  sn);
2551
                self.resolve_error((*imports)[index].span, &err[..]);
2552
            }
2553 2554 2555
        }

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

2558
        for (_, child_node) in &*module_.children.borrow() {
2559 2560 2561 2562 2563 2564
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
2565 2566 2567 2568
                }
            }
        }

2569
        for (_, module_) in &*module_.anonymous_children.borrow() {
E
Eduard Burtescu 已提交
2570
            self.report_unresolved_imports(module_.clone());
2571 2572 2573 2574 2575
        }
    }

    // AST resolution
    //
2576
    // We maintain a list of value ribs and type ribs.
2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591
    //
    // 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 已提交
2592 2593 2594
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
2595
        let orig_module = self.current_module.clone();
2596 2597

        // Move down in the graph.
2598
        match name {
B
Brian Anderson 已提交
2599
            None => {
2600 2601
                // Nothing to do.
            }
B
Brian Anderson 已提交
2602
            Some(name) => {
2603
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
2604

2605
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
2606
                    None => {
2607
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
2608
                               token::get_name(name),
2609
                               self.module_to_string(&*orig_module));
2610
                    }
B
Brian Anderson 已提交
2611
                    Some(name_bindings) => {
2612
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
2613
                            None => {
2614
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
2615
                                        for `{}` in `{}`",
2616
                                       token::get_name(name),
2617
                                       self.module_to_string(&*orig_module));
2618
                            }
B
Brian Anderson 已提交
2619
                            Some(module_) => {
2620
                                self.current_module = module_;
2621 2622 2623 2624 2625 2626 2627
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
2628
        f(self);
2629 2630 2631 2632

        self.current_module = orig_module;
    }

2633
    /// Wraps the given definition in the appropriate number of `DefUpvar`
2634
    /// wrappers.
E
Eduard Burtescu 已提交
2635
    fn upvarify(&self,
E
Eduard Burtescu 已提交
2636
                ribs: &[Rib],
E
Eduard Burtescu 已提交
2637 2638 2639
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
2640 2641 2642 2643 2644 2645
        let mut def = match def_like {
            DlDef(def) => def,
            _ => return Some(def_like)
        };
        match def {
            DefUpvar(..) => {
2646
                self.session.span_bug(span,
2647
                    &format!("unexpected {:?} in bindings", def))
2648
            }
2649
            DefLocal(node_id) => {
2650
                for rib in ribs {
2651 2652 2653 2654
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
2655
                        ClosureRibKind(function_id) => {
2656
                            let prev_def = def;
2657
                            def = DefUpvar(node_id, function_id);
2658

2659
                            let mut seen = self.freevars_seen.borrow_mut();
2660
                            let seen = match seen.entry(function_id) {
2661
                                Occupied(v) => v.into_mut(),
2662
                                Vacant(v) => v.insert(NodeSet()),
2663
                            };
2664 2665 2666
                            if seen.contains(&node_id) {
                                continue;
                            }
2667
                            match self.freevars.borrow_mut().entry(function_id) {
2668
                                Occupied(v) => v.into_mut(),
2669
                                Vacant(v) => v.insert(vec![]),
2670
                            }.push(Freevar { def: prev_def, span: span });
2671 2672
                            seen.insert(node_id);
                        }
2673
                        ItemRibKind | MethodRibKind => {
2674 2675 2676
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
2677

2678
                            self.resolve_error(span,
2679
                                "can't capture dynamic environment in a fn item; \
2680
                                 use the || { ... } closure form instead");
2681 2682 2683 2684 2685 2686 2687
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
                            self.resolve_error(span,
                                               "attempt to use a non-constant \
                                                value in a constant");
2688
                            return None;
2689
                        }
2690 2691
                    }
                }
2692
            }
2693
            DefTyParam(..) | DefSelfTy(_) => {
2694
                for rib in ribs {
2695
                    match rib.kind {
2696
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
2697 2698 2699 2700 2701
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
2702

2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713
                            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");
2714
                            return None;
2715 2716
                        }
                    }
2717
                }
2718
            }
2719
            _ => {}
2720
        }
2721
        Some(DlDef(def))
2722 2723
    }

S
Seo Sanghyeon 已提交
2724 2725
    /// Searches the current set of local scopes and
    /// applies translations for closures.
E
Eduard Burtescu 已提交
2726
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
2727
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
2728 2729 2730
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
2731
        // FIXME #4950: Try caching?
2732

2733
        for (i, rib) in ribs.iter().enumerate().rev() {
2734 2735
            if let Some(def_like) = rib.bindings.get(&name).cloned() {
                return self.upvarify(&ribs[i + 1..], def_like, span);
2736 2737 2738
            }
        }

2739
        None
2740 2741
    }

S
Seo Sanghyeon 已提交
2742 2743
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755
    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 已提交
2756 2757
            if result.is_some() {
                return result
2758 2759 2760 2761 2762
            }
        }
        None
    }

2763
    fn resolve_crate(&mut self, krate: &ast::Crate) {
2764
        debug!("(resolving crate) starting");
2765

2766
        visit::walk_crate(self, krate);
2767 2768
    }

W
we 已提交
2769 2770
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
V
Vadim Petrochenkov 已提交
2771
            span_err!(self.session, span, E0317,
W
we 已提交
2772 2773 2774 2775
                "user-defined types or type parameters cannot shadow the primitive types");
        }
    }

2776
    fn resolve_item(&mut self, item: &Item) {
2777 2778
        let name = item.ident.name;

2779
        debug!("(resolving item) resolving {}",
2780
               token::get_name(name));
2781

2782
        match item.node {
2783 2784 2785
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
2786 2787
                self.check_if_primitive_type_name(name, item.span);

2788
                self.with_type_parameter_rib(HasTypeParameters(generics,
2789
                                                               TypeSpace,
2790
                                                               ItemRibKind),
2791
                                             |this| visit::walk_item(this, item));
2792
            }
2793
            ItemFn(_, _, _, ref generics, _) => {
2794
                self.with_type_parameter_rib(HasTypeParameters(generics,
2795
                                                               FnSpace,
2796
                                                               ItemRibKind),
2797
                                             |this| visit::walk_item(this, item));
2798 2799
            }

F
Flavio Percoco 已提交
2800
            ItemDefaultImpl(_, ref trait_ref) => {
E
Eduard Burtescu 已提交
2801
                self.with_optional_trait_ref(Some(trait_ref), |_| {});
2802
            }
2803
            ItemImpl(_, _,
2804
                     ref generics,
2805 2806
                     ref implemented_traits,
                     ref self_type,
2807
                     ref impl_items) => {
2808
                self.resolve_implementation(generics,
2809
                                            implemented_traits,
2810
                                            &**self_type,
2811
                                            &impl_items[..]);
2812 2813
            }

N
Nick Cameron 已提交
2814
            ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
W
we 已提交
2815 2816
                self.check_if_primitive_type_name(name, item.span);

2817
                // Create a new rib for the self type.
2818
                let mut self_type_rib = Rib::new(ItemRibKind);
2819

J
John Clements 已提交
2820 2821
                // plain insert (no renaming, types are not currently hygienic....)
                let name = self.type_self_name;
2822 2823
                self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
                self.type_ribs.push(self_type_rib);
2824

2825
                // Create a new rib for the trait-wide type parameters.
2826
                self.with_type_parameter_rib(HasTypeParameters(generics,
2827
                                                               TypeSpace,
2828 2829
                                                               NormalRibKind),
                                             |this| {
2830 2831
                    this.visit_generics(generics);
                    visit::walk_ty_param_bounds_helper(this, bounds);
2832

2833
                    for trait_item in trait_items {
2834
                        // Create a new rib for the trait_item-specific type
2835 2836
                        // parameters.
                        //
2837
                        // FIXME #4951: Do we need a node ID here?
2838

2839
                        let type_parameters = match trait_item.node {
2840
                            ast::MethodTraitItem(ref sig, _) => {
2841
                                HasTypeParameters(&sig.generics,
2842 2843 2844
                                                  FnSpace,
                                                  MethodRibKind)
                            }
2845 2846 2847
                            ast::TypeTraitItem(..) => {
                                this.check_if_primitive_type_name(trait_item.ident.name,
                                                                  trait_item.span);
2848 2849
                                NoTypeParameters
                            }
2850 2851 2852 2853
                        };
                        this.with_type_parameter_rib(type_parameters, |this| {
                            visit::walk_trait_item(this, trait_item)
                        });
2854
                    }
2855
                });
2856

2857
                self.type_ribs.pop();
2858 2859
            }

2860
            ItemMod(_) | ItemForeignMod(_) => {
2861
                self.with_scope(Some(name), |this| {
2862
                    visit::walk_item(this, item);
2863
                });
2864 2865
            }

2866
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2867
                self.with_constant_rib(|this| {
2868
                    visit::walk_item(this, item);
2869
                });
2870
            }
2871

W
we 已提交
2872 2873 2874
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
                if let ast::ViewPathSimple(ident, _) = view_path.node {
2875 2876
                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
W
we 已提交
2877 2878 2879 2880 2881 2882 2883 2884
                            self.check_if_primitive_type_name(ident.name, item.span);
                        }
                        _ => {}
                    }
                }
            }

            ItemExternCrate(_) | ItemMac(..) => {
2885
                // do nothing, these are just around to be encoded
2886
            }
2887 2888 2889
        }
    }

J
Jorge Aparicio 已提交
2890 2891 2892
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
2893
        match type_parameters {
2894
            HasTypeParameters(generics, space, rib_kind) => {
2895
                let mut function_type_rib = Rib::new(rib_kind);
2896
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2897
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2898
                    let name = type_parameter.ident.name;
2899
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2900

2901
                    if seen_bindings.contains(&name) {
2902
                        self.resolve_error(type_parameter.span,
J
Jorge Aparicio 已提交
2903
                                           &format!("the name `{}` is already \
2904 2905 2906 2907
                                                     used for a type \
                                                     parameter in this type \
                                                     parameter list",
                                                    token::get_name(name)))
2908
                    }
2909
                    seen_bindings.insert(name);
2910

2911
                    // plain insert (no renaming)
2912 2913 2914 2915 2916
                    function_type_rib.bindings.insert(name,
                        DlDef(DefTyParam(space,
                                         index as u32,
                                         local_def(type_parameter.id),
                                         name)));
2917
                }
2918
                self.type_ribs.push(function_type_rib);
2919 2920
            }

B
Brian Anderson 已提交
2921
            NoTypeParameters => {
2922 2923 2924 2925
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2926
        f(self);
2927

2928
        match type_parameters {
2929
            HasTypeParameters(..) => { self.type_ribs.pop(); }
2930
            NoTypeParameters => { }
2931 2932 2933
        }
    }

J
Jorge Aparicio 已提交
2934 2935 2936
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2937
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2938
        f(self);
2939
        self.label_ribs.pop();
2940
    }
2941

J
Jorge Aparicio 已提交
2942 2943 2944
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2945 2946
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2947
        f(self);
2948 2949
        self.type_ribs.pop();
        self.value_ribs.pop();
2950 2951
    }

F
Felix S. Klock II 已提交
2952
    fn resolve_function(&mut self,
2953
                        rib_kind: RibKind,
2954
                        declaration: &FnDecl,
2955
                        block: &Block) {
2956
        // Create a value rib for the function.
2957
        self.value_ribs.push(Rib::new(rib_kind));
2958

2959
        // Create a label rib for the function.
2960
        self.label_ribs.push(Rib::new(rib_kind));
2961

2962 2963 2964 2965 2966 2967
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
            self.resolve_pattern(&*argument.pat,
                                 ArgumentIrrefutableMode,
                                 &mut bindings_list);
2968

2969
            self.visit_ty(&*argument.ty);
2970

2971 2972 2973
            debug!("(resolving function) recorded argument");
        }
        visit::walk_fn_ret_ty(self, &declaration.output);
2974

2975 2976
        // Resolve the function body.
        self.visit_block(&*block);
2977

2978
        debug!("(resolving function) leaving function");
2979

2980 2981
        self.label_ribs.pop();
        self.value_ribs.pop();
2982 2983
    }

F
Felix S. Klock II 已提交
2984
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2985
                               id: NodeId,
2986
                               trait_path: &Path,
2987
                               path_depth: usize)
2988 2989 2990 2991 2992 2993
                               -> Result<PathResolution, ()> {
        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
            if let DefTrait(_) = path_res.base_def {
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
2994 2995 2996 2997 2998
                self.resolve_error(trait_path.span,
                    &format!("`{}` is not a trait",
                             self.path_names_to_string(trait_path, path_depth)));

                // If it's a typedef, give a note
2999
                if let DefTy(..) = path_res.base_def {
3000 3001
                    self.session.span_note(trait_path.span,
                                           "`type` aliases cannot be used for traits");
3002
                }
3003 3004
                Err(())
            }
3005 3006 3007
        } else {
            let msg = format!("use of undeclared trait name `{}`",
                              self.path_names_to_string(trait_path, path_depth));
3008
            self.resolve_error(trait_path.span, &msg);
3009
            Err(())
3010 3011 3012
        }
    }

3013
    fn resolve_generics(&mut self, generics: &Generics) {
3014
        for type_parameter in &*generics.ty_params {
3015 3016 3017
            self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
        }
        for predicate in &generics.where_clause.predicates {
3018
            match predicate {
3019
                &ast::WherePredicate::BoundPredicate(_) |
3020
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
3021
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
3022 3023 3024 3025 3026
                    let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
                        self.record_def(eq_pred.id, path_res.unwrap());
                    } else {
                        self.resolve_error(eq_pred.path.span, "undeclared associated type");
3027 3028
                    }
                }
3029 3030
            }
        }
3031
        visit::walk_generics(self, generics);
3032 3033
    }

J
Jorge Aparicio 已提交
3034 3035 3036
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3037 3038 3039 3040 3041 3042 3043
        // 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
    }

3044
    fn with_optional_trait_ref<T, F>(&mut self,
E
Eduard Burtescu 已提交
3045
                                     opt_trait_ref: Option<&TraitRef>,
J
Jorge Aparicio 已提交
3046 3047 3048
                                     f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3049
        let mut new_val = None;
E
Eduard Burtescu 已提交
3050
        if let Some(trait_ref) = opt_trait_ref {
3051
            match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
3052 3053 3054
                Ok(path_res) => {
                    self.record_def(trait_ref.ref_id, path_res);
                    new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
3055
                }
3056
                Err(_) => { /* error was already reported */ }
3057
            }
3058 3059
            visit::walk_trait_ref(self, trait_ref);
        }
3060 3061 3062 3063 3064 3065
        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 已提交
3066
    fn resolve_implementation(&mut self,
3067 3068 3069
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
3070
                              impl_items: &[P<ImplItem>]) {
3071
        // If applicable, create a rib for the type parameters.
3072
        self.with_type_parameter_rib(HasTypeParameters(generics,
3073
                                                       TypeSpace,
3074
                                                       ItemRibKind),
3075
                                     |this| {
3076
            // Resolve the type parameters.
3077
            this.visit_generics(generics);
3078

3079
            // Resolve the trait reference, if necessary.
E
Eduard Burtescu 已提交
3080
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this| {
3081
                // Resolve the self type.
3082
                this.visit_ty(self_type);
3083 3084

                this.with_current_self_type(self_type, |this| {
3085
                    for impl_item in impl_items {
3086
                        match impl_item.node {
3087
                            MethodImplItem(ref sig, _) => {
3088 3089
                                // If this is a trait impl, ensure the method
                                // exists in trait
3090 3091
                                this.check_trait_item(impl_item.ident.name,
                                                      impl_item.span);
3092 3093 3094

                                // We also need a new scope for the method-
                                // specific type parameters.
3095
                                let type_parameters =
3096
                                    HasTypeParameters(&sig.generics,
3097 3098 3099
                                                      FnSpace,
                                                      MethodRibKind);
                                this.with_type_parameter_rib(type_parameters, |this| {
3100
                                    visit::walk_impl_item(this, impl_item);
3101
                                });
3102
                            }
3103
                            TypeImplItem(ref ty) => {
3104 3105
                                // If this is a trait impl, ensure the method
                                // exists in trait
3106 3107
                                this.check_trait_item(impl_item.ident.name,
                                                      impl_item.span);
3108

3109
                                this.visit_ty(ty);
3110
                            }
3111
                            ast::MacImplItem(_) => {}
3112
                        }
3113
                    }
3114 3115
                });
            });
3116
        });
3117 3118
    }

3119
    fn check_trait_item(&self, name: Name, span: Span) {
3120
        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
3121
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
3122
            if !self.trait_item_map.contains_key(&(name, did)) {
3123
                let path_str = self.path_names_to_string(&trait_ref.path, 0);
3124
                self.resolve_error(span,
J
Jorge Aparicio 已提交
3125
                                    &format!("method `{}` is not a member of trait `{}`",
3126
                                            token::get_name(name),
3127
                                            path_str));
3128 3129 3130 3131
            }
        }
    }

E
Eduard Burtescu 已提交
3132
    fn resolve_local(&mut self, local: &Local) {
3133
        // Resolve the type.
3134
        visit::walk_ty_opt(self, &local.ty);
3135

3136 3137
        // Resolve the initializer.
        visit::walk_expr_opt(self, &local.init);
3138 3139

        // Resolve the pattern.
3140 3141
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
3142
                             &mut HashMap::new());
3143 3144
    }

J
John Clements 已提交
3145 3146 3147 3148
    // 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 已提交
3149
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
3150
        let mut result = HashMap::new();
3151 3152
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
3153 3154 3155 3156
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
3157
        });
3158
        return result;
3159 3160
    }

J
John Clements 已提交
3161 3162
    // 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 已提交
3163
    fn check_consistent_bindings(&mut self, arm: &Arm) {
3164 3165 3166
        if arm.pats.len() == 0 {
            return
        }
3167
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
3168
        for (i, p) in arm.pats.iter().enumerate() {
3169
            let map_i = self.binding_mode_map(&**p);
3170

3171
            for (&key, &binding_0) in &map_0 {
3172
                match map_i.get(&key) {
3173 3174 3175
                  None => {
                    self.resolve_error(
                        p.span,
J
Jorge Aparicio 已提交
3176
                        &format!("variable `{}` from pattern #1 is \
3177 3178
                                  not bound in pattern #{}",
                                token::get_name(key),
3179
                                i + 1));
3180 3181 3182 3183 3184
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
                        self.resolve_error(
                            binding_i.span,
J
Jorge Aparicio 已提交
3185
                            &format!("variable `{}` is bound with different \
3186 3187
                                      mode in pattern #{} than in pattern #1",
                                    token::get_name(key),
3188
                                    i + 1));
3189 3190
                    }
                  }
3191 3192 3193
                }
            }

3194
            for (&key, &binding) in &map_i {
3195
                if !map_0.contains_key(&key) {
3196
                    self.resolve_error(
3197
                        binding.span,
J
Jorge Aparicio 已提交
3198
                        &format!("variable `{}` from pattern {}{} is \
3199
                                  not bound in pattern {}1",
3200
                                token::get_name(key),
3201
                                "#", i + 1, "#"));
3202 3203 3204
                }
            }
        }
3205 3206
    }

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

3210
        let mut bindings_list = HashMap::new();
3211
        for pattern in &arm.pats {
3212
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
3213 3214
        }

3215 3216 3217 3218
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

3219
        visit::walk_expr_opt(self, &arm.guard);
3220
        self.visit_expr(&*arm.body);
3221

3222
        self.value_ribs.pop();
3223 3224
    }

E
Eduard Burtescu 已提交
3225
    fn resolve_block(&mut self, block: &Block) {
3226
        debug!("(resolving block) entering block");
3227
        self.value_ribs.push(Rib::new(NormalRibKind));
3228 3229

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
3230
        let orig_module = self.current_module.clone();
3231
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
3232
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
3233
            Some(anonymous_module) => {
3234
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
3235
                        down");
E
Eduard Burtescu 已提交
3236
                self.current_module = anonymous_module.clone();
3237 3238 3239
            }
        }

3240 3241
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
3242
        for statement in &block.stmts {
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259
            if let ast::StmtDecl(ref declaration, _) = statement.node {
                if let ast::DeclItem(ref i) = declaration.node {
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
                            span_err!(self.session, i.span, E0154,
                                "imports are not allowed after non-item statements");
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

3260
        // Descend into the block.
3261
        visit::walk_block(self, block);
3262 3263 3264 3265

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

3266
        self.value_ribs.pop();
3267
        debug!("(resolving block) leaving block");
3268 3269
    }

F
Felix S. Klock II 已提交
3270
    fn resolve_type(&mut self, ty: &Ty) {
3271
        match ty.node {
3272 3273
            // `<T>::a::b::c` is resolved by typeck alone.
            TyPath(Some(ast::QSelf { position: 0, .. }), _) => {}
3274

3275 3276
            TyPath(ref maybe_qself, ref path) => {
                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
3277
                    // Make sure the trait is valid.
3278
                    let _ = self.resolve_trait_reference(ty.id, path, 1);
3279
                    path.segments.len() - qself.position
3280 3281 3282 3283
                } else {
                    path.segments.len()
                };

3284
                let mut resolution = None;
3285 3286
                for depth in 0..max_assoc_types {
                    self.with_no_errors(|this| {
3287
                        resolution = this.resolve_path(ty.id, path, depth, TypeNS, true);
3288
                    });
3289
                    if resolution.is_some() {
3290 3291 3292
                        break;
                    }
                }
3293
                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
3294
                    // A module is not a valid type.
3295
                    resolution = None;
3296
                }
3297 3298

                // This is a path in the type namespace. Walk through scopes
3299
                // looking for it.
3300
                match resolution {
B
Brian Anderson 已提交
3301
                    Some(def) => {
3302
                        // Write the result into the def map.
3303
                        debug!("(resolving type) writing resolution for `{}` \
3304
                                (id {}) = {:?}",
3305
                               self.path_names_to_string(path, 0),
3306 3307
                               ty.id, def);
                        self.record_def(ty.id, def);
3308
                    }
B
Brian Anderson 已提交
3309
                    None => {
3310 3311 3312
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

3313 3314 3315 3316
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
3317
                        };
3318

3319
                        let msg = format!("use of undeclared {} `{}`", kind,
3320
                                          self.path_names_to_string(path, 0));
3321
                        self.resolve_error(ty.span, &msg[..]);
3322 3323
                    }
                }
3324
            }
3325
            _ => {}
3326
        }
3327 3328
        // Resolve embedded types.
        visit::walk_ty(self, ty);
3329 3330
    }

F
Felix S. Klock II 已提交
3331
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
3332
                       pattern: &Pat,
3333 3334 3335
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
3336
                       bindings_list: &mut HashMap<Name, NodeId>) {
3337
        let pat_id = pattern.id;
3338
        walk_pat(pattern, |pattern| {
3339
            match pattern.node {
3340
                PatIdent(binding_mode, ref path1, _) => {
3341 3342

                    // The meaning of pat_ident with no type parameters
3343 3344 3345 3346 3347 3348 3349
                    // 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).
3350

3351
                    let ident = path1.node;
3352
                    let renamed = mtwt::resolve(ident);
3353

3354
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
3355
                        FoundStructOrEnumVariant(def, lp)
3356
                                if mode == RefutableMode => {
3357
                            debug!("(resolving pattern) resolving `{}` to \
3358
                                    struct or enum variant",
3359
                                   token::get_name(renamed));
3360

3361 3362 3363 3364
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
3365 3366 3367 3368 3369
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
3370
                        }
A
Alex Crichton 已提交
3371
                        FoundStructOrEnumVariant(..) => {
3372 3373
                            self.resolve_error(
                                pattern.span,
J
Jorge Aparicio 已提交
3374
                                &format!("declaration of `{}` shadows an enum \
3375 3376
                                         variant or unit-like struct in \
                                         scope",
3377
                                        token::get_name(renamed)));
3378
                        }
3379
                        FoundConst(def, lp) if mode == RefutableMode => {
3380
                            debug!("(resolving pattern) resolving `{}` to \
3381
                                    constant",
3382
                                   token::get_name(renamed));
3383

3384 3385 3386 3387
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
3388 3389 3390 3391 3392
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
3393
                        }
A
Alex Crichton 已提交
3394
                        FoundConst(..) => {
3395
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
3396
                                                  "only irrefutable patterns \
3397
                                                   allowed here");
3398
                        }
3399
                        BareIdentifierPatternUnresolved => {
3400
                            debug!("(resolving pattern) binding `{}`",
3401
                                   token::get_name(renamed));
3402

3403
                            let def = DefLocal(pattern.id);
3404 3405 3406 3407 3408

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

3409 3410 3411 3412 3413
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: LastMod(AllPublic),
                                depth: 0
                            });
3414 3415 3416 3417 3418 3419

                            // 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.)
3420 3421
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
3422 3423
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
3424
                                bindings_list.insert(renamed, pat_id);
3425 3426 3427 3428 3429
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
                                self.resolve_error(pattern.span,
J
Jorge Aparicio 已提交
3430
                                                   &format!("identifier `{}` \
3431 3432 3433 3434 3435 3436
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
3437
                                                   )
3438
                            } else if bindings_list.get(&renamed) ==
3439 3440 3441 3442
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
                                self.resolve_error(pattern.span,
J
Jorge Aparicio 已提交
3443
                                    &format!("identifier `{}` is bound \
3444 3445
                                             more than once in the same \
                                             pattern",
3446
                                            token::get_ident(ident)));
3447
                            }
3448 3449
                            // Else, not bound in the same pattern: do
                            // nothing.
3450 3451 3452 3453
                        }
                    }
                }

3454
                PatEnum(ref path, _) => {
3455
                    // This must be an enum variant, struct or const.
3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472
                    if let Some(path_res) = self.resolve_path(pat_id, path, 0, ValueNS, false) {
                        match path_res.base_def {
                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
                                self.resolve_error(path.span,
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
                            }
                            _ => {
                                self.resolve_error(path.span,
                                    &format!("`{}` is not an enum variant, struct or const",
                                        token::get_ident(
                                            path.segments.last().unwrap().identifier)));
                            }
3473
                        }
3474 3475 3476 3477
                    } else {
                        self.resolve_error(path.span,
                            &format!("unresolved enum variant, struct or const `{}`",
                                token::get_ident(path.segments.last().unwrap().identifier)));
3478
                    }
3479
                    visit::walk_path(self, path);
3480 3481
                }

3482
                PatStruct(ref path, _, _) => {
3483
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
3484
                        Some(definition) => {
3485 3486
                            self.record_def(pattern.id, definition);
                        }
3487
                        result => {
3488
                            debug!("(resolving pattern) didn't find struct \
3489
                                    def: {:?}", result);
A
Alex Crichton 已提交
3490
                            let msg = format!("`{}` does not name a structure",
3491
                                              self.path_names_to_string(path, 0));
3492
                            self.resolve_error(path.span, &msg[..]);
3493 3494
                        }
                    }
3495 3496 3497 3498 3499
                    visit::walk_path(self, path);
                }

                PatLit(_) | PatRange(..) => {
                    visit::walk_pat(self, pattern);
3500 3501
                }

3502
                _ => {
3503 3504 3505
                    // Nothing to do.
                }
            }
3506
            true
3507
        });
3508 3509
    }

3510
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
3511 3512 3513
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3514
                                                 name,
3515
                                                 ValueNS) {
3516
            Success((target, _)) => {
3517
                debug!("(resolve bare identifier pattern) succeeded in \
3518
                         finding {} at {:?}",
3519
                        token::get_name(name),
E
Erick Tryzelaar 已提交
3520 3521
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
3522
                    None => {
S
Steve Klabnik 已提交
3523
                        panic!("resolved name in the value namespace to a \
3524
                              set of name bindings with no def?!");
3525
                    }
B
Brian Anderson 已提交
3526
                    Some(def) => {
3527 3528 3529
                        // 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.
3530
                        match def.def {
A
Alex Crichton 已提交
3531
                            def @ DefVariant(..) | def @ DefStruct(..) => {
3532
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
3533
                            }
3534
                            def @ DefConst(..) => {
3535
                                return FoundConst(def, LastMod(AllPublic));
3536
                            }
3537
                            DefStatic(..) => {
3538
                                self.resolve_error(span,
3539 3540 3541
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
3542 3543
                                return BareIdentifierPatternUnresolved;
                            }
3544
                            _ => {
3545
                                return BareIdentifierPatternUnresolved;
3546 3547
                            }
                        }
3548 3549 3550 3551
                    }
                }
            }

B
Brian Anderson 已提交
3552
            Indeterminate => {
S
Steve Klabnik 已提交
3553
                panic!("unexpected indeterminate result");
3554
            }
3555 3556 3557
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
J
Jorge Aparicio 已提交
3558
                        self.resolve_error(span, &format!("failed to resolve: {}",
3559
                                                         msg));
3560 3561 3562
                    }
                    None => ()
                }
3563

3564
                debug!("(resolve bare identifier pattern) failed to find {}",
3565
                        token::get_name(name));
3566
                return BareIdentifierPatternUnresolved;
3567 3568 3569 3570
            }
        }
    }

3571 3572
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
3573 3574
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
F
Felix S. Klock II 已提交
3575
    fn resolve_path(&mut self,
3576 3577
                    id: NodeId,
                    path: &Path,
3578
                    path_depth: usize,
3579
                    namespace: Namespace,
3580
                    check_ribs: bool) -> Option<PathResolution> {
3581 3582 3583
        let span = path.span;
        let segments = &path.segments[..path.segments.len()-path_depth];

3584 3585 3586 3587 3588 3589
        let mk_res = |(def, lp)| PathResolution {
            base_def: def,
            last_private: lp,
            depth: path_depth
        };

3590
        if path.global {
3591
            let def = self.resolve_crate_relative_path(span, segments, namespace);
3592
            return def.map(mk_res);
3593 3594
        }

3595
        // Try to find a path to an item in a module.
3596
        let unqualified_def =
3597
                self.resolve_identifier(segments.last().unwrap().identifier,
3598 3599
                                        namespace,
                                        check_ribs,
3600
                                        span);
3601

3602 3603
        if segments.len() > 1 {
            let def = self.resolve_module_relative_path(span, segments, namespace);
3604
            match (def, unqualified_def) {
3605
                (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
3606
                    self.session
A
Aaron Turon 已提交
3607
                        .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
3608
                                  id, span,
3609
                                  "unnecessary qualification".to_string());
3610 3611 3612
                }
                _ => ()
            }
3613

3614
            def.map(mk_res)
3615
        } else {
3616
            unqualified_def.map(mk_res)
3617 3618 3619
        }
    }

J
John Clements 已提交
3620
    // resolve a single identifier (used as a varref)
F
Felix S. Klock II 已提交
3621
    fn resolve_identifier(&mut self,
3622 3623 3624 3625 3626
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3627 3628 3629 3630 3631 3632 3633 3634 3635
        // First, check to see whether the name is a primitive type.
        if namespace == TypeNS {
            if let Some(&prim_ty) = self.primitive_type_table
                                        .primitive_types
                                        .get(&identifier.name) {
                return Some((DefPrimTy(prim_ty), LastMod(AllPublic)));
            }
        }

3636
        if check_ribs {
3637 3638 3639 3640
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier,
                                                                     namespace,
                                                                     span) {
                return Some((def, LastMod(AllPublic)));
3641 3642 3643
            }
        }

3644
        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
3645 3646
    }

3647
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3648
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3649
                                            containing_module: Rc<Module>,
3650
                                            name: Name,
3651
                                            namespace: Namespace)
3652
                                            -> NameDefinition {
3653
        // First, search children.
3654
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3655

3656
        match containing_module.children.borrow().get(&name) {
3657 3658 3659 3660 3661 3662 3663
            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 {
3664
                            LastMod(DependsOn(def.def_id()))
3665 3666
                        };
                        return ChildNameDefinition(def, lp);
3667
                    }
3668
                    None => {}
3669 3670
                }
            }
3671
            None => {}
3672 3673 3674
        }

        // Next, search import resolutions.
3675
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3676
            Some(import_resolution) if import_resolution.is_public => {
3677 3678 3679 3680 3681 3682 3683
                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));
3684
                            self.record_import_use(id, name);
3685 3686 3687 3688 3689
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
3690
                            }
3691 3692 3693 3694 3695
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
3696 3697 3698 3699
                        }
                    }
                }
            }
A
Alex Crichton 已提交
3700
            Some(..) | None => {} // Continue.
3701 3702 3703 3704
        }

        // Finally, search through external children.
        if namespace == TypeNS {
3705 3706 3707 3708 3709 3710 3711 3712 3713
            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);
3714
                }
3715 3716
            }
        }
3717 3718

        return NoNameDefinition;
3719 3720
    }

3721
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3722
    fn resolve_module_relative_path(&mut self,
3723 3724
                                    span: Span,
                                    segments: &[ast::PathSegment],
3725 3726
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
3727 3728 3729
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3730

3731
        let containing_module;
3732
        let last_private;
E
Eduard Burtescu 已提交
3733 3734
        let module = self.current_module.clone();
        match self.resolve_module_path(module,
3735
                                       &module_path[..],
3736
                                       UseLexicalScope,
3737
                                       span,
3738
                                       PathSearch) {
3739 3740 3741 3742
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3743
                        let msg = format!("Use of undeclared type or module `{}`",
3744
                                          self.names_to_string(&module_path));
3745
                        (span, msg)
3746 3747
                    }
                };
3748

J
Jorge Aparicio 已提交
3749
                self.resolve_error(span, &format!("failed to resolve. {}",
3750
                                                 msg));
3751
                return None;
3752
            }
S
Steve Klabnik 已提交
3753
            Indeterminate => panic!("indeterminate unexpected"),
3754
            Success((resulting_module, resulting_last_private)) => {
3755
                containing_module = resulting_module;
3756
                last_private = resulting_last_private;
3757 3758 3759
            }
        }

3760
        let name = segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
3761
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
3762
                                                                  name,
3763
                                                                  namespace) {
B
Brian Anderson 已提交
3764
            NoNameDefinition => {
3765
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3766
                return None;
3767
            }
3768 3769
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
3770
            }
3771
        };
3772 3773
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
3774
        }
3775
        return Some(def);
3776 3777
    }

3778 3779
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3780
    fn resolve_crate_relative_path(&mut self,
3781 3782
                                   span: Span,
                                   segments: &[ast::PathSegment],
3783 3784
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
3785 3786 3787
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3788

3789
        let root_module = self.graph_root.get_module();
3790

3791
        let containing_module;
3792
        let last_private;
3793
        match self.resolve_module_path_from_root(root_module,
3794
                                                 &module_path[..],
3795
                                                 0,
3796
                                                 span,
3797
                                                 PathSearch,
3798
                                                 LastMod(AllPublic)) {
3799 3800 3801 3802 3803
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3804
                                          self.names_to_string(&module_path[..]));
3805
                        (span, msg)
3806 3807 3808
                    }
                };

J
Jorge Aparicio 已提交
3809
                self.resolve_error(span, &format!("failed to resolve. {}",
3810
                                                 msg));
B
Brian Anderson 已提交
3811
                return None;
3812 3813
            }

B
Brian Anderson 已提交
3814
            Indeterminate => {
S
Steve Klabnik 已提交
3815
                panic!("indeterminate unexpected");
3816 3817
            }

3818
            Success((resulting_module, resulting_last_private)) => {
3819
                containing_module = resulting_module;
3820
                last_private = resulting_last_private;
3821 3822 3823
            }
        }

3824
        let name = segments.last().unwrap().identifier.name;
3825
        match self.resolve_definition_of_name_in_module(containing_module,
3826
                                                        name,
3827
                                                        namespace) {
B
Brian Anderson 已提交
3828
            NoNameDefinition => {
3829
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3830
                return None;
3831
            }
3832 3833
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
3834 3835 3836 3837
            }
        }
    }

F
Felix S. Klock II 已提交
3838
    fn resolve_identifier_in_local_ribs(&mut self,
3839 3840 3841 3842
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
3843
        // Check the local set of ribs.
3844
        let search_result = match namespace {
B
Brian Anderson 已提交
3845
            ValueNS => {
3846
                let renamed = mtwt::resolve(ident);
3847
                self.search_ribs(&self.value_ribs, renamed, span)
3848
            }
B
Brian Anderson 已提交
3849
            TypeNS => {
3850
                let name = ident.name;
3851
                self.search_ribs(&self.type_ribs, name, span)
3852
            }
3853
        };
3854

3855
        match search_result {
3856
            Some(DlDef(def)) => {
3857
                debug!("(resolving path in local ribs) resolved `{}` to \
3858
                        local: {:?}",
3859
                       token::get_ident(ident),
P
Paul Stansifer 已提交
3860
                       def);
3861
                Some(def)
3862
            }
3863
            Some(DlField) | Some(DlImpl(_)) | None => {
3864
                None
3865 3866 3867 3868
            }
        }
    }

3869 3870 3871 3872
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
3873
        // Check the items.
E
Eduard Burtescu 已提交
3874 3875
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3876
                                                 name,
3877
                                                 namespace) {
3878
            Success((target, _)) => {
3879
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
3880
                    None => {
3881 3882
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
3883
                        debug!("(resolving item path by identifier in lexical \
3884
                                 scope) failed to resolve {} after success...",
3885
                                 token::get_name(name));
3886
                        return None;
3887
                    }
B
Brian Anderson 已提交
3888
                    Some(def) => {
3889
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
3890
                                resolved `{}` to item",
3891
                               token::get_name(name));
3892 3893 3894
                        // 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.
3895
                        return Some((def, LastMod(AllPublic)));
3896 3897 3898
                    }
                }
            }
B
Brian Anderson 已提交
3899
            Indeterminate => {
S
Steve Klabnik 已提交
3900
                panic!("unexpected indeterminate result");
3901
            }
3902 3903 3904
            Failed(err) => {
                match err {
                    Some((span, msg)) =>
J
Jorge Aparicio 已提交
3905
                        self.resolve_error(span, &format!("failed to resolve. {}",
3906
                                                         msg)),
3907 3908 3909
                    None => ()
                }

3910
                debug!("(resolving item path by identifier in lexical scope) \
3911
                         failed to resolve {}", token::get_name(name));
B
Brian Anderson 已提交
3912
                return None;
3913 3914 3915 3916
            }
        }
    }

J
Jorge Aparicio 已提交
3917 3918 3919
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3920
        self.emit_errors = false;
A
Alex Crichton 已提交
3921
        let rs = f(self);
3922 3923 3924 3925
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
3926
    fn resolve_error(&self, span: Span, s: &str) {
3927
        if self.emit_errors {
A
Alex Crichton 已提交
3928
            self.session.span_err(span, s);
3929 3930 3931
        }
    }

3932
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
3933 3934 3935
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
3936
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3937 3938
                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),
3939 3940 3941 3942 3943 3944 3945
                // 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,
            }
        }

3946
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
3947 3948
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
3949
            let last_name = name_path.last().unwrap();
3950

3951
            if name_path.len() == 1 {
3952
                match this.primitive_type_table.primitive_types.get(last_name) {
3953 3954
                    Some(_) => None,
                    None => {
3955
                        match this.current_module.children.borrow().get(last_name) {
3956 3957 3958 3959 3960 3961 3962
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
3963
                                                &name_path[..],
3964 3965 3966 3967 3968 3969 3970 3971 3972
                                                UseLexicalScope,
                                                span,
                                                PathSearch) {
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

3973 3974
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
            if did.krate == ast::LOCAL_CRATE {
3975
                let sig = match this.ast_map.get(did.node) {
3976
                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
3977
                        ast::MethodTraitItem(ref sig, _) => sig,
3978 3979
                        _ => return false
                    },
3980
                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
3981
                        ast::MethodImplItem(ref sig, _) => sig,
3982 3983 3984 3985
                        _ => return false
                    },
                    _ => return false
                };
3986
                sig.explicit_self.node == ast::SelfStatic
3987 3988 3989 3990 3991
            } else {
                csearch::is_static_method(&this.session.cstore, did)
            }
        }

3992 3993 3994 3995
        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,
3996 3997 3998 3999
            },
            None => return NoSuggestion,
        };

4000 4001
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
4002 4003 4004 4005
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
                Some(DefTy(did, _)) |
                Some(DefStruct(did)) |
                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
4006 4007 4008 4009 4010
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
4011
                    }
4012 4013 4014
                },
                _ => {} // Self type didn't resolve properly
            }
4015 4016
        }

4017
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
4018 4019

        // Look for a method in the current self type's impl module.
4020 4021 4022 4023 4024 4025 4026 4027 4028 4029
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
                if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
                    if is_static_method(self, did) {
                        return StaticMethod(self.path_names_to_string(&path, 0))
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
4030 4031
                    }
                }
4032
            }
4033 4034 4035
        }

        // Look for a method in the current trait.
4036 4037 4038 4039 4040 4041
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
            if let Some(&did) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method(self, did) {
                    return TraitMethod(self.path_names_to_string(&trait_ref.path, 0));
                } else {
                    return TraitItem;
4042 4043 4044 4045 4046 4047 4048
                }
            }
        }

        NoSuggestion
    }

4049
    fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
4050
                                -> Option<String> {
4051 4052
        let this = &mut *self;

4053 4054
        let mut maybes: Vec<token::InternedString> = Vec::new();
        let mut values: Vec<uint> = Vec::new();
4055

4056
        for rib in this.value_ribs.iter().rev() {
4057
            for (&k, _) in &rib.bindings {
4058
                maybes.push(token::get_name(k));
4059
                values.push(usize::MAX);
4060 4061 4062 4063
            }
        }

        let mut smallest = 0;
P
Patrick Walton 已提交
4064
        for (i, other) in maybes.iter().enumerate() {
4065
            values[i] = lev_distance(name, &other);
4066

4067
            if values[i] <= values[smallest] {
4068 4069 4070 4071
                smallest = i;
            }
        }

Y
Youngmin Yoo 已提交
4072
        if values.len() > 0 &&
4073
            values[smallest] != usize::MAX &&
4074 4075
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
4076
            name != &maybes[smallest][..] {
4077

4078
            Some(maybes[smallest].to_string())
4079 4080 4081 4082 4083 4084

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
4085
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
4086 4087
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
4088 4089 4090

        self.record_candidate_traits_for_expr_if_necessary(expr);

4091
        // Next, resolve the node.
4092
        match expr.node {
4093 4094 4095 4096 4097 4098 4099
            // `<T>::a::b::c` is resolved by typeck alone.
            ExprPath(Some(ast::QSelf { position: 0, .. }), ref path) => {
                let method_name = path.segments.last().unwrap().identifier.name;
                let traits = self.search_for_traits_containing_method(method_name);
                self.trait_map.insert(expr.id, traits);
                visit::walk_expr(self, expr);
            }
4100

4101 4102
            ExprPath(ref maybe_qself, ref path) => {
                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
4103
                    // Make sure the trait is valid.
4104
                    let _ = self.resolve_trait_reference(expr.id, path, 1);
4105
                    path.segments.len() - qself.position
4106 4107 4108 4109
                } else {
                    path.segments.len()
                };

4110
                let mut resolution = self.with_no_errors(|this| {
4111 4112 4113
                    this.resolve_path(expr.id, path, 0, ValueNS, true)
                });
                for depth in 1..max_assoc_types {
4114
                    if resolution.is_some() {
4115 4116 4117
                        break;
                    }
                    self.with_no_errors(|this| {
4118
                        resolution = this.resolve_path(expr.id, path, depth, TypeNS, true);
4119 4120
                    });
                }
4121
                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
4122
                    // A module is not a valid type or value.
4123
                    resolution = None;
4124
                }
4125

4126 4127
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
4128
                if let Some(path_res) = resolution {
4129
                    // Check if struct variant
4130
                    if let DefVariant(_, _, true) = path_res.base_def {
4131
                        let path_name = self.path_names_to_string(path, 0);
4132
                        self.resolve_error(expr.span,
4133 4134 4135 4136
                                &format!("`{}` is a struct variant name, but \
                                          this expression \
                                          uses it like a function name",
                                         path_name));
4137

4138 4139 4140 4141 4142 4143 4144 4145
                        let msg = format!("Did you mean to write: \
                                           `{} {{ /* fields */ }}`?",
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
4146
                    } else {
4147
                        // Write the result into the def map.
4148
                        debug!("(resolving expr) resolved `{}`",
4149
                               self.path_names_to_string(path, 0));
4150

4151 4152
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
4153
                        if path_res.depth != 0 {
4154 4155 4156 4157 4158
                            let method_name = path.segments.last().unwrap().identifier.name;
                            let traits = self.search_for_traits_containing_method(method_name);
                            self.trait_map.insert(expr.id, traits);
                        }

4159
                        self.record_def(expr.id, path_res);
4160
                    }
4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172
                } else {
                    // 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.)
                    let path_name = self.path_names_to_string(path, 0);
                    let type_res = self.with_no_errors(|this| {
                        this.resolve_path(expr.id, path, 0, TypeNS, false)
                    });
                    match type_res.map(|r| r.base_def) {
                        Some(DefTy(struct_id, _))
                            if self.structs.contains_key(&struct_id) => {
4173
                                self.resolve_error(expr.span,
4174 4175 4176 4177 4178
                                    &format!("`{}` is a structure name, but \
                                                this expression \
                                                uses it like a function name",
                                                path_name));

4179 4180 4181 4182 4183 4184 4185 4186 4187
                                let msg = format!("Did you mean to write: \
                                                     `{} {{ /* fields */ }}`?",
                                                    path_name);
                                if self.emit_errors {
                                    self.session.fileline_help(expr.span, &msg);
                                } else {
                                    self.session.span_help(expr.span, &msg);
                                }
                            }
4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200
                        _ => {
                            // Keep reporting some errors even if they're ignored above.
                            self.resolve_path(expr.id, path, 0, ValueNS, true);

                            let mut method_scope = false;
                            self.value_ribs.iter().rev().all(|rib| {
                                method_scope = match rib.kind {
                                    MethodRibKind => true,
                                    ItemRibKind | ConstantItemRibKind => false,
                                    _ => return true, // Keep advancing
                                };
                                false // Stop advancing
                            });
4201

4202 4203
                            if method_scope && &token::get_name(self.self_name)[..]
                                                                == path_name {
4204 4205
                                    self.resolve_error(
                                        expr.span,
4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229
                                        "`self` is not available \
                                         in a static method. Maybe a \
                                         `self` argument is missing?");
                            } else {
                                let last_name = path.segments.last().unwrap().identifier.name;
                                let mut msg = match self.find_fallback_in_self_type(last_name) {
                                    NoSuggestion => {
                                        // limit search to 5 to reduce the number
                                        // of stupid suggestions
                                        self.find_best_match_for_name(&path_name, 5)
                                                            .map_or("".to_string(),
                                                                    |x| format!("`{}`", x))
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
                                    TraitItem =>
                                        format!("to call `self.{}`", path_name),
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
                                        format!("to call `{}::{}`", path_str, path_name)
                                };

                                if msg.len() > 0 {
                                    msg = format!(". Did you mean {}?", msg)
4230
                                }
4231 4232 4233 4234 4235

                                self.resolve_error(
                                    expr.span,
                                    &format!("unresolved name `{}`{}",
                                             path_name, msg));
4236
                            }
V
Vincent Belliard 已提交
4237
                        }
4238 4239 4240
                    }
                }

4241
                visit::walk_expr(self, expr);
4242 4243
            }

4244
            ExprStruct(ref path, _, _) => {
4245 4246 4247
                // 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.
4248
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
4249
                    Some(definition) => self.record_def(expr.id, definition),
4250 4251
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
A
Alex Crichton 已提交
4252
                        let msg = format!("`{}` does not name a structure",
4253
                                          self.path_names_to_string(path, 0));
4254
                        self.resolve_error(path.span, &msg[..]);
4255 4256 4257
                    }
                }

4258
                visit::walk_expr(self, expr);
4259 4260
            }

P
Pythoner6 已提交
4261
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
4262
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
4263
                    let def_like = DlDef(DefLabel(expr.id));
4264

4265
                    {
4266
                        let rib = this.label_ribs.last_mut().unwrap();
4267
                        let renamed = mtwt::resolve(label);
4268
                        rib.bindings.insert(renamed, def_like);
4269
                    }
4270

4271
                    visit::walk_expr(this, expr);
4272
                })
4273 4274
            }

4275
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
4276
                let renamed = mtwt::resolve(label);
4277
                match self.search_label(renamed) {
4278 4279 4280
                    None => {
                        self.resolve_error(
                            expr.span,
J
Jorge Aparicio 已提交
4281
                            &format!("use of undeclared label `{}`",
4282
                                    token::get_ident(label)))
4283
                    }
4284
                    Some(DlDef(def @ DefLabel(_))) => {
4285
                        // Since this def is a label, it is never read.
4286 4287 4288 4289 4290
                        self.record_def(expr.id, PathResolution {
                            base_def: def,
                            last_private: LastMod(AllPublic),
                            depth: 0
                        })
4291 4292
                    }
                    Some(_) => {
4293
                        self.session.span_bug(expr.span,
4294 4295
                                              "label wasn't mapped to a \
                                               label def!")
4296 4297 4298 4299
                    }
                }
            }

B
Brian Anderson 已提交
4300
            _ => {
4301
                visit::walk_expr(self, expr);
4302 4303 4304 4305
            }
        }
    }

E
Eduard Burtescu 已提交
4306
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
4307
        match expr.node {
4308
            ExprField(_, ident) => {
4309 4310 4311 4312
                // 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.
4313
                let traits = self.search_for_traits_containing_method(ident.node.name);
4314
                self.trait_map.insert(expr.id, traits);
4315
            }
4316
            ExprMethodCall(ident, _, _) => {
4317
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
4318
                        traits for {}",
4319
                       expr.id);
4320
                let traits = self.search_for_traits_containing_method(ident.node.name);
4321
                self.trait_map.insert(expr.id, traits);
4322
            }
4323
            _ => {
4324 4325 4326 4327 4328
                // Nothing to do.
            }
        }
    }

E
Eduard Burtescu 已提交
4329
    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
4330
        debug!("(searching for traits containing method) looking for '{}'",
E
Eduard Burtescu 已提交
4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341
               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);
        }
4342

4343
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
4344
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
4345 4346
        loop {
            // Look for the current trait.
4347 4348
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
4349
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
4350
                        add_trait_info(&mut found_traits, trait_def_id, name);
4351 4352
                    }
                }
4353
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
4354
            }
4355

E
Eduard Burtescu 已提交
4356
            // Look for trait children.
4357
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
4358

E
Eduard Burtescu 已提交
4359
            {
4360
                for (_, child_names) in &*search_module.children.borrow() {
4361 4362 4363 4364 4365
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
                        None => continue
                    };
                    let trait_def_id = match def {
4366
                        DefTrait(trait_def_id) => trait_def_id,
4367 4368
                        _ => continue,
                    };
4369
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
4370
                        add_trait_info(&mut found_traits, trait_def_id, name);
4371 4372
                    }
                }
E
Eduard Burtescu 已提交
4373
            }
4374

E
Eduard Burtescu 已提交
4375
            // Look for imports.
4376
            for (_, import) in &*search_module.import_resolutions.borrow() {
E
Eduard Burtescu 已提交
4377 4378 4379 4380 4381
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
4382
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
4383 4384
                    Some(..) | None => continue,
                };
4385
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
4386
                    add_trait_info(&mut found_traits, did, name);
4387 4388 4389 4390
                    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);
4391 4392
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
4393
                    }
4394
                }
E
Eduard Burtescu 已提交
4395
            }
4396

E
Eduard Burtescu 已提交
4397
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
4398 4399
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
4400
                    search_module = parent_module.upgrade().unwrap();
4401
                }
E
Eduard Burtescu 已提交
4402
            }
4403 4404
        }

E
Eduard Burtescu 已提交
4405
        found_traits
4406 4407
    }

4408 4409 4410
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
        assert!(match resolution.last_private {LastImport{..} => false, _ => true},
4411
                "Import should only be used for `use` directives");
4412

4413 4414 4415 4416 4417
        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
            self.session.span_bug(span, &format!("path resolved multiple times \
                                                  ({:?} before, {:?} now)",
                                                 prev_res, resolution));
4418
        }
4419 4420
    }

F
Felix S. Klock II 已提交
4421
    fn enforce_default_binding_mode(&mut self,
4422
                                        pat: &Pat,
4423
                                        pat_binding_mode: BindingMode,
4424
                                        descr: &str) {
4425
        match pat_binding_mode {
4426
            BindByValue(_) => {}
A
Alex Crichton 已提交
4427
            BindByRef(..) => {
4428
                self.resolve_error(pat.span,
J
Jorge Aparicio 已提交
4429
                                   &format!("cannot use `ref` binding mode \
4430
                                            with {}",
4431
                                           descr));
4432 4433 4434 4435
            }
        }
    }

4436 4437 4438 4439 4440 4441 4442
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

4447
        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
E
Eduard Burtescu 已提交
4448 4449 4450
            match module.parent_link {
                NoParentLink => {}
                ModuleParentLink(ref module, name) => {
4451 4452
                    names.push(name);
                    collect_mod(names, &*module.upgrade().unwrap());
4453
                }
E
Eduard Burtescu 已提交
4454
                BlockParentLink(ref module, _) => {
J
John Clements 已提交
4455
                    // danger, shouldn't be ident?
4456 4457
                    names.push(special_idents::opaque.name);
                    collect_mod(names, &*module.upgrade().unwrap());
4458 4459 4460
                }
            }
        }
4461
        collect_mod(&mut names, module);
4462

4463
        if names.len() == 0 {
4464
            return "???".to_string();
4465
        }
J
Jorge Aparicio 已提交
4466
        self.names_to_string(&names.into_iter().rev()
4467
                                  .collect::<Vec<ast::Name>>())
4468 4469
    }

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

4474
        debug!("Children:");
4475
        build_reduced_graph::populate_module_if_necessary(self, &module_);
4476
        for (&name, _) in &*module_.children.borrow() {
4477
            debug!("* {}", token::get_name(name));
4478 4479
        }

4480
        debug!("Import resolutions:");
4481
        let import_resolutions = module_.import_resolutions.borrow();
4482
        for (&name, import_resolution) in &*import_resolutions {
N
Niko Matsakis 已提交
4483
            let value_repr;
4484
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
4485
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4486
                Some(_) => {
R
Richo Healey 已提交
4487
                    value_repr = " value:?".to_string();
4488
                    // FIXME #4954
4489 4490 4491
                }
            }

N
Niko Matsakis 已提交
4492
            let type_repr;
4493
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
4494
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
4495
                Some(_) => {
R
Richo Healey 已提交
4496
                    type_repr = " type:?".to_string();
4497
                    // FIXME #4954
4498 4499 4500
                }
            }

4501
            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
4502 4503 4504 4505
        }
    }
}

4506
pub struct CrateMap {
4507
    pub def_map: DefMap,
4508
    pub freevars: RefCell<FreevarMap>,
4509
    pub export_map: ExportMap,
4510 4511
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
4512 4513 4514
    pub glob_map: Option<GlobMap>
}

4515
#[derive(PartialEq,Copy)]
4516 4517 4518
pub enum MakeGlobMap {
    Yes,
    No
4519 4520
}

4521
/// Entry point to crate resolution.
4522 4523 4524 4525 4526 4527 4528
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);
4529

4530
    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
4531 4532 4533 4534 4535
    session.abort_if_errors();

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

4536
    record_exports::record(&mut resolver);
4537 4538 4539 4540 4541 4542 4543
    session.abort_if_errors();

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

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

4544
    CrateMap {
4545 4546
        def_map: resolver.def_map,
        freevars: resolver.freevars,
4547
        export_map: resolver.export_map,
4548 4549
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
4550 4551 4552 4553 4554
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
4555
    }
4556
}