lib.rs 155.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")]
15
#![cfg_attr(stage0, 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
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::NamespaceResult::*;
use self::ResolveResult::*;
use self::FallbackSuggestion::*;
use self::TypeParameters::*;
use self::RibKind::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
48
use self::AssocItemResolveResult::*;
S
Steven Fackler 已提交
49 50 51 52 53
use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;
use self::FallbackChecks::*;

54
use rustc::front::map as hir_map;
55 56
use rustc::session::Session;
use rustc::lint;
57
use rustc::middle::cstore::{CrateStore, DefLike, DlDef};
58
use rustc::middle::def::*;
59
use rustc::middle::def_id::DefId;
60
use rustc::middle::pat_util::pat_bindings;
61 62
use rustc::middle::privacy::*;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
63
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
64
use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
65

P
Patrick Walton 已提交
66
use syntax::ast;
67
use syntax::ast::{CRATE_NODE_ID, Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
68
use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32};
69
use syntax::attr::AttrMetaMethods;
70
use syntax::parse::token::{self, special_names, special_idents};
71
use syntax::codemap::{self, Span, Pos};
72
use syntax::util::lev_distance::{lev_distance, max_suggestion_distance};
73

74
use rustc_front::intravisit::{self, FnKind, Visitor};
75 76
use rustc_front::hir;
use rustc_front::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
77
use rustc_front::hir::Crate;
78 79 80 81 82 83 84
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};
85
use rustc_front::hir::Local;
86 87
use rustc_front::hir::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
use rustc_front::hir::{PatRange, PatStruct, Path, PrimTy};
88 89
use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt};
use rustc_front::hir::{TyRptr, TyStr, TyUint, TyPath, TyPtr};
90
use rustc_front::util::walk_pat;
91

92
use std::collections::{HashMap, HashSet};
93
use std::cell::{Cell, RefCell};
94
use std::fmt;
95
use std::mem::replace;
E
Eduard Burtescu 已提交
96
use std::rc::{Rc, Weak};
97
use std::usize;
98

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

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

A
Alex Crichton 已提交
106 107
mod check_unused;
mod record_exports;
108
mod build_reduced_graph;
109
mod resolve_imports;
110

111 112 113 114 115 116 117 118 119 120 121
// 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;
            }
        }
    )
}

122 123 124 125 126 127
enum SuggestionType {
    Macro(String),
    Function(String),
    NotFound,
}

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

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

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

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

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

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

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

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

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

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

626 627
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
628
enum ResolveResult<T> {
C
corentih 已提交
629 630 631
    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.
632 633
}

634
impl<T> ResolveResult<T> {
635
    fn success(&self) -> bool {
C
corentih 已提交
636 637 638 639
        match *self {
            Success(_) => true,
            _ => false,
        }
640 641 642
    }
}

643 644 645 646
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
647
    TraitItem,
648
    StaticMethod(String),
649
    TraitMethod(String),
650 651
}

N
Niko Matsakis 已提交
652
#[derive(Copy, Clone)]
E
Erik Price 已提交
653
enum TypeParameters<'a> {
654
    NoTypeParameters,
C
corentih 已提交
655 656
    HasTypeParameters(// Type parameters.
                      &'a Generics,
657

C
corentih 已提交
658 659 660
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
661

C
corentih 已提交
662 663
                      // The kind of the rib used for type parameters.
                      RibKind),
664 665
}

666 667
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
668
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
669
enum RibKind {
670 671
    // No translation needs to be applied.
    NormalRibKind,
672

673 674
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
675
    ClosureRibKind(NodeId /* func id */),
676

677
    // We passed through an impl or trait and are now in one of its
678
    // methods. Allow references to ty params that impl or trait
679 680
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
681
    MethodRibKind,
682

683 684
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
685 686

    // We're in a constant item. Can't refer to dynamic stuff.
C
corentih 已提交
687
    ConstantItemRibKind,
688 689
}

N
Niko Matsakis 已提交
690
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
691
enum UseLexicalScopeFlag {
692
    DontUseLexicalScope,
C
corentih 已提交
693
    UseLexicalScope,
694 695
}

F
Felix S. Klock II 已提交
696
enum ModulePrefixResult {
697
    NoPrefixFound,
C
corentih 已提交
698
    PrefixFound(Rc<Module>, usize),
699 700
}

701 702 703 704 705 706 707 708 709
#[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 已提交
710
#[derive(Copy, Clone, PartialEq)]
711
enum NameSearchType {
712 713 714 715
    /// 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
716 717
    /// expression, or a path pattern.
    PathSearch,
718 719
}

N
Niko Matsakis 已提交
720
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
721
enum BareIdentifierPatternResolution {
722
    FoundStructOrEnumVariant(Def, LastPrivate),
723
    FoundConst(Def, LastPrivate, Name),
C
corentih 已提交
724
    BareIdentifierPatternUnresolved,
725 726
}

727
/// One local scope.
J
Jorge Aparicio 已提交
728
#[derive(Debug)]
F
Felix S. Klock II 已提交
729
struct Rib {
730
    bindings: HashMap<Name, DefLike>,
731
    kind: RibKind,
B
Brian Anderson 已提交
732
}
733

734
impl Rib {
F
Felix S. Klock II 已提交
735
    fn new(kind: RibKind) -> Rib {
736
        Rib {
737
            bindings: HashMap::new(),
C
corentih 已提交
738
            kind: kind,
739
        }
740 741 742
    }
}

743 744 745
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
746
    def: Def,
747 748 749 750 751 752
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
753
            def: def,
754 755 756 757
        }
    }
}

758
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
759
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
760
enum ParentLink {
761
    NoParentLink,
762
    ModuleParentLink(Weak<Module>, Name),
C
corentih 已提交
763
    BlockParentLink(Weak<Module>, NodeId),
764 765
}

766
/// One node in the tree of modules.
767
pub struct Module {
768
    parent_link: ParentLink,
769
    def: Cell<Option<Def>>,
770
    is_public: bool,
771

772
    children: RefCell<HashMap<Name, NameBindings>>,
E
Eduard Burtescu 已提交
773
    imports: RefCell<Vec<ImportDirective>>,
774

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

779 780 781 782 783 784 785 786 787 788 789 790 791 792
    // 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 已提交
793
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
794 795

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

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

801 802 803 804 805 806
    // 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>,

807
    // The index of the import we're resolving.
808
    resolved_import_count: Cell<usize>,
809 810 811 812

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

816
impl Module {
F
Felix S. Klock II 已提交
817
    fn new(parent_link: ParentLink,
818
           def: Option<Def>,
819 820
           external: bool,
           is_public: bool)
821 822
           -> Rc<Module> {
        Rc::new(Module {
823
            parent_link: parent_link,
824
            def: Cell::new(def),
825
            is_public: is_public,
826
            children: RefCell::new(HashMap::new()),
827
            imports: RefCell::new(Vec::new()),
828
            external_module_children: RefCell::new(HashMap::new()),
829
            anonymous_children: RefCell::new(NodeMap()),
830
            import_resolutions: RefCell::new(HashMap::new()),
831
            glob_count: Cell::new(0),
832 833
            pub_count: Cell::new(0),
            pub_glob_count: Cell::new(0),
834
            resolved_import_count: Cell::new(0),
835
            populated: Cell::new(!external),
836
        })
B
Brian Anderson 已提交
837 838
    }

839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
    fn def_id(&self) -> Option<DefId> {
        self.def.get().as_ref().map(Def::def_id)
    }

    fn is_normal(&self) -> bool {
        match self.def.get() {
            Some(DefMod(_)) | Some(DefForeignMod(_)) => true,
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
        match self.def.get() {
            Some(DefTrait(_)) => true,
            _ => false,
854
        }
B
Brian Anderson 已提交
855 856
    }

F
Felix S. Klock II 已提交
857
    fn all_imports_resolved(&self) -> bool {
858 859 860 861 862 863
        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()
        }
864 865 866
    }
}

V
Victor Berger 已提交
867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890
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);
    }
}

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

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

912
// Records a possibly-private value, type, or module definition.
913
#[derive(Debug)]
914
struct NsDef {
915
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
916
    def_or_module: DefOrModule,
917
    span: Option<Span>,
918 919
}

J
Jorge Aparicio 已提交
920
#[derive(Debug)]
921 922 923
enum DefOrModule {
    Def(Def),
    Module(Rc<Module>),
924 925
}

926
impl NsDef {
927 928
    fn create_from_module(module: Rc<Module>, span: Option<Span>) -> Self {
        let modifiers = if module.is_public {
T
Fallout  
Tamir Duberstein 已提交
929 930 931 932
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
933

934
        NsDef { modifiers: modifiers, def_or_module: DefOrModule::Module(module), span: span }
935 936
    }

937 938 939 940 941 942 943 944
    fn create_from_def(def: Def, modifiers: DefModifiers, span: Option<Span>) -> Self {
        NsDef { modifiers: modifiers, def_or_module: DefOrModule::Def(def), span: span }
    }

    fn module(&self) -> Option<Rc<Module>> {
        match self.def_or_module {
            DefOrModule::Module(ref module) => Some(module.clone()),
            DefOrModule::Def(_) => None,
945 946 947
        }
    }

948
    fn def(&self) -> Option<Def> {
949 950 951
        match self.def_or_module {
            DefOrModule::Def(def) => Some(def),
            DefOrModule::Module(ref module) => module.def.get(),
952
        }
953
    }
954
}
955

956 957 958 959 960 961 962
// Records at most one definition that a name in a namespace is bound to
#[derive(Clone,Debug)]
pub struct NameBinding(Rc<RefCell<Option<NsDef>>>);

impl NameBinding {
    fn new() -> Self {
        NameBinding(Rc::new(RefCell::new(None)))
963 964
    }

965
    fn create_from_module(module: Rc<Module>) -> Self {
966
        NameBinding(Rc::new(RefCell::new(Some(NsDef::create_from_module(module, None)))))
967 968
    }

969 970
    fn set(&self, ns_def: NsDef) {
        *self.0.borrow_mut() = Some(ns_def);
971 972
    }

973 974 975
    fn set_modifiers(&self, modifiers: DefModifiers) {
        if let Some(ref mut ns_def) = *self.0.borrow_mut() {
            ns_def.modifiers = modifiers
976 977 978
        }
    }

979 980
    fn borrow(&self) -> ::std::cell::Ref<Option<NsDef>> {
        self.0.borrow()
981 982
    }

983
    // Lifted versions of the NsDef methods and fields
984 985 986 987 988 989 990 991 992 993 994
    fn def(&self) -> Option<Def> {
        self.borrow().as_ref().and_then(NsDef::def)
    }
    fn module(&self) -> Option<Rc<Module>> {
        self.borrow().as_ref().and_then(NsDef::module)
    }
    fn span(&self) -> Option<Span> {
        self.borrow().as_ref().and_then(|def| def.span)
    }
    fn modifiers(&self) -> Option<DefModifiers> {
        self.borrow().as_ref().and_then(|def| Some(def.modifiers))
995 996
    }

997 998
    fn defined(&self) -> bool {
        self.borrow().is_some()
999 1000
    }

1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
    fn defined_with(&self, modifiers: DefModifiers) -> bool {
        self.modifiers().map(|m| m.contains(modifiers)).unwrap_or(false)
    }

    fn is_public(&self) -> bool {
        self.defined_with(DefModifiers::PUBLIC)
    }

    fn def_and_lp(&self) -> (Def, LastPrivate) {
        let def = self.def().unwrap();
        (def, LastMod(if self.is_public() { AllPublic } else { DependsOn(def.def_id()) }))
    }
1013 1014
}

1015 1016
// Records the definitions (at most one for each namespace) that a name is
// bound to.
1017
#[derive(Clone,Debug)]
1018
pub struct NameBindings {
1019 1020 1021 1022 1023 1024 1025 1026 1027
    type_ns: NameBinding, // < Meaning in type namespace.
    value_ns: NameBinding, // < Meaning in value namespace.
}

impl ::std::ops::Index<Namespace> for NameBindings {
    type Output = NameBinding;
    fn index(&self, namespace: Namespace) -> &NameBinding {
        match namespace { TypeNS => &self.type_ns, ValueNS => &self.value_ns }
    }
1028 1029
}

1030
impl NameBindings {
K
Kevin Butler 已提交
1031 1032
    fn new() -> NameBindings {
        NameBindings {
1033 1034
            type_ns: NameBinding::new(),
            value_ns: NameBinding::new(),
1035 1036
        }
    }
K
Kevin Butler 已提交
1037

1038
    /// Creates a new module in this set of name bindings.
1039 1040
    fn define_module(&self, module: Rc<Module>, sp: Span) {
        self.type_ns.set(NsDef::create_from_module(module, Some(sp)));
1041 1042
    }

1043
    /// Records a type definition.
1044
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
1045 1046
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
        self.type_ns.set(NsDef::create_from_def(def, modifiers, Some(sp)));
1047 1048
    }

1049
    /// Records a value definition.
1050
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
1051 1052
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
        self.value_ns.set(NsDef::create_from_def(def, modifiers, Some(sp)));
1053 1054 1055
    }
}

1056
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1057
struct PrimitiveTypeTable {
1058
    primitive_types: HashMap<Name, PrimTy>,
1059
}
1060

1061
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1062
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
        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 已提交
1080 1081 1082 1083

        table
    }

1084
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1085
        self.primitive_types.insert(token::intern(string), primitive_type);
1086 1087 1088
    }
}

1089
/// The main resolver class.
C
corentih 已提交
1090
pub struct Resolver<'a, 'tcx: 'a> {
E
Eduard Burtescu 已提交
1091
    session: &'a Session,
1092

1093
    ast_map: &'a hir_map::Map<'tcx>,
1094

1095
    graph_root: Rc<Module>,
1096

1097
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1098

1099
    structs: FnvHashMap<DefId, Vec<Name>>,
1100

1101
    // The number of imports that are currently unresolved.
1102
    unresolved_imports: usize,
1103 1104

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
1105
    current_module: Rc<Module>,
1106 1107

    // The current set of local scopes, for values.
1108
    // FIXME #4948: Reuse ribs to avoid allocation.
1109
    value_ribs: Vec<Rib>,
1110 1111

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

1114
    // The current set of local scopes, for labels.
1115
    label_ribs: Vec<Rib>,
1116

1117
    // The trait that the current context can refer to.
1118 1119 1120 1121
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1123
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1124
    primitive_type_table: PrimitiveTypeTable,
1125

J
Jonathan S 已提交
1126
    def_map: RefCell<DefMap>,
1127 1128
    freevars: FreevarMap,
    freevars_seen: NodeMap<NodeMap<usize>>,
1129
    export_map: ExportMap,
1130
    trait_map: TraitMap,
1131
    external_exports: ExternalExports,
1132

1133 1134 1135 1136 1137
    // 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,

1138 1139 1140 1141 1142
    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,

1143
    used_imports: HashSet<(NodeId, Namespace)>,
1144
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1145 1146

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

1153
#[derive(PartialEq)]
S
Steven Fackler 已提交
1154 1155
enum FallbackChecks {
    Everything,
C
corentih 已提交
1156
    OnlyTraitAndStatics,
S
Steven Fackler 已提交
1157 1158
}

1159 1160
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1161
           ast_map: &'a hir_map::Map<'tcx>,
C
corentih 已提交
1162 1163
           make_glob_map: MakeGlobMap)
           -> Resolver<'a, 'tcx> {
1164
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
1165
        let graph_root = Module::new(NoParentLink, Some(DefMod(root_def_id)), false, true);
K
Kevin Butler 已提交
1166 1167 1168 1169

        Resolver {
            session: session,

1170 1171
            ast_map: ast_map,

K
Kevin Butler 已提交
1172 1173
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1174
            graph_root: graph_root.clone(),
K
Kevin Butler 已提交
1175

1176 1177
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1178 1179 1180

            unresolved_imports: 0,

1181
            current_module: graph_root,
1182 1183 1184
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1185 1186 1187 1188 1189 1190

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1191
            def_map: RefCell::new(NodeMap()),
1192 1193
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1194 1195
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1196
            used_imports: HashSet::new(),
1197
            used_crates: HashSet::new(),
1198
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1199 1200

            emit_errors: true,
1201 1202
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
G
Garming Sam 已提交
1203 1204 1205

            callback: None,
            resolved: false,
K
Kevin Butler 已提交
1206 1207
        }
    }
1208

1209 1210 1211 1212 1213 1214
    #[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) {
1215
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1216 1217 1218 1219 1220 1221 1222 1223 1224
            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 {
1225 1226
        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
            self.ast_map.expect_item(node_id).name
1227
        } else {
1228
            self.session.cstore.item_name(did)
1229 1230 1231
        }
    }

1232 1233 1234 1235 1236 1237 1238
    /// 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 已提交
1239 1240 1241 1242 1243
            span_err!(self.session,
                      span,
                      E0259,
                      "an external crate named `{}` has already been imported into this module",
                      name);
1244 1245 1246 1247 1248 1249 1250 1251 1252
        }
    }

    /// 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 已提交
1253 1254 1255 1256 1257 1258
            span_err!(self.session,
                      span,
                      E0260,
                      "the name `{}` conflicts with an external crate that has been imported \
                       into this module",
                      name);
1259
        }
1260 1261
    }

1262
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1263
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1264
                                     module_: Rc<Module>,
1265
                                     module_path: &[Name],
1266
                                     index: usize,
1267 1268 1269
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
C
corentih 已提交
1270 1271
                                     -> ResolveResult<(Rc<Module>, LastPrivate)> {
        fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Module>> {
1272 1273 1274 1275 1276
            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())
1277
                    }
C
corentih 已提交
1278 1279
                    _ => None,
                },
1280
            }
1281 1282
        }

1283
        let mut search_module = module_;
1284
        let mut index = index;
A
Alex Crichton 已提交
1285
        let module_path_len = module_path.len();
1286
        let mut closest_private = lp;
1287 1288 1289 1290 1291

        // 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 已提交
1292
            let name = module_path[index];
E
Eduard Burtescu 已提交
1293
            match self.resolve_name_in_module(search_module.clone(),
1294
                                              name,
1295
                                              TypeNS,
1296 1297
                                              name_search_type,
                                              false) {
1298
                Failed(None) => {
1299
                    let segment_name = name.as_str();
1300
                    let module_name = module_to_string(&*search_module);
1301
                    let mut span = span;
1302
                    let msg = if "???" == &module_name[..] {
1303
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1304

C
corentih 已提交
1305
                        match search_parent_externals(name, &self.current_module) {
1306
                            Some(module) => {
1307 1308
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
C
corentih 已提交
1309
                                let current_mod_str = module_to_string(&*self.current_module);
1310 1311 1312 1313 1314 1315 1316

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

1317
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1318 1319
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1320
                        }
1321
                    } else {
C
corentih 已提交
1322
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1323
                    };
1324

1325
                    return Failed(Some((span, msg)));
1326
                }
1327
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1328
                Indeterminate => {
C
corentih 已提交
1329 1330 1331
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1332
                    return Indeterminate;
1333
                }
1334
                Success((target, used_proxy)) => {
1335 1336
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
1337 1338
                    if let Some(module_def) = target.binding.module() {
                        // track extern crates for unused_extern_crate lint
1339
                        if let Some(did) = module_def.def_id() {
1340 1341
                            self.used_crates.insert(did.krate);
                        }
1342

1343
                        search_module = module_def;
1344

1345 1346 1347
                        // Keep track of the closest private module used
                        // when resolving this import chain.
                        if !used_proxy && !search_module.is_public {
1348
                            if let Some(did) = search_module.def_id() {
1349
                                closest_private = LastMod(DependsOn(did));
1350 1351
                            }
                        }
1352 1353 1354
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1355 1356 1357 1358
                    }
                }
            }

T
Tim Chevalier 已提交
1359
            index += 1;
1360 1361
        }

1362
        return Success((search_module, closest_private));
1363 1364
    }

1365 1366
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1367 1368 1369
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1370
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
1371
                           module_: Rc<Module>,
1372
                           module_path: &[Name],
1373 1374 1375
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1376
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
1377
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1378
        assert!(module_path_len > 0);
1379

1380
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1381 1382
               names_to_string(module_path),
               module_to_string(&*module_));
1383

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

1387 1388
        let search_module;
        let start_index;
1389
        let last_private;
1390
        match module_prefix_result {
1391
            Failed(None) => {
1392
                let mpath = names_to_string(module_path);
1393
                let mpath = &mpath[..];
1394
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1395
                    Some(idx) => {
1396
                        let msg = format!("Could not find `{}` in `{}`",
C
corentih 已提交
1397 1398 1399 1400
                                          // idx +- 1 to account for the
                                          // colons on either side
                                          &mpath[idx + 1..],
                                          &mpath[..idx - 1]);
1401
                        return Failed(Some((span, msg)));
C
corentih 已提交
1402
                    }
1403
                    None => {
C
corentih 已提交
1404
                        return Failed(None);
1405
                    }
1406
                }
1407
            }
1408
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1409
            Indeterminate => {
C
corentih 已提交
1410
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1411
                return Indeterminate;
1412
            }
1413 1414 1415 1416 1417 1418 1419 1420
            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.
1421
                        search_module = self.graph_root.clone();
1422
                        start_index = 0;
1423
                        last_private = LastMod(AllPublic);
1424 1425 1426 1427 1428
                    }
                    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 已提交
1429
                        match self.resolve_module_in_lexical_scope(module_, module_path[0]) {
1430
                            Failed(err) => return Failed(err),
1431
                            Indeterminate => {
C
corentih 已提交
1432
                                debug!("(resolving module path for import) indeterminate; bailing");
1433 1434 1435 1436 1437
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1438
                                last_private = LastMod(AllPublic);
1439 1440 1441 1442 1443
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1444 1445
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
1446
                start_index = index;
1447
                last_private = LastMod(DependsOn(containing_module.def_id()
1448
                                                                  .unwrap()));
1449 1450 1451
            }
        }

1452 1453 1454 1455
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1456 1457
                                           name_search_type,
                                           last_private)
1458 1459
    }

1460 1461
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1462
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1463
                                     module_: Rc<Module>,
1464
                                     name: Name,
1465
                                     namespace: Namespace)
C
corentih 已提交
1466 1467
                                     -> ResolveResult<(Target, bool)> {
        debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
1468
               name,
1469
               namespace,
1470
               module_to_string(&*module_));
1471 1472 1473

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

1476
        match module_.children.borrow().get(&name) {
1477
            Some(name_bindings) if name_bindings[namespace].defined() => {
1478
                debug!("top name bindings succeeded");
1479
                return Success((Target::new(module_.clone(),
1480
                                            name_bindings[namespace].clone(),
1481
                                            Shadowable::Never),
C
corentih 已提交
1482 1483 1484 1485
                                false));
            }
            Some(_) | None => {
                // Not found; continue.
1486 1487 1488 1489 1490 1491 1492
            }
        }

        // 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.
1493 1494 1495 1496
        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
            match (*import_resolution).target_for_namespace(namespace) {
                None => {
                    // Not found; continue.
C
corentih 已提交
1497 1498
                    debug!("(resolving item in lexical scope) found import resolution, but not \
                            in namespace {:?}",
1499 1500 1501
                           namespace);
                }
                Some(target) => {
C
corentih 已提交
1502
                    debug!("(resolving item in lexical scope) using import resolution");
1503
                    // track used imports and extern crates as well
1504 1505 1506
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
1507
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
C
corentih 已提交
1508
                        self.used_crates.insert(kid);
1509
                    }
1510
                    return Success((target, false));
1511 1512 1513 1514
                }
            }
        }

1515 1516
        // Search for external modules.
        if namespace == TypeNS {
1517 1518 1519
            // FIXME (21114): In principle unclear `child` *has* to be lifted.
            let child = module_.external_module_children.borrow().get(&name).cloned();
            if let Some(module) = child {
1520
                let name_binding = NameBinding::create_from_module(module);
1521
                debug!("lower name bindings succeeded");
1522
                return Success((Target::new(module_, name_binding, Shadowable::Never),
1523
                                false));
1524 1525 1526
            }
        }

1527
        // Finally, proceed up the scope chain looking for parent modules.
1528
        let mut search_module = module_;
1529 1530
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
1531
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
1532
                NoParentLink => {
1533
                    // No more parents. This module was unresolved.
C
corentih 已提交
1534
                    debug!("(resolving item in lexical scope) unresolved module");
1535
                    return Failed(None);
1536
                }
1537
                ModuleParentLink(parent_module_node, _) => {
1538 1539 1540 1541
                    if search_module.is_normal() {
                        // We stop the search here.
                        debug!("(resolving item in lexical scope) unresolved module: not \
                                searching through module parents");
1542
                            return Failed(None);
1543 1544
                    } else {
                        search_module = parent_module_node.upgrade().unwrap();
1545 1546
                    }
                }
E
Eduard Burtescu 已提交
1547 1548
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
1549 1550 1551 1552
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
1553
            match self.resolve_name_in_module(search_module.clone(),
1554
                                              name,
1555
                                              namespace,
1556 1557
                                              PathSearch,
                                              true) {
1558
                Failed(Some((span, msg))) => {
1559
                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
C
corentih 已提交
1560
                }
1561
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1562
                Indeterminate => {
1563 1564 1565
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

C
corentih 已提交
1566
                    debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
B
Brian Anderson 已提交
1567
                    return Indeterminate;
1568
                }
1569
                Success((target, used_reexport)) => {
1570
                    // We found the module.
C
corentih 已提交
1571
                    debug!("(resolving item in lexical scope) found name in module, done");
1572
                    return Success((target, used_reexport));
1573 1574 1575 1576 1577
                }
            }
        }
    }

1578
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1579
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1580
                                       module_: Rc<Module>,
1581
                                       name: Name)
C
corentih 已提交
1582
                                       -> ResolveResult<Rc<Module>> {
1583 1584
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1585
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
1586
        match resolve_result {
1587
            Success((target, _)) => {
1588 1589 1590 1591 1592 1593
                if let Some(module_def) = target.binding.module() {
                    return Success(module_def)
                } else {
                    debug!("!!! (resolving module in lexical scope) module \
                            wasn't actually a module!");
                    return Failed(None);
1594 1595
                }
            }
B
Brian Anderson 已提交
1596
            Indeterminate => {
C
corentih 已提交
1597
                debug!("(resolving module in lexical scope) indeterminate; bailing");
B
Brian Anderson 已提交
1598
                return Indeterminate;
1599
            }
1600 1601 1602
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1603 1604 1605 1606
            }
        }
    }

1607
    /// Returns the nearest normal module parent of the given module.
C
corentih 已提交
1608
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc<Module>> {
1609 1610
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
1611
            match module_.parent_link.clone() {
1612 1613 1614
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
1615
                    let new_module = new_module.upgrade().unwrap();
1616 1617
                    if new_module.is_normal() {
                        return Some(new_module);
1618
                    }
1619
                    module_ = new_module;
1620 1621 1622 1623 1624
                }
            }
        }
    }

1625 1626
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
C
corentih 已提交
1627
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> Rc<Module> {
1628 1629 1630 1631 1632 1633
        if module_.is_normal() {
            return module_;
        }
        match self.get_nearest_normal_module_parent(module_.clone()) {
            None => module_,
            Some(new_module) => new_module,
1634 1635 1636
        }
    }

1637
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1638
    /// (b) some chain of `super::`.
1639
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1640
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
1641
                             module_: Rc<Module>,
1642
                             module_path: &[Name])
C
corentih 已提交
1643
                             -> ResolveResult<ModulePrefixResult> {
1644 1645
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1646 1647 1648 1649 1650 1651
        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_);
1652 1653

        // Now loop through all the `super`s we find.
1654
        while i < module_path.len() && "super" == module_path[i].as_str() {
1655
            debug!("(resolving module prefix) resolving `super` at {}",
1656
                   module_to_string(&*containing_module));
1657
            match self.get_nearest_normal_module_parent(containing_module) {
1658
                None => return Failed(None),
1659 1660 1661
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1662 1663 1664 1665
                }
            }
        }

1666
        debug!("(resolving module prefix) finished resolving prefix at {}",
1667
               module_to_string(&*containing_module));
1668 1669

        return Success(PrefixFound(containing_module, i));
1670 1671
    }

1672 1673 1674
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1675 1676 1677
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1678
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
1679
                              module_: Rc<Module>,
1680
                              name: Name,
1681
                              namespace: Namespace,
1682 1683
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1684
                              -> ResolveResult<(Target, bool)> {
1685
        debug!("(resolving name in module) resolving `{}` in `{}`",
1686
               name,
1687
               module_to_string(&*module_));
1688 1689

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

1692
        match module_.children.borrow().get(&name) {
1693
            Some(name_bindings) if name_bindings[namespace].defined() => {
1694
                debug!("(resolving name in module) found node as child");
1695
                return Success((Target::new(module_.clone(),
1696
                                            name_bindings[namespace].clone(),
1697
                                            Shadowable::Never),
C
corentih 已提交
1698
                                false));
1699 1700 1701
            }
            Some(_) | None => {
                // Continue.
1702 1703 1704
            }
        }

1705 1706 1707 1708
        // 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.
1709
        if name_search_type == PathSearch {
1710
            assert_eq!(module_.glob_count.get(), 0);
1711 1712
        }

1713
        // Check the list of resolved imports.
1714
        match module_.import_resolutions.borrow().get(&name) {
C
corentih 已提交
1715
            Some(import_resolution) if allow_private_imports || import_resolution.is_public => {
1716

C
corentih 已提交
1717 1718
                if import_resolution.is_public && import_resolution.outstanding_references != 0 {
                    debug!("(resolving name in module) import unresolved; bailing out");
B
Brian Anderson 已提交
1719
                    return Indeterminate;
1720
                }
1721
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1722
                    None => {
C
corentih 已提交
1723
                        debug!("(resolving name in module) name found, but not in namespace {:?}",
P
Paul Stansifer 已提交
1724
                               namespace);
1725
                    }
1726
                    Some(target) => {
C
corentih 已提交
1727
                        debug!("(resolving name in module) resolved to import");
1728
                        // track used imports and extern crates as well
1729 1730 1731
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1732
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
1733
                            self.used_crates.insert(kid);
1734
                        }
1735
                        return Success((target, true));
1736
                    }
1737 1738
                }
            }
1739
            Some(..) | None => {} // Continue.
1740 1741 1742 1743
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1744 1745 1746
            // 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 {
1747 1748
                let name_binding = NameBinding::create_from_module(module);
                return Success((Target::new(module_, name_binding, Shadowable::Never),
1749
                                false));
1750 1751 1752 1753
            }
        }

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

E
Eduard Burtescu 已提交
1758
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
1759
        let index = module_.resolved_import_count.get();
1760 1761
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1762
        if index != import_count {
1763 1764 1765
            resolve_error(self,
                          (*imports)[index].span,
                          ResolutionError::UnresolvedImport(None));
1766 1767 1768
        }

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

1771
        for (_, child_node) in module_.children.borrow().iter() {
1772
            match child_node.type_ns.module() {
1773 1774 1775 1776 1777
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1778 1779 1780 1781
                }
            }
        }

1782
        for (_, module_) in module_.anonymous_children.borrow().iter() {
E
Eduard Burtescu 已提交
1783
            self.report_unresolved_imports(module_.clone());
1784 1785 1786 1787 1788
        }
    }

    // AST resolution
    //
1789
    // We maintain a list of value ribs and type ribs.
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804
    //
    // 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 已提交
1805 1806
    fn with_scope<F>(&mut self, name: Option<Name>, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1807
    {
E
Eduard Burtescu 已提交
1808
        let orig_module = self.current_module.clone();
1809 1810

        // Move down in the graph.
1811
        match name {
B
Brian Anderson 已提交
1812
            None => {
1813 1814
                // Nothing to do.
            }
B
Brian Anderson 已提交
1815
            Some(name) => {
1816
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1817

1818
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
1819
                    None => {
1820
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
1821
                               name,
1822
                               module_to_string(&*orig_module));
1823
                    }
B
Brian Anderson 已提交
1824
                    Some(name_bindings) => {
1825
                        match name_bindings.type_ns.module() {
B
Brian Anderson 已提交
1826
                            None => {
C
corentih 已提交
1827
                                debug!("!!! (with scope) didn't find module for `{}` in `{}`",
1828
                                       name,
1829
                                       module_to_string(&*orig_module));
1830
                            }
B
Brian Anderson 已提交
1831
                            Some(module_) => {
1832
                                self.current_module = module_;
1833 1834 1835 1836 1837 1838 1839
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
1840
        f(self);
1841 1842 1843 1844

        self.current_module = orig_module;
    }

S
Seo Sanghyeon 已提交
1845 1846
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1847 1848 1849 1850 1851 1852 1853 1854
    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 已提交
1855
                    return None;
1856 1857 1858
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1859
            if result.is_some() {
C
corentih 已提交
1860
                return result;
1861 1862 1863 1864 1865
            }
        }
        None
    }

1866
    fn resolve_crate(&mut self, krate: &hir::Crate) {
1867
        debug!("(resolving crate) starting");
1868

1869
        intravisit::walk_crate(self, krate);
1870 1871
    }

W
we 已提交
1872 1873
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
C
corentih 已提交
1874 1875 1876 1877
            span_err!(self.session,
                      span,
                      E0317,
                      "user-defined types or type parameters cannot shadow the primitive types");
W
we 已提交
1878 1879 1880
        }
    }

1881
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
1882
        let name = item.name;
1883

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

1886
        match item.node {
1887 1888 1889
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
1890 1891
                self.check_if_primitive_type_name(name, item.span);

C
corentih 已提交
1892
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1893
                                             |this| intravisit::walk_item(this, item));
1894
            }
1895
            ItemFn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1896
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
1897
                                             |this| intravisit::walk_item(this, item));
1898 1899
            }

F
Flavio Percoco 已提交
1900
            ItemDefaultImpl(_, ref trait_ref) => {
1901
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1902
            }
C
corentih 已提交
1903
            ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
1904
                self.resolve_implementation(generics,
1905
                                            opt_trait_ref,
1906
                                            &**self_type,
1907
                                            item.id,
1908
                                            impl_items);
1909 1910
            }

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

1914 1915 1916 1917 1918
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
1919 1920
                    let local_def_id = this.ast_map.local_def_id(item.id);
                    this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
1921
                        this.visit_generics(generics);
1922
                        walk_list!(this, visit_ty_param_bound, bounds);
1923 1924

                        for trait_item in trait_items {
1925
                            match trait_item.node {
1926
                                hir::ConstTraitItem(_, ref default) => {
1927 1928 1929 1930 1931
                                    // 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| {
1932
                                            intravisit::walk_trait_item(this, trait_item)
1933 1934
                                        });
                                    } else {
1935
                                        intravisit::walk_trait_item(this, trait_item)
1936 1937
                                    }
                                }
1938
                                hir::MethodTraitItem(ref sig, _) => {
1939 1940 1941 1942 1943
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
1944
                                        intravisit::walk_trait_item(this, trait_item)
1945
                                    });
1946
                                }
1947
                                hir::TypeTraitItem(..) => {
V
Vadim Petrochenkov 已提交
1948
                                    this.check_if_primitive_type_name(trait_item.name,
1949
                                                                      trait_item.span);
1950
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1951
                                        intravisit::walk_trait_item(this, trait_item)
1952
                                    });
1953 1954 1955 1956
                                }
                            };
                        }
                    });
1957
                });
1958 1959
            }

1960
            ItemMod(_) | ItemForeignMod(_) => {
1961
                self.with_scope(Some(name), |this| {
1962
                    intravisit::walk_item(this, item);
1963
                });
1964 1965
            }

1966
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
1967
                self.with_constant_rib(|this| {
1968
                    intravisit::walk_item(this, item);
1969
                });
1970
            }
1971

W
we 已提交
1972 1973
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
1974
                let check_rename = |this: &Self, id, name| {
1975
                    match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
1976
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
1977
                            this.check_if_primitive_type_name(name, item.span);
W
we 已提交
1978 1979 1980
                        }
                        _ => {}
                    }
1981 1982 1983
                };

                match view_path.node {
1984 1985
                    hir::ViewPathSimple(name, _) => {
                        check_rename(self, item.id, name);
1986
                    }
1987
                    hir::ViewPathList(ref prefix, ref items) => {
1988
                        for item in items {
1989 1990
                            if let Some(name) = item.node.rename() {
                                check_rename(self, item.node.id(), name);
1991 1992 1993 1994 1995 1996 1997 1998
                            }
                        }

                        // 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 已提交
1999 2000
                                Some((def, lp)) =>
                                    self.record_def(item.id, PathResolution::new(def, lp, 0)),
2001 2002 2003 2004 2005 2006
                                None => {
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
                                }
2007 2008 2009 2010
                            }
                        }
                    }
                    _ => {}
W
we 已提交
2011 2012 2013
                }
            }

2014
            ItemExternCrate(_) => {
2015
                // do nothing, these are just around to be encoded
2016
            }
2017 2018 2019
        }
    }

C
corentih 已提交
2020 2021
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2022
    {
2023
        match type_parameters {
2024
            HasTypeParameters(generics, space, rib_kind) => {
2025
                let mut function_type_rib = Rib::new(rib_kind);
2026
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2027
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2028
                    let name = type_parameter.name;
2029
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2030

2031
                    if seen_bindings.contains(&name) {
2032 2033
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
2034
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
2035
                    }
2036
                    seen_bindings.insert(name);
2037

2038
                    // plain insert (no renaming)
C
corentih 已提交
2039 2040 2041 2042 2043 2044 2045
                    function_type_rib.bindings
                                     .insert(name,
                                             DlDef(DefTyParam(space,
                                                              index as u32,
                                                              self.ast_map
                                                                  .local_def_id(type_parameter.id),
                                                              name)));
2046
                }
2047
                self.type_ribs.push(function_type_rib);
2048 2049
            }

B
Brian Anderson 已提交
2050
            NoTypeParameters => {
2051 2052 2053 2054
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2055
        f(self);
2056

2057
        match type_parameters {
C
corentih 已提交
2058 2059 2060 2061 2062 2063
            HasTypeParameters(..) => {
                if !self.resolved {
                    self.type_ribs.pop();
                }
            }
            NoTypeParameters => {}
2064 2065 2066
        }
    }

C
corentih 已提交
2067 2068
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2069
    {
2070
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2071
        f(self);
G
Garming Sam 已提交
2072 2073 2074
        if !self.resolved {
            self.label_ribs.pop();
        }
2075
    }
2076

C
corentih 已提交
2077 2078
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2079
    {
2080 2081
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2082
        f(self);
G
Garming Sam 已提交
2083 2084 2085 2086
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
2087 2088
    }

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

2093
        // Create a label rib for the function.
2094
        self.label_ribs.push(Rib::new(rib_kind));
2095

2096 2097 2098
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
C
corentih 已提交
2099
            self.resolve_pattern(&*argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
2100

2101
            self.visit_ty(&*argument.ty);
2102

2103 2104
            debug!("(resolving function) recorded argument");
        }
2105
        intravisit::walk_fn_ret_ty(self, &declaration.output);
2106

2107
        // Resolve the function body.
2108
        self.visit_block(block);
2109

2110
        debug!("(resolving function) leaving function");
2111

G
Garming Sam 已提交
2112 2113 2114 2115
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
2116 2117
    }

F
Felix S. Klock II 已提交
2118
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2119
                               id: NodeId,
2120
                               trait_path: &Path,
2121
                               path_depth: usize)
2122 2123 2124 2125 2126 2127
                               -> 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 {
2128 2129
                resolve_error(self,
                              trait_path.span,
2130
                              ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
C
corentih 已提交
2131
                                                                                  path_depth)));
2132 2133

                // If it's a typedef, give a note
2134
                if let DefTy(..) = path_res.base_def {
C
corentih 已提交
2135 2136
                    self.session
                        .span_note(trait_path.span, "`type` aliases cannot be used for traits");
2137
                }
2138 2139
                Err(())
            }
2140
        } else {
2141 2142
            resolve_error(self,
                          trait_path.span,
C
corentih 已提交
2143 2144
                          ResolutionError::UndeclaredTraitName(&*path_names_to_string(trait_path,
                                                                                      path_depth)));
2145
            Err(())
2146 2147 2148
        }
    }

2149
    fn resolve_generics(&mut self, generics: &Generics) {
2150
        for type_parameter in generics.ty_params.iter() {
2151
            self.check_if_primitive_type_name(type_parameter.name, type_parameter.span);
2152 2153
        }
        for predicate in &generics.where_clause.predicates {
2154
            match predicate {
2155 2156 2157
                &hir::WherePredicate::BoundPredicate(_) |
                &hir::WherePredicate::RegionPredicate(_) => {}
                &hir::WherePredicate::EqPredicate(ref eq_pred) => {
2158 2159 2160 2161
                    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 {
2162 2163
                        resolve_error(self,
                                      eq_pred.span,
2164
                                      ResolutionError::UndeclaredAssociatedType);
2165 2166
                    }
                }
2167 2168
            }
        }
2169
        intravisit::walk_generics(self, generics);
2170 2171
    }

2172 2173
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2174
    {
2175 2176 2177 2178 2179 2180 2181
        // 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 已提交
2182
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2183
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2184
    {
2185
        let mut new_val = None;
2186
        let mut new_id = None;
E
Eduard Burtescu 已提交
2187
        if let Some(trait_ref) = opt_trait_ref {
2188
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
2189 2190
                                                               &trait_ref.path,
                                                               0) {
2191 2192 2193 2194
                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());
2195
            }
2196
            intravisit::walk_trait_ref(self, trait_ref);
2197
        }
2198
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2199
        let result = f(self, new_id);
2200 2201 2202 2203
        self.current_trait_ref = original_trait_ref;
        result
    }

2204 2205 2206 2207 2208 2209 2210 2211 2212 2213
    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 已提交
2214 2215 2216
        if !self.resolved {
            self.type_ribs.pop();
        }
2217 2218
    }

F
Felix S. Klock II 已提交
2219
    fn resolve_implementation(&mut self,
2220 2221 2222
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2223
                              item_id: NodeId,
2224
                              impl_items: &[ImplItem]) {
2225
        // If applicable, create a rib for the type parameters.
2226
        self.with_type_parameter_rib(HasTypeParameters(generics,
2227
                                                       TypeSpace,
2228
                                                       ItemRibKind),
2229
                                     |this| {
2230
            // Resolve the type parameters.
2231
            this.visit_generics(generics);
2232

2233
            // Resolve the trait reference, if necessary.
2234
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2235
                // Resolve the self type.
2236
                this.visit_ty(self_type);
2237

2238 2239 2240 2241
                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 {
2242
                                hir::ImplItemKind::Const(..) => {
2243
                                    // If this is a trait impl, ensure the const
2244
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2245
                                    this.check_trait_item(impl_item.name,
2246 2247
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2248
                                    this.with_constant_rib(|this| {
2249
                                        intravisit::walk_impl_item(this, impl_item);
2250 2251
                                    });
                                }
2252
                                hir::ImplItemKind::Method(ref sig, _) => {
2253 2254
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2255
                                    this.check_trait_item(impl_item.name,
2256 2257
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
2258 2259 2260 2261 2262 2263 2264 2265

                                    // 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| {
2266
                                        intravisit::walk_impl_item(this, impl_item);
2267 2268
                                    });
                                }
2269
                                hir::ImplItemKind::Type(ref ty) => {
2270
                                    // If this is a trait impl, ensure the type
2271
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2272
                                    this.check_trait_item(impl_item.name,
2273 2274
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2275

2276 2277
                                    this.visit_ty(ty);
                                }
2278
                            }
2279
                        }
2280
                    });
2281 2282
                });
            });
2283
        });
2284 2285
    }

2286
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
2287 2288 2289 2290
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2291
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2292
            if !self.trait_item_map.contains_key(&(name, did)) {
2293
                let path_str = path_names_to_string(&trait_ref.path, 0);
C
corentih 已提交
2294
                resolve_error(self, span, err(name, &*path_str));
2295 2296 2297 2298
            }
        }
    }

E
Eduard Burtescu 已提交
2299
    fn resolve_local(&mut self, local: &Local) {
2300
        // Resolve the type.
2301
        walk_list!(self, visit_ty, &local.ty);
2302

2303
        // Resolve the initializer.
2304
        walk_list!(self, visit_expr, &local.init);
2305 2306

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

J
John Clements 已提交
2310 2311 2312 2313
    // 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 已提交
2314
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2315
        let mut result = HashMap::new();
2316 2317
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = path1.node;
C
corentih 已提交
2318 2319 2320 2321 2322
            result.insert(name,
                          BindingInfo {
                              span: sp,
                              binding_mode: binding_mode,
                          });
2323
        });
2324
        return result;
2325 2326
    }

J
John Clements 已提交
2327 2328
    // 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 已提交
2329
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2330
        if arm.pats.is_empty() {
C
corentih 已提交
2331
            return;
2332
        }
2333
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2334
        for (i, p) in arm.pats.iter().enumerate() {
2335
            let map_i = self.binding_mode_map(&**p);
2336

2337
            for (&key, &binding_0) in &map_0 {
2338
                match map_i.get(&key) {
C
corentih 已提交
2339
                    None => {
2340
                        resolve_error(self,
C
corentih 已提交
2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
                                      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));
                        }
2351
                    }
2352 2353 2354
                }
            }

2355
            for (&key, &binding) in &map_i {
2356
                if !map_0.contains_key(&key) {
2357 2358
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2359
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2360 2361 2362
                }
            }
        }
2363 2364
    }

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

2368
        let mut bindings_list = HashMap::new();
2369
        for pattern in &arm.pats {
2370
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2371 2372
        }

2373 2374 2375 2376
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2377
        walk_list!(self, visit_expr, &arm.guard);
2378
        self.visit_expr(&*arm.body);
2379

G
Garming Sam 已提交
2380 2381 2382
        if !self.resolved {
            self.value_ribs.pop();
        }
2383 2384
    }

E
Eduard Burtescu 已提交
2385
    fn resolve_block(&mut self, block: &Block) {
2386
        debug!("(resolving block) entering block");
2387
        self.value_ribs.push(Rib::new(NormalRibKind));
2388 2389

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
2390
        let orig_module = self.current_module.clone();
2391
        match orig_module.anonymous_children.borrow().get(&block.id) {
C
corentih 已提交
2392 2393 2394
            None => {
                // Nothing to do.
            }
E
Eduard Burtescu 已提交
2395
            Some(anonymous_module) => {
C
corentih 已提交
2396
                debug!("(resolving block) found anonymous module, moving down");
E
Eduard Burtescu 已提交
2397
                self.current_module = anonymous_module.clone();
2398 2399 2400
            }
        }

2401 2402
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2403
        for statement in &block.stmts {
2404
            if let hir::StmtDecl(ref declaration, _) = statement.node {
2405 2406
                if let hir::DeclItem(i) = declaration.node {
                    let i = self.ast_map.expect_item(i.id);
2407 2408
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
C
corentih 已提交
2409 2410 2411 2412
                            span_err!(self.session,
                                      i.span,
                                      E0154,
                                      "imports are not allowed after non-item statements");
2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

2424
        // Descend into the block.
2425
        intravisit::walk_block(self, block);
2426 2427

        // Move back up.
G
Garming Sam 已提交
2428
        if !self.resolved {
2429
            self.current_module = orig_module;
G
Garming Sam 已提交
2430 2431
            self.value_ribs.pop();
        }
2432
        debug!("(resolving block) leaving block");
2433 2434
    }

F
Felix S. Klock II 已提交
2435
    fn resolve_type(&mut self, ty: &Ty) {
2436
        match ty.node {
2437
            TyPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2438 2439 2440 2441 2442 2443 2444 2445
                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.
2446
                        intravisit::walk_ty(self, ty);
C
corentih 已提交
2447 2448 2449 2450
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2451 2452

                // This is a path in the type namespace. Walk through scopes
2453
                // looking for it.
2454
                match resolution {
B
Brian Anderson 已提交
2455
                    Some(def) => {
2456
                        // Write the result into the def map.
C
corentih 已提交
2457
                        debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2458
                               path_names_to_string(path, 0),
C
corentih 已提交
2459 2460
                               ty.id,
                               def);
2461
                        self.record_def(ty.id, def);
2462
                    }
B
Brian Anderson 已提交
2463
                    None => {
2464 2465 2466
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2467 2468 2469 2470
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2471
                        };
2472

2473
                        let self_type_name = special_idents::type_self.name;
C
corentih 已提交
2474 2475 2476 2477
                        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 已提交
2478
                        if is_invalid_self_type_name {
2479 2480
                            resolve_error(self,
                                          ty.span,
2481
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2482
                        } else {
2483 2484
                            resolve_error(self,
                                          ty.span,
2485
                                          ResolutionError::UseOfUndeclared(
2486 2487 2488 2489
                                                                    kind,
                                                                    &*path_names_to_string(path,
                                                                                           0))
                                         );
G
Guillaume Gomez 已提交
2490
                        }
2491 2492
                    }
                }
2493
            }
2494
            _ => {}
2495
        }
2496
        // Resolve embedded types.
2497
        intravisit::walk_ty(self, ty);
2498 2499
    }

F
Felix S. Klock II 已提交
2500
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2501
                       pattern: &Pat,
2502 2503 2504
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2505
                       bindings_list: &mut HashMap<Name, NodeId>) {
2506
        let pat_id = pattern.id;
2507
        walk_pat(pattern, |pattern| {
2508
            match pattern.node {
2509 2510
                PatIdent(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatIdent with no type parameters
2511 2512 2513 2514
                    // 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
2515 2516 2517 2518
                    // 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();
2519

2520
                    let ident = path1.node;
2521
                    let renamed = ident.name;
2522

2523 2524
                    match self.resolve_bare_identifier_pattern(ident.unhygienic_name,
                                                               pattern.span) {
2525
                        FoundStructOrEnumVariant(def, lp) if const_ok => {
C
corentih 已提交
2526
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2527
                                   renamed);
2528

C
corentih 已提交
2529 2530 2531 2532 2533 2534 2535 2536 2537
                            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,
                                            });
2538
                        }
A
Alex Crichton 已提交
2539
                        FoundStructOrEnumVariant(..) => {
2540
                            resolve_error(
2541
                                self,
2542
                                pattern.span,
2543
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2544 2545
                                    renamed)
                            );
2546
                        }
2547
                        FoundConst(def, lp, _) if const_ok => {
C
corentih 已提交
2548 2549 2550 2551 2552 2553 2554 2555 2556
                            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,
                                            });
2557
                        }
2558
                        FoundConst(def, _, name) => {
2559
                            resolve_error(
2560 2561
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2562 2563
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2564
                            );
2565
                        }
2566
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2567
                            debug!("(resolving pattern) binding `{}`", renamed);
2568

2569 2570
                            let def_id = self.ast_map.local_def_id(pattern.id);
                            let def = DefLocal(def_id, pattern.id);
2571 2572 2573 2574 2575

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

C
corentih 已提交
2576 2577 2578 2579 2580 2581
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: LastMod(AllPublic),
                                                depth: 0,
                                            });
2582 2583 2584 2585 2586 2587

                            // 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.)
2588 2589
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2590 2591
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2592
                                bindings_list.insert(renamed, pat_id);
2593
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2594
                               bindings_list.contains_key(&renamed) {
2595 2596
                                // Forbid duplicate bindings in the same
                                // parameter list.
2597
                                resolve_error(
2598 2599
                                    self,
                                    pattern.span,
2600
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2601
                                        &ident.name.as_str())
2602
                                );
C
corentih 已提交
2603
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2604 2605
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2606
                                resolve_error(
2607 2608
                                    self,
                                    pattern.span,
2609
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2610
                                        &ident.name.as_str())
2611
                                );
2612
                            }
2613 2614
                            // Else, not bound in the same pattern: do
                            // nothing.
2615 2616 2617 2618
                        }
                    }
                }

2619
                PatEnum(ref path, _) => {
2620
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638
                    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,
                    };
2639
                    if let Some(path_res) = resolution {
2640
                        match path_res.base_def {
2641
                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
2642 2643 2644
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
2645 2646
                                resolve_error(&self,
                                              path.span,
2647
                                              ResolutionError::StaticVariableReference);
2648
                            }
2649 2650 2651 2652
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2653
                                // be a `T::CONST` that typeck will resolve.
2654
                                if path_res.depth == 0 {
2655
                                    resolve_error(
2656
                                        self,
2657
                                        path.span,
2658
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2659 2660 2661 2662 2663 2664
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2665
                                    );
2666
                                } else {
C
corentih 已提交
2667 2668 2669 2670 2671
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2672 2673
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2674 2675 2676 2677 2678
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2679
                        resolve_error(
2680 2681
                            self,
                            path.span,
2682
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2683
                                &path.segments.last().unwrap().identifier.name.as_str())
2684
                        );
2685
                    }
2686
                    intravisit::walk_path(self, path);
2687 2688 2689 2690
                }

                PatQPath(ref qself, ref path) => {
                    // Associated constants only.
C
corentih 已提交
2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706
                    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);
2707
                            intravisit::walk_pat(self, pattern);
C
corentih 已提交
2708 2709 2710 2711
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2712 2713 2714 2715 2716 2717 2718
                    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);
                            }
2719
                            _ => {
2720
                                resolve_error(
2721 2722
                                    self,
                                    path.span,
2723
                                    ResolutionError::NotAnAssociatedConst(
2724
                                        &path.segments.last().unwrap().identifier.name.as_str()
2725 2726
                                    )
                                );
2727
                            }
2728
                        }
2729
                    } else {
C
corentih 已提交
2730 2731 2732 2733 2734 2735 2736 2737
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2738
                    }
2739
                    intravisit::walk_pat(self, pattern);
2740 2741
                }

2742
                PatStruct(ref path, _, _) => {
2743
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2744
                        Some(definition) => {
2745 2746
                            self.record_def(pattern.id, definition);
                        }
2747
                        result => {
C
corentih 已提交
2748
                            debug!("(resolving pattern) didn't find struct def: {:?}", result);
2749 2750 2751
                            resolve_error(
                                self,
                                path.span,
2752
                                ResolutionError::DoesNotNameAStruct(
2753 2754
                                    &*path_names_to_string(path, 0))
                            );
2755 2756
                        }
                    }
2757
                    intravisit::walk_path(self, path);
2758 2759 2760
                }

                PatLit(_) | PatRange(..) => {
2761
                    intravisit::walk_pat(self, pattern);
2762 2763
                }

2764
                _ => {
2765 2766 2767
                    // Nothing to do.
                }
            }
2768
            true
2769
        });
2770 2771
    }

C
corentih 已提交
2772 2773 2774
    fn resolve_bare_identifier_pattern(&mut self,
                                       name: Name,
                                       span: Span)
E
Eduard Burtescu 已提交
2775 2776
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
C
corentih 已提交
2777
        match self.resolve_item_in_lexical_scope(module, name, ValueNS) {
2778
            Success((target, _)) => {
C
corentih 已提交
2779 2780
                debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
                       name,
2781 2782
                       target.binding.borrow());
                match target.binding.def() {
B
Brian Anderson 已提交
2783
                    None => {
C
corentih 已提交
2784 2785
                        panic!("resolved name in the value namespace to a set of name bindings \
                                with no def?!");
2786
                    }
2787 2788 2789 2790 2791 2792 2793 2794
                    // 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.
                    Some(def @ DefVariant(..)) | Some(def @ DefStruct(..)) => {
                        return FoundStructOrEnumVariant(def, LastMod(AllPublic));
                    }
                    Some(def @ DefConst(..)) | Some(def @ DefAssociatedConst(..)) => {
                        return FoundConst(def, LastMod(AllPublic), name);
2795
                    }
2796 2797 2798
                    Some(DefStatic(..)) => {
                        resolve_error(self, span, ResolutionError::StaticVariableReference);
                        return BareIdentifierPatternUnresolved;
2799
                    }
2800
                    _ => return BareIdentifierPatternUnresolved
2801 2802 2803
                }
            }

B
Brian Anderson 已提交
2804
            Indeterminate => {
S
Steve Klabnik 已提交
2805
                panic!("unexpected indeterminate result");
2806
            }
2807 2808 2809
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
2810
                        resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
2811
                    }
C
corentih 已提交
2812
                    None => (),
2813
                }
2814

C
corentih 已提交
2815
                debug!("(resolve bare identifier pattern) failed to find {}", name);
2816
                return BareIdentifierPatternUnresolved;
2817 2818 2819 2820
            }
        }
    }

2821 2822 2823
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2824
                                   maybe_qself: Option<&hir::QSelf>,
2825 2826 2827
                                   path: &Path,
                                   namespace: Namespace,
                                   check_ribs: bool)
C
corentih 已提交
2828
                                   -> AssocItemResolveResult {
2829 2830
        let max_assoc_types;

2831
        match maybe_qself {
2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842
            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();
            }
2843 2844 2845 2846 2847 2848 2849 2850 2851 2852
        }

        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 已提交
2853
                resolution = this.resolve_path(id, path, depth, TypeNS, true);
2854 2855 2856 2857 2858 2859 2860 2861 2862
            });
        }
        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

2863 2864
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
2865 2866
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
G
Garming Sam 已提交
2867 2868 2869 2870 2871
    pub fn resolve_path(&mut self,
                        id: NodeId,
                        path: &Path,
                        path_depth: usize,
                        namespace: Namespace,
C
corentih 已提交
2872 2873
                        check_ribs: bool)
                        -> Option<PathResolution> {
2874
        let span = path.span;
C
corentih 已提交
2875
        let segments = &path.segments[..path.segments.len() - path_depth];
2876

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

2879
        if path.global {
2880
            let def = self.resolve_crate_relative_path(span, segments, namespace);
2881
            return def.map(mk_res);
2882 2883
        }

2884
        // Try to find a path to an item in a module.
C
corentih 已提交
2885 2886 2887
        let unqualified_def = self.resolve_identifier(segments.last().unwrap().identifier,
                                                      namespace,
                                                      check_ribs);
2888

N
Nick Cameron 已提交
2889
        if segments.len() <= 1 {
C
corentih 已提交
2890 2891 2892 2893
            return unqualified_def.and_then(|def| self.adjust_local_def(def, span))
                                  .map(|def| {
                                      PathResolution::new(def, LastMod(AllPublic), path_depth)
                                  });
N
Nick Cameron 已提交
2894
        }
2895

N
Nick Cameron 已提交
2896 2897
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
2898
            (Some((ref d, _)), Some(ref ud)) if *d == ud.def => {
N
Nick Cameron 已提交
2899 2900
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
2901 2902
                              id,
                              span,
N
Nick Cameron 已提交
2903 2904 2905
                              "unnecessary qualification".to_string());
            }
            _ => {}
2906
        }
N
Nick Cameron 已提交
2907 2908

        def.map(mk_res)
2909 2910
    }

2911
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2912
    fn resolve_identifier(&mut self,
2913
                          identifier: hir::Ident,
2914
                          namespace: Namespace,
2915 2916
                          check_ribs: bool)
                          -> Option<LocalDef> {
2917 2918 2919 2920
        // 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
2921
                                        .get(&identifier.unhygienic_name) {
2922
                return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
2923 2924 2925
            }
        }

2926
        if check_ribs {
C
corentih 已提交
2927
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, namespace) {
2928
                return Some(def);
2929 2930 2931
            }
        }

2932
        self.resolve_item_by_name_in_lexical_scope(identifier.unhygienic_name, namespace)
2933 2934 2935 2936
            .map(LocalDef::from_def)
    }

    // Resolve a local definition, potentially adjusting for closures.
2937
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
2938
        let ribs = match local_def.ribs {
C
corentih 已提交
2939 2940 2941
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
2942 2943 2944 2945
        };
        let mut def = local_def.def;
        match def {
            DefUpvar(..) => {
C
corentih 已提交
2946
                self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957
            }
            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 已提交
2958 2959 2960
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2961 2962 2963 2964
                            if let Some(&index) = seen.get(&node_id) {
                                def = DefUpvar(node_def_id, node_id, index, function_id);
                                continue;
                            }
C
corentih 已提交
2965 2966 2967
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2968
                            let depth = vec.len();
C
corentih 已提交
2969 2970 2971 2972
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2973 2974 2975 2976 2977 2978 2979 2980

                            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 已提交
2981 2982 2983
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2984 2985 2986 2987
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2988 2989 2990
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021
                            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);
3022 3023
    }

3024
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3025
    fn resolve_module_relative_path(&mut self,
3026
                                    span: Span,
3027
                                    segments: &[hir::PathSegment],
3028 3029
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
C
corentih 已提交
3030 3031 3032 3033 3034 3035
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3036

3037
        let containing_module;
3038
        let last_private;
N
Nick Cameron 已提交
3039 3040
        let current_module = self.current_module.clone();
        match self.resolve_module_path(current_module,
3041
                                       &module_path[..],
3042
                                       UseLexicalScope,
3043
                                       span,
3044
                                       PathSearch) {
3045 3046 3047 3048
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3049
                        let msg = format!("Use of undeclared type or module `{}`",
3050
                                          names_to_string(&module_path));
3051
                        (span, msg)
3052 3053
                    }
                };
3054

3055
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3056
                return None;
3057
            }
S
Steve Klabnik 已提交
3058
            Indeterminate => panic!("indeterminate unexpected"),
3059
            Success((resulting_module, resulting_last_private)) => {
3060
                containing_module = resulting_module;
3061
                last_private = resulting_last_private;
3062 3063 3064
            }
        }

3065
        let name = segments.last().unwrap().identifier.name;
3066 3067 3068 3069 3070 3071 3072
        let def = match self.resolve_name_in_module(containing_module.clone(),
                                                    name,
                                                    namespace,
                                                    NameSearchType::PathSearch,
                                                    false) {
            Success((Target { binding, .. }, _)) => {
                let (def, lp) = binding.def_and_lp();
3073
                (def, last_private.or(lp))
3074
            }
3075
            _ => return None,
3076
        };
3077
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id() {
3078
            self.used_crates.insert(kid);
3079
        }
3080
        return Some(def);
3081 3082
    }

3083 3084
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3085
    fn resolve_crate_relative_path(&mut self,
3086
                                   span: Span,
3087
                                   segments: &[hir::PathSegment],
3088
                                   namespace: Namespace)
C
corentih 已提交
3089 3090 3091 3092 3093 3094 3095
                                   -> Option<(Def, LastPrivate)> {
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3096

3097
        let root_module = self.graph_root.clone();
3098

3099
        let containing_module;
3100
        let last_private;
3101
        match self.resolve_module_path_from_root(root_module,
3102
                                                 &module_path[..],
3103
                                                 0,
3104
                                                 span,
3105
                                                 PathSearch,
3106
                                                 LastMod(AllPublic)) {
3107 3108 3109 3110 3111
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3112
                                          names_to_string(&module_path[..]));
3113
                        (span, msg)
3114 3115 3116
                    }
                };

3117
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
B
Brian Anderson 已提交
3118
                return None;
3119 3120
            }

B
Brian Anderson 已提交
3121
            Indeterminate => {
S
Steve Klabnik 已提交
3122
                panic!("indeterminate unexpected");
3123 3124
            }

3125
            Success((resulting_module, resulting_last_private)) => {
3126
                containing_module = resulting_module;
3127
                last_private = resulting_last_private;
3128 3129 3130
            }
        }

3131
        let name = segments.last().unwrap().identifier.name;
3132 3133 3134 3135 3136 3137 3138 3139
        match self.resolve_name_in_module(containing_module,
                                          name,
                                          namespace,
                                          NameSearchType::PathSearch,
                                          false) {
            Success((Target { binding, .. }, _)) => {
                let (def, lp) = binding.def_and_lp();
                Some((def, last_private.or(lp)))
3140
            }
3141
            _ => None,
3142 3143 3144
        }
    }

F
Felix S. Klock II 已提交
3145
    fn resolve_identifier_in_local_ribs(&mut self,
3146
                                        ident: hir::Ident,
3147 3148
                                        namespace: Namespace)
                                        -> Option<LocalDef> {
3149
        // Check the local set of ribs.
3150
        let (name, ribs) = match namespace {
3151 3152
            ValueNS => (ident.name, &self.value_ribs),
            TypeNS => (ident.unhygienic_name, &self.type_ribs),
3153
        };
3154

3155 3156 3157 3158 3159
        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 已提交
3160 3161 3162
                               name,
                               def,
                               i);
3163 3164
                        return Some(LocalDef {
                            ribs: Some((namespace, i)),
C
corentih 已提交
3165
                            def: def,
3166 3167 3168 3169
                        });
                    }
                    def_like => {
                        debug!("(resolving path in local ribs) resolved `{}` to pseudo-def {:?}",
C
corentih 已提交
3170 3171
                               name,
                               def_like);
3172 3173 3174
                        return None;
                    }
                }
3175 3176
            }
        }
3177 3178

        None
3179 3180
    }

3181 3182 3183
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
C
corentih 已提交
3184
                                             -> Option<Def> {
3185
        // Check the items.
E
Eduard Burtescu 已提交
3186
        let module = self.current_module.clone();
C
corentih 已提交
3187
        match self.resolve_item_in_lexical_scope(module, name, namespace) {
3188
            Success((target, _)) => {
3189
                match target.binding.def() {
B
Brian Anderson 已提交
3190
                    None => {
3191 3192
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
C
corentih 已提交
3193 3194 3195
                        debug!("(resolving item path by identifier in lexical scope) failed to \
                                resolve {} after success...",
                               name);
3196
                        None
3197
                    }
B
Brian Anderson 已提交
3198
                    Some(def) => {
C
corentih 已提交
3199
                        debug!("(resolving item path in lexical scope) resolved `{}` to item",
3200
                               name);
3201 3202 3203
                        // 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.
3204
                        Some(def)
3205 3206 3207
                    }
                }
            }
B
Brian Anderson 已提交
3208
            Indeterminate => {
S
Steve Klabnik 已提交
3209
                panic!("unexpected indeterminate result");
3210
            }
3211
            Failed(err) => {
C
corentih 已提交
3212 3213
                debug!("(resolving item path by identifier in lexical scope) failed to resolve {}",
                       name);
N
Nick Cameron 已提交
3214 3215

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

3219
                None
3220 3221 3222 3223
            }
        }
    }

C
corentih 已提交
3224 3225
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
3226
    {
3227
        self.emit_errors = false;
A
Alex Crichton 已提交
3228
        let rs = f(self);
3229 3230 3231 3232
        self.emit_errors = true;
        rs
    }

3233
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
C
corentih 已提交
3234 3235 3236
        fn extract_path_and_node_id(t: &Ty,
                                    allow: FallbackChecks)
                                    -> Option<(Path, NodeId, FallbackChecks)> {
3237
            match t.node {
3238
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3239 3240
                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),
3241 3242 3243 3244 3245 3246 3247
                // 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 已提交
3248 3249 3250 3251
        fn get_module(this: &mut Resolver,
                      span: Span,
                      name_path: &[ast::Name])
                      -> Option<Rc<Module>> {
3252
            let root = this.current_module.clone();
3253
            let last_name = name_path.last().unwrap();
3254

3255
            if name_path.len() == 1 {
3256
                match this.primitive_type_table.primitive_types.get(last_name) {
3257 3258
                    Some(_) => None,
                    None => {
3259
                        match this.current_module.children.borrow().get(last_name) {
3260
                            Some(child) => child.type_ns.module(),
C
corentih 已提交
3261
                            None => None,
3262 3263 3264 3265 3266
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
3267 3268 3269 3270
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
3271
                    Success((module, _)) => Some(module),
C
corentih 已提交
3272
                    _ => None,
3273 3274 3275 3276
                }
            }
        }

3277
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
3278 3279
            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
                let sig = match this.ast_map.get(node_id) {
3280 3281
                    hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                        hir::MethodTraitItem(ref sig, _) => sig,
C
corentih 已提交
3282
                        _ => return false,
3283
                    },
3284
                    hir_map::NodeImplItem(impl_item) => match impl_item.node {
3285
                        hir::ImplItemKind::Method(ref sig, _) => sig,
C
corentih 已提交
3286
                        _ => return false,
3287
                    },
C
corentih 已提交
3288
                    _ => return false,
3289
                };
3290
                sig.explicit_self.node == hir::SelfStatic
3291
            } else {
3292
                this.session.cstore.is_static_method(did)
3293 3294 3295
            }
        }

3296 3297 3298 3299
        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,
3300 3301 3302 3303
            },
            None => return NoSuggestion,
        };

3304 3305
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3306 3307 3308 3309
            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) {
3310 3311 3312 3313 3314
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3315
                    }
3316 3317 3318
                },
                _ => {} // Self type didn't resolve properly
            }
3319 3320
        }

3321
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3322 3323

        // Look for a method in the current self type's impl module.
3324 3325
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
3326
                if let Some(DefMethod(did)) = binding.value_ns.def() {
3327
                    if is_static_method(self, did) {
C
corentih 已提交
3328
                        return StaticMethod(path_names_to_string(&path, 0));
3329 3330 3331 3332 3333
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3334 3335
                    }
                }
3336
            }
3337 3338 3339
        }

        // Look for a method in the current trait.
3340 3341 3342
        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) {
3343
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3344 3345
                } else {
                    return TraitItem;
3346 3347 3348 3349 3350 3351 3352
                }
            }
        }

        NoSuggestion
    }

3353
    fn find_best_match_for_name(&mut self, name: &str) -> SuggestionType {
3354
        let mut maybes: Vec<token::InternedString> = Vec::new();
3355
        let mut values: Vec<usize> = Vec::new();
3356

3357 3358 3359 3360 3361
        if let Some(macro_name) = self.session.available_macros
                                 .borrow().iter().find(|n| n.as_str() == name) {
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

3362
        for rib in self.value_ribs.iter().rev() {
3363
            for (&k, _) in &rib.bindings {
3364
                maybes.push(k.as_str());
3365
                values.push(usize::MAX);
3366 3367 3368 3369
            }
        }

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

3373
            if values[i] <= values[smallest] {
3374 3375 3376 3377
                smallest = i;
            }
        }

3378
        let max_distance = max_suggestion_distance(name);
C
corentih 已提交
3379
        if !values.is_empty() && values[smallest] <= max_distance && name != &maybes[smallest][..] {
3380

3381
            SuggestionType::Function(maybes[smallest].to_string())
3382 3383

        } else {
3384
            SuggestionType::NotFound
3385 3386 3387
        }
    }

E
Eduard Burtescu 已提交
3388
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3389 3390
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3391 3392 3393

        self.record_candidate_traits_for_expr_if_necessary(expr);

3394
        // Next, resolve the node.
3395
        match expr.node {
3396
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
3397 3398 3399 3400 3401 3402 3403 3404 3405 3406
                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);
3407
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
3408 3409 3410 3411
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
3412

3413 3414
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3415
                if let Some(path_res) = resolution {
3416
                    // Check if struct variant
3417
                    if let DefVariant(_, _, true) = path_res.base_def {
3418
                        let path_name = path_names_to_string(path, 0);
3419

3420 3421
                        resolve_error(self,
                                      expr.span,
3422
                                      ResolutionError::StructVariantUsedAsFunction(&*path_name));
3423

C
corentih 已提交
3424
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3425 3426 3427 3428 3429 3430
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
3431
                    } else {
3432
                        // Write the result into the def map.
3433
                        debug!("(resolving expr) resolved `{}`",
3434
                               path_names_to_string(path, 0));
3435

3436 3437
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3438
                        if path_res.depth != 0 {
3439
                            let method_name = path.segments.last().unwrap().identifier.name;
3440
                            let traits = self.get_traits_containing_item(method_name);
3441 3442 3443
                            self.trait_map.insert(expr.id, traits);
                        }

3444
                        self.record_def(expr.id, path_res);
3445
                    }
3446 3447 3448 3449 3450
                } 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.)
3451
                    let path_name = path_names_to_string(path, 0);
3452 3453 3454 3455
                    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 已提交
3456 3457
                        Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
                            resolve_error(
3458 3459
                                    self,
                                    expr.span,
3460
                                    ResolutionError::StructVariantUsedAsFunction(
3461 3462
                                        &*path_name)
                                );
3463

C
corentih 已提交
3464 3465 3466 3467 3468 3469
                            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);
3470
                            }
C
corentih 已提交
3471
                        }
3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484
                        _ => {
                            // 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
                            });
3485

3486
                            if method_scope && special_names::self_.as_str() == &path_name[..] {
C
corentih 已提交
3487 3488 3489
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3490 3491 3492 3493 3494 3495
                            } 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
3496 3497 3498 3499 3500 3501 3502
                                        match self.find_best_match_for_name(&path_name) {
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
3503 3504 3505
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
C
corentih 已提交
3506
                                    TraitItem => format!("to call `self.{}`", path_name),
3507 3508
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
C
corentih 已提交
3509
                                        format!("to call `{}::{}`", path_str, path_name),
3510 3511
                                };

3512
                                if !msg.is_empty() {
3513
                                    msg = format!(". Did you mean {}?", msg)
3514
                                }
3515

3516 3517
                                resolve_error(self,
                                              expr.span,
C
corentih 已提交
3518
                                              ResolutionError::UnresolvedName(&*path_name, &*msg));
3519
                            }
V
Vincent Belliard 已提交
3520
                        }
3521 3522 3523
                    }
                }

3524
                intravisit::walk_expr(self, expr);
3525 3526
            }

3527
            ExprStruct(ref path, _, _) => {
3528 3529 3530
                // 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.
3531
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3532
                    Some(definition) => self.record_def(expr.id, definition),
3533 3534
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3535

3536 3537
                        resolve_error(self,
                                      path.span,
3538
                                      ResolutionError::DoesNotNameAStruct(
3539 3540
                                                                &*path_names_to_string(path, 0))
                                     );
3541 3542 3543
                    }
                }

3544
                intravisit::walk_expr(self, expr);
3545 3546
            }

P
Pythoner6 已提交
3547
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3548
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3549
                    let def_like = DlDef(DefLabel(expr.id));
3550

3551
                    {
3552
                        let rib = this.label_ribs.last_mut().unwrap();
3553
                        rib.bindings.insert(label.name, def_like);
3554
                    }
3555

3556
                    intravisit::walk_expr(this, expr);
3557
                })
3558 3559
            }

3560
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3561
                match self.search_label(label.node.name) {
3562
                    None => {
3563
                        resolve_error(self,
3564 3565
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3566
                    }
3567
                    Some(DlDef(def @ DefLabel(_))) => {
3568
                        // Since this def is a label, it is never read.
C
corentih 已提交
3569 3570 3571 3572 3573 3574
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            last_private: LastMod(AllPublic),
                                            depth: 0,
                                        })
3575 3576
                    }
                    Some(_) => {
C
corentih 已提交
3577
                        self.session.span_bug(expr.span, "label wasn't mapped to a label def!")
3578 3579 3580 3581
                    }
                }
            }

B
Brian Anderson 已提交
3582
            _ => {
3583
                intravisit::walk_expr(self, expr);
3584 3585 3586 3587
            }
        }
    }

E
Eduard Burtescu 已提交
3588
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3589
        match expr.node {
3590
            ExprField(_, name) => {
3591 3592 3593 3594
                // 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.
3595
                let traits = self.get_traits_containing_item(name.node);
3596
                self.trait_map.insert(expr.id, traits);
3597
            }
3598
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3599
                debug!("(recording candidate traits for expr) recording traits for {}",
3600
                       expr.id);
3601
                let traits = self.get_traits_containing_item(name.node);
3602
                self.trait_map.insert(expr.id, traits);
3603
            }
3604
            _ => {
3605 3606 3607 3608 3609
                // Nothing to do.
            }
        }
    }

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

C
corentih 已提交
3613
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3614
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3615 3616
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3617 3618
            found_traits.push(trait_def_id);
        }
3619

3620
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
3621
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
3622 3623
        loop {
            // Look for the current trait.
3624 3625
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3626
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3627
                        add_trait_info(&mut found_traits, trait_def_id, name);
3628 3629
                    }
                }
3630
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3631
            }
3632

E
Eduard Burtescu 已提交
3633
            // Look for trait children.
3634
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3635

E
Eduard Burtescu 已提交
3636
            {
3637
                for (_, child_names) in search_module.children.borrow().iter() {
3638
                    let def = match child_names.type_ns.def() {
3639
                        Some(def) => def,
C
corentih 已提交
3640
                        None => continue,
3641 3642
                    };
                    let trait_def_id = match def {
3643
                        DefTrait(trait_def_id) => trait_def_id,
3644 3645
                        _ => continue,
                    };
3646
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3647
                        add_trait_info(&mut found_traits, trait_def_id, name);
3648 3649
                    }
                }
E
Eduard Burtescu 已提交
3650
            }
3651

E
Eduard Burtescu 已提交
3652
            // Look for imports.
3653
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
3654 3655 3656 3657
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
3658
                let did = match target.binding.def() {
3659
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3660 3661
                    Some(..) | None => continue,
                };
3662
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3663
                    add_trait_info(&mut found_traits, did, name);
3664 3665 3666 3667
                    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);
3668
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
3669
                        self.used_crates.insert(kid);
3670
                    }
3671
                }
E
Eduard Burtescu 已提交
3672
            }
3673

E
Eduard Burtescu 已提交
3674
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
3675 3676
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
3677
                    search_module = parent_module.upgrade().unwrap();
3678
                }
E
Eduard Burtescu 已提交
3679
            }
3680 3681
        }

E
Eduard Burtescu 已提交
3682
        found_traits
3683 3684
    }

3685 3686
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
C
corentih 已提交
3687 3688 3689 3690
        assert!(match resolution.last_private {
                    LastImport{..} => false,
                    _ => true,
                },
3691
                "Import should only be used for `use` directives");
3692

3693 3694
        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 已提交
3695 3696 3697 3698
            self.session.span_bug(span,
                                  &format!("path resolved multiple times ({:?} before, {:?} now)",
                                           prev_res,
                                           resolution));
3699
        }
3700 3701
    }

F
Felix S. Klock II 已提交
3702
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3703 3704 3705
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3706
        match pat_binding_mode {
3707
            BindByValue(_) => {}
A
Alex Crichton 已提交
3708
            BindByRef(..) => {
3709 3710
                resolve_error(self,
                              pat.span,
3711
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3712 3713 3714 3715
            }
        }
    }

3716 3717 3718 3719 3720 3721 3722
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

3727
        debug!("Children:");
3728
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3729
        for (&name, _) in module_.children.borrow().iter() {
3730
            debug!("* {}", name);
3731 3732
        }

3733
        debug!("Import resolutions:");
3734
        let import_resolutions = module_.import_resolutions.borrow();
3735
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
3736
            let value_repr;
3737
            match import_resolution.target_for_namespace(ValueNS) {
C
corentih 已提交
3738 3739 3740
                None => {
                    value_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
3741
                Some(_) => {
R
Richo Healey 已提交
3742
                    value_repr = " value:?".to_string();
3743
                    // FIXME #4954
3744 3745 3746
                }
            }

N
Niko Matsakis 已提交
3747
            let type_repr;
3748
            match import_resolution.target_for_namespace(TypeNS) {
C
corentih 已提交
3749 3750 3751
                None => {
                    type_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
3752
                Some(_) => {
R
Richo Healey 已提交
3753
                    type_repr = " type:?".to_string();
3754
                    // FIXME #4954
3755 3756 3757
                }
            }

3758
            debug!("* {}:{}{}", name, value_repr, type_repr);
3759 3760 3761 3762
        }
    }
}

3763 3764 3765 3766 3767 3768 3769 3770 3771 3772

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("::")
        }
3773
        result.push_str(&name.as_str());
C
corentih 已提交
3774
    }
3775 3776 3777 3778
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3779
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805
                                    .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);

3806
    if names.is_empty() {
3807 3808 3809 3810 3811 3812
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}


3813
pub struct CrateMap {
J
Jonathan S 已提交
3814
    pub def_map: RefCell<DefMap>,
3815
    pub freevars: FreevarMap,
3816
    pub export_map: ExportMap,
3817 3818
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
C
corentih 已提交
3819
    pub glob_map: Option<GlobMap>,
3820 3821
}

N
Niko Matsakis 已提交
3822
#[derive(PartialEq,Copy, Clone)]
3823 3824
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3825
    No,
3826 3827
}

3828
/// Entry point to crate resolution.
3829
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3830
                               ast_map: &'a hir_map::Map<'tcx>,
3831 3832
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3833
    let krate = ast_map.krate();
3834
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
3835 3836 3837 3838 3839 3840

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

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

3841
    CrateMap {
3842 3843
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3844
        export_map: resolver.export_map,
3845 3846
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
3847
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
3848 3849 3850 3851
            Some(resolver.glob_map)
        } else {
            None
        },
3852
    }
3853
}
3854

3855 3856 3857 3858 3859 3860 3861 3862
/// 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 已提交
3863
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
3864
                                 ast_map: &'a hir_map::Map<'tcx>,
G
Garming Sam 已提交
3865 3866
                                 krate: &'a Crate,
                                 make_glob_map: MakeGlobMap,
3867
                                 callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
G
Garming Sam 已提交
3868
                                 -> Resolver<'a, 'tcx> {
3869
    let mut resolver = Resolver::new(session, ast_map, make_glob_map);
G
Garming Sam 已提交
3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884

    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
}

3885
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }