lib.rs 141.1 KB
Newer Older
1
// Copyright 2012-2015 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
#![feature(alloc)]
#![feature(collections)]
A
Alex Crichton 已提交
24
#![feature(rustc_diagnostic_macros)]
25
#![feature(rustc_private)]
A
Alex Crichton 已提交
26
#![feature(staged_api)]
27

A
Alex Crichton 已提交
28 29
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
30
#[macro_use] #[no_link] extern crate rustc_bitflags;
31 32 33

extern crate rustc;

S
Steven Fackler 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::NamespaceResult::*;
use self::NameDefinition::*;
use self::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::*;

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

63
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
64
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
65
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
66
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
67
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
68
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
F
Flavio Percoco 已提交
69
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
70
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
71
use syntax::ast::{Local, MethodImplItem, Name, NodeId};
72
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
73 74 75
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};
76
use syntax::ast::{TyPath, TyPtr};
77
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
78
use syntax::ast::TypeImplItem;
P
Patrick Walton 已提交
79
use syntax::ast;
80
use syntax::ast_map;
81
use syntax::ast_util::{local_def, walk_pat};
82
use syntax::attr::AttrMetaMethods;
83
use syntax::ext::mtwt;
84
use syntax::parse::token::{self, special_names, special_idents};
85
use syntax::ptr::P;
86
use syntax::codemap::{self, Span, Pos};
87
use syntax::visit::{self, Visitor};
88

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

97 98 99 100
use resolve_imports::{Target, ImportDirective, ImportResolution};
use resolve_imports::Shadowable;


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
mod resolve_imports;
109

N
Niko Matsakis 已提交
110
#[derive(Copy, Clone)]
111
struct BindingInfo {
112
    span: Span,
113
    binding_mode: BindingMode,
114 115 116
}

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

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

N
Niko Matsakis 已提交
126
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
F
Felix S. Klock II 已提交
127
enum Namespace {
128
    TypeNS,
129
    ValueNS
130 131
}

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

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

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

173
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
174
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
175
        self.resolve_item(item);
176
    }
177
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
178
        self.resolve_arm(arm);
179
    }
180
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
181
        self.resolve_block(block);
182
    }
183
    fn visit_expr(&mut self, expr: &Expr) {
A
Alex Crichton 已提交
184
        self.resolve_expr(expr);
185
    }
186
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
187
        self.resolve_local(local);
188
    }
189
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
190
        self.resolve_type(ty);
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 {
245
            visit::FkItemFn(_, generics, _, _, _) => {
246 247 248
                self.visit_generics(generics);
                ItemRibKind
            }
249
            visit::FkMethod(_, sig, _) => {
250 251
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
252 253 254 255 256 257
                MethodRibKind
            }
            visit::FkFnBlock(..) => ClosureRibKind(node_id)
        };
        self.resolve_function(rib_kind, declaration, block);
    }
258
}
259

260 261
type ErrorMessage = Option<(Span, String)>;

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

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

274 275 276 277
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
278
    TraitItem,
279
    StaticMethod(String),
280
    TraitMethod(String),
281 282
}

N
Niko Matsakis 已提交
283
#[derive(Copy, Clone)]
E
Erik Price 已提交
284
enum TypeParameters<'a> {
285 286 287 288 289 290 291 292 293 294 295
    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)
296 297
}

298 299
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
300
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
301
enum RibKind {
302 303
    // No translation needs to be applied.
    NormalRibKind,
304

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

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

315 316
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
317 318 319

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

N
Niko Matsakis 已提交
322
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
323
enum UseLexicalScopeFlag {
324 325 326 327
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
328
enum ModulePrefixResult {
329
    NoPrefixFound,
330
    PrefixFound(Rc<Module>, usize)
331 332
}

N
Niko Matsakis 已提交
333
#[derive(Copy, Clone, PartialEq)]
334
enum NameSearchType {
335 336 337 338
    /// 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
339 340
    /// expression, or a path pattern.
    PathSearch,
341 342
}

N
Niko Matsakis 已提交
343
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
344
enum BareIdentifierPatternResolution {
345 346
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
347
    BareIdentifierPatternUnresolved
348 349
}

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

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

366
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
367
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
368
enum ParentLink {
369
    NoParentLink,
370
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
371
    BlockParentLink(Weak<Module>, NodeId)
372 373
}

374
/// The type of module this is.
N
Niko Matsakis 已提交
375
#[derive(Copy, Clone, PartialEq, Debug)]
F
Felix S. Klock II 已提交
376
enum ModuleKind {
377 378
    NormalModuleKind,
    TraitModuleKind,
379
    EnumModuleKind,
380
    TypeModuleKind,
381 382 383
    AnonymousModuleKind,
}

384
/// One node in the tree of modules.
385
pub struct Module {
386
    parent_link: ParentLink,
387
    def_id: Cell<Option<DefId>>,
388
    kind: Cell<ModuleKind>,
389
    is_public: bool,
390

E
Eduard Burtescu 已提交
391 392
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
393

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

398 399 400 401 402 403 404 405 406 407 408 409 410 411
    // 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 已提交
412
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
413 414

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

    // The number of unresolved globs that this module exports.
418
    glob_count: Cell<usize>,
419 420

    // The index of the import we're resolving.
421
    resolved_import_count: Cell<usize>,
422 423 424 425

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

429
impl Module {
F
Felix S. Klock II 已提交
430
    fn new(parent_link: ParentLink,
431 432 433 434
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
435
           -> Module {
436 437
        Module {
            parent_link: parent_link,
438
            def_id: Cell::new(def_id),
439
            kind: Cell::new(kind),
440
            is_public: is_public,
441
            children: RefCell::new(HashMap::new()),
442
            imports: RefCell::new(Vec::new()),
443
            external_module_children: RefCell::new(HashMap::new()),
444
            anonymous_children: RefCell::new(NodeMap()),
445
            import_resolutions: RefCell::new(HashMap::new()),
446
            glob_count: Cell::new(0),
447
            resolved_import_count: Cell::new(0),
448
            populated: Cell::new(!external),
449
        }
B
Brian Anderson 已提交
450 451
    }

F
Felix S. Klock II 已提交
452
    fn all_imports_resolved(&self) -> bool {
453
        self.imports.borrow().len() == self.resolved_import_count.get()
454 455 456
    }
}

457
impl fmt::Debug for Module {
458
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459
        write!(f, "{:?}, kind: {:?}, {}",
460 461 462 463 464 465
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

466
bitflags! {
J
Jorge Aparicio 已提交
467
    #[derive(Debug)]
468 469 470 471 472 473
    flags DefModifiers: u8 {
        const PUBLIC            = 0b0000_0001,
        const IMPORTABLE        = 0b0000_0010,
    }
}

474
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
475
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
476
struct TypeNsDef {
477
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
478
    module_def: Option<Rc<Module>>,
479
    type_def: Option<Def>,
480
    type_span: Option<Span>
481 482 483
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
484
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
485
struct ValueNsDef {
486
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
487
    def: Def,
488
    value_span: Option<Span>,
489 490
}

491 492
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
493
#[derive(Debug)]
494
pub struct NameBindings {
495
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
496
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
497 498
}

499
impl NameBindings {
K
Kevin Butler 已提交
500 501 502 503 504 505 506
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

507
    /// Creates a new module in this set of name bindings.
508
    fn define_module(&self,
509 510 511 512 513 514
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
515
        // Merges the module with the existing type def or creates a new one.
516
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
517 518 519 520
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
521
                                          is_public));
E
Erick Tryzelaar 已提交
522 523
        let type_def = self.type_def.borrow().clone();
        match type_def {
524
            None => {
E
Erick Tryzelaar 已提交
525
                *self.type_def.borrow_mut() = Some(TypeNsDef {
526
                    modifiers: modifiers,
527
                    module_def: Some(module_),
528 529
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
530
                });
531
            }
532
            Some(type_def) => {
E
Erick Tryzelaar 已提交
533
                *self.type_def.borrow_mut() = Some(TypeNsDef {
534
                    modifiers: modifiers,
535
                    module_def: Some(module_),
536
                    type_span: Some(sp),
537
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
538
                });
539
            }
540 541 542
        }
    }

543
    /// Sets the kind of the module, creating a new one if necessary.
544
    fn set_module_kind(&self,
545 546 547 548 549 550
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
551
        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
E
Erick Tryzelaar 已提交
552 553
        let type_def = self.type_def.borrow().clone();
        match type_def {
554
            None => {
555 556 557 558 559
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
560
                *self.type_def.borrow_mut() = Some(TypeNsDef {
561
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
562
                    module_def: Some(Rc::new(module)),
563 564
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
565
                });
566 567 568 569
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
570 571 572 573 574
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
575
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
576
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
577
                            module_def: Some(Rc::new(module)),
578 579
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
580
                        });
581
                    }
582
                    Some(module_def) => module_def.kind.set(kind),
583 584 585 586 587
                }
            }
        }
    }

588
    /// Records a type definition.
589
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
590
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
591
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
592 593
        let type_def = self.type_def.borrow().clone();
        match type_def {
594
            None => {
E
Erick Tryzelaar 已提交
595
                *self.type_def.borrow_mut() = Some(TypeNsDef {
596
                    module_def: None,
597
                    type_def: Some(def),
598
                    type_span: Some(sp),
599
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
600
                });
601
            }
602
            Some(type_def) => {
E
Erick Tryzelaar 已提交
603
                *self.type_def.borrow_mut() = Some(TypeNsDef {
604
                    module_def: type_def.module_def,
605
                    type_def: Some(def),
606
                    type_span: Some(sp),
607
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
608
                });
609 610
            }
        }
611 612
    }

613
    /// Records a value definition.
614
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
615
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
616
        *self.value_def.borrow_mut() = Some(ValueNsDef {
617 618
            def: def,
            value_span: Some(sp),
619
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
620
        });
621 622
    }

623
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
624
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
625
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
626
            Some(ref type_def) => type_def.module_def.clone(),
627
            None => None
628 629 630
        }
    }

S
Steve Klabnik 已提交
631 632
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
633
    fn get_module(&self) -> Rc<Module> {
634 635
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
636
                panic!("get_module called on a node with no module \
637
                       definition!")
638
            }
639
            Some(module_def) => module_def
640 641 642
        }
    }

F
Felix S. Klock II 已提交
643
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
644
        match namespace {
E
Erick Tryzelaar 已提交
645 646
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
647 648 649
        }
    }

F
Felix S. Klock II 已提交
650
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
651 652 653 654
        self.defined_in_namespace_with(namespace, PUBLIC)
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
655
        match namespace {
E
Erick Tryzelaar 已提交
656
            TypeNS => match *self.type_def.borrow() {
657
                Some(ref def) => def.modifiers.contains(modifiers), None => false
658
            },
E
Erick Tryzelaar 已提交
659
            ValueNS => match *self.value_def.borrow() {
660
                Some(ref def) => def.modifiers.contains(modifiers), None => false
661 662 663 664
            }
        }
    }

F
Felix S. Klock II 已提交
665
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
666
        match namespace {
667
            TypeNS => {
E
Erick Tryzelaar 已提交
668
                match *self.type_def.borrow() {
669
                    None => None,
E
Eduard Burtescu 已提交
670
                    Some(ref type_def) => {
671
                        match type_def.type_def {
672
                            Some(type_def) => Some(type_def),
673 674
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
675
                                    Some(ref module) => {
676
                                        match module.def_id.get() {
677
                                            Some(did) => Some(DefMod(did)),
678 679 680 681 682 683
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
684
                        }
685 686
                    }
                }
687 688
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
689
                match *self.value_def.borrow() {
690 691 692 693 694 695 696
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
697
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
698
        if self.defined_in_namespace(namespace) {
699
            match namespace {
700
                TypeNS  => {
E
Erick Tryzelaar 已提交
701
                    match *self.type_def.borrow() {
702
                        None => None,
E
Eduard Burtescu 已提交
703
                        Some(ref type_def) => type_def.type_span
704 705 706
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
707
                    match *self.value_def.borrow() {
708
                        None => None,
E
Eduard Burtescu 已提交
709
                        Some(ref value_def) => value_def.value_span
710 711
                    }
                }
712
            }
713 714
        } else {
            None
715 716
        }
    }
717 718 719 720 721 722 723 724 725 726 727 728 729

    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)
            }
        }
    }
730 731
}

732
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
733
struct PrimitiveTypeTable {
734
    primitive_types: HashMap<Name, PrimTy>,
735
}
736

737
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
738 739 740 741 742 743 744 745 746
    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));
747
        table.intern("isize",   TyInt(TyIs));
K
Kevin Butler 已提交
748 749 750 751 752
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
753
        table.intern("usize",   TyUint(TyUs));
K
Kevin Butler 已提交
754 755 756 757 758 759 760 761
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

762
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
763
        self.primitive_types.insert(token::intern(string), primitive_type);
764 765 766
    }
}

767
/// The main resolver class.
768
pub struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
769
    session: &'a Session,
770

771 772
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
773
    graph_root: NameBindings,
774

775
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
776

777
    structs: FnvHashMap<DefId, Vec<Name>>,
778

779
    // The number of imports that are currently unresolved.
780
    unresolved_imports: usize,
781 782

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
783
    current_module: Rc<Module>,
784 785

    // The current set of local scopes, for values.
786
    // FIXME #4948: Reuse ribs to avoid allocation.
787
    value_ribs: Vec<Rib>,
788 789

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

792
    // The current set of local scopes, for labels.
793
    label_ribs: Vec<Rib>,
794

795
    // The trait that the current context can refer to.
796 797 798 799
    current_trait_ref: Option<(DefId, TraitRef)>,

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

801
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
802
    primitive_type_table: PrimitiveTypeTable,
803

804
    def_map: DefMap,
805 806
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
807
    export_map: ExportMap,
808
    trait_map: TraitMap,
809
    external_exports: ExternalExports,
810

811 812 813 814 815
    // 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,

816 817 818 819 820
    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,

821
    used_imports: HashSet<(NodeId, Namespace)>,
822
    used_crates: HashSet<CrateNum>,
823 824
}

825
#[derive(PartialEq)]
S
Steven Fackler 已提交
826 827 828 829 830
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}

831 832 833 834 835
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 已提交
836 837 838 839 840 841 842 843 844 845 846 847 848 849
        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,

850 851
            ast_map: ast_map,

K
Kevin Butler 已提交
852 853 854 855 856
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

857 858
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
859 860 861 862

            unresolved_imports: 0,

            current_module: current_module,
863 864 865
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
866 867 868 869 870 871

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

872 873 874 875 876
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
877
            used_imports: HashSet::new(),
878
            used_crates: HashSet::new(),
879
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
880 881

            emit_errors: true,
882 883
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
884 885
        }
    }
886

887 888 889 890 891 892
    #[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) {
893
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
894 895 896 897 898 899 900 901 902
            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 {
903
        if did.krate == ast::LOCAL_CRATE {
904 905 906 907 908 909
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

E
Eduard Burtescu 已提交
910
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
911
        NameBindings {
912
            type_def: RefCell::new(Some(TypeNsDef {
913
                modifiers: IMPORTABLE,
914 915
                module_def: Some(module),
                type_def: None,
916
                type_span: None
917
            })),
918
            value_def: RefCell::new(None),
919 920 921
        }
    }

922 923 924 925 926 927 928
    /// 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 已提交
929 930
                span_err!(self.session, span, E0259,
                          "an external crate named `{}` has already \
931
                                   been imported into this module",
932
                                  &token::get_name(name));
933 934 935 936 937 938 939 940 941
        }
    }

    /// 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 已提交
942 943
                span_err!(self.session, span, E0260,
                          "the name `{}` conflicts with an external \
944 945
                                   crate that has been imported into this \
                                   module",
946
                                  &token::get_name(name));
947
        }
948 949
    }

950
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
951
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
952
                                     module_: Rc<Module>,
953
                                     module_path: &[Name],
954
                                     index: usize,
955 956 957
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
958
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
959 960
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
961 962 963 964 965
            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())
966 967 968
                    }
                   _ => None
                }
969
            }
970 971
        }

972
        let mut search_module = module_;
973
        let mut index = index;
A
Alex Crichton 已提交
974
        let module_path_len = module_path.len();
975
        let mut closest_private = lp;
976 977 978 979 980

        // 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 已提交
981
            let name = module_path[index];
E
Eduard Burtescu 已提交
982
            match self.resolve_name_in_module(search_module.clone(),
983
                                              name,
984
                                              TypeNS,
985 986
                                              name_search_type,
                                              false) {
987
                Failed(None) => {
988
                    let segment_name = token::get_name(name);
989
                    let module_name = module_to_string(&*search_module);
990
                    let mut span = span;
991
                    let msg = if "???" == &module_name[..] {
992
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
993

994
                        match search_parent_externals(name,
995
                                                     &self.current_module) {
996
                            Some(module) => {
997 998
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
999
                                let current_mod_str =
1000
                                    module_to_string(&*self.current_module);
1001 1002 1003 1004 1005 1006 1007

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

1008
                                format!("Did you mean `{}{}`?", prefix, path_str)
1009
                            },
1010 1011
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
1012
                        }
1013
                    } else {
1014
                        format!("Could not find `{}` in `{}`",
1015 1016 1017
                                segment_name,
                                module_name)
                    };
1018

1019
                    return Failed(Some((span, msg)));
1020
                }
1021
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1022
                Indeterminate => {
1023
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
1024
                            resolution is indeterminate: {}",
1025
                            token::get_name(name));
B
Brian Anderson 已提交
1026
                    return Indeterminate;
1027
                }
1028
                Success((target, used_proxy)) => {
1029 1030
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
1031
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1032
                        Some(ref type_def) => {
1033 1034
                            match type_def.module_def {
                                None => {
1035
                                    let msg = format!("Not a module `{}`",
1036
                                                        token::get_name(name));
1037 1038

                                    return Failed(Some((span, msg)));
1039
                                }
E
Eduard Burtescu 已提交
1040
                                Some(ref module_def) => {
1041 1042 1043
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
1044 1045
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
1046
                                    }
1047

1048 1049 1050
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
1051 1052 1053
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
1054
                                        }
1055
                                    }
1056 1057 1058 1059 1060
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
1061
                            let msg = format!("Not a module `{}`",
1062
                                              token::get_name(name));
1063
                            return Failed(Some((span, msg)));
1064 1065 1066 1067 1068
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
1069
            index += 1;
1070 1071
        }

1072
        return Success((search_module, closest_private));
1073 1074
    }

1075 1076
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1077 1078 1079
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1080
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
1081
                           module_: Rc<Module>,
1082
                           module_path: &[Name],
1083 1084 1085
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1086
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
1087
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1088
        assert!(module_path_len > 0);
1089

1090
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1091 1092
               names_to_string(module_path),
               module_to_string(&*module_));
1093

1094
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
1095
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
1096
                                                              module_path);
1097

1098 1099
        let search_module;
        let start_index;
1100
        let last_private;
1101
        match module_prefix_result {
1102
            Failed(None) => {
1103
                let mpath = names_to_string(module_path);
1104
                let mpath = &mpath[..];
1105
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1106
                    Some(idx) => {
1107 1108 1109
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
1110 1111
                                            &mpath[idx + 1..],
                                            &mpath[..idx - 1]);
1112
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
1113
                    },
1114 1115 1116
                    None => {
                        return Failed(None)
                    }
1117
                }
1118
            }
1119
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1120
            Indeterminate => {
1121
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
1122
                        bailing");
B
Brian Anderson 已提交
1123
                return Indeterminate;
1124
            }
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
            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;
1135
                        last_private = LastMod(AllPublic);
1136 1137 1138 1139 1140
                    }
                    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.
1141 1142
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
1143
                            Failed(err) => return Failed(err),
1144
                            Indeterminate => {
1145
                                debug!("(resolving module path for import) \
1146 1147 1148 1149 1150 1151
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1152
                                last_private = LastMod(AllPublic);
1153 1154 1155 1156 1157
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1158 1159
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
1160
                start_index = index;
1161 1162 1163
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
1164 1165 1166
            }
        }

1167 1168 1169 1170
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1171 1172
                                           name_search_type,
                                           last_private)
1173 1174
    }

1175 1176
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1177
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1178
                                     module_: Rc<Module>,
1179
                                     name: Name,
1180
                                     namespace: Namespace)
1181
                                    -> ResolveResult<(Target, bool)> {
1182
        debug!("(resolving item in lexical scope) resolving `{}` in \
1183
                namespace {:?} in `{}`",
1184
               token::get_name(name),
1185
               namespace,
1186
               module_to_string(&*module_));
1187 1188 1189

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

1192
        match module_.children.borrow().get(&name) {
1193 1194 1195
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
1196 1197
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1198
                                            Shadowable::Never),
1199
                               false));
1200
            }
1201
            Some(_) | None => { /* Not found; continue. */ }
1202 1203 1204 1205 1206 1207
        }

        // 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.
1208 1209 1210 1211 1212
        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 \
1213
                            import resolution, but not in namespace {:?}",
1214 1215 1216 1217 1218 1219
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
1220 1221 1222
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
1223
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
1224
                         self.used_crates.insert(kid);
1225
                    }
1226
                    return Success((target, false));
1227 1228 1229 1230
                }
            }
        }

1231 1232
        // Search for external modules.
        if namespace == TypeNS {
1233 1234 1235
            // 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 {
1236 1237 1238
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
                debug!("lower name bindings succeeded");
1239 1240 1241
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1242
                                false));
1243 1244 1245
            }
        }

1246
        // Finally, proceed up the scope chain looking for parent modules.
1247
        let mut search_module = module_;
1248 1249
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
1250
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
1251
                NoParentLink => {
1252
                    // No more parents. This module was unresolved.
1253
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
1254
                            module");
1255
                    return Failed(None);
1256
                }
1257
                ModuleParentLink(parent_module_node, _) => {
1258 1259 1260 1261 1262 1263 1264
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
1265
                            return Failed(None);
1266
                        }
1267
                        TraitModuleKind |
1268
                        EnumModuleKind |
1269
                        TypeModuleKind |
1270
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1271
                            search_module = parent_module_node.upgrade().unwrap();
1272 1273 1274
                        }
                    }
                }
E
Eduard Burtescu 已提交
1275 1276
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
1277 1278 1279 1280
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
1281
            match self.resolve_name_in_module(search_module.clone(),
1282
                                              name,
1283
                                              namespace,
1284 1285
                                              PathSearch,
                                              true) {
1286
                Failed(Some((span, msg))) =>
J
Jorge Aparicio 已提交
1287
                    self.resolve_error(span, &format!("failed to resolve. {}",
1288
                                                     msg)),
1289
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1290
                Indeterminate => {
1291 1292 1293
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

1294
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
1295
                            higher scope; bailing");
B
Brian Anderson 已提交
1296
                    return Indeterminate;
1297
                }
1298
                Success((target, used_reexport)) => {
1299
                    // We found the module.
1300
                    debug!("(resolving item in lexical scope) found name \
1301 1302
                            in module, done");
                    return Success((target, used_reexport));
1303 1304 1305 1306 1307
                }
            }
        }
    }

1308
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1309
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1310
                                       module_: Rc<Module>,
1311
                                       name: Name)
E
Eduard Burtescu 已提交
1312
                                -> ResolveResult<Rc<Module>> {
1313 1314
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1315
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
1316
        match resolve_result {
1317
            Success((target, _)) => {
1318
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
1319
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1320
                    Some(ref type_def) => {
1321
                        match type_def.module_def {
1322
                            None => {
1323
                                debug!("!!! (resolving module in lexical \
1324 1325
                                        scope) module wasn't actually a \
                                        module!");
1326
                                return Failed(None);
1327
                            }
E
Eduard Burtescu 已提交
1328 1329
                            Some(ref module_def) => {
                                return Success(module_def.clone());
1330 1331 1332 1333
                            }
                        }
                    }
                    None => {
1334
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
1335
                                wasn't actually a module!");
1336
                        return Failed(None);
1337 1338 1339
                    }
                }
            }
B
Brian Anderson 已提交
1340
            Indeterminate => {
1341
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
1342
                        bailing");
B
Brian Anderson 已提交
1343
                return Indeterminate;
1344
            }
1345 1346 1347
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1348 1349 1350 1351
            }
        }
    }

1352
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
1353 1354
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
1355 1356
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
1357
            match module_.parent_link.clone() {
1358 1359 1360
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
1361
                    let new_module = new_module.upgrade().unwrap();
1362
                    match new_module.kind.get() {
1363 1364
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
1365
                        EnumModuleKind |
1366
                        TypeModuleKind |
1367 1368 1369 1370 1371 1372 1373
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

1374 1375
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
1376 1377
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
1378
        match module_.kind.get() {
1379
            NormalModuleKind => return module_,
1380
            TraitModuleKind |
1381
            EnumModuleKind |
1382
            TypeModuleKind |
1383
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1384
                match self.get_nearest_normal_module_parent(module_.clone()) {
1385 1386 1387 1388 1389 1390 1391
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

1392
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1393
    /// (b) some chain of `super::`.
1394
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1395
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
1396
                             module_: Rc<Module>,
1397
                             module_path: &[Name])
1398
                                 -> ResolveResult<ModulePrefixResult> {
1399 1400 1401 1402
        // 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;
1403
        let first_module_path_string = token::get_name(module_path[0]);
1404
        if "self" == &first_module_path_string[..] {
1405 1406 1407
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 1;
1408
        } else if "super" == &first_module_path_string[..] {
1409 1410 1411 1412 1413 1414 1415 1416
            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.
1417
        while i < module_path.len() {
1418
            let string = token::get_name(module_path[i]);
1419
            if "super" != &string[..] {
1420 1421
                break
            }
1422
            debug!("(resolving module prefix) resolving `super` at {}",
1423
                   module_to_string(&*containing_module));
1424
            match self.get_nearest_normal_module_parent(containing_module) {
1425
                None => return Failed(None),
1426 1427 1428
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1429 1430 1431 1432
                }
            }
        }

1433
        debug!("(resolving module prefix) finished resolving prefix at {}",
1434
               module_to_string(&*containing_module));
1435 1436

        return Success(PrefixFound(containing_module, i));
1437 1438
    }

1439 1440 1441
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1442 1443 1444
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1445
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
1446
                              module_: Rc<Module>,
1447
                              name: Name,
1448
                              namespace: Namespace,
1449 1450
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1451
                              -> ResolveResult<(Target, bool)> {
1452
        debug!("(resolving name in module) resolving `{}` in `{}`",
1453
               &token::get_name(name),
1454
               module_to_string(&*module_));
1455 1456

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

1459
        match module_.children.borrow().get(&name) {
1460 1461 1462
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
1463 1464
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1465
                                            Shadowable::Never),
1466 1467 1468 1469
                               false));
            }
            Some(_) | None => {
                // Continue.
1470 1471 1472
            }
        }

1473 1474 1475 1476
        // 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.
1477
        if name_search_type == PathSearch {
1478
            assert_eq!(module_.glob_count.get(), 0);
1479 1480
        }

1481
        // Check the list of resolved imports.
1482
        match module_.import_resolutions.borrow().get(&name) {
1483
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
1484
                                       import_resolution.is_public => {
1485

E
Eduard Burtescu 已提交
1486 1487
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
1488
                    debug!("(resolving name in module) import \
1489
                           unresolved; bailing out");
B
Brian Anderson 已提交
1490
                    return Indeterminate;
1491
                }
1492
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1493
                    None => {
1494
                        debug!("(resolving name in module) name found, \
1495
                                but not in namespace {:?}",
P
Paul Stansifer 已提交
1496
                               namespace);
1497
                    }
1498
                    Some(target) => {
1499
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
1500
                                import");
1501
                        // track used imports and extern crates as well
1502 1503 1504
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1505 1506
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
1507
                        }
1508
                        return Success((target, true));
1509
                    }
1510 1511
                }
            }
1512
            Some(..) | None => {} // Continue.
1513 1514 1515 1516
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1517 1518 1519
            // 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 {
1520 1521
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
1522 1523 1524
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1525
                                false));
1526 1527 1528 1529
            }
        }

        // We're out of luck.
1530
        debug!("(resolving name in module) failed to resolve `{}`",
1531
               &token::get_name(name));
1532
        return Failed(None);
1533 1534
    }

E
Eduard Burtescu 已提交
1535
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
1536
        let index = module_.resolved_import_count.get();
1537 1538
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1539
        if index != import_count {
1540
            let sn = self.session
E
Eduard Burtescu 已提交
1541
                         .codemap()
1542
                         .span_to_snippet((*imports)[index].span)
1543
                         .unwrap();
1544
            if sn.contains("::") {
1545
                self.resolve_error((*imports)[index].span,
1546
                                   "unresolved import");
1547
            } else {
A
Alex Crichton 已提交
1548
                let err = format!("unresolved import (maybe you meant `{}::*`?)",
A
Alex Crichton 已提交
1549
                                  sn);
1550
                self.resolve_error((*imports)[index].span, &err[..]);
1551
            }
1552 1553 1554
        }

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

1557
        for (_, child_node) in &*module_.children.borrow() {
1558 1559 1560 1561 1562 1563
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1564 1565 1566 1567
                }
            }
        }

1568
        for (_, module_) in &*module_.anonymous_children.borrow() {
E
Eduard Burtescu 已提交
1569
            self.report_unresolved_imports(module_.clone());
1570 1571 1572 1573 1574
        }
    }

    // AST resolution
    //
1575
    // We maintain a list of value ribs and type ribs.
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
    //
    // 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 已提交
1591 1592 1593
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
1594
        let orig_module = self.current_module.clone();
1595 1596

        // Move down in the graph.
1597
        match name {
B
Brian Anderson 已提交
1598
            None => {
1599 1600
                // Nothing to do.
            }
B
Brian Anderson 已提交
1601
            Some(name) => {
1602
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1603

1604
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
1605
                    None => {
1606
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
1607
                               token::get_name(name),
1608
                               module_to_string(&*orig_module));
1609
                    }
B
Brian Anderson 已提交
1610
                    Some(name_bindings) => {
1611
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
1612
                            None => {
1613
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
1614
                                        for `{}` in `{}`",
1615
                                       token::get_name(name),
1616
                                       module_to_string(&*orig_module));
1617
                            }
B
Brian Anderson 已提交
1618
                            Some(module_) => {
1619
                                self.current_module = module_;
1620 1621 1622 1623 1624 1625 1626
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
1627
        f(self);
1628 1629 1630 1631

        self.current_module = orig_module;
    }

1632
    /// Wraps the given definition in the appropriate number of `DefUpvar`
1633
    /// wrappers.
E
Eduard Burtescu 已提交
1634
    fn upvarify(&self,
E
Eduard Burtescu 已提交
1635
                ribs: &[Rib],
E
Eduard Burtescu 已提交
1636 1637 1638
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
1639 1640 1641 1642 1643 1644
        let mut def = match def_like {
            DlDef(def) => def,
            _ => return Some(def_like)
        };
        match def {
            DefUpvar(..) => {
1645
                self.session.span_bug(span,
1646
                    &format!("unexpected {:?} in bindings", def))
1647
            }
1648
            DefLocal(node_id) => {
1649
                for rib in ribs {
1650 1651 1652 1653
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
1654
                        ClosureRibKind(function_id) => {
1655
                            let prev_def = def;
1656
                            def = DefUpvar(node_id, function_id);
1657

1658
                            let mut seen = self.freevars_seen.borrow_mut();
1659
                            let seen = match seen.entry(function_id) {
1660
                                Occupied(v) => v.into_mut(),
1661
                                Vacant(v) => v.insert(NodeSet()),
1662
                            };
1663 1664 1665
                            if seen.contains(&node_id) {
                                continue;
                            }
1666
                            match self.freevars.borrow_mut().entry(function_id) {
1667
                                Occupied(v) => v.into_mut(),
1668
                                Vacant(v) => v.insert(vec![]),
1669
                            }.push(Freevar { def: prev_def, span: span });
1670 1671
                            seen.insert(node_id);
                        }
1672
                        ItemRibKind | MethodRibKind => {
1673 1674 1675
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
1676

1677
                            self.resolve_error(span,
1678
                                "can't capture dynamic environment in a fn item; \
1679
                                 use the || { ... } closure form instead");
1680 1681 1682 1683 1684 1685 1686
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
                            self.resolve_error(span,
                                               "attempt to use a non-constant \
                                                value in a constant");
1687
                            return None;
1688
                        }
1689 1690
                    }
                }
1691
            }
1692
            DefTyParam(..) | DefSelfTy(..) => {
1693
                for rib in ribs {
1694
                    match rib.kind {
1695
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
1696 1697 1698 1699 1700
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
1701

1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712
                            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");
1713
                            return None;
1714 1715
                        }
                    }
1716
                }
1717
            }
1718
            _ => {}
1719
        }
1720
        Some(DlDef(def))
1721 1722
    }

S
Seo Sanghyeon 已提交
1723 1724
    /// Searches the current set of local scopes and
    /// applies translations for closures.
E
Eduard Burtescu 已提交
1725
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
1726
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
1727 1728 1729
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
1730
        // FIXME #4950: Try caching?
1731

1732
        for (i, rib) in ribs.iter().enumerate().rev() {
1733 1734
            if let Some(def_like) = rib.bindings.get(&name).cloned() {
                return self.upvarify(&ribs[i + 1..], def_like, span);
1735 1736 1737
            }
        }

1738
        None
1739 1740
    }

S
Seo Sanghyeon 已提交
1741 1742
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
    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 已提交
1755 1756
            if result.is_some() {
                return result
1757 1758 1759 1760 1761
            }
        }
        None
    }

1762
    fn resolve_crate(&mut self, krate: &ast::Crate) {
1763
        debug!("(resolving crate) starting");
1764

1765
        visit::walk_crate(self, krate);
1766 1767
    }

W
we 已提交
1768 1769
    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 已提交
1770
            span_err!(self.session, span, E0317,
W
we 已提交
1771 1772 1773 1774
                "user-defined types or type parameters cannot shadow the primitive types");
        }
    }

1775
    fn resolve_item(&mut self, item: &Item) {
1776 1777
        let name = item.ident.name;

1778
        debug!("(resolving item) resolving {}",
1779
               token::get_name(name));
1780

1781
        match item.node {
1782 1783 1784
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
1785 1786
                self.check_if_primitive_type_name(name, item.span);

1787
                self.with_type_parameter_rib(HasTypeParameters(generics,
1788
                                                               TypeSpace,
1789
                                                               ItemRibKind),
1790
                                             |this| visit::walk_item(this, item));
1791
            }
1792
            ItemFn(_, _, _, ref generics, _) => {
1793
                self.with_type_parameter_rib(HasTypeParameters(generics,
1794
                                                               FnSpace,
1795
                                                               ItemRibKind),
1796
                                             |this| visit::walk_item(this, item));
1797 1798
            }

F
Flavio Percoco 已提交
1799
            ItemDefaultImpl(_, ref trait_ref) => {
1800
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1801
            }
1802 1803
            ItemImpl(_,
                     _,
1804
                     ref generics,
1805
                     ref opt_trait_ref,
1806
                     ref self_type,
1807
                     ref impl_items) => {
1808
                self.resolve_implementation(generics,
1809
                                            opt_trait_ref,
1810
                                            &**self_type,
1811
                                            item.id,
1812
                                            &impl_items[..]);
1813 1814
            }

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

1818 1819 1820 1821 1822 1823
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
                    this.with_self_rib(DefSelfTy(Some(local_def(item.id)), None), |this| {
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849
                        this.visit_generics(generics);
                        visit::walk_ty_param_bounds_helper(this, bounds);

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

                            let type_parameters = match trait_item.node {
                                ast::MethodTraitItem(ref sig, _) => {
                                    HasTypeParameters(&sig.generics,
                                                      FnSpace,
                                                      MethodRibKind)
                                }
                                ast::TypeTraitItem(..) => {
                                    this.check_if_primitive_type_name(trait_item.ident.name,
                                                                      trait_item.span);
                                    NoTypeParameters
                                }
                            };
                            this.with_type_parameter_rib(type_parameters, |this| {
                                visit::walk_trait_item(this, trait_item)
                            });
                        }
                    });
1850
                });
1851 1852
            }

1853
            ItemMod(_) | ItemForeignMod(_) => {
1854
                self.with_scope(Some(name), |this| {
1855
                    visit::walk_item(this, item);
1856
                });
1857 1858
            }

1859
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
1860
                self.with_constant_rib(|this| {
1861
                    visit::walk_item(this, item);
1862
                });
1863
            }
1864

W
we 已提交
1865 1866 1867
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
                if let ast::ViewPathSimple(ident, _) = view_path.node {
1868 1869
                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
W
we 已提交
1870 1871 1872 1873 1874 1875 1876 1877
                            self.check_if_primitive_type_name(ident.name, item.span);
                        }
                        _ => {}
                    }
                }
            }

            ItemExternCrate(_) | ItemMac(..) => {
1878
                // do nothing, these are just around to be encoded
1879
            }
1880 1881 1882
        }
    }

J
Jorge Aparicio 已提交
1883 1884 1885
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
1886
        match type_parameters {
1887
            HasTypeParameters(generics, space, rib_kind) => {
1888
                let mut function_type_rib = Rib::new(rib_kind);
1889
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
1890
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
1891
                    let name = type_parameter.ident.name;
1892
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1893

1894
                    if seen_bindings.contains(&name) {
1895
                        self.resolve_error(type_parameter.span,
J
Jorge Aparicio 已提交
1896
                                           &format!("the name `{}` is already \
1897 1898 1899 1900
                                                     used for a type \
                                                     parameter in this type \
                                                     parameter list",
                                                    token::get_name(name)))
1901
                    }
1902
                    seen_bindings.insert(name);
1903

1904
                    // plain insert (no renaming)
1905 1906 1907 1908 1909
                    function_type_rib.bindings.insert(name,
                        DlDef(DefTyParam(space,
                                         index as u32,
                                         local_def(type_parameter.id),
                                         name)));
1910
                }
1911
                self.type_ribs.push(function_type_rib);
1912 1913
            }

B
Brian Anderson 已提交
1914
            NoTypeParameters => {
1915 1916 1917 1918
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1919
        f(self);
1920

1921
        match type_parameters {
1922
            HasTypeParameters(..) => { self.type_ribs.pop(); }
1923
            NoTypeParameters => { }
1924 1925 1926
        }
    }

J
Jorge Aparicio 已提交
1927 1928 1929
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
1930
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1931
        f(self);
1932
        self.label_ribs.pop();
1933
    }
1934

J
Jorge Aparicio 已提交
1935 1936 1937
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
1938 1939
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1940
        f(self);
1941 1942
        self.type_ribs.pop();
        self.value_ribs.pop();
1943 1944
    }

F
Felix S. Klock II 已提交
1945
    fn resolve_function(&mut self,
1946
                        rib_kind: RibKind,
1947
                        declaration: &FnDecl,
1948
                        block: &Block) {
1949
        // Create a value rib for the function.
1950
        self.value_ribs.push(Rib::new(rib_kind));
1951

1952
        // Create a label rib for the function.
1953
        self.label_ribs.push(Rib::new(rib_kind));
1954

1955 1956 1957 1958 1959 1960
        // 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);
1961

1962
            self.visit_ty(&*argument.ty);
1963

1964 1965 1966
            debug!("(resolving function) recorded argument");
        }
        visit::walk_fn_ret_ty(self, &declaration.output);
1967

1968 1969
        // Resolve the function body.
        self.visit_block(&*block);
1970

1971
        debug!("(resolving function) leaving function");
1972

1973 1974
        self.label_ribs.pop();
        self.value_ribs.pop();
1975 1976
    }

F
Felix S. Klock II 已提交
1977
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
1978
                               id: NodeId,
1979
                               trait_path: &Path,
1980
                               path_depth: usize)
1981 1982 1983 1984 1985 1986
                               -> 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 {
1987 1988
                self.resolve_error(trait_path.span,
                    &format!("`{}` is not a trait",
1989
                             path_names_to_string(trait_path, path_depth)));
1990 1991

                // If it's a typedef, give a note
1992
                if let DefTy(..) = path_res.base_def {
1993 1994
                    self.session.span_note(trait_path.span,
                                           "`type` aliases cannot be used for traits");
1995
                }
1996 1997
                Err(())
            }
1998 1999
        } else {
            let msg = format!("use of undeclared trait name `{}`",
2000
                              path_names_to_string(trait_path, path_depth));
2001
            self.resolve_error(trait_path.span, &msg);
2002
            Err(())
2003 2004 2005
        }
    }

2006
    fn resolve_generics(&mut self, generics: &Generics) {
2007
        for type_parameter in &*generics.ty_params {
2008 2009 2010
            self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
        }
        for predicate in &generics.where_clause.predicates {
2011
            match predicate {
2012
                &ast::WherePredicate::BoundPredicate(_) |
2013
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
2014
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
2015 2016 2017 2018 2019
                    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");
2020 2021
                    }
                }
2022 2023
            }
        }
2024
        visit::walk_generics(self, generics);
2025 2026
    }

2027 2028
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2029
    {
2030 2031 2032 2033 2034 2035 2036
        // 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
    }

2037
    fn with_optional_trait_ref<T, F>(&mut self,
E
Eduard Burtescu 已提交
2038
                                     opt_trait_ref: Option<&TraitRef>,
N
Nick Cameron 已提交
2039 2040
                                     f: F)
                                     -> T
2041
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2042
    {
2043
        let mut new_val = None;
2044
        let mut new_id = None;
E
Eduard Burtescu 已提交
2045
        if let Some(trait_ref) = opt_trait_ref {
2046 2047 2048 2049 2050 2051
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
                                                               &trait_ref.path, 0) {
                assert!(path_res.depth == 0);
                self.record_def(trait_ref.ref_id, path_res);
                new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                new_id = Some(path_res.base_def.def_id());
2052
            }
2053 2054
            visit::walk_trait_ref(self, trait_ref);
        }
2055
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2056
        let result = f(self, new_id);
2057 2058 2059 2060
        self.current_trait_ref = original_trait_ref;
        result
    }

2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073
    fn with_self_rib<F>(&mut self, self_def: Def, f: F)
        where F: FnOnce(&mut Resolver)
    {
        let mut self_type_rib = Rib::new(NormalRibKind);

        // plain insert (no renaming, types are not currently hygienic....)
        let name = special_names::type_self;
        self_type_rib.bindings.insert(name, DlDef(self_def));
        self.type_ribs.push(self_type_rib);
        f(self);
        self.type_ribs.pop();
    }

F
Felix S. Klock II 已提交
2074
    fn resolve_implementation(&mut self,
2075 2076 2077
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2078
                              item_id: NodeId,
2079
                              impl_items: &[P<ImplItem>]) {
2080
        // If applicable, create a rib for the type parameters.
2081
        self.with_type_parameter_rib(HasTypeParameters(generics,
2082
                                                       TypeSpace,
2083
                                                       ItemRibKind),
2084
                                     |this| {
2085
            // Resolve the type parameters.
2086
            this.visit_generics(generics);
2087

2088
            // Resolve the trait reference, if necessary.
2089
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2090
                // Resolve the self type.
2091
                this.visit_ty(self_type);
2092

2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117
                this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
                            match impl_item.node {
                                MethodImplItem(ref sig, _) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
                                                          impl_item.span);

                                    // We also need a new scope for the method-
                                    // specific type parameters.
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
                                        visit::walk_impl_item(this, impl_item);
                                    });
                                }
                                TypeImplItem(ref ty) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
                                                          impl_item.span);
2118

2119 2120 2121
                                    this.visit_ty(ty);
                                }
                                ast::MacImplItem(_) => {}
2122
                            }
2123
                        }
2124
                    });
2125 2126
                });
            });
2127
        });
2128 2129
    }

2130
    fn check_trait_item(&self, name: Name, span: Span) {
2131
        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
2132
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2133
            if !self.trait_item_map.contains_key(&(name, did)) {
2134
                let path_str = path_names_to_string(&trait_ref.path, 0);
2135
                self.resolve_error(span,
J
Jorge Aparicio 已提交
2136
                                    &format!("method `{}` is not a member of trait `{}`",
2137
                                            token::get_name(name),
2138
                                            path_str));
2139 2140 2141 2142
            }
        }
    }

E
Eduard Burtescu 已提交
2143
    fn resolve_local(&mut self, local: &Local) {
2144
        // Resolve the type.
2145
        visit::walk_ty_opt(self, &local.ty);
2146

2147 2148
        // Resolve the initializer.
        visit::walk_expr_opt(self, &local.init);
2149 2150

        // Resolve the pattern.
2151 2152
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
2153
                             &mut HashMap::new());
2154 2155
    }

J
John Clements 已提交
2156 2157 2158 2159
    // 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 已提交
2160
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2161
        let mut result = HashMap::new();
2162 2163
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
2164 2165 2166 2167
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
2168
        });
2169
        return result;
2170 2171
    }

J
John Clements 已提交
2172 2173
    // 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 已提交
2174
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2175
        if arm.pats.is_empty() {
2176 2177
            return
        }
2178
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2179
        for (i, p) in arm.pats.iter().enumerate() {
2180
            let map_i = self.binding_mode_map(&**p);
2181

2182
            for (&key, &binding_0) in &map_0 {
2183
                match map_i.get(&key) {
2184 2185 2186
                  None => {
                    self.resolve_error(
                        p.span,
J
Jorge Aparicio 已提交
2187
                        &format!("variable `{}` from pattern #1 is \
2188 2189
                                  not bound in pattern #{}",
                                token::get_name(key),
2190
                                i + 1));
2191 2192 2193 2194 2195
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
                        self.resolve_error(
                            binding_i.span,
J
Jorge Aparicio 已提交
2196
                            &format!("variable `{}` is bound with different \
2197 2198
                                      mode in pattern #{} than in pattern #1",
                                    token::get_name(key),
2199
                                    i + 1));
2200 2201
                    }
                  }
2202 2203 2204
                }
            }

2205
            for (&key, &binding) in &map_i {
2206
                if !map_0.contains_key(&key) {
2207
                    self.resolve_error(
2208
                        binding.span,
J
Jorge Aparicio 已提交
2209
                        &format!("variable `{}` from pattern {}{} is \
2210
                                  not bound in pattern {}1",
2211
                                token::get_name(key),
2212
                                "#", i + 1, "#"));
2213 2214 2215
                }
            }
        }
2216 2217
    }

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

2221
        let mut bindings_list = HashMap::new();
2222
        for pattern in &arm.pats {
2223
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2224 2225
        }

2226 2227 2228 2229
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2230
        visit::walk_expr_opt(self, &arm.guard);
2231
        self.visit_expr(&*arm.body);
2232

2233
        self.value_ribs.pop();
2234 2235
    }

E
Eduard Burtescu 已提交
2236
    fn resolve_block(&mut self, block: &Block) {
2237
        debug!("(resolving block) entering block");
2238
        self.value_ribs.push(Rib::new(NormalRibKind));
2239 2240

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
2241
        let orig_module = self.current_module.clone();
2242
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
2243
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
2244
            Some(anonymous_module) => {
2245
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
2246
                        down");
E
Eduard Burtescu 已提交
2247
                self.current_module = anonymous_module.clone();
2248 2249 2250
            }
        }

2251 2252
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2253
        for statement in &block.stmts {
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270
            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;
            }
        }

2271
        // Descend into the block.
2272
        visit::walk_block(self, block);
2273 2274 2275 2276

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

2277
        self.value_ribs.pop();
2278
        debug!("(resolving block) leaving block");
2279 2280
    }

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

2286 2287
            TyPath(ref maybe_qself, ref path) => {
                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
2288
                    // Make sure the trait is valid.
2289
                    let _ = self.resolve_trait_reference(ty.id, path, 1);
2290
                    path.segments.len() - qself.position
2291 2292 2293 2294
                } else {
                    path.segments.len()
                };

2295
                let mut resolution = None;
2296 2297
                for depth in 0..max_assoc_types {
                    self.with_no_errors(|this| {
2298
                        resolution = this.resolve_path(ty.id, path, depth, TypeNS, true);
2299
                    });
2300
                    if resolution.is_some() {
2301 2302 2303
                        break;
                    }
                }
2304
                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
2305
                    // A module is not a valid type.
2306
                    resolution = None;
2307
                }
2308 2309

                // This is a path in the type namespace. Walk through scopes
2310
                // looking for it.
2311
                match resolution {
B
Brian Anderson 已提交
2312
                    Some(def) => {
2313
                        // Write the result into the def map.
2314
                        debug!("(resolving type) writing resolution for `{}` \
2315
                                (id {}) = {:?}",
2316
                               path_names_to_string(path, 0),
2317 2318
                               ty.id, def);
                        self.record_def(ty.id, def);
2319
                    }
B
Brian Anderson 已提交
2320
                    None => {
2321 2322 2323
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2324 2325 2326 2327
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2328
                        };
2329

2330
                        let msg = format!("use of undeclared {} `{}`", kind,
2331
                                          path_names_to_string(path, 0));
2332
                        self.resolve_error(ty.span, &msg[..]);
2333 2334
                    }
                }
2335
            }
2336
            _ => {}
2337
        }
2338 2339
        // Resolve embedded types.
        visit::walk_ty(self, ty);
2340 2341
    }

F
Felix S. Klock II 已提交
2342
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2343
                       pattern: &Pat,
2344 2345 2346
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2347
                       bindings_list: &mut HashMap<Name, NodeId>) {
2348
        let pat_id = pattern.id;
2349
        walk_pat(pattern, |pattern| {
2350
            match pattern.node {
2351
                PatIdent(binding_mode, ref path1, _) => {
2352 2353

                    // The meaning of pat_ident with no type parameters
2354 2355 2356 2357 2358 2359 2360
                    // 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).
2361

2362
                    let ident = path1.node;
2363
                    let renamed = mtwt::resolve(ident);
2364

2365
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
2366
                        FoundStructOrEnumVariant(def, lp)
2367
                                if mode == RefutableMode => {
2368
                            debug!("(resolving pattern) resolving `{}` to \
2369
                                    struct or enum variant",
2370
                                   token::get_name(renamed));
2371

2372 2373 2374 2375
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
2376 2377 2378 2379 2380
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2381
                        }
A
Alex Crichton 已提交
2382
                        FoundStructOrEnumVariant(..) => {
2383 2384
                            self.resolve_error(
                                pattern.span,
J
Jorge Aparicio 已提交
2385
                                &format!("declaration of `{}` shadows an enum \
2386 2387
                                         variant or unit-like struct in \
                                         scope",
2388
                                        token::get_name(renamed)));
2389
                        }
2390
                        FoundConst(def, lp) if mode == RefutableMode => {
2391
                            debug!("(resolving pattern) resolving `{}` to \
2392
                                    constant",
2393
                                   token::get_name(renamed));
2394

2395 2396 2397 2398
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
2399 2400 2401 2402 2403
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2404
                        }
A
Alex Crichton 已提交
2405
                        FoundConst(..) => {
2406
                            self.resolve_error(pattern.span,
F
Felix S. Klock II 已提交
2407
                                                  "only irrefutable patterns \
2408
                                                   allowed here");
2409
                        }
2410
                        BareIdentifierPatternUnresolved => {
2411
                            debug!("(resolving pattern) binding `{}`",
2412
                                   token::get_name(renamed));
2413

2414
                            let def = DefLocal(pattern.id);
2415 2416 2417 2418 2419

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

2420 2421 2422 2423 2424
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: LastMod(AllPublic),
                                depth: 0
                            });
2425 2426 2427 2428 2429 2430

                            // 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.)
2431 2432
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2433 2434
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2435
                                bindings_list.insert(renamed, pat_id);
2436 2437 2438 2439 2440
                            } 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 已提交
2441
                                                   &format!("identifier `{}` \
2442 2443 2444 2445 2446 2447
                                                            is bound more \
                                                            than once in \
                                                            this parameter \
                                                            list",
                                                           token::get_ident(
                                                               ident))
2448
                                                   )
2449
                            } else if bindings_list.get(&renamed) ==
2450 2451 2452 2453
                                    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 已提交
2454
                                    &format!("identifier `{}` is bound \
2455 2456
                                             more than once in the same \
                                             pattern",
2457
                                            token::get_ident(ident)));
2458
                            }
2459 2460
                            // Else, not bound in the same pattern: do
                            // nothing.
2461 2462 2463 2464
                        }
                    }
                }

2465
                PatEnum(ref path, _) => {
2466
                    // This must be an enum variant, struct or const.
2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483
                    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)));
                            }
2484
                        }
2485 2486 2487 2488
                    } else {
                        self.resolve_error(path.span,
                            &format!("unresolved enum variant, struct or const `{}`",
                                token::get_ident(path.segments.last().unwrap().identifier)));
2489
                    }
2490
                    visit::walk_path(self, path);
2491 2492
                }

2493
                PatStruct(ref path, _, _) => {
2494
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2495
                        Some(definition) => {
2496 2497
                            self.record_def(pattern.id, definition);
                        }
2498
                        result => {
2499
                            debug!("(resolving pattern) didn't find struct \
2500
                                    def: {:?}", result);
A
Alex Crichton 已提交
2501
                            let msg = format!("`{}` does not name a structure",
2502
                                              path_names_to_string(path, 0));
2503
                            self.resolve_error(path.span, &msg[..]);
2504 2505
                        }
                    }
2506 2507 2508 2509 2510
                    visit::walk_path(self, path);
                }

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

2513
                _ => {
2514 2515 2516
                    // Nothing to do.
                }
            }
2517
            true
2518
        });
2519 2520
    }

2521
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
2522 2523 2524
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
2525
                                                 name,
2526
                                                 ValueNS) {
2527
            Success((target, _)) => {
2528
                debug!("(resolve bare identifier pattern) succeeded in \
2529
                         finding {} at {:?}",
2530
                        token::get_name(name),
E
Erick Tryzelaar 已提交
2531 2532
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
2533
                    None => {
S
Steve Klabnik 已提交
2534
                        panic!("resolved name in the value namespace to a \
2535
                              set of name bindings with no def?!");
2536
                    }
B
Brian Anderson 已提交
2537
                    Some(def) => {
2538 2539 2540
                        // 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.
2541
                        match def.def {
A
Alex Crichton 已提交
2542
                            def @ DefVariant(..) | def @ DefStruct(..) => {
2543
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
2544
                            }
2545
                            def @ DefConst(..) => {
2546
                                return FoundConst(def, LastMod(AllPublic));
2547
                            }
2548
                            DefStatic(..) => {
2549
                                self.resolve_error(span,
2550 2551 2552
                                                   "static variables cannot be \
                                                    referenced in a pattern, \
                                                    use a `const` instead");
2553 2554
                                return BareIdentifierPatternUnresolved;
                            }
2555
                            _ => {
2556
                                return BareIdentifierPatternUnresolved;
2557 2558
                            }
                        }
2559 2560 2561 2562
                    }
                }
            }

B
Brian Anderson 已提交
2563
            Indeterminate => {
S
Steve Klabnik 已提交
2564
                panic!("unexpected indeterminate result");
2565
            }
2566 2567 2568
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
J
Jorge Aparicio 已提交
2569
                        self.resolve_error(span, &format!("failed to resolve: {}",
2570
                                                         msg));
2571 2572 2573
                    }
                    None => ()
                }
2574

2575
                debug!("(resolve bare identifier pattern) failed to find {}",
2576
                        token::get_name(name));
2577
                return BareIdentifierPatternUnresolved;
2578 2579 2580 2581
            }
        }
    }

2582 2583
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
2584 2585
    /// 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 已提交
2586
    fn resolve_path(&mut self,
2587 2588
                    id: NodeId,
                    path: &Path,
2589
                    path_depth: usize,
2590
                    namespace: Namespace,
2591
                    check_ribs: bool) -> Option<PathResolution> {
2592 2593 2594
        let span = path.span;
        let segments = &path.segments[..path.segments.len()-path_depth];

N
Nick Cameron 已提交
2595
        let mk_res = |(def, lp)| PathResolution::new(def, lp, path_depth);
2596

2597
        if path.global {
2598
            let def = self.resolve_crate_relative_path(span, segments, namespace);
2599
            return def.map(mk_res);
2600 2601
        }

2602
        // Try to find a path to an item in a module.
2603
        let unqualified_def =
2604
                self.resolve_identifier(segments.last().unwrap().identifier,
2605 2606
                                        namespace,
                                        check_ribs,
2607
                                        span);
2608

N
Nick Cameron 已提交
2609 2610 2611
        if segments.len() <= 1 {
            return unqualified_def.map(mk_res);
        }
2612

N
Nick Cameron 已提交
2613 2614 2615 2616 2617 2618 2619 2620 2621
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
            (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
                              id, span,
                              "unnecessary qualification".to_string());
            }
            _ => {}
2622
        }
N
Nick Cameron 已提交
2623 2624

        def.map(mk_res)
2625 2626
    }

N
Nick Cameron 已提交
2627
    // Resolve a single identifier.
F
Felix S. Klock II 已提交
2628
    fn resolve_identifier(&mut self,
2629 2630 2631 2632 2633
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
2634 2635 2636 2637 2638 2639 2640 2641 2642
        // 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)));
            }
        }

2643
        if check_ribs {
2644 2645 2646 2647
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier,
                                                                     namespace,
                                                                     span) {
                return Some((def, LastMod(AllPublic)));
2648 2649 2650
            }
        }

2651
        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
2652 2653
    }

2654
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
2655
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
2656
                                            containing_module: Rc<Module>,
2657
                                            name: Name,
2658
                                            namespace: Namespace)
2659
                                            -> NameDefinition {
2660
        // First, search children.
2661
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
2662

2663
        match containing_module.children.borrow().get(&name) {
2664 2665 2666 2667
            Some(child_name_bindings) => {
                match child_name_bindings.def_for_namespace(namespace) {
                    Some(def) => {
                        // Found it. Stop the search here.
N
Nick Cameron 已提交
2668
                        let p = child_name_bindings.defined_in_public_namespace(namespace);
2669
                        let lp = if p {LastMod(AllPublic)} else {
2670
                            LastMod(DependsOn(def.def_id()))
2671 2672
                        };
                        return ChildNameDefinition(def, lp);
2673
                    }
2674
                    None => {}
2675 2676
                }
            }
2677
            None => {}
2678 2679 2680
        }

        // Next, search import resolutions.
2681
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
2682
            Some(import_resolution) if import_resolution.is_public => {
2683 2684 2685 2686 2687 2688 2689
                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));
2690
                            self.record_import_use(id, name);
2691 2692 2693 2694 2695
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
2696
                            }
2697 2698 2699 2700 2701
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
2702 2703 2704 2705
                        }
                    }
                }
            }
A
Alex Crichton 已提交
2706
            Some(..) | None => {} // Continue.
2707 2708 2709 2710
        }

        // Finally, search through external children.
        if namespace == TypeNS {
2711 2712 2713 2714 2715 2716 2717 2718 2719
            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);
2720
                }
2721 2722
            }
        }
2723 2724

        return NoNameDefinition;
2725 2726
    }

2727
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
2728
    fn resolve_module_relative_path(&mut self,
2729 2730
                                    span: Span,
                                    segments: &[ast::PathSegment],
2731 2732
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
2733 2734 2735
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
2736

2737
        let containing_module;
2738
        let last_private;
N
Nick Cameron 已提交
2739 2740
        let current_module = self.current_module.clone();
        match self.resolve_module_path(current_module,
2741
                                       &module_path[..],
2742
                                       UseLexicalScope,
2743
                                       span,
2744
                                       PathSearch) {
2745 2746 2747 2748
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
2749
                        let msg = format!("Use of undeclared type or module `{}`",
2750
                                          names_to_string(&module_path));
2751
                        (span, msg)
2752 2753
                    }
                };
2754

J
Jorge Aparicio 已提交
2755
                self.resolve_error(span, &format!("failed to resolve. {}",
2756
                                                 msg));
2757
                return None;
2758
            }
S
Steve Klabnik 已提交
2759
            Indeterminate => panic!("indeterminate unexpected"),
2760
            Success((resulting_module, resulting_last_private)) => {
2761
                containing_module = resulting_module;
2762
                last_private = resulting_last_private;
2763 2764 2765
            }
        }

2766
        let name = segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
2767
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
2768
                                                                  name,
2769
                                                                  namespace) {
B
Brian Anderson 已提交
2770
            NoNameDefinition => {
2771
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
2772
                return None;
2773
            }
2774 2775
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
2776
            }
2777
        };
2778 2779
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
2780
        }
2781
        return Some(def);
2782 2783
    }

2784 2785
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2786
    fn resolve_crate_relative_path(&mut self,
2787 2788
                                   span: Span,
                                   segments: &[ast::PathSegment],
2789 2790
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
2791 2792 2793
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
2794

2795
        let root_module = self.graph_root.get_module();
2796

2797
        let containing_module;
2798
        let last_private;
2799
        match self.resolve_module_path_from_root(root_module,
2800
                                                 &module_path[..],
2801
                                                 0,
2802
                                                 span,
2803
                                                 PathSearch,
2804
                                                 LastMod(AllPublic)) {
2805 2806 2807 2808 2809
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
2810
                                          names_to_string(&module_path[..]));
2811
                        (span, msg)
2812 2813 2814
                    }
                };

J
Jorge Aparicio 已提交
2815
                self.resolve_error(span, &format!("failed to resolve. {}",
2816
                                                 msg));
B
Brian Anderson 已提交
2817
                return None;
2818 2819
            }

B
Brian Anderson 已提交
2820
            Indeterminate => {
S
Steve Klabnik 已提交
2821
                panic!("indeterminate unexpected");
2822 2823
            }

2824
            Success((resulting_module, resulting_last_private)) => {
2825
                containing_module = resulting_module;
2826
                last_private = resulting_last_private;
2827 2828 2829
            }
        }

2830
        let name = segments.last().unwrap().identifier.name;
2831
        match self.resolve_definition_of_name_in_module(containing_module,
2832
                                                        name,
2833
                                                        namespace) {
B
Brian Anderson 已提交
2834
            NoNameDefinition => {
2835
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
2836
                return None;
2837
            }
2838 2839
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
2840 2841 2842 2843
            }
        }
    }

F
Felix S. Klock II 已提交
2844
    fn resolve_identifier_in_local_ribs(&mut self,
2845 2846 2847 2848
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
2849
        // Check the local set of ribs.
2850
        let search_result = match namespace {
B
Brian Anderson 已提交
2851
            ValueNS => {
2852
                let renamed = mtwt::resolve(ident);
2853
                self.search_ribs(&self.value_ribs, renamed, span)
2854
            }
B
Brian Anderson 已提交
2855
            TypeNS => {
2856
                let name = ident.name;
2857
                self.search_ribs(&self.type_ribs, name, span)
2858
            }
2859
        };
2860

2861
        match search_result {
2862
            Some(DlDef(def)) => {
N
Nick Cameron 已提交
2863
                debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
2864
                       token::get_ident(ident),
P
Paul Stansifer 已提交
2865
                       def);
2866
                Some(def)
2867
            }
2868
            Some(DlField) | Some(DlImpl(_)) | None => {
2869
                None
2870 2871 2872 2873
            }
        }
    }

2874 2875 2876 2877
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
2878
        // Check the items.
E
Eduard Burtescu 已提交
2879 2880
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
2881
                                                 name,
2882
                                                 namespace) {
2883
            Success((target, _)) => {
2884
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
2885
                    None => {
2886 2887
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
2888
                        debug!("(resolving item path by identifier in lexical \
2889
                                 scope) failed to resolve {} after success...",
2890
                                 token::get_name(name));
2891
                        return None;
2892
                    }
B
Brian Anderson 已提交
2893
                    Some(def) => {
2894
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
2895
                                resolved `{}` to item",
2896
                               token::get_name(name));
2897 2898 2899
                        // 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.
2900
                        return Some((def, LastMod(AllPublic)));
2901 2902 2903
                    }
                }
            }
B
Brian Anderson 已提交
2904
            Indeterminate => {
S
Steve Klabnik 已提交
2905
                panic!("unexpected indeterminate result");
2906
            }
2907
            Failed(err) => {
2908
                debug!("(resolving item path by identifier in lexical scope) \
2909
                         failed to resolve {}", token::get_name(name));
N
Nick Cameron 已提交
2910 2911 2912 2913 2914

                if let Some((span, msg)) = err {
                    self.resolve_error(span, &format!("failed to resolve. {}", msg))
                }

B
Brian Anderson 已提交
2915
                return None;
2916 2917 2918 2919
            }
        }
    }

J
Jorge Aparicio 已提交
2920 2921 2922
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
2923
        self.emit_errors = false;
A
Alex Crichton 已提交
2924
        let rs = f(self);
2925 2926 2927 2928
        self.emit_errors = true;
        rs
    }

A
Alex Crichton 已提交
2929
    fn resolve_error(&self, span: Span, s: &str) {
2930
        if self.emit_errors {
A
Alex Crichton 已提交
2931
            self.session.span_err(span, s);
2932 2933 2934
        }
    }

2935
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
2936 2937 2938
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
2939
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
2940 2941
                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),
2942 2943 2944 2945 2946 2947 2948
                // 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,
            }
        }

2949
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
2950 2951
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
2952
            let last_name = name_path.last().unwrap();
2953

2954
            if name_path.len() == 1 {
2955
                match this.primitive_type_table.primitive_types.get(last_name) {
2956 2957
                    Some(_) => None,
                    None => {
2958
                        match this.current_module.children.borrow().get(last_name) {
2959 2960 2961 2962 2963 2964 2965
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
2966 2967 2968 2969
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
2970 2971 2972 2973 2974 2975
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

2976 2977
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
            if did.krate == ast::LOCAL_CRATE {
2978
                let sig = match this.ast_map.get(did.node) {
2979
                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
2980
                        ast::MethodTraitItem(ref sig, _) => sig,
2981 2982
                        _ => return false
                    },
2983
                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
2984
                        ast::MethodImplItem(ref sig, _) => sig,
2985 2986 2987 2988
                        _ => return false
                    },
                    _ => return false
                };
2989
                sig.explicit_self.node == ast::SelfStatic
2990 2991 2992 2993 2994
            } else {
                csearch::is_static_method(&this.session.cstore, did)
            }
        }

2995 2996 2997 2998
        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,
2999 3000 3001 3002
            },
            None => return NoSuggestion,
        };

3003 3004
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3005 3006 3007 3008
            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) {
3009 3010 3011 3012 3013
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3014
                    }
3015 3016 3017
                },
                _ => {} // Self type didn't resolve properly
            }
3018 3019
        }

3020
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3021 3022

        // Look for a method in the current self type's impl module.
3023 3024 3025 3026
        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) {
3027
                        return StaticMethod(path_names_to_string(&path, 0))
3028 3029 3030 3031 3032
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3033 3034
                    }
                }
3035
            }
3036 3037 3038
        }

        // Look for a method in the current trait.
3039 3040 3041
        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) {
3042
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3043 3044
                } else {
                    return TraitItem;
3045 3046 3047 3048 3049 3050 3051
                }
            }
        }

        NoSuggestion
    }

3052
    fn find_best_match_for_name(&mut self, name: &str, max_distance: usize)
3053
                                -> Option<String> {
3054 3055
        let this = &mut *self;

3056
        let mut maybes: Vec<token::InternedString> = Vec::new();
3057
        let mut values: Vec<usize> = Vec::new();
3058

3059
        for rib in this.value_ribs.iter().rev() {
3060
            for (&k, _) in &rib.bindings {
3061
                maybes.push(token::get_name(k));
3062
                values.push(usize::MAX);
3063 3064 3065 3066
            }
        }

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

3070
            if values[i] <= values[smallest] {
3071 3072 3073 3074
                smallest = i;
            }
        }

3075
        if !values.is_empty() &&
3076
            values[smallest] != usize::MAX &&
3077 3078
            values[smallest] < name.len() + 2 &&
            values[smallest] <= max_distance &&
3079
            name != &maybes[smallest][..] {
3080

3081
            Some(maybes[smallest].to_string())
3082 3083 3084 3085 3086 3087

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
3088
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3089 3090
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3091 3092 3093

        self.record_candidate_traits_for_expr_if_necessary(expr);

3094
        // Next, resolve the node.
3095
        match expr.node {
3096 3097 3098 3099 3100 3101 3102
            // `<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);
            }
3103

3104 3105
            ExprPath(ref maybe_qself, ref path) => {
                let max_assoc_types = if let Some(ref qself) = *maybe_qself {
3106
                    // Make sure the trait is valid.
3107
                    let _ = self.resolve_trait_reference(expr.id, path, 1);
3108
                    path.segments.len() - qself.position
3109 3110 3111 3112
                } else {
                    path.segments.len()
                };

3113
                let mut resolution = self.with_no_errors(|this| {
3114 3115 3116
                    this.resolve_path(expr.id, path, 0, ValueNS, true)
                });
                for depth in 1..max_assoc_types {
3117
                    if resolution.is_some() {
3118 3119 3120
                        break;
                    }
                    self.with_no_errors(|this| {
3121
                        resolution = this.resolve_path(expr.id, path, depth, TypeNS, true);
3122 3123
                    });
                }
3124
                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
3125
                    // A module is not a valid type or value.
3126
                    resolution = None;
3127
                }
3128

3129 3130
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3131
                if let Some(path_res) = resolution {
3132
                    // Check if struct variant
3133
                    if let DefVariant(_, _, true) = path_res.base_def {
3134
                        let path_name = path_names_to_string(path, 0);
3135
                        self.resolve_error(expr.span,
3136 3137 3138 3139
                                &format!("`{}` is a struct variant name, but \
                                          this expression \
                                          uses it like a function name",
                                         path_name));
3140

3141
                        let msg = format!("did you mean to write: \
3142 3143 3144 3145 3146 3147 3148
                                           `{} {{ /* fields */ }}`?",
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
3149
                    } else {
3150
                        // Write the result into the def map.
3151
                        debug!("(resolving expr) resolved `{}`",
3152
                               path_names_to_string(path, 0));
3153

3154 3155
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3156
                        if path_res.depth != 0 {
3157 3158 3159 3160 3161
                            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);
                        }

3162
                        self.record_def(expr.id, path_res);
3163
                    }
3164 3165 3166 3167 3168
                } 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.)
3169
                    let path_name = path_names_to_string(path, 0);
3170 3171 3172 3173 3174 3175
                    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) => {
3176
                                self.resolve_error(expr.span,
3177 3178 3179 3180 3181
                                    &format!("`{}` is a structure name, but \
                                                this expression \
                                                uses it like a function name",
                                                path_name));

3182
                                let msg = format!("did you mean to write: \
3183 3184 3185 3186 3187 3188 3189 3190
                                                     `{} {{ /* fields */ }}`?",
                                                    path_name);
                                if self.emit_errors {
                                    self.session.fileline_help(expr.span, &msg);
                                } else {
                                    self.session.span_help(expr.span, &msg);
                                }
                            }
3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203
                        _ => {
                            // 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
                            });
3204

N
Nick Cameron 已提交
3205 3206
                            if method_scope &&
                               &token::get_name(special_names::self_)[..] == path_name {
3207 3208
                                    self.resolve_error(
                                        expr.span,
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230
                                        "`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)
                                };

3231
                                if !msg.is_empty() {
3232
                                    msg = format!(". Did you mean {}?", msg)
3233
                                }
3234 3235 3236 3237 3238

                                self.resolve_error(
                                    expr.span,
                                    &format!("unresolved name `{}`{}",
                                             path_name, msg));
3239
                            }
V
Vincent Belliard 已提交
3240
                        }
3241 3242 3243
                    }
                }

3244
                visit::walk_expr(self, expr);
3245 3246
            }

3247
            ExprStruct(ref path, _, _) => {
3248 3249 3250
                // 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.
3251
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3252
                    Some(definition) => self.record_def(expr.id, definition),
3253 3254
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
A
Alex Crichton 已提交
3255
                        let msg = format!("`{}` does not name a structure",
3256
                                          path_names_to_string(path, 0));
3257
                        self.resolve_error(path.span, &msg[..]);
3258 3259 3260
                    }
                }

3261
                visit::walk_expr(self, expr);
3262 3263
            }

P
Pythoner6 已提交
3264
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3265
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3266
                    let def_like = DlDef(DefLabel(expr.id));
3267

3268
                    {
3269
                        let rib = this.label_ribs.last_mut().unwrap();
3270
                        let renamed = mtwt::resolve(label);
3271
                        rib.bindings.insert(renamed, def_like);
3272
                    }
3273

3274
                    visit::walk_expr(this, expr);
3275
                })
3276 3277
            }

3278
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3279
                let renamed = mtwt::resolve(label);
3280
                match self.search_label(renamed) {
3281 3282 3283
                    None => {
                        self.resolve_error(
                            expr.span,
J
Jorge Aparicio 已提交
3284
                            &format!("use of undeclared label `{}`",
3285
                                    token::get_ident(label)))
3286
                    }
3287
                    Some(DlDef(def @ DefLabel(_))) => {
3288
                        // Since this def is a label, it is never read.
3289 3290 3291 3292 3293
                        self.record_def(expr.id, PathResolution {
                            base_def: def,
                            last_private: LastMod(AllPublic),
                            depth: 0
                        })
3294 3295
                    }
                    Some(_) => {
3296
                        self.session.span_bug(expr.span,
3297 3298
                                              "label wasn't mapped to a \
                                               label def!")
3299 3300 3301 3302
                    }
                }
            }

B
Brian Anderson 已提交
3303
            _ => {
3304
                visit::walk_expr(self, expr);
3305 3306 3307 3308
            }
        }
    }

E
Eduard Burtescu 已提交
3309
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3310
        match expr.node {
3311
            ExprField(_, ident) => {
3312 3313 3314 3315
                // 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.
3316
                let traits = self.search_for_traits_containing_method(ident.node.name);
3317
                self.trait_map.insert(expr.id, traits);
3318
            }
3319
            ExprMethodCall(ident, _, _) => {
3320
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
3321
                        traits for {}",
3322
                       expr.id);
3323
                let traits = self.search_for_traits_containing_method(ident.node.name);
3324
                self.trait_map.insert(expr.id, traits);
3325
            }
3326
            _ => {
3327 3328 3329 3330 3331
                // Nothing to do.
            }
        }
    }

E
Eduard Burtescu 已提交
3332
    fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
3333
        debug!("(searching for traits containing method) looking for '{}'",
E
Eduard Burtescu 已提交
3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344
               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);
        }
3345

3346
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
3347
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
3348 3349
        loop {
            // Look for the current trait.
3350 3351
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3352
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3353
                        add_trait_info(&mut found_traits, trait_def_id, name);
3354 3355
                    }
                }
3356
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3357
            }
3358

E
Eduard Burtescu 已提交
3359
            // Look for trait children.
3360
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3361

E
Eduard Burtescu 已提交
3362
            {
3363
                for (_, child_names) in &*search_module.children.borrow() {
3364 3365 3366 3367 3368
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
                        None => continue
                    };
                    let trait_def_id = match def {
3369
                        DefTrait(trait_def_id) => trait_def_id,
3370 3371
                        _ => continue,
                    };
3372
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3373
                        add_trait_info(&mut found_traits, trait_def_id, name);
3374 3375
                    }
                }
E
Eduard Burtescu 已提交
3376
            }
3377

E
Eduard Burtescu 已提交
3378
            // Look for imports.
3379
            for (_, import) in &*search_module.import_resolutions.borrow() {
E
Eduard Burtescu 已提交
3380 3381 3382 3383 3384
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
3385
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3386 3387
                    Some(..) | None => continue,
                };
3388
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3389
                    add_trait_info(&mut found_traits, did, name);
3390 3391 3392 3393
                    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);
3394 3395
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
3396
                    }
3397
                }
E
Eduard Burtescu 已提交
3398
            }
3399

E
Eduard Burtescu 已提交
3400
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
3401 3402
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
3403
                    search_module = parent_module.upgrade().unwrap();
3404
                }
E
Eduard Burtescu 已提交
3405
            }
3406 3407
        }

E
Eduard Burtescu 已提交
3408
        found_traits
3409 3410
    }

3411 3412 3413
    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},
3414
                "Import should only be used for `use` directives");
3415

3416 3417 3418 3419 3420
        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));
3421
        }
3422 3423
    }

F
Felix S. Klock II 已提交
3424
    fn enforce_default_binding_mode(&mut self,
3425
                                        pat: &Pat,
3426
                                        pat_binding_mode: BindingMode,
3427
                                        descr: &str) {
3428
        match pat_binding_mode {
3429
            BindByValue(_) => {}
A
Alex Crichton 已提交
3430
            BindByRef(..) => {
3431
                self.resolve_error(pat.span,
J
Jorge Aparicio 已提交
3432
                                   &format!("cannot use `ref` binding mode \
3433
                                            with {}",
3434
                                           descr));
3435 3436 3437 3438
            }
        }
    }

3439 3440 3441 3442 3443 3444 3445
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

3450
        debug!("Children:");
3451
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3452
        for (&name, _) in &*module_.children.borrow() {
3453
            debug!("* {}", token::get_name(name));
3454 3455
        }

3456
        debug!("Import resolutions:");
3457
        let import_resolutions = module_.import_resolutions.borrow();
3458
        for (&name, import_resolution) in &*import_resolutions {
N
Niko Matsakis 已提交
3459
            let value_repr;
3460
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
3461
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3462
                Some(_) => {
R
Richo Healey 已提交
3463
                    value_repr = " value:?".to_string();
3464
                    // FIXME #4954
3465 3466 3467
                }
            }

N
Niko Matsakis 已提交
3468
            let type_repr;
3469
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
3470
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3471
                Some(_) => {
R
Richo Healey 已提交
3472
                    type_repr = " type:?".to_string();
3473
                    // FIXME #4954
3474 3475 3476
                }
            }

3477
            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
3478 3479 3480 3481
        }
    }
}

3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524

fn names_to_string(names: &[Name]) -> String {
    let mut first = true;
    let mut result = String::new();
    for name in names {
        if first {
            first = false
        } else {
            result.push_str("::")
        }
        result.push_str(&token::get_name(*name));
    };
    result
}

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

/// A somewhat inefficient routine to obtain the name of a module.
fn module_to_string(module: &Module) -> String {
    let mut names = Vec::new();

    fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
                collect_mod(names, &*module.upgrade().unwrap());
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
                names.push(special_idents::opaque.name);
                collect_mod(names, &*module.upgrade().unwrap());
            }
        }
    }
    collect_mod(&mut names, module);

3525
    if names.is_empty() {
3526 3527 3528 3529 3530 3531
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}


3532
pub struct CrateMap {
3533
    pub def_map: DefMap,
3534
    pub freevars: RefCell<FreevarMap>,
3535
    pub export_map: ExportMap,
3536 3537
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
3538 3539 3540
    pub glob_map: Option<GlobMap>
}

N
Niko Matsakis 已提交
3541
#[derive(PartialEq,Copy, Clone)]
3542 3543 3544
pub enum MakeGlobMap {
    Yes,
    No
3545 3546
}

3547
/// Entry point to crate resolution.
3548 3549 3550 3551 3552 3553 3554
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);
3555

3556
    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
3557 3558
    session.abort_if_errors();

3559
    resolve_imports::resolve_imports(&mut resolver);
3560 3561
    session.abort_if_errors();

3562
    record_exports::record(&mut resolver);
3563 3564 3565 3566 3567 3568 3569
    session.abort_if_errors();

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

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

3570
    CrateMap {
3571 3572
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3573
        export_map: resolver.export_map,
3574 3575
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
3576 3577 3578 3579 3580
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
3581
    }
3582
}