lib.rs 166.0 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", issue = "27812")]
B
Brian Anderson 已提交
15
#![staged_api]
16 17
#![crate_type = "dylib"]
#![crate_type = "rlib"]
18
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
19
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
20
      html_root_url = "https://doc.rust-lang.org/nightly/")]
21

T
Fallout  
Tamir Duberstein 已提交
22
#![feature(associated_consts)]
23
#![feature(borrow_state)]
A
Alex Crichton 已提交
24
#![feature(rustc_diagnostic_macros)]
25
#![feature(rustc_private)]
A
Alex Crichton 已提交
26
#![feature(staged_api)]
27

C
corentih 已提交
28 29 30 31 32 33 34
#[macro_use]
extern crate log;
#[macro_use]
extern crate syntax;
#[macro_use]
#[no_link]
extern crate rustc_bitflags;
35
extern crate rustc_front;
36 37 38

extern crate rustc;

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

56
use rustc::front::map as hir_map;
57 58 59
use rustc::session::Session;
use rustc::lint;
use rustc::metadata::csearch;
60
use rustc::metadata::decoder::{DefLike, DlDef};
61
use rustc::middle::def::*;
62
use rustc::middle::def_id::DefId;
63
use rustc::middle::pat_util::pat_bindings_hygienic;
64 65
use rustc::middle::privacy::*;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
66
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
67
use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
A
Alex Crichton 已提交
68
use rustc::util::lev_distance::lev_distance;
69

P
Patrick Walton 已提交
70
use syntax::ast;
71
use syntax::ast::{CRATE_NODE_ID, Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
72
use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32};
73
use syntax::attr::AttrMetaMethods;
74
use syntax::ext::mtwt;
75
use syntax::parse::token::{self, special_names, special_idents};
76
use syntax::ptr::P;
77
use syntax::codemap::{self, Span, Pos};
78

79
use rustc_front::intravisit::{self, FnKind, Visitor};
80 81
use rustc_front::hir;
use rustc_front::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
82
use rustc_front::hir::Crate;
83 84 85 86 87 88 89
use rustc_front::hir::{Expr, ExprAgain, ExprBreak, ExprField};
use rustc_front::hir::{ExprLoop, ExprWhile, ExprMethodCall};
use rustc_front::hir::{ExprPath, ExprStruct, FnDecl};
use rustc_front::hir::{ForeignItemFn, ForeignItemStatic, Generics};
use rustc_front::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use rustc_front::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
90
use rustc_front::hir::Local;
91 92
use rustc_front::hir::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
use rustc_front::hir::{PatRange, PatStruct, Path, PrimTy};
93 94
use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt};
use rustc_front::hir::{TyRptr, TyStr, TyUint, TyPath, TyPtr};
95
use rustc_front::util::walk_pat;
96

97
use std::collections::{HashMap, HashSet};
98
use std::cell::{Cell, RefCell};
99
use std::fmt;
100
use std::mem::replace;
E
Eduard Burtescu 已提交
101
use std::rc::{Rc, Weak};
102
use std::usize;
103

104 105 106
use resolve_imports::{Target, ImportDirective, ImportResolution};
use resolve_imports::Shadowable;

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

A
Alex Crichton 已提交
111 112
mod check_unused;
mod record_exports;
113
mod build_reduced_graph;
114
mod resolve_imports;
115

116 117 118 119 120 121 122 123 124 125 126
// Perform the callback, not walking deeper if the return is true
macro_rules! execute_callback {
    ($node: expr, $walker: expr) => (
        if let Some(ref callback) = $walker.callback {
            if callback($node, &mut $walker.resolved) {
                return;
            }
        }
    )
}

127
pub enum ResolutionError<'a> {
128
    /// error E0401: can't use type parameters from outer function
129
    TypeParametersFromOuterFunction,
130
    /// error E0402: cannot use an outer type parameter in this context
131
    OuterTypeParameterContext,
132
    /// error E0403: the name is already used for a type parameter in this type parameter list
133
    NameAlreadyUsedInTypeParameterList(Name),
134
    /// error E0404: is not a trait
135
    IsNotATrait(&'a str),
136
    /// error E0405: use of undeclared trait name
137
    UndeclaredTraitName(&'a str),
138
    /// error E0406: undeclared associated type
139
    UndeclaredAssociatedType,
140
    /// error E0407: method is not a member of trait
141
    MethodNotMemberOfTrait(Name, &'a str),
142 143 144 145
    /// error E0437: type is not a member of trait
    TypeNotMemberOfTrait(Name, &'a str),
    /// error E0438: const is not a member of trait
    ConstNotMemberOfTrait(Name, &'a str),
146
    /// error E0408: variable `{}` from pattern #1 is not bound in pattern
147
    VariableNotBoundInPattern(Name, usize),
148
    /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
149
    VariableBoundWithDifferentMode(Name, usize),
150
    /// error E0410: variable from pattern is not bound in pattern #1
151
    VariableNotBoundInParentPattern(Name, usize),
152
    /// error E0411: use of `Self` outside of an impl or trait
153
    SelfUsedOutsideImplOrTrait,
154
    /// error E0412: use of undeclared
155
    UseOfUndeclared(&'a str, &'a str),
156
    /// error E0413: declaration shadows an enum variant or unit-like struct in scope
157
    DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
158
    /// error E0414: only irrefutable patterns allowed here
159
    OnlyIrrefutablePatternsAllowedHere(DefId, Name),
160
    /// error E0415: identifier is bound more than once in this parameter list
161
    IdentifierBoundMoreThanOnceInParameterList(&'a str),
162
    /// error E0416: identifier is bound more than once in the same pattern
163
    IdentifierBoundMoreThanOnceInSamePattern(&'a str),
164
    /// error E0417: static variables cannot be referenced in a pattern
165
    StaticVariableReference,
166
    /// error E0418: is not an enum variant, struct or const
167
    NotAnEnumVariantStructOrConst(&'a str),
168
    /// error E0419: unresolved enum variant, struct or const
169
    UnresolvedEnumVariantStructOrConst(&'a str),
170
    /// error E0420: is not an associated const
171
    NotAnAssociatedConst(&'a str),
172
    /// error E0421: unresolved associated const
173
    UnresolvedAssociatedConst(&'a str),
174
    /// error E0422: does not name a struct
175
    DoesNotNameAStruct(&'a str),
176
    /// error E0423: is a struct variant name, but this expression uses it like a function name
177
    StructVariantUsedAsFunction(&'a str),
178
    /// error E0424: `self` is not available in a static method
179
    SelfNotAvailableInStaticMethod,
180
    /// error E0425: unresolved name
181
    UnresolvedName(&'a str, &'a str),
182
    /// error E0426: use of undeclared label
183
    UndeclaredLabel(&'a str),
184
    /// error E0427: cannot use `ref` binding mode with ...
185
    CannotUseRefBindingModeWith(&'a str),
186
    /// error E0428: duplicate definition
187
    DuplicateDefinition(&'a str, Name),
188
    /// error E0429: `self` imports are only allowed within a { } list
189
    SelfImportsOnlyAllowedWithin,
190
    /// error E0430: `self` import can only appear once in the list
191
    SelfImportCanOnlyAppearOnceInTheList,
192
    /// error E0431: `self` import can only appear in an import list with a non-empty prefix
193
    SelfImportOnlyInImportListWithNonEmptyPrefix,
194
    /// error E0432: unresolved import
195
    UnresolvedImport(Option<(&'a str, &'a str)>),
196
    /// error E0433: failed to resolve
197
    FailedToResolve(&'a str),
198
    /// error E0434: can't capture dynamic environment in a fn item
199
    CannotCaptureDynamicEnvironmentInFnItem,
200
    /// error E0435: attempt to use a non-constant value in a constant
201
    AttemptToUseNonConstantValueInConstant,
202 203
}

C
corentih 已提交
204 205 206
fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                       span: syntax::codemap::Span,
                                       resolution_error: ResolutionError<'b>) {
207 208 209
    if !resolver.emit_errors {
        return;
    }
210
    match resolution_error {
211
        ResolutionError::TypeParametersFromOuterFunction => {
C
corentih 已提交
212 213 214 215 216 217
            span_err!(resolver.session,
                      span,
                      E0401,
                      "can't use type parameters from outer function; try using a local type \
                       parameter instead");
        }
218
        ResolutionError::OuterTypeParameterContext => {
C
corentih 已提交
219 220 221 222 223
            span_err!(resolver.session,
                      span,
                      E0402,
                      "cannot use an outer type parameter in this context");
        }
224
        ResolutionError::NameAlreadyUsedInTypeParameterList(name) => {
C
corentih 已提交
225 226 227 228 229 230 231
            span_err!(resolver.session,
                      span,
                      E0403,
                      "the name `{}` is already used for a type parameter in this type parameter \
                       list",
                      name);
        }
232
        ResolutionError::IsNotATrait(name) => {
C
corentih 已提交
233 234
            span_err!(resolver.session, span, E0404, "`{}` is not a trait", name);
        }
235
        ResolutionError::UndeclaredTraitName(name) => {
C
corentih 已提交
236 237 238 239 240 241
            span_err!(resolver.session,
                      span,
                      E0405,
                      "use of undeclared trait name `{}`",
                      name);
        }
242 243
        ResolutionError::UndeclaredAssociatedType => {
            span_err!(resolver.session, span, E0406, "undeclared associated type");
C
corentih 已提交
244
        }
245
        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
C
corentih 已提交
246 247 248 249 250 251 252
            span_err!(resolver.session,
                      span,
                      E0407,
                      "method `{}` is not a member of trait `{}`",
                      method,
                      trait_);
        }
253
        ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
C
corentih 已提交
254 255 256 257 258 259 260
            span_err!(resolver.session,
                      span,
                      E0437,
                      "type `{}` is not a member of trait `{}`",
                      type_,
                      trait_);
        }
261
        ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
C
corentih 已提交
262 263 264 265 266 267 268
            span_err!(resolver.session,
                      span,
                      E0438,
                      "const `{}` is not a member of trait `{}`",
                      const_,
                      trait_);
        }
269
        ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
C
corentih 已提交
270 271 272 273 274 275 276
            span_err!(resolver.session,
                      span,
                      E0408,
                      "variable `{}` from pattern #1 is not bound in pattern #{}",
                      variable_name,
                      pattern_number);
        }
277
        ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
C
corentih 已提交
278 279 280 281 282 283 284 285
            span_err!(resolver.session,
                      span,
                      E0409,
                      "variable `{}` is bound with different mode in pattern #{} than in pattern \
                       #1",
                      variable_name,
                      pattern_number);
        }
286
        ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
C
corentih 已提交
287 288 289 290 291 292 293
            span_err!(resolver.session,
                      span,
                      E0410,
                      "variable `{}` from pattern #{} is not bound in pattern #1",
                      variable_name,
                      pattern_number);
        }
294
        ResolutionError::SelfUsedOutsideImplOrTrait => {
C
corentih 已提交
295 296 297 298 299
            span_err!(resolver.session,
                      span,
                      E0411,
                      "use of `Self` outside of an impl or trait");
        }
300
        ResolutionError::UseOfUndeclared(kind, name) => {
C
corentih 已提交
301 302 303 304 305 306 307
            span_err!(resolver.session,
                      span,
                      E0412,
                      "use of undeclared {} `{}`",
                      kind,
                      name);
        }
308
        ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
C
corentih 已提交
309 310 311 312 313 314
            span_err!(resolver.session,
                      span,
                      E0413,
                      "declaration of `{}` shadows an enum variant or unit-like struct in scope",
                      name);
        }
315
        ResolutionError::OnlyIrrefutablePatternsAllowedHere(did, name) => {
C
corentih 已提交
316 317 318 319 320 321 322
            span_err!(resolver.session,
                      span,
                      E0414,
                      "only irrefutable patterns allowed here");
            resolver.session.span_note(span,
                                       "there already is a constant in scope sharing the same \
                                        name as this pattern");
323 324 325
            if let Some(sp) = resolver.ast_map.span_if_local(did) {
                resolver.session.span_note(sp, "constant defined here");
            }
M
Manish Goregaokar 已提交
326 327
            if let Some(directive) = resolver.current_module
                                             .import_resolutions
C
corentih 已提交
328 329
                                             .borrow()
                                             .get(&name) {
330 331 332
                let item = resolver.ast_map.expect_item(directive.value_id);
                resolver.session.span_note(item.span, "constant imported here");
            }
C
corentih 已提交
333
        }
334
        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
C
corentih 已提交
335 336 337 338 339 340
            span_err!(resolver.session,
                      span,
                      E0415,
                      "identifier `{}` is bound more than once in this parameter list",
                      identifier);
        }
341
        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
C
corentih 已提交
342 343 344 345 346 347
            span_err!(resolver.session,
                      span,
                      E0416,
                      "identifier `{}` is bound more than once in the same pattern",
                      identifier);
        }
348
        ResolutionError::StaticVariableReference => {
C
corentih 已提交
349 350 351 352 353
            span_err!(resolver.session,
                      span,
                      E0417,
                      "static variables cannot be referenced in a pattern, use a `const` instead");
        }
354
        ResolutionError::NotAnEnumVariantStructOrConst(name) => {
C
corentih 已提交
355 356 357 358 359 360
            span_err!(resolver.session,
                      span,
                      E0418,
                      "`{}` is not an enum variant, struct or const",
                      name);
        }
361
        ResolutionError::UnresolvedEnumVariantStructOrConst(name) => {
C
corentih 已提交
362 363 364 365 366 367
            span_err!(resolver.session,
                      span,
                      E0419,
                      "unresolved enum variant, struct or const `{}`",
                      name);
        }
368
        ResolutionError::NotAnAssociatedConst(name) => {
C
corentih 已提交
369 370 371 372 373 374
            span_err!(resolver.session,
                      span,
                      E0420,
                      "`{}` is not an associated const",
                      name);
        }
375
        ResolutionError::UnresolvedAssociatedConst(name) => {
C
corentih 已提交
376 377 378 379 380 381
            span_err!(resolver.session,
                      span,
                      E0421,
                      "unresolved associated const `{}`",
                      name);
        }
382
        ResolutionError::DoesNotNameAStruct(name) => {
C
corentih 已提交
383 384 385 386 387 388
            span_err!(resolver.session,
                      span,
                      E0422,
                      "`{}` does not name a structure",
                      name);
        }
389
        ResolutionError::StructVariantUsedAsFunction(path_name) => {
C
corentih 已提交
390 391 392 393 394 395 396
            span_err!(resolver.session,
                      span,
                      E0423,
                      "`{}` is the name of a struct or struct variant, but this expression uses \
                       it like a function name",
                      path_name);
        }
397
        ResolutionError::SelfNotAvailableInStaticMethod => {
C
corentih 已提交
398 399 400 401 402 403
            span_err!(resolver.session,
                      span,
                      E0424,
                      "`self` is not available in a static method. Maybe a `self` argument is \
                       missing?");
        }
404
        ResolutionError::UnresolvedName(path, name) => {
C
corentih 已提交
405 406 407 408 409 410 411
            span_err!(resolver.session,
                      span,
                      E0425,
                      "unresolved name `{}`{}",
                      path,
                      name);
        }
412
        ResolutionError::UndeclaredLabel(name) => {
C
corentih 已提交
413 414 415 416 417 418
            span_err!(resolver.session,
                      span,
                      E0426,
                      "use of undeclared label `{}`",
                      name);
        }
419
        ResolutionError::CannotUseRefBindingModeWith(descr) => {
C
corentih 已提交
420 421 422 423 424 425
            span_err!(resolver.session,
                      span,
                      E0427,
                      "cannot use `ref` binding mode with {}",
                      descr);
        }
426
        ResolutionError::DuplicateDefinition(namespace, name) => {
C
corentih 已提交
427 428 429 430 431 432 433
            span_err!(resolver.session,
                      span,
                      E0428,
                      "duplicate definition of {} `{}`",
                      namespace,
                      name);
        }
434
        ResolutionError::SelfImportsOnlyAllowedWithin => {
C
corentih 已提交
435 436 437 438 439 440
            span_err!(resolver.session,
                      span,
                      E0429,
                      "{}",
                      "`self` imports are only allowed within a { } list");
        }
441
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
C
corentih 已提交
442 443 444 445 446
            span_err!(resolver.session,
                      span,
                      E0430,
                      "`self` import can only appear once in the list");
        }
447
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
C
corentih 已提交
448 449 450 451
            span_err!(resolver.session,
                      span,
                      E0431,
                      "`self` import can only appear in an import list with a non-empty prefix");
452
        }
453
        ResolutionError::UnresolvedImport(name) => {
454
            let msg = match name {
455
                Some((n, p)) => format!("unresolved import `{}`{}", n, p),
C
corentih 已提交
456
                None => "unresolved import".to_owned(),
457
            };
458
            span_err!(resolver.session, span, E0432, "{}", msg);
C
corentih 已提交
459
        }
460 461
        ResolutionError::FailedToResolve(msg) => {
            span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg);
C
corentih 已提交
462
        }
463
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
C
corentih 已提交
464 465 466 467 468 469 470 471 472 473 474 475 476
            span_err!(resolver.session,
                      span,
                      E0434,
                      "{}",
                      "can't capture dynamic environment in a fn item; use the || { ... } \
                       closure form instead");
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
            span_err!(resolver.session,
                      span,
                      E0435,
                      "attempt to use a non-constant value in a constant");
        }
477
    }
478 479
}

N
Niko Matsakis 已提交
480
#[derive(Copy, Clone)]
481
struct BindingInfo {
482
    span: Span,
483
    binding_mode: BindingMode,
484 485 486
}

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

N
Niko Matsakis 已提交
489
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
490
enum PatternBindingMode {
491
    RefutableMode,
492
    LocalIrrefutableMode,
493
    ArgumentIrrefutableMode,
494 495
}

N
Niko Matsakis 已提交
496
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
497
pub enum Namespace {
498
    TypeNS,
C
corentih 已提交
499
    ValueNS,
500 501
}

B
Brian Anderson 已提交
502 503 504
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
505
#[derive(Clone)]
F
Felix S. Klock II 已提交
506
enum NamespaceResult {
T
Tim Chevalier 已提交
507 508 509
    /// 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.)
510
    UnknownResult,
B
Brian Anderson 已提交
511 512
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
513
    UnboundResult,
T
Tim Chevalier 已提交
514 515
    /// Means that resolve has determined that the name is bound in the Module
    /// argument, and specified by the NameBindings argument.
C
corentih 已提交
516
    BoundResult(Rc<Module>, Rc<NameBindings>),
517 518
}

519
impl NamespaceResult {
F
Felix S. Klock II 已提交
520
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
521
        match *self {
522
            UnknownResult => true,
C
corentih 已提交
523
            _ => false,
524 525
        }
    }
526 527 528
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
C
corentih 已提交
529
            _ => false,
530 531
        }
    }
532 533
}

F
Felix S. Klock II 已提交
534
enum NameDefinition {
N
Nick Cameron 已提交
535 536 537 538 539 540
    // The name was unbound.
    NoNameDefinition,
    // The name identifies an immediate child.
    ChildNameDefinition(Def, LastPrivate),
    // The name identifies an import.
    ImportNameDefinition(Def, LastPrivate),
541 542
}

543
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
544 545 546
    fn visit_nested_item(&mut self, item: hir::ItemId) {
        self.visit_item(self.ast_map.expect_item(item.id))
    }
547
    fn visit_item(&mut self, item: &Item) {
548
        execute_callback!(hir_map::Node::NodeItem(item), self);
A
Alex Crichton 已提交
549
        self.resolve_item(item);
550
    }
551
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
552
        self.resolve_arm(arm);
553
    }
554
    fn visit_block(&mut self, block: &Block) {
555
        execute_callback!(hir_map::Node::NodeBlock(block), self);
A
Alex Crichton 已提交
556
        self.resolve_block(block);
557
    }
558
    fn visit_expr(&mut self, expr: &Expr) {
559
        execute_callback!(hir_map::Node::NodeExpr(expr), self);
A
Alex Crichton 已提交
560
        self.resolve_expr(expr);
561
    }
562
    fn visit_local(&mut self, local: &Local) {
563
        execute_callback!(hir_map::Node::NodeLocal(&*local.pat), self);
A
Alex Crichton 已提交
564
        self.resolve_local(local);
565
    }
566
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
567
        self.resolve_type(ty);
568
    }
569 570 571
    fn visit_generics(&mut self, generics: &Generics) {
        self.resolve_generics(generics);
    }
C
corentih 已提交
572
    fn visit_poly_trait_ref(&mut self, tref: &hir::PolyTraitRef, m: &hir::TraitBoundModifier) {
573 574
        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),
C
corentih 已提交
575 576 577
            Err(_) => {
                // error already reported
            }
578
        }
579
        intravisit::walk_poly_trait_ref(self, tref, m);
580
    }
C
corentih 已提交
581 582 583 584
    fn visit_variant(&mut self,
                     variant: &hir::Variant,
                     generics: &Generics,
                     item_id: ast::NodeId) {
585
        execute_callback!(hir_map::Node::NodeVariant(variant), self);
586 587 588
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
589
                this.visit_expr(dis_expr);
590 591 592
            });
        }

593
        // `intravisit::walk_variant` without the discriminant expression.
C
corentih 已提交
594 595 596 597 598
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
599
    }
600 601
    fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
        execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
602 603 604 605
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
C
corentih 已提交
606
            ForeignItemStatic(..) => NoTypeParameters,
607 608
        };
        self.with_type_parameter_rib(type_parameters, |this| {
609
            intravisit::walk_foreign_item(this, foreign_item);
610 611 612
        });
    }
    fn visit_fn(&mut self,
613
                function_kind: FnKind<'v>,
614 615 616 617 618
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
619
            FnKind::ItemFn(_, generics, _, _, _, _) => {
620 621 622
                self.visit_generics(generics);
                ItemRibKind
            }
623
            FnKind::Method(_, sig, _) => {
624 625
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
626 627
                MethodRibKind
            }
C
corentih 已提交
628
            FnKind::Closure(..) => ClosureRibKind(node_id),
629 630 631
        };
        self.resolve_function(rib_kind, declaration, block);
    }
632
}
633

634 635
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
636
enum ResolveResult<T> {
C
corentih 已提交
637 638 639
    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.
640 641
}

642
impl<T> ResolveResult<T> {
643
    fn success(&self) -> bool {
C
corentih 已提交
644 645 646 647
        match *self {
            Success(_) => true,
            _ => false,
        }
648 649 650
    }
}

651 652 653 654
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
655
    TraitItem,
656
    StaticMethod(String),
657
    TraitMethod(String),
658 659
}

N
Niko Matsakis 已提交
660
#[derive(Copy, Clone)]
E
Erik Price 已提交
661
enum TypeParameters<'a> {
662
    NoTypeParameters,
C
corentih 已提交
663 664
    HasTypeParameters(// Type parameters.
                      &'a Generics,
665

C
corentih 已提交
666 667 668
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
669

C
corentih 已提交
670 671
                      // The kind of the rib used for type parameters.
                      RibKind),
672 673
}

674 675
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
676
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
677
enum RibKind {
678 679
    // No translation needs to be applied.
    NormalRibKind,
680

681 682
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
683
    ClosureRibKind(NodeId /* func id */),
684

685
    // We passed through an impl or trait and are now in one of its
686
    // methods. Allow references to ty params that impl or trait
687 688
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
689
    MethodRibKind,
690

691 692
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
693 694

    // We're in a constant item. Can't refer to dynamic stuff.
C
corentih 已提交
695
    ConstantItemRibKind,
696 697
}

N
Niko Matsakis 已提交
698
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
699
enum UseLexicalScopeFlag {
700
    DontUseLexicalScope,
C
corentih 已提交
701
    UseLexicalScope,
702 703
}

F
Felix S. Klock II 已提交
704
enum ModulePrefixResult {
705
    NoPrefixFound,
C
corentih 已提交
706
    PrefixFound(Rc<Module>, usize),
707 708
}

709 710 711 712 713 714 715 716 717
#[derive(Copy, Clone)]
enum AssocItemResolveResult {
    /// Syntax such as `<T>::item`, which can't be resolved until type
    /// checking.
    TypecheckRequired,
    /// We should have been able to resolve the associated item.
    ResolveAttempt(Option<PathResolution>),
}

N
Niko Matsakis 已提交
718
#[derive(Copy, Clone, PartialEq)]
719
enum NameSearchType {
720 721 722 723
    /// 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
724 725
    /// expression, or a path pattern.
    PathSearch,
726 727
}

N
Niko Matsakis 已提交
728
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
729
enum BareIdentifierPatternResolution {
730
    FoundStructOrEnumVariant(Def, LastPrivate),
731
    FoundConst(Def, LastPrivate, Name),
C
corentih 已提交
732
    BareIdentifierPatternUnresolved,
733 734
}

735
/// One local scope.
J
Jorge Aparicio 已提交
736
#[derive(Debug)]
F
Felix S. Klock II 已提交
737
struct Rib {
738
    bindings: HashMap<Name, DefLike>,
739
    kind: RibKind,
B
Brian Anderson 已提交
740
}
741

742
impl Rib {
F
Felix S. Klock II 已提交
743
    fn new(kind: RibKind) -> Rib {
744
        Rib {
745
            bindings: HashMap::new(),
C
corentih 已提交
746
            kind: kind,
747
        }
748 749 750
    }
}

751 752 753
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
754
    def: Def,
755 756 757 758 759 760
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
761
            def: def,
762 763 764 765
        }
    }
}

766
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
767
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
768
enum ParentLink {
769
    NoParentLink,
770
    ModuleParentLink(Weak<Module>, Name),
C
corentih 已提交
771
    BlockParentLink(Weak<Module>, NodeId),
772 773
}

774
/// The type of module this is.
N
Niko Matsakis 已提交
775
#[derive(Copy, Clone, PartialEq, Debug)]
F
Felix S. Klock II 已提交
776
enum ModuleKind {
777 778
    NormalModuleKind,
    TraitModuleKind,
779
    EnumModuleKind,
780
    TypeModuleKind,
781 782 783
    AnonymousModuleKind,
}

784
/// One node in the tree of modules.
785
pub struct Module {
786
    parent_link: ParentLink,
787
    def_id: Cell<Option<DefId>>,
788
    kind: Cell<ModuleKind>,
789
    is_public: bool,
790

E
Eduard Burtescu 已提交
791 792
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
793

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

798 799 800 801 802 803 804 805 806 807 808 809 810 811
    // 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 已提交
812
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
813 814

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

    // The number of unresolved globs that this module exports.
818
    glob_count: Cell<usize>,
819

820 821 822 823 824 825
    // The number of unresolved pub imports (both regular and globs) in this module
    pub_count: Cell<usize>,

    // The number of unresolved pub glob imports in this module
    pub_glob_count: Cell<usize>,

826
    // The index of the import we're resolving.
827
    resolved_import_count: Cell<usize>,
828 829 830 831

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

835
impl Module {
F
Felix S. Klock II 已提交
836
    fn new(parent_link: ParentLink,
837 838 839 840
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
841
           -> Module {
842 843
        Module {
            parent_link: parent_link,
844
            def_id: Cell::new(def_id),
845
            kind: Cell::new(kind),
846
            is_public: is_public,
847
            children: RefCell::new(HashMap::new()),
848
            imports: RefCell::new(Vec::new()),
849
            external_module_children: RefCell::new(HashMap::new()),
850
            anonymous_children: RefCell::new(NodeMap()),
851
            import_resolutions: RefCell::new(HashMap::new()),
852
            glob_count: Cell::new(0),
853 854
            pub_count: Cell::new(0),
            pub_glob_count: Cell::new(0),
855
            resolved_import_count: Cell::new(0),
856
            populated: Cell::new(!external),
857
        }
B
Brian Anderson 已提交
858 859
    }

F
Felix S. Klock II 已提交
860
    fn all_imports_resolved(&self) -> bool {
861 862 863 864 865 866
        if self.imports.borrow_state() == ::std::cell::BorrowState::Writing {
            // it is currently being resolved ! so nope
            false
        } else {
            self.imports.borrow().len() == self.resolved_import_count.get()
        }
867 868 869
    }
}

V
Victor Berger 已提交
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
impl Module {
    pub fn inc_glob_count(&self) {
        self.glob_count.set(self.glob_count.get() + 1);
    }
    pub fn dec_glob_count(&self) {
        assert!(self.glob_count.get() > 0);
        self.glob_count.set(self.glob_count.get() - 1);
    }
    pub fn inc_pub_count(&self) {
        self.pub_count.set(self.pub_count.get() + 1);
    }
    pub fn dec_pub_count(&self) {
        assert!(self.pub_count.get() > 0);
        self.pub_count.set(self.pub_count.get() - 1);
    }
    pub fn inc_pub_glob_count(&self) {
        self.pub_glob_count.set(self.pub_glob_count.get() + 1);
    }
    pub fn dec_pub_glob_count(&self) {
        assert!(self.pub_glob_count.get() > 0);
        self.pub_glob_count.set(self.pub_glob_count.get() - 1);
    }
}

894
impl fmt::Debug for Module {
895
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
C
corentih 已提交
896 897
        write!(f,
               "{:?}, kind: {:?}, {}",
898 899
               self.def_id,
               self.kind,
C
corentih 已提交
900 901 902 903 904
               if self.is_public {
                   "public"
               } else {
                   "private"
               })
905 906 907
    }
}

908
bitflags! {
J
Jorge Aparicio 已提交
909
    #[derive(Debug)]
910
    flags DefModifiers: u8 {
T
Fallout  
Tamir Duberstein 已提交
911 912
        const PUBLIC     = 1 << 0,
        const IMPORTABLE = 1 << 1,
913 914 915
    }
}

916
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
917
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
918
struct TypeNsDef {
919
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
920
    module_def: Option<Rc<Module>>,
921
    type_def: Option<Def>,
C
corentih 已提交
922
    type_span: Option<Span>,
923 924 925
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
926
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
927
struct ValueNsDef {
928
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
929
    def: Def,
930
    value_span: Option<Span>,
931 932
}

933 934
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
935
#[derive(Debug)]
936
pub struct NameBindings {
C
corentih 已提交
937 938
    type_def: RefCell<Option<TypeNsDef>>, // < Meaning in type namespace.
    value_def: RefCell<Option<ValueNsDef>>, // < Meaning in value namespace.
939 940
}

941
impl NameBindings {
K
Kevin Butler 已提交
942 943 944 945 946 947 948
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

949
    /// Creates a new module in this set of name bindings.
950
    fn define_module(&self,
951 952 953 954 955 956
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
957
        // Merges the module with the existing type def or creates a new one.
T
Fallout  
Tamir Duberstein 已提交
958 959 960 961 962
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
C
corentih 已提交
963
        let module_ = Rc::new(Module::new(parent_link, def_id, kind, external, is_public));
E
Erick Tryzelaar 已提交
964 965
        let type_def = self.type_def.borrow().clone();
        match type_def {
966
            None => {
E
Erick Tryzelaar 已提交
967
                *self.type_def.borrow_mut() = Some(TypeNsDef {
968
                    modifiers: modifiers,
969
                    module_def: Some(module_),
970
                    type_def: None,
C
corentih 已提交
971
                    type_span: Some(sp),
E
Erick Tryzelaar 已提交
972
                });
973
            }
974
            Some(type_def) => {
E
Erick Tryzelaar 已提交
975
                *self.type_def.borrow_mut() = Some(TypeNsDef {
976
                    modifiers: modifiers,
977
                    module_def: Some(module_),
978
                    type_span: Some(sp),
C
corentih 已提交
979
                    type_def: type_def.type_def,
E
Erick Tryzelaar 已提交
980
                });
981
            }
982 983 984
        }
    }

985
    /// Sets the kind of the module, creating a new one if necessary.
986
    fn set_module_kind(&self,
987 988 989 990 991 992
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
T
Fallout  
Tamir Duberstein 已提交
993 994 995 996 997
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
E
Erick Tryzelaar 已提交
998 999
        let type_def = self.type_def.borrow().clone();
        match type_def {
1000
            None => {
C
corentih 已提交
1001
                let module = Module::new(parent_link, def_id, kind, external, is_public);
E
Erick Tryzelaar 已提交
1002
                *self.type_def.borrow_mut() = Some(TypeNsDef {
1003
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
1004
                    module_def: Some(Rc::new(module)),
1005 1006
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
1007
                });
1008 1009 1010 1011
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
C
corentih 已提交
1012
                        let module = Module::new(parent_link, def_id, kind, external, is_public);
E
Erick Tryzelaar 已提交
1013
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
1014
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
1015
                            module_def: Some(Rc::new(module)),
1016 1017
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
1018
                        });
1019
                    }
1020
                    Some(module_def) => module_def.kind.set(kind),
1021 1022 1023 1024 1025
                }
            }
        }
    }

1026
    /// Records a type definition.
1027
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
C
corentih 已提交
1028 1029 1030
        debug!("defining type for def {:?} with modifiers {:?}",
               def,
               modifiers);
1031
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
1032 1033
        let type_def = self.type_def.borrow().clone();
        match type_def {
1034
            None => {
E
Erick Tryzelaar 已提交
1035
                *self.type_def.borrow_mut() = Some(TypeNsDef {
1036
                    module_def: None,
1037
                    type_def: Some(def),
1038
                    type_span: Some(sp),
1039
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
1040
                });
1041
            }
1042
            Some(type_def) => {
E
Erick Tryzelaar 已提交
1043
                *self.type_def.borrow_mut() = Some(TypeNsDef {
1044
                    module_def: type_def.module_def,
1045
                    type_def: Some(def),
1046
                    type_span: Some(sp),
1047
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
1048
                });
1049 1050
            }
        }
1051 1052
    }

1053
    /// Records a value definition.
1054
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
C
corentih 已提交
1055 1056 1057
        debug!("defining value for def {:?} with modifiers {:?}",
               def,
               modifiers);
E
Erick Tryzelaar 已提交
1058
        *self.value_def.borrow_mut() = Some(ValueNsDef {
1059 1060
            def: def,
            value_span: Some(sp),
1061
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
1062
        });
1063 1064
    }

1065
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
1066
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
1067
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
1068
            Some(ref type_def) => type_def.module_def.clone(),
C
corentih 已提交
1069
            None => None,
1070 1071 1072
        }
    }

S
Steve Klabnik 已提交
1073 1074
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
1075
    fn get_module(&self) -> Rc<Module> {
1076 1077
        match self.get_module_if_available() {
            None => {
C
corentih 已提交
1078
                panic!("get_module called on a node with no module definition!")
1079
            }
C
corentih 已提交
1080
            Some(module_def) => module_def,
1081 1082 1083
        }
    }

F
Felix S. Klock II 已提交
1084
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
1085
        match namespace {
C
corentih 已提交
1086 1087
            TypeNS => return self.type_def.borrow().is_some(),
            ValueNS => return self.value_def.borrow().is_some(),
1088 1089 1090
        }
    }

F
Felix S. Klock II 已提交
1091
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
T
Fallout  
Tamir Duberstein 已提交
1092
        self.defined_in_namespace_with(namespace, DefModifiers::PUBLIC)
1093 1094 1095
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
1096
        match namespace {
E
Erick Tryzelaar 已提交
1097
            TypeNS => match *self.type_def.borrow() {
C
corentih 已提交
1098 1099
                Some(ref def) => def.modifiers.contains(modifiers),
                None => false,
1100
            },
E
Erick Tryzelaar 已提交
1101
            ValueNS => match *self.value_def.borrow() {
C
corentih 已提交
1102 1103 1104
                Some(ref def) => def.modifiers.contains(modifiers),
                None => false,
            },
1105 1106 1107
        }
    }

F
Felix S. Klock II 已提交
1108
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
1109
        match namespace {
1110
            TypeNS => {
E
Erick Tryzelaar 已提交
1111
                match *self.type_def.borrow() {
1112
                    None => None,
E
Eduard Burtescu 已提交
1113
                    Some(ref type_def) => {
1114
                        match type_def.type_def {
1115
                            Some(type_def) => Some(type_def),
1116 1117
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
1118
                                    Some(ref module) => {
1119
                                        match module.def_id.get() {
1120
                                            Some(did) => Some(DefMod(did)),
1121 1122 1123 1124 1125 1126
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
1127
                        }
1128 1129
                    }
                }
1130 1131
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
1132
                match *self.value_def.borrow() {
1133
                    None => None,
C
corentih 已提交
1134
                    Some(value_def) => Some(value_def.def),
1135 1136 1137 1138 1139
                }
            }
        }
    }

F
Felix S. Klock II 已提交
1140
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
1141
        if self.defined_in_namespace(namespace) {
1142
            match namespace {
C
corentih 已提交
1143
                TypeNS => {
E
Erick Tryzelaar 已提交
1144
                    match *self.type_def.borrow() {
1145
                        None => None,
C
corentih 已提交
1146
                        Some(ref type_def) => type_def.type_span,
1147 1148 1149
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
1150
                    match *self.value_def.borrow() {
1151
                        None => None,
C
corentih 已提交
1152
                        Some(ref value_def) => value_def.value_span,
1153 1154
                    }
                }
1155
            }
1156 1157
        } else {
            None
1158 1159
        }
    }
1160 1161 1162

    fn is_public(&self, namespace: Namespace) -> bool {
        match namespace {
C
corentih 已提交
1163
            TypeNS => {
1164
                let type_def = self.type_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1165
                type_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1166 1167 1168
            }
            ValueNS => {
                let value_def = self.value_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1169
                value_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1170 1171 1172
            }
        }
    }
1173 1174
}

1175
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1176
struct PrimitiveTypeTable {
1177
    primitive_types: HashMap<Name, PrimTy>,
1178
}
1179

1180
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1181
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
        table.intern("f32", TyFloat(TyF32));
        table.intern("f64", TyFloat(TyF64));
        table.intern("isize", TyInt(TyIs));
        table.intern("i8", TyInt(TyI8));
        table.intern("i16", TyInt(TyI16));
        table.intern("i32", TyInt(TyI32));
        table.intern("i64", TyInt(TyI64));
        table.intern("str", TyStr);
        table.intern("usize", TyUint(TyUs));
        table.intern("u8", TyUint(TyU8));
        table.intern("u16", TyUint(TyU16));
        table.intern("u32", TyUint(TyU32));
        table.intern("u64", TyUint(TyU64));
K
Kevin Butler 已提交
1199 1200 1201 1202

        table
    }

1203
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1204
        self.primitive_types.insert(token::intern(string), primitive_type);
1205 1206 1207
    }
}

1208
/// The main resolver class.
C
corentih 已提交
1209
pub struct Resolver<'a, 'tcx: 'a> {
E
Eduard Burtescu 已提交
1210
    session: &'a Session,
1211

1212
    ast_map: &'a hir_map::Map<'tcx>,
1213

E
Eduard Burtescu 已提交
1214
    graph_root: NameBindings,
1215

1216
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1217

1218
    structs: FnvHashMap<DefId, Vec<Name>>,
1219

1220
    // The number of imports that are currently unresolved.
1221
    unresolved_imports: usize,
1222 1223

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
1224
    current_module: Rc<Module>,
1225 1226

    // The current set of local scopes, for values.
1227
    // FIXME #4948: Reuse ribs to avoid allocation.
1228
    value_ribs: Vec<Rib>,
1229 1230

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

1233
    // The current set of local scopes, for labels.
1234
    label_ribs: Vec<Rib>,
1235

1236
    // The trait that the current context can refer to.
1237 1238 1239 1240
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1242
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1243
    primitive_type_table: PrimitiveTypeTable,
1244

J
Jonathan S 已提交
1245
    def_map: RefCell<DefMap>,
1246 1247
    freevars: FreevarMap,
    freevars_seen: NodeMap<NodeMap<usize>>,
1248
    export_map: ExportMap,
1249
    trait_map: TraitMap,
1250
    external_exports: ExternalExports,
1251

1252 1253 1254 1255 1256
    // 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,

1257 1258 1259 1260 1261
    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,

1262
    used_imports: HashSet<(NodeId, Namespace)>,
1263
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1264 1265

    // Callback function for intercepting walks
1266
    callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>,
G
Garming Sam 已提交
1267 1268 1269
    // The intention is that the callback modifies this flag.
    // Once set, the resolver falls out of the walk, preserving the ribs.
    resolved: bool,
1270 1271
}

1272
#[derive(PartialEq)]
S
Steven Fackler 已提交
1273 1274
enum FallbackChecks {
    Everything,
C
corentih 已提交
1275
    OnlyTraitAndStatics,
S
Steven Fackler 已提交
1276 1277
}

1278 1279
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1280
           ast_map: &'a hir_map::Map<'tcx>,
1281
           crate_span: Span,
C
corentih 已提交
1282 1283
           make_glob_map: MakeGlobMap)
           -> Resolver<'a, 'tcx> {
K
Kevin Butler 已提交
1284 1285
        let graph_root = NameBindings::new();

1286
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
K
Kevin Butler 已提交
1287
        graph_root.define_module(NoParentLink,
1288
                                 Some(root_def_id),
K
Kevin Butler 已提交
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
                                 NormalModuleKind,
                                 false,
                                 true,
                                 crate_span);

        let current_module = graph_root.get_module();

        Resolver {
            session: session,

1299 1300
            ast_map: ast_map,

K
Kevin Butler 已提交
1301 1302 1303 1304
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
            graph_root: graph_root,

1305 1306
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1307 1308 1309 1310

            unresolved_imports: 0,

            current_module: current_module,
1311 1312 1313
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1314 1315 1316 1317 1318 1319

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1320
            def_map: RefCell::new(NodeMap()),
1321 1322
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1323 1324
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1325
            used_imports: HashSet::new(),
1326
            used_crates: HashSet::new(),
1327
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1328 1329

            emit_errors: true,
1330 1331
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
G
Garming Sam 已提交
1332 1333 1334

            callback: None,
            resolved: false,
K
Kevin Butler 已提交
1335 1336
        }
    }
1337

1338 1339 1340 1341 1342 1343
    #[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) {
1344
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1345 1346 1347 1348 1349 1350 1351 1352 1353
            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 {
1354 1355
        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
            self.ast_map.expect_item(node_id).name
1356 1357 1358 1359 1360
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

E
Eduard Burtescu 已提交
1361
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1362
        NameBindings {
1363
            type_def: RefCell::new(Some(TypeNsDef {
T
Fallout  
Tamir Duberstein 已提交
1364
                modifiers: DefModifiers::IMPORTABLE,
1365 1366
                module_def: Some(module),
                type_def: None,
C
corentih 已提交
1367
                type_span: None,
1368
            })),
1369
            value_def: RefCell::new(None),
1370 1371 1372
        }
    }

1373 1374 1375 1376 1377 1378 1379
    /// 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) {
C
corentih 已提交
1380 1381 1382 1383 1384
            span_err!(self.session,
                      span,
                      E0259,
                      "an external crate named `{}` has already been imported into this module",
                      name);
1385 1386 1387 1388 1389 1390 1391 1392 1393
        }
    }

    /// 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) {
C
corentih 已提交
1394 1395 1396 1397 1398 1399
            span_err!(self.session,
                      span,
                      E0260,
                      "the name `{}` conflicts with an external crate that has been imported \
                       into this module",
                      name);
1400
        }
1401 1402
    }

1403
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1404
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1405
                                     module_: Rc<Module>,
1406
                                     module_path: &[Name],
1407
                                     index: usize,
1408 1409 1410
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
C
corentih 已提交
1411 1412
                                     -> ResolveResult<(Rc<Module>, LastPrivate)> {
        fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Module>> {
1413 1414 1415 1416 1417
            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())
1418
                    }
C
corentih 已提交
1419 1420
                    _ => None,
                },
1421
            }
1422 1423
        }

1424
        let mut search_module = module_;
1425
        let mut index = index;
A
Alex Crichton 已提交
1426
        let module_path_len = module_path.len();
1427
        let mut closest_private = lp;
1428 1429 1430 1431 1432

        // 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 已提交
1433
            let name = module_path[index];
E
Eduard Burtescu 已提交
1434
            match self.resolve_name_in_module(search_module.clone(),
1435
                                              name,
1436
                                              TypeNS,
1437 1438
                                              name_search_type,
                                              false) {
1439
                Failed(None) => {
1440
                    let segment_name = name.as_str();
1441
                    let module_name = module_to_string(&*search_module);
1442
                    let mut span = span;
1443
                    let msg = if "???" == &module_name[..] {
1444
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1445

C
corentih 已提交
1446
                        match search_parent_externals(name, &self.current_module) {
1447
                            Some(module) => {
1448 1449
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
C
corentih 已提交
1450
                                let current_mod_str = module_to_string(&*self.current_module);
1451 1452 1453 1454 1455 1456 1457

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

1458
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1459 1460
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1461
                        }
1462
                    } else {
C
corentih 已提交
1463
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1464
                    };
1465

1466
                    return Failed(Some((span, msg)));
1467
                }
1468
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1469
                Indeterminate => {
C
corentih 已提交
1470 1471 1472
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1473
                    return Indeterminate;
1474
                }
1475
                Success((target, used_proxy)) => {
1476 1477
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
1478
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1479
                        Some(ref type_def) => {
1480 1481
                            match type_def.module_def {
                                None => {
C
corentih 已提交
1482
                                    let msg = format!("Not a module `{}`", name);
1483 1484

                                    return Failed(Some((span, msg)));
1485
                                }
E
Eduard Burtescu 已提交
1486
                                Some(ref module_def) => {
1487 1488 1489
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
1490 1491
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
1492
                                    }
1493

1494 1495 1496
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
1497 1498 1499
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
1500
                                        }
1501
                                    }
1502 1503 1504 1505 1506
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
C
corentih 已提交
1507
                            let msg = format!("Not a module `{}`", name);
1508
                            return Failed(Some((span, msg)));
1509 1510 1511 1512 1513
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
1514
            index += 1;
1515 1516
        }

1517
        return Success((search_module, closest_private));
1518 1519
    }

1520 1521
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1522 1523 1524
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1525
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
1526
                           module_: Rc<Module>,
1527
                           module_path: &[Name],
1528 1529 1530
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1531
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
1532
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1533
        assert!(module_path_len > 0);
1534

1535
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1536 1537
               names_to_string(module_path),
               module_to_string(&*module_));
1538

1539
        // Resolve the module prefix, if any.
C
corentih 已提交
1540
        let module_prefix_result = self.resolve_module_prefix(module_.clone(), module_path);
1541

1542 1543
        let search_module;
        let start_index;
1544
        let last_private;
1545
        match module_prefix_result {
1546
            Failed(None) => {
1547
                let mpath = names_to_string(module_path);
1548
                let mpath = &mpath[..];
1549
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1550
                    Some(idx) => {
1551
                        let msg = format!("Could not find `{}` in `{}`",
C
corentih 已提交
1552 1553 1554 1555
                                          // idx +- 1 to account for the
                                          // colons on either side
                                          &mpath[idx + 1..],
                                          &mpath[..idx - 1]);
1556
                        return Failed(Some((span, msg)));
C
corentih 已提交
1557
                    }
1558
                    None => {
C
corentih 已提交
1559
                        return Failed(None);
1560
                    }
1561
                }
1562
            }
1563
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1564
            Indeterminate => {
C
corentih 已提交
1565
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1566
                return Indeterminate;
1567
            }
1568 1569 1570 1571 1572 1573 1574 1575 1576 1577
            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;
1578
                        last_private = LastMod(AllPublic);
1579 1580 1581 1582 1583
                    }
                    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.
C
corentih 已提交
1584
                        match self.resolve_module_in_lexical_scope(module_, module_path[0]) {
1585
                            Failed(err) => return Failed(err),
1586
                            Indeterminate => {
C
corentih 已提交
1587
                                debug!("(resolving module path for import) indeterminate; bailing");
1588 1589 1590 1591 1592
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1593
                                last_private = LastMod(AllPublic);
1594 1595 1596 1597 1598
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1599 1600
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
1601
                start_index = index;
1602 1603 1604
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
1605 1606 1607
            }
        }

1608 1609 1610 1611
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1612 1613
                                           name_search_type,
                                           last_private)
1614 1615
    }

1616 1617
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1618
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1619
                                     module_: Rc<Module>,
1620
                                     name: Name,
1621
                                     namespace: Namespace)
C
corentih 已提交
1622 1623
                                     -> ResolveResult<(Target, bool)> {
        debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
1624
               name,
1625
               namespace,
1626
               module_to_string(&*module_));
1627 1628 1629

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

1632
        match module_.children.borrow().get(&name) {
C
corentih 已提交
1633
            Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => {
1634
                debug!("top name bindings succeeded");
1635 1636
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1637
                                            Shadowable::Never),
C
corentih 已提交
1638 1639 1640 1641
                                false));
            }
            Some(_) | None => {
                // Not found; continue.
1642 1643 1644 1645 1646 1647 1648
            }
        }

        // 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.
1649 1650 1651 1652
        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
            match (*import_resolution).target_for_namespace(namespace) {
                None => {
                    // Not found; continue.
C
corentih 已提交
1653 1654
                    debug!("(resolving item in lexical scope) found import resolution, but not \
                            in namespace {:?}",
1655 1656 1657
                           namespace);
                }
                Some(target) => {
C
corentih 已提交
1658
                    debug!("(resolving item in lexical scope) using import resolution");
1659
                    // track used imports and extern crates as well
1660 1661 1662
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
1663
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
C
corentih 已提交
1664
                        self.used_crates.insert(kid);
1665
                    }
1666
                    return Success((target, false));
1667 1668 1669 1670
                }
            }
        }

1671 1672
        // Search for external modules.
        if namespace == TypeNS {
1673 1674 1675
            // 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 {
C
corentih 已提交
1676
                let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module));
1677
                debug!("lower name bindings succeeded");
C
corentih 已提交
1678
                return Success((Target::new(module_, name_bindings, Shadowable::Never),
1679
                                false));
1680 1681 1682
            }
        }

1683
        // Finally, proceed up the scope chain looking for parent modules.
1684
        let mut search_module = module_;
1685 1686
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
1687
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
1688
                NoParentLink => {
1689
                    // No more parents. This module was unresolved.
C
corentih 已提交
1690
                    debug!("(resolving item in lexical scope) unresolved module");
1691
                    return Failed(None);
1692
                }
1693
                ModuleParentLink(parent_module_node, _) => {
1694 1695 1696
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
C
corentih 已提交
1697 1698
                            debug!("(resolving item in lexical scope) unresolved module: not \
                                    searching through module parents");
1699
                            return Failed(None);
1700
                        }
1701
                        TraitModuleKind |
1702
                        EnumModuleKind |
1703
                        TypeModuleKind |
1704
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1705
                            search_module = parent_module_node.upgrade().unwrap();
1706 1707 1708
                        }
                    }
                }
E
Eduard Burtescu 已提交
1709 1710
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
1711 1712 1713 1714
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
1715
            match self.resolve_name_in_module(search_module.clone(),
1716
                                              name,
1717
                                              namespace,
1718 1719
                                              PathSearch,
                                              true) {
1720
                Failed(Some((span, msg))) => {
1721
                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
C
corentih 已提交
1722
                }
1723
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1724
                Indeterminate => {
1725 1726 1727
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

C
corentih 已提交
1728
                    debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
B
Brian Anderson 已提交
1729
                    return Indeterminate;
1730
                }
1731
                Success((target, used_reexport)) => {
1732
                    // We found the module.
C
corentih 已提交
1733
                    debug!("(resolving item in lexical scope) found name in module, done");
1734
                    return Success((target, used_reexport));
1735 1736 1737 1738 1739
                }
            }
        }
    }

1740
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1741
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1742
                                       module_: Rc<Module>,
1743
                                       name: Name)
C
corentih 已提交
1744
                                       -> ResolveResult<Rc<Module>> {
1745 1746
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1747
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
1748
        match resolve_result {
1749
            Success((target, _)) => {
1750
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
1751
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1752
                    Some(ref type_def) => {
1753
                        match type_def.module_def {
1754
                            None => {
C
corentih 已提交
1755 1756
                                debug!("!!! (resolving module in lexical scope) module wasn't \
                                        actually a module!");
1757
                                return Failed(None);
1758
                            }
E
Eduard Burtescu 已提交
1759 1760
                            Some(ref module_def) => {
                                return Success(module_def.clone());
1761 1762 1763 1764
                            }
                        }
                    }
                    None => {
1765
                        debug!("!!! (resolving module in lexical scope) module
C
corentih 已提交
1766
                                \
P
Paul Stansifer 已提交
1767
                                wasn't actually a module!");
1768
                        return Failed(None);
1769 1770 1771
                    }
                }
            }
B
Brian Anderson 已提交
1772
            Indeterminate => {
C
corentih 已提交
1773
                debug!("(resolving module in lexical scope) indeterminate; bailing");
B
Brian Anderson 已提交
1774
                return Indeterminate;
1775
            }
1776 1777 1778
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1779 1780 1781 1782
            }
        }
    }

1783
    /// Returns the nearest normal module parent of the given module.
C
corentih 已提交
1784
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc<Module>> {
1785 1786
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
1787
            match module_.parent_link.clone() {
1788 1789 1790
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
1791
                    let new_module = new_module.upgrade().unwrap();
1792
                    match new_module.kind.get() {
1793 1794
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
1795
                        EnumModuleKind |
1796
                        TypeModuleKind |
1797 1798 1799 1800 1801 1802 1803
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

1804 1805
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
C
corentih 已提交
1806
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> Rc<Module> {
1807
        match module_.kind.get() {
1808
            NormalModuleKind => return module_,
1809
            TraitModuleKind |
1810
            EnumModuleKind |
1811
            TypeModuleKind |
1812
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1813
                match self.get_nearest_normal_module_parent(module_.clone()) {
1814
                    None => module_,
C
corentih 已提交
1815
                    Some(new_module) => new_module,
1816 1817 1818 1819 1820
                }
            }
        }
    }

1821
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1822
    /// (b) some chain of `super::`.
1823
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1824
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
1825
                             module_: Rc<Module>,
1826
                             module_path: &[Name])
C
corentih 已提交
1827
                             -> ResolveResult<ModulePrefixResult> {
1828 1829
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1830 1831 1832 1833 1834 1835
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1836 1837

        // Now loop through all the `super`s we find.
1838
        while i < module_path.len() && "super" == module_path[i].as_str() {
1839
            debug!("(resolving module prefix) resolving `super` at {}",
1840
                   module_to_string(&*containing_module));
1841
            match self.get_nearest_normal_module_parent(containing_module) {
1842
                None => return Failed(None),
1843 1844 1845
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1846 1847 1848 1849
                }
            }
        }

1850
        debug!("(resolving module prefix) finished resolving prefix at {}",
1851
               module_to_string(&*containing_module));
1852 1853

        return Success(PrefixFound(containing_module, i));
1854 1855
    }

1856 1857 1858
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1859 1860 1861
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1862
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
1863
                              module_: Rc<Module>,
1864
                              name: Name,
1865
                              namespace: Namespace,
1866 1867
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1868
                              -> ResolveResult<(Target, bool)> {
1869
        debug!("(resolving name in module) resolving `{}` in `{}`",
1870
               name,
1871
               module_to_string(&*module_));
1872 1873

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

1876
        match module_.children.borrow().get(&name) {
C
corentih 已提交
1877
            Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => {
1878
                debug!("(resolving name in module) found node as child");
1879 1880
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1881
                                            Shadowable::Never),
C
corentih 已提交
1882
                                false));
1883 1884 1885
            }
            Some(_) | None => {
                // Continue.
1886 1887 1888
            }
        }

1889 1890 1891 1892
        // 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.
1893
        if name_search_type == PathSearch {
1894
            assert_eq!(module_.glob_count.get(), 0);
1895 1896
        }

1897
        // Check the list of resolved imports.
1898
        match module_.import_resolutions.borrow().get(&name) {
C
corentih 已提交
1899
            Some(import_resolution) if allow_private_imports || import_resolution.is_public => {
1900

C
corentih 已提交
1901 1902
                if import_resolution.is_public && import_resolution.outstanding_references != 0 {
                    debug!("(resolving name in module) import unresolved; bailing out");
B
Brian Anderson 已提交
1903
                    return Indeterminate;
1904
                }
1905
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1906
                    None => {
C
corentih 已提交
1907
                        debug!("(resolving name in module) name found, but not in namespace {:?}",
P
Paul Stansifer 已提交
1908
                               namespace);
1909
                    }
1910
                    Some(target) => {
C
corentih 已提交
1911
                        debug!("(resolving name in module) resolved to import");
1912
                        // track used imports and extern crates as well
1913 1914 1915
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1916 1917
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
1918
                        }
1919
                        return Success((target, true));
1920
                    }
1921 1922
                }
            }
1923
            Some(..) | None => {} // Continue.
1924 1925 1926 1927
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1928 1929 1930
            // 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 {
C
corentih 已提交
1931 1932
                let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module));
                return Success((Target::new(module_, name_bindings, Shadowable::Never),
1933
                                false));
1934 1935 1936 1937
            }
        }

        // We're out of luck.
C
corentih 已提交
1938
        debug!("(resolving name in module) failed to resolve `{}`", name);
1939
        return Failed(None);
1940 1941
    }

E
Eduard Burtescu 已提交
1942
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
1943
        let index = module_.resolved_import_count.get();
1944 1945
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1946
        if index != import_count {
1947 1948 1949
            resolve_error(self,
                          (*imports)[index].span,
                          ResolutionError::UnresolvedImport(None));
1950 1951 1952
        }

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

1955
        for (_, child_node) in module_.children.borrow().iter() {
1956 1957 1958 1959 1960 1961
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1962 1963 1964 1965
                }
            }
        }

1966
        for (_, module_) in module_.anonymous_children.borrow().iter() {
E
Eduard Burtescu 已提交
1967
            self.report_unresolved_imports(module_.clone());
1968 1969 1970 1971 1972
        }
    }

    // AST resolution
    //
1973
    // We maintain a list of value ribs and type ribs.
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988
    //
    // 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.

C
corentih 已提交
1989 1990
    fn with_scope<F>(&mut self, name: Option<Name>, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1991
    {
E
Eduard Burtescu 已提交
1992
        let orig_module = self.current_module.clone();
1993 1994

        // Move down in the graph.
1995
        match name {
B
Brian Anderson 已提交
1996
            None => {
1997 1998
                // Nothing to do.
            }
B
Brian Anderson 已提交
1999
            Some(name) => {
2000
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
2001

2002
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
2003
                    None => {
2004
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
2005
                               name,
2006
                               module_to_string(&*orig_module));
2007
                    }
B
Brian Anderson 已提交
2008
                    Some(name_bindings) => {
2009
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
2010
                            None => {
C
corentih 已提交
2011
                                debug!("!!! (with scope) didn't find module for `{}` in `{}`",
2012
                                       name,
2013
                                       module_to_string(&*orig_module));
2014
                            }
B
Brian Anderson 已提交
2015
                            Some(module_) => {
2016
                                self.current_module = module_;
2017 2018 2019 2020 2021 2022 2023
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
2024
        f(self);
2025 2026 2027 2028

        self.current_module = orig_module;
    }

S
Seo Sanghyeon 已提交
2029 2030
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2031 2032 2033 2034 2035 2036 2037 2038
    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
C
corentih 已提交
2039
                    return None;
2040 2041 2042
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
2043
            if result.is_some() {
C
corentih 已提交
2044
                return result;
2045 2046 2047 2048 2049
            }
        }
        None
    }

2050
    fn resolve_crate(&mut self, krate: &hir::Crate) {
2051
        debug!("(resolving crate) starting");
2052

2053
        intravisit::walk_crate(self, krate);
2054 2055
    }

W
we 已提交
2056 2057
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
C
corentih 已提交
2058 2059 2060 2061
            span_err!(self.session,
                      span,
                      E0317,
                      "user-defined types or type parameters cannot shadow the primitive types");
W
we 已提交
2062 2063 2064
        }
    }

2065
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
2066
        let name = item.name;
2067

C
corentih 已提交
2068
        debug!("(resolving item) resolving {}", name);
2069

2070
        match item.node {
2071 2072 2073
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
2074 2075
                self.check_if_primitive_type_name(name, item.span);

C
corentih 已提交
2076
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
2077
                                             |this| intravisit::walk_item(this, item));
2078
            }
2079
            ItemFn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
2080
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
2081
                                             |this| intravisit::walk_item(this, item));
2082 2083
            }

F
Flavio Percoco 已提交
2084
            ItemDefaultImpl(_, ref trait_ref) => {
2085
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
2086
            }
C
corentih 已提交
2087
            ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
2088
                self.resolve_implementation(generics,
2089
                                            opt_trait_ref,
2090
                                            &**self_type,
2091
                                            item.id,
2092
                                            &impl_items[..]);
2093 2094
            }

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

2098 2099 2100 2101 2102
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
2103 2104
                    let local_def_id = this.ast_map.local_def_id(item.id);
                    this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
2105
                        this.visit_generics(generics);
2106
                        walk_list!(this, visit_ty_param_bound, bounds);
2107 2108

                        for trait_item in trait_items {
2109
                            match trait_item.node {
2110
                                hir::ConstTraitItem(_, ref default) => {
2111 2112 2113 2114 2115
                                    // Only impose the restrictions of
                                    // ConstRibKind if there's an actual constant
                                    // expression in a provided default.
                                    if default.is_some() {
                                        this.with_constant_rib(|this| {
2116
                                            intravisit::walk_trait_item(this, trait_item)
2117 2118
                                        });
                                    } else {
2119
                                        intravisit::walk_trait_item(this, trait_item)
2120 2121
                                    }
                                }
2122
                                hir::MethodTraitItem(ref sig, _) => {
2123 2124 2125 2126 2127
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
2128
                                        intravisit::walk_trait_item(this, trait_item)
2129
                                    });
2130
                                }
2131
                                hir::TypeTraitItem(..) => {
V
Vadim Petrochenkov 已提交
2132
                                    this.check_if_primitive_type_name(trait_item.name,
2133
                                                                      trait_item.span);
2134
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
2135
                                        intravisit::walk_trait_item(this, trait_item)
2136
                                    });
2137 2138 2139 2140
                                }
                            };
                        }
                    });
2141
                });
2142 2143
            }

2144
            ItemMod(_) | ItemForeignMod(_) => {
2145
                self.with_scope(Some(name), |this| {
2146
                    intravisit::walk_item(this, item);
2147
                });
2148 2149
            }

2150
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2151
                self.with_constant_rib(|this| {
2152
                    intravisit::walk_item(this, item);
2153
                });
2154
            }
2155

W
we 已提交
2156 2157
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
2158
                let check_rename = |this: &Self, id, name| {
2159
                    match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
2160
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
2161
                            this.check_if_primitive_type_name(name, item.span);
W
we 已提交
2162 2163 2164
                        }
                        _ => {}
                    }
2165 2166 2167
                };

                match view_path.node {
2168 2169
                    hir::ViewPathSimple(name, _) => {
                        check_rename(self, item.id, name);
2170
                    }
2171
                    hir::ViewPathList(ref prefix, ref items) => {
2172
                        for item in items {
2173 2174
                            if let Some(name) = item.node.rename() {
                                check_rename(self, item.node.id(), name);
2175 2176 2177 2178 2179 2180 2181 2182
                            }
                        }

                        // Resolve prefix of an import with empty braces (issue #28388)
                        if items.is_empty() && !prefix.segments.is_empty() {
                            match self.resolve_crate_relative_path(prefix.span,
                                                                   &prefix.segments,
                                                                   TypeNS) {
C
corentih 已提交
2183 2184
                                Some((def, lp)) =>
                                    self.record_def(item.id, PathResolution::new(def, lp, 0)),
2185 2186 2187 2188 2189 2190
                                None => {
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
                                }
2191 2192 2193 2194
                            }
                        }
                    }
                    _ => {}
W
we 已提交
2195 2196 2197
                }
            }

2198
            ItemExternCrate(_) => {
2199
                // do nothing, these are just around to be encoded
2200
            }
2201 2202 2203
        }
    }

C
corentih 已提交
2204 2205
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2206
    {
2207
        match type_parameters {
2208
            HasTypeParameters(generics, space, rib_kind) => {
2209
                let mut function_type_rib = Rib::new(rib_kind);
2210
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2211
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2212
                    let name = type_parameter.name;
2213
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2214

2215
                    if seen_bindings.contains(&name) {
2216 2217
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
2218
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
2219
                    }
2220
                    seen_bindings.insert(name);
2221

2222
                    // plain insert (no renaming)
C
corentih 已提交
2223 2224 2225 2226 2227 2228 2229
                    function_type_rib.bindings
                                     .insert(name,
                                             DlDef(DefTyParam(space,
                                                              index as u32,
                                                              self.ast_map
                                                                  .local_def_id(type_parameter.id),
                                                              name)));
2230
                }
2231
                self.type_ribs.push(function_type_rib);
2232 2233
            }

B
Brian Anderson 已提交
2234
            NoTypeParameters => {
2235 2236 2237 2238
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2239
        f(self);
2240

2241
        match type_parameters {
C
corentih 已提交
2242 2243 2244 2245 2246 2247
            HasTypeParameters(..) => {
                if !self.resolved {
                    self.type_ribs.pop();
                }
            }
            NoTypeParameters => {}
2248 2249 2250
        }
    }

C
corentih 已提交
2251 2252
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2253
    {
2254
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2255
        f(self);
G
Garming Sam 已提交
2256 2257 2258
        if !self.resolved {
            self.label_ribs.pop();
        }
2259
    }
2260

C
corentih 已提交
2261 2262
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2263
    {
2264 2265
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2266
        f(self);
G
Garming Sam 已提交
2267 2268 2269 2270
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
2271 2272
    }

C
corentih 已提交
2273
    fn resolve_function(&mut self, rib_kind: RibKind, declaration: &FnDecl, block: &Block) {
2274
        // Create a value rib for the function.
2275
        self.value_ribs.push(Rib::new(rib_kind));
2276

2277
        // Create a label rib for the function.
2278
        self.label_ribs.push(Rib::new(rib_kind));
2279

2280 2281 2282
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
C
corentih 已提交
2283
            self.resolve_pattern(&*argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
2284

2285
            self.visit_ty(&*argument.ty);
2286

2287 2288
            debug!("(resolving function) recorded argument");
        }
2289
        intravisit::walk_fn_ret_ty(self, &declaration.output);
2290

2291
        // Resolve the function body.
2292
        self.visit_block(block);
2293

2294
        debug!("(resolving function) leaving function");
2295

G
Garming Sam 已提交
2296 2297 2298 2299
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
2300 2301
    }

F
Felix S. Klock II 已提交
2302
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2303
                               id: NodeId,
2304
                               trait_path: &Path,
2305
                               path_depth: usize)
2306 2307 2308 2309 2310 2311
                               -> 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 {
2312 2313
                resolve_error(self,
                              trait_path.span,
2314
                              ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
C
corentih 已提交
2315
                                                                                  path_depth)));
2316 2317

                // If it's a typedef, give a note
2318
                if let DefTy(..) = path_res.base_def {
C
corentih 已提交
2319 2320
                    self.session
                        .span_note(trait_path.span, "`type` aliases cannot be used for traits");
2321
                }
2322 2323
                Err(())
            }
2324
        } else {
2325 2326
            resolve_error(self,
                          trait_path.span,
C
corentih 已提交
2327 2328
                          ResolutionError::UndeclaredTraitName(&*path_names_to_string(trait_path,
                                                                                      path_depth)));
2329
            Err(())
2330 2331 2332
        }
    }

2333
    fn resolve_generics(&mut self, generics: &Generics) {
2334
        for type_parameter in generics.ty_params.iter() {
2335
            self.check_if_primitive_type_name(type_parameter.name, type_parameter.span);
2336 2337
        }
        for predicate in &generics.where_clause.predicates {
2338
            match predicate {
2339 2340 2341
                &hir::WherePredicate::BoundPredicate(_) |
                &hir::WherePredicate::RegionPredicate(_) => {}
                &hir::WherePredicate::EqPredicate(ref eq_pred) => {
2342 2343 2344 2345
                    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 {
2346 2347
                        resolve_error(self,
                                      eq_pred.span,
2348
                                      ResolutionError::UndeclaredAssociatedType);
2349 2350
                    }
                }
2351 2352
            }
        }
2353
        intravisit::walk_generics(self, generics);
2354 2355
    }

2356 2357
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2358
    {
2359 2360 2361 2362 2363 2364 2365
        // 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
    }

C
corentih 已提交
2366
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2367
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2368
    {
2369
        let mut new_val = None;
2370
        let mut new_id = None;
E
Eduard Burtescu 已提交
2371
        if let Some(trait_ref) = opt_trait_ref {
2372
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
2373 2374
                                                               &trait_ref.path,
                                                               0) {
2375 2376 2377 2378
                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());
2379
            }
2380
            intravisit::walk_trait_ref(self, trait_ref);
2381
        }
2382
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2383
        let result = f(self, new_id);
2384 2385 2386 2387
        self.current_trait_ref = original_trait_ref;
        result
    }

2388 2389 2390 2391 2392 2393 2394 2395 2396 2397
    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);
G
Garming Sam 已提交
2398 2399 2400
        if !self.resolved {
            self.type_ribs.pop();
        }
2401 2402
    }

F
Felix S. Klock II 已提交
2403
    fn resolve_implementation(&mut self,
2404 2405 2406
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2407
                              item_id: NodeId,
2408
                              impl_items: &[P<ImplItem>]) {
2409
        // If applicable, create a rib for the type parameters.
2410
        self.with_type_parameter_rib(HasTypeParameters(generics,
2411
                                                       TypeSpace,
2412
                                                       ItemRibKind),
2413
                                     |this| {
2414
            // Resolve the type parameters.
2415
            this.visit_generics(generics);
2416

2417
            // Resolve the trait reference, if necessary.
2418
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2419
                // Resolve the self type.
2420
                this.visit_ty(self_type);
2421

2422 2423 2424 2425
                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 {
2426
                                hir::ImplItemKind::Const(..) => {
2427
                                    // If this is a trait impl, ensure the const
2428
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2429
                                    this.check_trait_item(impl_item.name,
2430 2431
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2432
                                    this.with_constant_rib(|this| {
2433
                                        intravisit::walk_impl_item(this, impl_item);
2434 2435
                                    });
                                }
2436
                                hir::ImplItemKind::Method(ref sig, _) => {
2437 2438
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2439
                                    this.check_trait_item(impl_item.name,
2440 2441
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
2442 2443 2444 2445 2446 2447 2448 2449

                                    // 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| {
2450
                                        intravisit::walk_impl_item(this, impl_item);
2451 2452
                                    });
                                }
2453
                                hir::ImplItemKind::Type(ref ty) => {
2454
                                    // If this is a trait impl, ensure the type
2455
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2456
                                    this.check_trait_item(impl_item.name,
2457 2458
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2459

2460 2461
                                    this.visit_ty(ty);
                                }
2462
                            }
2463
                        }
2464
                    });
2465 2466
                });
            });
2467
        });
2468 2469
    }

2470
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
2471 2472 2473 2474
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2475
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2476
            if !self.trait_item_map.contains_key(&(name, did)) {
2477
                let path_str = path_names_to_string(&trait_ref.path, 0);
C
corentih 已提交
2478
                resolve_error(self, span, err(name, &*path_str));
2479 2480 2481 2482
            }
        }
    }

E
Eduard Burtescu 已提交
2483
    fn resolve_local(&mut self, local: &Local) {
2484
        // Resolve the type.
2485
        walk_list!(self, visit_ty, &local.ty);
2486

2487
        // Resolve the initializer.
2488
        walk_list!(self, visit_expr, &local.init);
2489 2490

        // Resolve the pattern.
C
corentih 已提交
2491
        self.resolve_pattern(&*local.pat, LocalIrrefutableMode, &mut HashMap::new());
2492 2493
    }

J
John Clements 已提交
2494 2495 2496 2497
    // 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 已提交
2498
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2499
        let mut result = HashMap::new();
2500
        pat_bindings_hygienic(&self.def_map, pat, |binding_mode, _id, sp, path1| {
2501
            let name = mtwt::resolve(path1.node);
C
corentih 已提交
2502 2503 2504 2505 2506
            result.insert(name,
                          BindingInfo {
                              span: sp,
                              binding_mode: binding_mode,
                          });
2507
        });
2508
        return result;
2509 2510
    }

J
John Clements 已提交
2511 2512
    // 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 已提交
2513
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2514
        if arm.pats.is_empty() {
C
corentih 已提交
2515
            return;
2516
        }
2517
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2518
        for (i, p) in arm.pats.iter().enumerate() {
2519
            let map_i = self.binding_mode_map(&**p);
2520

2521
            for (&key, &binding_0) in &map_0 {
2522
                match map_i.get(&key) {
C
corentih 已提交
2523
                    None => {
2524
                        resolve_error(self,
C
corentih 已提交
2525 2526 2527 2528 2529 2530 2531 2532 2533 2534
                                      p.span,
                                      ResolutionError::VariableNotBoundInPattern(key, i + 1));
                    }
                    Some(binding_i) => {
                        if binding_0.binding_mode != binding_i.binding_mode {
                            resolve_error(self,
                                          binding_i.span,
                                          ResolutionError::VariableBoundWithDifferentMode(key,
                                                                                          i + 1));
                        }
2535
                    }
2536 2537 2538
                }
            }

2539
            for (&key, &binding) in &map_i {
2540
                if !map_0.contains_key(&key) {
2541 2542
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2543
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2544 2545 2546
                }
            }
        }
2547 2548
    }

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

2552
        let mut bindings_list = HashMap::new();
2553
        for pattern in &arm.pats {
2554
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2555 2556
        }

2557 2558 2559 2560
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2561
        walk_list!(self, visit_expr, &arm.guard);
2562
        self.visit_expr(&*arm.body);
2563

G
Garming Sam 已提交
2564 2565 2566
        if !self.resolved {
            self.value_ribs.pop();
        }
2567 2568
    }

E
Eduard Burtescu 已提交
2569
    fn resolve_block(&mut self, block: &Block) {
2570
        debug!("(resolving block) entering block");
2571
        self.value_ribs.push(Rib::new(NormalRibKind));
2572 2573

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
2574
        let orig_module = self.current_module.clone();
2575
        match orig_module.anonymous_children.borrow().get(&block.id) {
C
corentih 已提交
2576 2577 2578
            None => {
                // Nothing to do.
            }
E
Eduard Burtescu 已提交
2579
            Some(anonymous_module) => {
C
corentih 已提交
2580
                debug!("(resolving block) found anonymous module, moving down");
E
Eduard Burtescu 已提交
2581
                self.current_module = anonymous_module.clone();
2582 2583 2584
            }
        }

2585 2586
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2587
        for statement in &block.stmts {
2588
            if let hir::StmtDecl(ref declaration, _) = statement.node {
2589 2590
                if let hir::DeclItem(i) = declaration.node {
                    let i = self.ast_map.expect_item(i.id);
2591 2592
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
C
corentih 已提交
2593 2594 2595 2596
                            span_err!(self.session,
                                      i.span,
                                      E0154,
                                      "imports are not allowed after non-item statements");
2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

2608
        // Descend into the block.
2609
        intravisit::walk_block(self, block);
2610 2611

        // Move back up.
G
Garming Sam 已提交
2612
        if !self.resolved {
2613
            self.current_module = orig_module;
G
Garming Sam 已提交
2614 2615
            self.value_ribs.pop();
        }
2616
        debug!("(resolving block) leaving block");
2617 2618
    }

F
Felix S. Klock II 已提交
2619
    fn resolve_type(&mut self, ty: &Ty) {
2620
        match ty.node {
2621
            TyPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2622 2623 2624 2625 2626 2627 2628 2629
                let resolution = match self.resolve_possibly_assoc_item(ty.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
                                                                        TypeNS,
                                                                        true) {
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        // Resolve embedded types.
2630
                        intravisit::walk_ty(self, ty);
C
corentih 已提交
2631 2632 2633 2634
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2635 2636

                // This is a path in the type namespace. Walk through scopes
2637
                // looking for it.
2638
                match resolution {
B
Brian Anderson 已提交
2639
                    Some(def) => {
2640
                        // Write the result into the def map.
C
corentih 已提交
2641
                        debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2642
                               path_names_to_string(path, 0),
C
corentih 已提交
2643 2644
                               ty.id,
                               def);
2645
                        self.record_def(ty.id, def);
2646
                    }
B
Brian Anderson 已提交
2647
                    None => {
2648 2649 2650
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2651 2652 2653 2654
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2655
                        };
2656

2657
                        let self_type_name = special_idents::type_self.name;
C
corentih 已提交
2658 2659 2660 2661
                        let is_invalid_self_type_name = path.segments.len() > 0 &&
                                                        maybe_qself.is_none() &&
                                                        path.segments[0].identifier.name ==
                                                        self_type_name;
G
Guillaume Gomez 已提交
2662
                        if is_invalid_self_type_name {
2663 2664
                            resolve_error(self,
                                          ty.span,
2665
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2666
                        } else {
2667 2668
                            resolve_error(self,
                                          ty.span,
2669
                                          ResolutionError::UseOfUndeclared(
2670 2671 2672 2673
                                                                    kind,
                                                                    &*path_names_to_string(path,
                                                                                           0))
                                         );
G
Guillaume Gomez 已提交
2674
                        }
2675 2676
                    }
                }
2677
            }
2678
            _ => {}
2679
        }
2680
        // Resolve embedded types.
2681
        intravisit::walk_ty(self, ty);
2682 2683
    }

F
Felix S. Klock II 已提交
2684
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2685
                       pattern: &Pat,
2686 2687 2688
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2689
                       bindings_list: &mut HashMap<Name, NodeId>) {
2690
        let pat_id = pattern.id;
2691
        walk_pat(pattern, |pattern| {
2692
            match pattern.node {
2693 2694
                PatIdent(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatIdent with no type parameters
2695 2696 2697 2698
                    // 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
2699 2700 2701 2702
                    // unit-like structs. For binding patterns (let
                    // and the LHS of @-patterns), matching such a value is
                    // simply disallowed (since it's rarely what you want).
                    let const_ok = mode == RefutableMode && at_rhs.is_none();
2703

2704
                    let ident = path1.node;
2705
                    let renamed = mtwt::resolve(ident);
2706

2707
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
2708
                        FoundStructOrEnumVariant(def, lp) if const_ok => {
C
corentih 已提交
2709
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2710
                                   renamed);
2711

C
corentih 已提交
2712 2713 2714 2715 2716 2717 2718 2719 2720
                            self.enforce_default_binding_mode(pattern,
                                                              binding_mode,
                                                              "an enum variant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: lp,
                                                depth: 0,
                                            });
2721
                        }
A
Alex Crichton 已提交
2722
                        FoundStructOrEnumVariant(..) => {
2723
                            resolve_error(
2724
                                self,
2725
                                pattern.span,
2726
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2727 2728
                                    renamed)
                            );
2729
                        }
2730
                        FoundConst(def, lp, _) if const_ok => {
C
corentih 已提交
2731 2732 2733 2734 2735 2736 2737 2738 2739
                            debug!("(resolving pattern) resolving `{}` to constant", renamed);

                            self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: lp,
                                                depth: 0,
                                            });
2740
                        }
2741
                        FoundConst(def, _, name) => {
2742
                            resolve_error(
2743 2744
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2745 2746
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2747
                            );
2748
                        }
2749
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2750
                            debug!("(resolving pattern) binding `{}`", renamed);
2751

2752 2753
                            let def_id = self.ast_map.local_def_id(pattern.id);
                            let def = DefLocal(def_id, pattern.id);
2754 2755 2756 2757 2758

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

C
corentih 已提交
2759 2760 2761 2762 2763 2764
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: LastMod(AllPublic),
                                                depth: 0,
                                            });
2765 2766 2767 2768 2769 2770

                            // 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.)
2771 2772
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2773 2774
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2775
                                bindings_list.insert(renamed, pat_id);
2776
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2777
                               bindings_list.contains_key(&renamed) {
2778 2779
                                // Forbid duplicate bindings in the same
                                // parameter list.
2780
                                resolve_error(
2781 2782
                                    self,
                                    pattern.span,
2783
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2784
                                        &ident.name.as_str())
2785
                                );
C
corentih 已提交
2786
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2787 2788
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2789
                                resolve_error(
2790 2791
                                    self,
                                    pattern.span,
2792
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2793
                                        &ident.name.as_str())
2794
                                );
2795
                            }
2796 2797
                            // Else, not bound in the same pattern: do
                            // nothing.
2798 2799 2800 2801
                        }
                    }
                }

2802
                PatEnum(ref path, _) => {
2803
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            None,
                                                                            path,
                                                                            ValueNS,
                                                                            false) {
                        // The below shouldn't happen because all
                        // qualified paths should be in PatQPath.
                        TypecheckRequired =>
                            self.session.span_bug(path.span,
                                                  "resolve_possibly_assoc_item claimed
                                     \
                                                   that a path in PatEnum requires typecheck
                                     \
                                                   to resolve, but qualified paths should be
                                     \
                                                   PatQPath"),
                        ResolveAttempt(resolution) => resolution,
                    };
2822
                    if let Some(path_res) = resolution {
2823
                        match path_res.base_def {
2824
                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
2825 2826 2827
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
2828 2829
                                resolve_error(&self,
                                              path.span,
2830
                                              ResolutionError::StaticVariableReference);
2831
                            }
2832 2833 2834 2835
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2836
                                // be a `T::CONST` that typeck will resolve.
2837
                                if path_res.depth == 0 {
2838
                                    resolve_error(
2839
                                        self,
2840
                                        path.span,
2841
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2842 2843 2844 2845 2846 2847
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2848
                                    );
2849
                                } else {
C
corentih 已提交
2850 2851 2852 2853 2854
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2855 2856
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2857 2858 2859 2860 2861
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2862
                        resolve_error(
2863 2864
                            self,
                            path.span,
2865
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2866
                                &path.segments.last().unwrap().identifier.name.as_str())
2867
                        );
2868
                    }
2869
                    intravisit::walk_path(self, path);
2870 2871 2872 2873
                }

                PatQPath(ref qself, ref path) => {
                    // Associated constants only.
C
corentih 已提交
2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            Some(qself),
                                                                            path,
                                                                            ValueNS,
                                                                            false) {
                        TypecheckRequired => {
                            // All `<T>::CONST` should end up here, and will
                            // require use of the trait map to resolve
                            // during typechecking.
                            let const_name = path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name;
                            let traits = self.get_traits_containing_item(const_name);
                            self.trait_map.insert(pattern.id, traits);
2890
                            intravisit::walk_pat(self, pattern);
C
corentih 已提交
2891 2892 2893 2894
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2895 2896 2897 2898 2899 2900 2901
                    if let Some(path_res) = resolution {
                        match path_res.base_def {
                            // All `<T as Trait>::CONST` should end up here, and
                            // have the trait already selected.
                            DefAssociatedConst(..) => {
                                self.record_def(pattern.id, path_res);
                            }
2902
                            _ => {
2903
                                resolve_error(
2904 2905
                                    self,
                                    path.span,
2906
                                    ResolutionError::NotAnAssociatedConst(
2907
                                        &path.segments.last().unwrap().identifier.name.as_str()
2908 2909
                                    )
                                );
2910
                            }
2911
                        }
2912
                    } else {
C
corentih 已提交
2913 2914 2915 2916 2917 2918 2919 2920
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2921
                    }
2922
                    intravisit::walk_pat(self, pattern);
2923 2924
                }

2925
                PatStruct(ref path, _, _) => {
2926
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2927
                        Some(definition) => {
2928 2929
                            self.record_def(pattern.id, definition);
                        }
2930
                        result => {
C
corentih 已提交
2931
                            debug!("(resolving pattern) didn't find struct def: {:?}", result);
2932 2933 2934
                            resolve_error(
                                self,
                                path.span,
2935
                                ResolutionError::DoesNotNameAStruct(
2936 2937
                                    &*path_names_to_string(path, 0))
                            );
2938 2939
                        }
                    }
2940
                    intravisit::walk_path(self, path);
2941 2942 2943
                }

                PatLit(_) | PatRange(..) => {
2944
                    intravisit::walk_pat(self, pattern);
2945 2946
                }

2947
                _ => {
2948 2949 2950
                    // Nothing to do.
                }
            }
2951
            true
2952
        });
2953 2954
    }

C
corentih 已提交
2955 2956 2957
    fn resolve_bare_identifier_pattern(&mut self,
                                       name: Name,
                                       span: Span)
E
Eduard Burtescu 已提交
2958 2959
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
C
corentih 已提交
2960
        match self.resolve_item_in_lexical_scope(module, name, ValueNS) {
2961
            Success((target, _)) => {
C
corentih 已提交
2962 2963 2964
                debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
                       name,
                       target.bindings.value_def.borrow());
E
Erick Tryzelaar 已提交
2965
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
2966
                    None => {
C
corentih 已提交
2967 2968
                        panic!("resolved name in the value namespace to a set of name bindings \
                                with no def?!");
2969
                    }
B
Brian Anderson 已提交
2970
                    Some(def) => {
2971 2972 2973
                        // 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.
2974
                        match def.def {
A
Alex Crichton 已提交
2975
                            def @ DefVariant(..) | def @ DefStruct(..) => {
2976
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
2977
                            }
2978
                            def @ DefConst(..) | def @ DefAssociatedConst(..) => {
2979
                                return FoundConst(def, LastMod(AllPublic), name);
2980
                            }
2981
                            DefStatic(..) => {
C
corentih 已提交
2982
                                resolve_error(self, span, ResolutionError::StaticVariableReference);
2983 2984
                                return BareIdentifierPatternUnresolved;
                            }
2985
                            _ => {
2986
                                return BareIdentifierPatternUnresolved;
2987 2988
                            }
                        }
2989 2990 2991 2992
                    }
                }
            }

B
Brian Anderson 已提交
2993
            Indeterminate => {
S
Steve Klabnik 已提交
2994
                panic!("unexpected indeterminate result");
2995
            }
2996 2997 2998
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
2999
                        resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3000
                    }
C
corentih 已提交
3001
                    None => (),
3002
                }
3003

C
corentih 已提交
3004
                debug!("(resolve bare identifier pattern) failed to find {}", name);
3005
                return BareIdentifierPatternUnresolved;
3006 3007 3008 3009
            }
        }
    }

3010 3011 3012
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
3013
                                   maybe_qself: Option<&hir::QSelf>,
3014 3015 3016
                                   path: &Path,
                                   namespace: Namespace,
                                   check_ribs: bool)
C
corentih 已提交
3017
                                   -> AssocItemResolveResult {
3018 3019
        let max_assoc_types;

3020
        match maybe_qself {
3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031
            Some(qself) => {
                if qself.position == 0 {
                    return TypecheckRequired;
                }
                max_assoc_types = path.segments.len() - qself.position;
                // Make sure the trait is valid.
                let _ = self.resolve_trait_reference(id, path, max_assoc_types);
            }
            None => {
                max_assoc_types = path.segments.len();
            }
3032 3033 3034 3035 3036 3037 3038 3039 3040 3041
        }

        let mut resolution = self.with_no_errors(|this| {
            this.resolve_path(id, path, 0, namespace, check_ribs)
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
C
corentih 已提交
3042
                resolution = this.resolve_path(id, path, depth, TypeNS, true);
3043 3044 3045 3046 3047 3048 3049 3050 3051
            });
        }
        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

3052 3053
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
3054 3055
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
G
Garming Sam 已提交
3056 3057 3058 3059 3060
    pub fn resolve_path(&mut self,
                        id: NodeId,
                        path: &Path,
                        path_depth: usize,
                        namespace: Namespace,
C
corentih 已提交
3061 3062
                        check_ribs: bool)
                        -> Option<PathResolution> {
3063
        let span = path.span;
C
corentih 已提交
3064
        let segments = &path.segments[..path.segments.len() - path_depth];
3065

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

3068
        if path.global {
3069
            let def = self.resolve_crate_relative_path(span, segments, namespace);
3070
            return def.map(mk_res);
3071 3072
        }

3073
        // Try to find a path to an item in a module.
C
corentih 已提交
3074 3075 3076
        let unqualified_def = self.resolve_identifier(segments.last().unwrap().identifier,
                                                      namespace,
                                                      check_ribs);
3077

N
Nick Cameron 已提交
3078
        if segments.len() <= 1 {
C
corentih 已提交
3079 3080 3081 3082
            return unqualified_def.and_then(|def| self.adjust_local_def(def, span))
                                  .map(|def| {
                                      PathResolution::new(def, LastMod(AllPublic), path_depth)
                                  });
N
Nick Cameron 已提交
3083
        }
3084

N
Nick Cameron 已提交
3085 3086
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
3087
            (Some((ref d, _)), Some(ref ud)) if *d == ud.def => {
N
Nick Cameron 已提交
3088 3089
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
3090 3091
                              id,
                              span,
N
Nick Cameron 已提交
3092 3093 3094
                              "unnecessary qualification".to_string());
            }
            _ => {}
3095
        }
N
Nick Cameron 已提交
3096 3097

        def.map(mk_res)
3098 3099
    }

3100
    // Resolve a single identifier
F
Felix S. Klock II 已提交
3101
    fn resolve_identifier(&mut self,
3102 3103
                          identifier: Ident,
                          namespace: Namespace,
3104 3105
                          check_ribs: bool)
                          -> Option<LocalDef> {
3106 3107 3108 3109 3110
        // 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) {
3111
                return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
3112 3113 3114
            }
        }

3115
        if check_ribs {
C
corentih 已提交
3116
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, namespace) {
3117
                return Some(def);
3118 3119 3120
            }
        }

3121
        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
3122 3123 3124 3125
            .map(LocalDef::from_def)
    }

    // Resolve a local definition, potentially adjusting for closures.
3126
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
3127
        let ribs = match local_def.ribs {
C
corentih 已提交
3128 3129 3130
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
3131 3132 3133 3134
        };
        let mut def = local_def.def;
        match def {
            DefUpvar(..) => {
C
corentih 已提交
3135
                self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146
            }
            DefLocal(_, node_id) => {
                for rib in ribs {
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;
                            let node_def_id = self.ast_map.local_def_id(node_id);

C
corentih 已提交
3147 3148 3149
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
3150 3151 3152 3153
                            if let Some(&index) = seen.get(&node_id) {
                                def = DefUpvar(node_def_id, node_id, index, function_id);
                                continue;
                            }
C
corentih 已提交
3154 3155 3156
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
3157
                            let depth = vec.len();
C
corentih 已提交
3158 3159 3160 3161
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
3162 3163 3164 3165 3166 3167 3168 3169

                            def = DefUpvar(node_def_id, node_id, depth, function_id);
                            seen.insert(node_id, depth);
                        }
                        ItemRibKind | MethodRibKind => {
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
C
corentih 已提交
3170 3171 3172
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
3173 3174 3175 3176
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
3177 3178 3179
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210
                            return None;
                        }
                    }
                }
            }
            DefTyParam(..) | DefSelfTy(..) => {
                for rib in ribs {
                    match rib.kind {
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.

                            resolve_error(self,
                                          span,
                                          ResolutionError::TypeParametersFromOuterFunction);
                            return None;
                        }
                        ConstantItemRibKind => {
                            // see #9186
                            resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
                            return None;
                        }
                    }
                }
            }
            _ => {}
        }
        return Some(def);
3211 3212
    }

3213
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3214
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3215
                                            containing_module: Rc<Module>,
3216
                                            name: Name,
3217
                                            namespace: Namespace)
3218
                                            -> NameDefinition {
3219
        // First, search children.
3220
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3221

3222
        match containing_module.children.borrow().get(&name) {
3223 3224 3225 3226
            Some(child_name_bindings) => {
                match child_name_bindings.def_for_namespace(namespace) {
                    Some(def) => {
                        // Found it. Stop the search here.
N
Nick Cameron 已提交
3227
                        let p = child_name_bindings.defined_in_public_namespace(namespace);
C
corentih 已提交
3228 3229 3230
                        let lp = if p {
                            LastMod(AllPublic)
                        } else {
3231
                            LastMod(DependsOn(def.def_id()))
3232 3233
                        };
                        return ChildNameDefinition(def, lp);
3234
                    }
3235
                    None => {}
3236 3237
                }
            }
3238
            None => {}
3239 3240 3241
        }

        // Next, search import resolutions.
3242
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3243
            Some(import_resolution) if import_resolution.is_public => {
3244 3245 3246 3247 3248 3249 3250
                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));
3251
                            self.record_import_use(id, name);
3252 3253 3254
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
C
corentih 已提交
3255
                                }
3256
                                _ => {}
3257
                            }
3258 3259 3260 3261 3262
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
3263 3264 3265 3266
                        }
                    }
                }
            }
A
Alex Crichton 已提交
3267
            Some(..) | None => {} // Continue.
3268 3269 3270 3271
        }

        // Finally, search through external children.
        if namespace == TypeNS {
C
corentih 已提交
3272 3273 3274 3275
            if let Some(module) = containing_module.external_module_children
                                                   .borrow()
                                                   .get(&name)
                                                   .cloned() {
3276 3277 3278
                if let Some(def_id) = module.def_id.get() {
                    // track used crates
                    self.used_crates.insert(def_id.krate);
C
corentih 已提交
3279 3280 3281
                    let lp = if module.is_public {
                        LastMod(AllPublic)
                    } else {
3282 3283 3284
                        LastMod(DependsOn(def_id))
                    };
                    return ChildNameDefinition(DefMod(def_id), lp);
3285
                }
3286 3287
            }
        }
3288 3289

        return NoNameDefinition;
3290 3291
    }

3292
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3293
    fn resolve_module_relative_path(&mut self,
3294
                                    span: Span,
3295
                                    segments: &[hir::PathSegment],
3296 3297
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
C
corentih 已提交
3298 3299 3300 3301 3302 3303
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3304

3305
        let containing_module;
3306
        let last_private;
N
Nick Cameron 已提交
3307 3308
        let current_module = self.current_module.clone();
        match self.resolve_module_path(current_module,
3309
                                       &module_path[..],
3310
                                       UseLexicalScope,
3311
                                       span,
3312
                                       PathSearch) {
3313 3314 3315 3316
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3317
                        let msg = format!("Use of undeclared type or module `{}`",
3318
                                          names_to_string(&module_path));
3319
                        (span, msg)
3320 3321
                    }
                };
3322

3323
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3324
                return None;
3325
            }
S
Steve Klabnik 已提交
3326
            Indeterminate => panic!("indeterminate unexpected"),
3327
            Success((resulting_module, resulting_last_private)) => {
3328
                containing_module = resulting_module;
3329
                last_private = resulting_last_private;
3330 3331 3332
            }
        }

3333
        let name = segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
3334
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
3335
                                                                  name,
3336
                                                                  namespace) {
B
Brian Anderson 已提交
3337
            NoNameDefinition => {
3338
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3339
                return None;
3340
            }
3341 3342
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
3343
            }
3344
        };
3345 3346
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
3347
        }
3348
        return Some(def);
3349 3350
    }

3351 3352
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3353
    fn resolve_crate_relative_path(&mut self,
3354
                                   span: Span,
3355
                                   segments: &[hir::PathSegment],
3356
                                   namespace: Namespace)
C
corentih 已提交
3357 3358 3359 3360 3361 3362 3363
                                   -> Option<(Def, LastPrivate)> {
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3364

3365
        let root_module = self.graph_root.get_module();
3366

3367
        let containing_module;
3368
        let last_private;
3369
        match self.resolve_module_path_from_root(root_module,
3370
                                                 &module_path[..],
3371
                                                 0,
3372
                                                 span,
3373
                                                 PathSearch,
3374
                                                 LastMod(AllPublic)) {
3375 3376 3377 3378 3379
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3380
                                          names_to_string(&module_path[..]));
3381
                        (span, msg)
3382 3383 3384
                    }
                };

3385
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
B
Brian Anderson 已提交
3386
                return None;
3387 3388
            }

B
Brian Anderson 已提交
3389
            Indeterminate => {
S
Steve Klabnik 已提交
3390
                panic!("indeterminate unexpected");
3391 3392
            }

3393
            Success((resulting_module, resulting_last_private)) => {
3394
                containing_module = resulting_module;
3395
                last_private = resulting_last_private;
3396 3397 3398
            }
        }

3399
        let name = segments.last().unwrap().identifier.name;
C
corentih 已提交
3400
        match self.resolve_definition_of_name_in_module(containing_module, name, namespace) {
B
Brian Anderson 已提交
3401
            NoNameDefinition => {
3402
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3403
                return None;
3404
            }
3405 3406
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
3407 3408 3409 3410
            }
        }
    }

F
Felix S. Klock II 已提交
3411
    fn resolve_identifier_in_local_ribs(&mut self,
3412
                                        ident: Ident,
3413 3414
                                        namespace: Namespace)
                                        -> Option<LocalDef> {
3415
        // Check the local set of ribs.
3416 3417
        let (name, ribs) = match namespace {
            ValueNS => (mtwt::resolve(ident), &self.value_ribs),
C
corentih 已提交
3418
            TypeNS => (ident.name, &self.type_ribs),
3419
        };
3420

3421 3422 3423 3424 3425
        for (i, rib) in ribs.iter().enumerate().rev() {
            if let Some(def_like) = rib.bindings.get(&name).cloned() {
                match def_like {
                    DlDef(def) => {
                        debug!("(resolving path in local ribs) resolved `{}` to {:?} at {}",
C
corentih 已提交
3426 3427 3428
                               name,
                               def,
                               i);
3429 3430
                        return Some(LocalDef {
                            ribs: Some((namespace, i)),
C
corentih 已提交
3431
                            def: def,
3432 3433 3434 3435
                        });
                    }
                    def_like => {
                        debug!("(resolving path in local ribs) resolved `{}` to pseudo-def {:?}",
C
corentih 已提交
3436 3437
                               name,
                               def_like);
3438 3439 3440
                        return None;
                    }
                }
3441 3442
            }
        }
3443 3444

        None
3445 3446
    }

3447 3448 3449
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
C
corentih 已提交
3450
                                             -> Option<Def> {
3451
        // Check the items.
E
Eduard Burtescu 已提交
3452
        let module = self.current_module.clone();
C
corentih 已提交
3453
        match self.resolve_item_in_lexical_scope(module, name, namespace) {
3454
            Success((target, _)) => {
3455
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
3456
                    None => {
3457 3458
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
C
corentih 已提交
3459 3460 3461
                        debug!("(resolving item path by identifier in lexical scope) failed to \
                                resolve {} after success...",
                               name);
3462
                        None
3463
                    }
B
Brian Anderson 已提交
3464
                    Some(def) => {
C
corentih 已提交
3465
                        debug!("(resolving item path in lexical scope) resolved `{}` to item",
3466
                               name);
3467 3468 3469
                        // 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.
3470
                        Some(def)
3471 3472 3473
                    }
                }
            }
B
Brian Anderson 已提交
3474
            Indeterminate => {
S
Steve Klabnik 已提交
3475
                panic!("unexpected indeterminate result");
3476
            }
3477
            Failed(err) => {
C
corentih 已提交
3478 3479
                debug!("(resolving item path by identifier in lexical scope) failed to resolve {}",
                       name);
N
Nick Cameron 已提交
3480 3481

                if let Some((span, msg)) = err {
3482
                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg))
N
Nick Cameron 已提交
3483 3484
                }

3485
                None
3486 3487 3488 3489
            }
        }
    }

C
corentih 已提交
3490 3491
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
3492
    {
3493
        self.emit_errors = false;
A
Alex Crichton 已提交
3494
        let rs = f(self);
3495 3496 3497 3498
        self.emit_errors = true;
        rs
    }

3499
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
C
corentih 已提交
3500 3501 3502
        fn extract_path_and_node_id(t: &Ty,
                                    allow: FallbackChecks)
                                    -> Option<(Path, NodeId, FallbackChecks)> {
3503
            match t.node {
3504
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3505 3506
                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),
3507 3508 3509 3510 3511 3512 3513
                // 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,
            }
        }

C
corentih 已提交
3514 3515 3516 3517
        fn get_module(this: &mut Resolver,
                      span: Span,
                      name_path: &[ast::Name])
                      -> Option<Rc<Module>> {
3518
            let root = this.current_module.clone();
3519
            let last_name = name_path.last().unwrap();
3520

3521
            if name_path.len() == 1 {
3522
                match this.primitive_type_table.primitive_types.get(last_name) {
3523 3524
                    Some(_) => None,
                    None => {
3525
                        match this.current_module.children.borrow().get(last_name) {
3526
                            Some(child) => child.get_module_if_available(),
C
corentih 已提交
3527
                            None => None,
3528 3529 3530 3531 3532
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
3533 3534 3535 3536
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
3537
                    Success((module, _)) => Some(module),
C
corentih 已提交
3538
                    _ => None,
3539 3540 3541 3542
                }
            }
        }

3543
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
3544 3545
            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
                let sig = match this.ast_map.get(node_id) {
3546 3547
                    hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                        hir::MethodTraitItem(ref sig, _) => sig,
C
corentih 已提交
3548
                        _ => return false,
3549
                    },
3550
                    hir_map::NodeImplItem(impl_item) => match impl_item.node {
3551
                        hir::ImplItemKind::Method(ref sig, _) => sig,
C
corentih 已提交
3552
                        _ => return false,
3553
                    },
C
corentih 已提交
3554
                    _ => return false,
3555
                };
3556
                sig.explicit_self.node == hir::SelfStatic
3557 3558 3559 3560 3561
            } else {
                csearch::is_static_method(&this.session.cstore, did)
            }
        }

3562 3563 3564 3565
        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,
3566 3567 3568 3569
            },
            None => return NoSuggestion,
        };

3570 3571
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3572 3573 3574 3575
            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) {
3576 3577 3578 3579 3580
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3581
                    }
3582 3583 3584
                },
                _ => {} // Self type didn't resolve properly
            }
3585 3586
        }

3587
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3588 3589

        // Look for a method in the current self type's impl module.
3590 3591
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
3592
                if let Some(DefMethod(did)) = binding.def_for_namespace(ValueNS) {
3593
                    if is_static_method(self, did) {
C
corentih 已提交
3594
                        return StaticMethod(path_names_to_string(&path, 0));
3595 3596 3597 3598 3599
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3600 3601
                    }
                }
3602
            }
3603 3604 3605
        }

        // Look for a method in the current trait.
3606 3607 3608
        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) {
3609
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3610 3611
                } else {
                    return TraitItem;
3612 3613 3614 3615 3616 3617 3618
                }
            }
        }

        NoSuggestion
    }

3619
    fn find_best_match_for_name(&mut self, name: &str) -> Option<String> {
3620
        let mut maybes: Vec<token::InternedString> = Vec::new();
3621
        let mut values: Vec<usize> = Vec::new();
3622

3623
        for rib in self.value_ribs.iter().rev() {
3624
            for (&k, _) in &rib.bindings {
3625
                maybes.push(k.as_str());
3626
                values.push(usize::MAX);
3627 3628 3629 3630
            }
        }

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

3634
            if values[i] <= values[smallest] {
3635 3636 3637 3638
                smallest = i;
            }
        }

3639 3640 3641 3642 3643
        // As a loose rule to avoid obviously incorrect suggestions, clamp the
        // maximum edit distance we will accept for a suggestion to one third of
        // the typo'd name's length.
        let max_distance = std::cmp::max(name.len(), 3) / 3;

C
corentih 已提交
3644
        if !values.is_empty() && values[smallest] <= max_distance && name != &maybes[smallest][..] {
3645

3646
            Some(maybes[smallest].to_string())
3647 3648 3649 3650 3651 3652

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
3653
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3654 3655
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3656 3657 3658

        self.record_candidate_traits_for_expr_if_necessary(expr);

3659
        // Next, resolve the node.
3660
        match expr.node {
3661
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
3662 3663 3664 3665 3666 3667 3668 3669 3670 3671
                let resolution = match self.resolve_possibly_assoc_item(expr.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
                                                                        ValueNS,
                                                                        true) {
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        let method_name = path.segments.last().unwrap().identifier.name;
                        let traits = self.get_traits_containing_item(method_name);
                        self.trait_map.insert(expr.id, traits);
3672
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
3673 3674 3675 3676
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
3677

3678 3679
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3680
                if let Some(path_res) = resolution {
3681
                    // Check if struct variant
3682
                    if let DefVariant(_, _, true) = path_res.base_def {
3683
                        let path_name = path_names_to_string(path, 0);
3684

3685 3686
                        resolve_error(self,
                                      expr.span,
3687
                                      ResolutionError::StructVariantUsedAsFunction(&*path_name));
3688

C
corentih 已提交
3689
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3690 3691 3692 3693 3694 3695
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
3696
                    } else {
3697
                        // Write the result into the def map.
3698
                        debug!("(resolving expr) resolved `{}`",
3699
                               path_names_to_string(path, 0));
3700

3701 3702
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3703
                        if path_res.depth != 0 {
3704
                            let method_name = path.segments.last().unwrap().identifier.name;
3705
                            let traits = self.get_traits_containing_item(method_name);
3706 3707 3708
                            self.trait_map.insert(expr.id, traits);
                        }

3709
                        self.record_def(expr.id, path_res);
3710
                    }
3711 3712 3713 3714 3715
                } 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.)
3716
                    let path_name = path_names_to_string(path, 0);
3717 3718 3719 3720
                    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) {
C
corentih 已提交
3721 3722
                        Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
                            resolve_error(
3723 3724
                                    self,
                                    expr.span,
3725
                                    ResolutionError::StructVariantUsedAsFunction(
3726 3727
                                        &*path_name)
                                );
3728

C
corentih 已提交
3729 3730 3731 3732 3733 3734
                            let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                              path_name);
                            if self.emit_errors {
                                self.session.fileline_help(expr.span, &msg);
                            } else {
                                self.session.span_help(expr.span, &msg);
3735
                            }
C
corentih 已提交
3736
                        }
3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749
                        _ => {
                            // 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
                            });
3750

3751
                            if method_scope && special_names::self_.as_str() == &path_name[..] {
C
corentih 已提交
3752 3753 3754
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3755 3756 3757 3758 3759 3760
                            } 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
3761
                                        self.find_best_match_for_name(&path_name)
C
corentih 已提交
3762
                                            .map_or("".to_string(), |x| format!("`{}`", x))
3763 3764 3765
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
C
corentih 已提交
3766
                                    TraitItem => format!("to call `self.{}`", path_name),
3767 3768
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
C
corentih 已提交
3769
                                        format!("to call `{}::{}`", path_str, path_name),
3770 3771
                                };

3772
                                if !msg.is_empty() {
3773
                                    msg = format!(". Did you mean {}?", msg)
3774
                                }
3775

3776 3777
                                resolve_error(self,
                                              expr.span,
C
corentih 已提交
3778
                                              ResolutionError::UnresolvedName(&*path_name, &*msg));
3779
                            }
V
Vincent Belliard 已提交
3780
                        }
3781 3782 3783
                    }
                }

3784
                intravisit::walk_expr(self, expr);
3785 3786
            }

3787
            ExprStruct(ref path, _, _) => {
3788 3789 3790
                // 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.
3791
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3792
                    Some(definition) => self.record_def(expr.id, definition),
3793 3794
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3795

3796 3797
                        resolve_error(self,
                                      path.span,
3798
                                      ResolutionError::DoesNotNameAStruct(
3799 3800
                                                                &*path_names_to_string(path, 0))
                                     );
3801 3802 3803
                    }
                }

3804
                intravisit::walk_expr(self, expr);
3805 3806
            }

P
Pythoner6 已提交
3807
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3808
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3809
                    let def_like = DlDef(DefLabel(expr.id));
3810

3811
                    {
3812
                        let rib = this.label_ribs.last_mut().unwrap();
3813
                        let renamed = mtwt::resolve(label);
3814
                        rib.bindings.insert(renamed, def_like);
3815
                    }
3816

3817
                    intravisit::walk_expr(this, expr);
3818
                })
3819 3820
            }

3821
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3822
                let renamed = mtwt::resolve(label.node);
3823
                match self.search_label(renamed) {
3824
                    None => {
3825
                        resolve_error(self,
3826 3827
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3828
                    }
3829
                    Some(DlDef(def @ DefLabel(_))) => {
3830
                        // Since this def is a label, it is never read.
C
corentih 已提交
3831 3832 3833 3834 3835 3836
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            last_private: LastMod(AllPublic),
                                            depth: 0,
                                        })
3837 3838
                    }
                    Some(_) => {
C
corentih 已提交
3839
                        self.session.span_bug(expr.span, "label wasn't mapped to a label def!")
3840 3841 3842 3843
                    }
                }
            }

B
Brian Anderson 已提交
3844
            _ => {
3845
                intravisit::walk_expr(self, expr);
3846 3847 3848 3849
            }
        }
    }

E
Eduard Burtescu 已提交
3850
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3851
        match expr.node {
3852
            ExprField(_, name) => {
3853 3854 3855 3856
                // 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.
3857
                let traits = self.get_traits_containing_item(name.node);
3858
                self.trait_map.insert(expr.id, traits);
3859
            }
3860
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3861
                debug!("(recording candidate traits for expr) recording traits for {}",
3862
                       expr.id);
3863
                let traits = self.get_traits_containing_item(name.node);
3864
                self.trait_map.insert(expr.id, traits);
3865
            }
3866
            _ => {
3867 3868 3869 3870 3871
                // Nothing to do.
            }
        }
    }

3872
    fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
C
corentih 已提交
3873
        debug!("(getting traits containing item) looking for '{}'", name);
E
Eduard Burtescu 已提交
3874

C
corentih 已提交
3875
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3876
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3877 3878
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3879 3880
            found_traits.push(trait_def_id);
        }
3881

3882
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
3883
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
3884 3885
        loop {
            // Look for the current trait.
3886 3887
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3888
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3889
                        add_trait_info(&mut found_traits, trait_def_id, name);
3890 3891
                    }
                }
3892
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3893
            }
3894

E
Eduard Burtescu 已提交
3895
            // Look for trait children.
3896
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3897

E
Eduard Burtescu 已提交
3898
            {
3899
                for (_, child_names) in search_module.children.borrow().iter() {
3900 3901
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
C
corentih 已提交
3902
                        None => continue,
3903 3904
                    };
                    let trait_def_id = match def {
3905
                        DefTrait(trait_def_id) => trait_def_id,
3906 3907
                        _ => continue,
                    };
3908
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3909
                        add_trait_info(&mut found_traits, trait_def_id, name);
3910 3911
                    }
                }
E
Eduard Burtescu 已提交
3912
            }
3913

E
Eduard Burtescu 已提交
3914
            // Look for imports.
3915
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
3916 3917 3918 3919 3920
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
3921
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3922 3923
                    Some(..) | None => continue,
                };
3924
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3925
                    add_trait_info(&mut found_traits, did, name);
3926 3927 3928 3929
                    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);
3930 3931
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
3932
                    }
3933
                }
E
Eduard Burtescu 已提交
3934
            }
3935

E
Eduard Burtescu 已提交
3936
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
3937 3938
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
3939
                    search_module = parent_module.upgrade().unwrap();
3940
                }
E
Eduard Burtescu 已提交
3941
            }
3942 3943
        }

E
Eduard Burtescu 已提交
3944
        found_traits
3945 3946
    }

3947 3948
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
C
corentih 已提交
3949 3950 3951 3952
        assert!(match resolution.last_private {
                    LastImport{..} => false,
                    _ => true,
                },
3953
                "Import should only be used for `use` directives");
3954

3955 3956
        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);
C
corentih 已提交
3957 3958 3959 3960
            self.session.span_bug(span,
                                  &format!("path resolved multiple times ({:?} before, {:?} now)",
                                           prev_res,
                                           resolution));
3961
        }
3962 3963
    }

F
Felix S. Klock II 已提交
3964
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3965 3966 3967
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3968
        match pat_binding_mode {
3969
            BindByValue(_) => {}
A
Alex Crichton 已提交
3970
            BindByRef(..) => {
3971 3972
                resolve_error(self,
                              pat.span,
3973
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3974 3975 3976 3977
            }
        }
    }

3978 3979 3980 3981 3982 3983 3984
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

3989
        debug!("Children:");
3990
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3991
        for (&name, _) in module_.children.borrow().iter() {
3992
            debug!("* {}", name);
3993 3994
        }

3995
        debug!("Import resolutions:");
3996
        let import_resolutions = module_.import_resolutions.borrow();
3997
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
3998
            let value_repr;
3999
            match import_resolution.target_for_namespace(ValueNS) {
C
corentih 已提交
4000 4001 4002
                None => {
                    value_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
4003
                Some(_) => {
R
Richo Healey 已提交
4004
                    value_repr = " value:?".to_string();
4005
                    // FIXME #4954
4006 4007 4008
                }
            }

N
Niko Matsakis 已提交
4009
            let type_repr;
4010
            match import_resolution.target_for_namespace(TypeNS) {
C
corentih 已提交
4011 4012 4013
                None => {
                    type_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
4014
                Some(_) => {
R
Richo Healey 已提交
4015
                    type_repr = " type:?".to_string();
4016
                    // FIXME #4954
4017 4018 4019
                }
            }

4020
            debug!("* {}:{}{}", name, value_repr, type_repr);
4021 4022 4023 4024
        }
    }
}

4025 4026 4027 4028 4029 4030 4031 4032 4033 4034

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("::")
        }
4035
        result.push_str(&name.as_str());
C
corentih 已提交
4036
    }
4037 4038 4039 4040
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
4041
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067
                                    .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);

4068
    if names.is_empty() {
4069 4070 4071 4072 4073 4074
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}


4075
pub struct CrateMap {
J
Jonathan S 已提交
4076
    pub def_map: RefCell<DefMap>,
4077
    pub freevars: FreevarMap,
4078
    pub export_map: ExportMap,
4079 4080
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
C
corentih 已提交
4081
    pub glob_map: Option<GlobMap>,
4082 4083
}

N
Niko Matsakis 已提交
4084
#[derive(PartialEq,Copy, Clone)]
4085 4086
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
4087
    No,
4088 4089
}

4090
/// Entry point to crate resolution.
4091
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
4092
                               ast_map: &'a hir_map::Map<'tcx>,
4093 4094
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
4095
    let krate = ast_map.krate();
4096
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
4097 4098 4099 4100 4101 4102

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

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

4103
    CrateMap {
4104 4105
        def_map: resolver.def_map,
        freevars: resolver.freevars,
4106
        export_map: resolver.export_map,
4107 4108
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
4109
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
4110 4111 4112 4113
            Some(resolver.glob_map)
        } else {
            None
        },
4114
    }
4115
}
4116

4117 4118 4119 4120 4121 4122 4123 4124
/// Builds a name resolution walker to be used within this module,
/// or used externally, with an optional callback function.
///
/// The callback takes a &mut bool which allows callbacks to end a
/// walk when set to true, passing through the rest of the walk, while
/// preserving the ribs + current module. This allows resolve_path
/// calls to be made with the correct scope info. The node in the
/// callback corresponds to the current node in the walk.
G
Garming Sam 已提交
4125
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
4126
                                 ast_map: &'a hir_map::Map<'tcx>,
G
Garming Sam 已提交
4127 4128
                                 krate: &'a Crate,
                                 make_glob_map: MakeGlobMap,
4129
                                 callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
G
Garming Sam 已提交
4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146
                                 -> Resolver<'a, 'tcx> {
    let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);

    resolver.callback = callback;

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

    resolve_imports::resolve_imports(&mut resolver);
    session.abort_if_errors();

    record_exports::record(&mut resolver);
    session.abort_if_errors();

    resolver
}

4147
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }