lib.rs 163.8 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
#![crate_name = "rustc_resolve"]
12
#![unstable(feature = "rustc_private", issue = "27812")]
13 14
#![crate_type = "dylib"]
#![crate_type = "rlib"]
15
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
16
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
17
      html_root_url = "https://doc.rust-lang.org/nightly/")]
18

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

C
corentih 已提交
25 26 27 28
#[macro_use]
extern crate log;
#[macro_use]
extern crate syntax;
29
extern crate arena;
C
corentih 已提交
30 31 32
#[macro_use]
#[no_link]
extern crate rustc_bitflags;
33
extern crate rustc_front;
34 35
extern crate rustc;

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

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

P
Patrick Walton 已提交
63
use syntax::ast;
J
Jeffrey Seyfried 已提交
64
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
65
use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32};
66
use syntax::attr::AttrMetaMethods;
67
use syntax::codemap::{self, Span, Pos};
N
Nick Cameron 已提交
68 69
use syntax::errors::DiagnosticBuilder;
use syntax::parse::token::{self, special_names, special_idents};
70
use syntax::util::lev_distance::find_best_match_for_name;
71

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

90
use std::collections::{HashMap, HashSet};
91
use std::cell::{Cell, RefCell};
92
use std::fmt;
93
use std::mem::replace;
94
use std::rc::Rc;
95

J
Jeffrey Seyfried 已提交
96
use resolve_imports::{Target, ImportDirective, ImportResolutionPerNamespace};
97 98
use resolve_imports::Shadowable;

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

A
Alex Crichton 已提交
103
mod check_unused;
104
mod build_reduced_graph;
105
mod resolve_imports;
106

107 108 109 110 111 112 113 114 115 116 117
// 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;
            }
        }
    )
}

118 119
enum SuggestionType {
    Macro(String),
120
    Function(token::InternedString),
121 122 123
    NotFound,
}

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

203
/// Context of where `ResolutionError::UnresolvedName` arose.
204 205
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum UnresolvedNameContext {
206 207 208 209
    /// `PathIsMod(id)` indicates that a given path, used in
    /// expression context, actually resolved to a module rather than
    /// a value. The `id` attached to the variant is the node id of
    /// the erroneous path expression.
210
    PathIsMod(ast::NodeId),
211 212 213 214

    /// `Other` means we have no extra information about the context
    /// of the unresolved name error. (Maybe we could eliminate all
    /// such cases; but for now, this is an information-free default.)
215 216 217
    Other,
}

C
corentih 已提交
218 219 220
fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                       span: syntax::codemap::Span,
                                       resolution_error: ResolutionError<'b>) {
N
Nick Cameron 已提交
221
    resolve_struct_error(resolver, span, resolution_error).emit();
N
Nick Cameron 已提交
222 223 224 225 226
}

fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                              span: syntax::codemap::Span,
                                              resolution_error: ResolutionError<'b>)
N
Nick Cameron 已提交
227
                                              -> DiagnosticBuilder<'a> {
228
    if !resolver.emit_errors {
N
Nick Cameron 已提交
229
        return resolver.session.diagnostic().struct_dummy();
230
    }
N
Nick Cameron 已提交
231

N
Nick Cameron 已提交
232
    match resolution_error {
233 234 235 236 237 238 239 240
        ResolutionError::NameConflictsWithExternCrate(name) => {
            struct_span_err!(resolver.session,
                             span,
                             E0260,
                             "the name `{}` conflicts with an external crate \
                             that has been imported into this module",
                             name)
        }
241
        ResolutionError::TypeParametersFromOuterFunction => {
N
Nick Cameron 已提交
242 243 244 245 246
            struct_span_err!(resolver.session,
                             span,
                             E0401,
                             "can't use type parameters from outer function; try using a local \
                              type parameter instead")
C
corentih 已提交
247
        }
248
        ResolutionError::OuterTypeParameterContext => {
N
Nick Cameron 已提交
249 250 251 252
            struct_span_err!(resolver.session,
                             span,
                             E0402,
                             "cannot use an outer type parameter in this context")
C
corentih 已提交
253
        }
254
        ResolutionError::NameAlreadyUsedInTypeParameterList(name) => {
N
Nick Cameron 已提交
255 256 257 258 259 260
            struct_span_err!(resolver.session,
                             span,
                             E0403,
                             "the name `{}` is already used for a type parameter in this type \
                              parameter list",
                             name)
C
corentih 已提交
261
        }
262
        ResolutionError::IsNotATrait(name) => {
N
Nick Cameron 已提交
263
            struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
C
corentih 已提交
264
        }
265
        ResolutionError::UndeclaredTraitName(name) => {
N
Nick Cameron 已提交
266 267 268 269 270
            struct_span_err!(resolver.session,
                             span,
                             E0405,
                             "use of undeclared trait name `{}`",
                             name)
C
corentih 已提交
271
        }
272
        ResolutionError::UndeclaredAssociatedType => {
N
Nick Cameron 已提交
273
            struct_span_err!(resolver.session, span, E0406, "undeclared associated type")
C
corentih 已提交
274
        }
275
        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
N
Nick Cameron 已提交
276 277 278 279 280 281
            struct_span_err!(resolver.session,
                             span,
                             E0407,
                             "method `{}` is not a member of trait `{}`",
                             method,
                             trait_)
C
corentih 已提交
282
        }
283
        ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
N
Nick Cameron 已提交
284 285 286 287 288 289
            struct_span_err!(resolver.session,
                             span,
                             E0437,
                             "type `{}` is not a member of trait `{}`",
                             type_,
                             trait_)
C
corentih 已提交
290
        }
291
        ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
N
Nick Cameron 已提交
292 293 294 295 296 297
            struct_span_err!(resolver.session,
                             span,
                             E0438,
                             "const `{}` is not a member of trait `{}`",
                             const_,
                             trait_)
C
corentih 已提交
298
        }
299
        ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
N
Nick Cameron 已提交
300 301 302 303 304 305
            struct_span_err!(resolver.session,
                             span,
                             E0408,
                             "variable `{}` from pattern #1 is not bound in pattern #{}",
                             variable_name,
                             pattern_number)
C
corentih 已提交
306
        }
307
        ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
N
Nick Cameron 已提交
308 309 310 311 312 313 314
            struct_span_err!(resolver.session,
                             span,
                             E0409,
                             "variable `{}` is bound with different mode in pattern #{} than in \
                              pattern #1",
                             variable_name,
                             pattern_number)
C
corentih 已提交
315
        }
316
        ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
N
Nick Cameron 已提交
317 318 319 320 321 322
            struct_span_err!(resolver.session,
                             span,
                             E0410,
                             "variable `{}` from pattern #{} is not bound in pattern #1",
                             variable_name,
                             pattern_number)
C
corentih 已提交
323
        }
324
        ResolutionError::SelfUsedOutsideImplOrTrait => {
N
Nick Cameron 已提交
325 326 327 328
            struct_span_err!(resolver.session,
                             span,
                             E0411,
                             "use of `Self` outside of an impl or trait")
C
corentih 已提交
329
        }
330
        ResolutionError::UseOfUndeclared(kind, name) => {
N
Nick Cameron 已提交
331 332 333 334 335 336
            struct_span_err!(resolver.session,
                             span,
                             E0412,
                             "use of undeclared {} `{}`",
                             kind,
                             name)
C
corentih 已提交
337
        }
338
        ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
N
Nick Cameron 已提交
339 340 341 342 343 344
            struct_span_err!(resolver.session,
                             span,
                             E0413,
                             "declaration of `{}` shadows an enum variant \
                              or unit-like struct in scope",
                             name)
C
corentih 已提交
345
        }
346
        ResolutionError::OnlyIrrefutablePatternsAllowedHere(did, name) => {
N
Nick Cameron 已提交
347 348 349 350 351 352 353
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0414,
                                           "only irrefutable patterns allowed here");
            err.span_note(span,
                          "there already is a constant in scope sharing the same \
                           name as this pattern");
354
            if let Some(sp) = resolver.ast_map.span_if_local(did) {
N
Nick Cameron 已提交
355
                err.span_note(sp, "constant defined here");
356
            }
M
Manish Goregaokar 已提交
357 358
            if let Some(directive) = resolver.current_module
                                             .import_resolutions
C
corentih 已提交
359 360
                                             .borrow()
                                             .get(&name) {
361
                let item = resolver.ast_map.expect_item(directive.value_ns.id);
N
Nick Cameron 已提交
362
                err.span_note(item.span, "constant imported here");
363
            }
N
Nick Cameron 已提交
364
            err
C
corentih 已提交
365
        }
366
        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
N
Nick Cameron 已提交
367 368 369 370 371
            struct_span_err!(resolver.session,
                             span,
                             E0415,
                             "identifier `{}` is bound more than once in this parameter list",
                             identifier)
C
corentih 已提交
372
        }
373
        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
N
Nick Cameron 已提交
374 375 376 377 378
            struct_span_err!(resolver.session,
                             span,
                             E0416,
                             "identifier `{}` is bound more than once in the same pattern",
                             identifier)
C
corentih 已提交
379
        }
380
        ResolutionError::StaticVariableReference => {
N
Nick Cameron 已提交
381 382 383 384 385
            struct_span_err!(resolver.session,
                             span,
                             E0417,
                             "static variables cannot be referenced in a pattern, use a \
                              `const` instead")
C
corentih 已提交
386
        }
387
        ResolutionError::NotAnEnumVariantStructOrConst(name) => {
N
Nick Cameron 已提交
388 389 390 391 392
            struct_span_err!(resolver.session,
                             span,
                             E0418,
                             "`{}` is not an enum variant, struct or const",
                             name)
C
corentih 已提交
393
        }
394
        ResolutionError::UnresolvedEnumVariantStructOrConst(name) => {
N
Nick Cameron 已提交
395 396 397 398 399
            struct_span_err!(resolver.session,
                             span,
                             E0419,
                             "unresolved enum variant, struct or const `{}`",
                             name)
C
corentih 已提交
400
        }
401
        ResolutionError::NotAnAssociatedConst(name) => {
N
Nick Cameron 已提交
402 403 404 405 406
            struct_span_err!(resolver.session,
                             span,
                             E0420,
                             "`{}` is not an associated const",
                             name)
C
corentih 已提交
407
        }
408
        ResolutionError::UnresolvedAssociatedConst(name) => {
N
Nick Cameron 已提交
409 410 411 412 413
            struct_span_err!(resolver.session,
                             span,
                             E0421,
                             "unresolved associated const `{}`",
                             name)
C
corentih 已提交
414
        }
415
        ResolutionError::DoesNotNameAStruct(name) => {
N
Nick Cameron 已提交
416 417 418 419 420
            struct_span_err!(resolver.session,
                             span,
                             E0422,
                             "`{}` does not name a structure",
                             name)
C
corentih 已提交
421
        }
422
        ResolutionError::StructVariantUsedAsFunction(path_name) => {
N
Nick Cameron 已提交
423 424 425 426 427 428
            struct_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)
C
corentih 已提交
429
        }
430
        ResolutionError::SelfNotAvailableInStaticMethod => {
N
Nick Cameron 已提交
431 432 433 434 435
            struct_span_err!(resolver.session,
                             span,
                             E0424,
                             "`self` is not available in a static method. Maybe a `self` \
                             argument is missing?")
C
corentih 已提交
436
        }
437
        ResolutionError::UnresolvedName(path, msg, context) => {
N
Nick Cameron 已提交
438 439 440 441 442 443
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0425,
                                           "unresolved name `{}`{}",
                                           path,
                                           msg);
444 445

            match context {
446
                UnresolvedNameContext::Other => { } // no help available
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
                UnresolvedNameContext::PathIsMod(id) => {
                    let mut help_msg = String::new();
                    let parent_id = resolver.ast_map.get_parent_node(id);
                    if let Some(hir_map::Node::NodeExpr(e)) = resolver.ast_map.find(parent_id) {
                        match e.node {
                            ExprField(_, ident) => {
                                help_msg = format!("To reference an item from the \
                                                    `{module}` module, use \
                                                    `{module}::{ident}`",
                                                   module = &*path,
                                                   ident = ident.node);
                            }
                            ExprMethodCall(ident, _, _) => {
                                help_msg = format!("To call a function from the \
                                                    `{module}` module, use \
                                                    `{module}::{ident}(..)`",
                                                   module = &*path,
                                                   ident = ident.node);
                            }
466 467 468 469 470
                            ExprCall(_, _) => {
                                help_msg = format!("No function corresponds to `{module}(..)`",
                                                   module = &*path);
                            }
                            _ => { } // no help available
471
                        }
472 473 474
                    } else {
                        help_msg = format!("Module `{module}` cannot be the value of an expression",
                                           module = &*path);
475 476 477
                    }

                    if !help_msg.is_empty() {
N
Nick Cameron 已提交
478
                        err.fileline_help(span, &help_msg);
479 480 481
                    }
                }
            }
N
Nick Cameron 已提交
482
            err
C
corentih 已提交
483
        }
484
        ResolutionError::UndeclaredLabel(name) => {
N
Nick Cameron 已提交
485 486 487 488 489
            struct_span_err!(resolver.session,
                             span,
                             E0426,
                             "use of undeclared label `{}`",
                             name)
C
corentih 已提交
490
        }
491
        ResolutionError::CannotUseRefBindingModeWith(descr) => {
N
Nick Cameron 已提交
492 493 494 495 496
            struct_span_err!(resolver.session,
                             span,
                             E0427,
                             "cannot use `ref` binding mode with {}",
                             descr)
C
corentih 已提交
497
        }
498
        ResolutionError::DuplicateDefinition(namespace, name) => {
N
Nick Cameron 已提交
499 500 501 502 503 504
            struct_span_err!(resolver.session,
                             span,
                             E0428,
                             "duplicate definition of {} `{}`",
                             namespace,
                             name)
C
corentih 已提交
505
        }
506
        ResolutionError::SelfImportsOnlyAllowedWithin => {
N
Nick Cameron 已提交
507 508 509 510 511
            struct_span_err!(resolver.session,
                             span,
                             E0429,
                             "{}",
                             "`self` imports are only allowed within a { } list")
C
corentih 已提交
512
        }
513
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
N
Nick Cameron 已提交
514 515 516 517
            struct_span_err!(resolver.session,
                             span,
                             E0430,
                             "`self` import can only appear once in the list")
C
corentih 已提交
518
        }
519
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
N
Nick Cameron 已提交
520 521 522 523 524
            struct_span_err!(resolver.session,
                             span,
                             E0431,
                             "`self` import can only appear in an import list with a \
                              non-empty prefix")
525
        }
526
        ResolutionError::UnresolvedImport(name) => {
527
            let msg = match name {
528
                Some((n, p)) => format!("unresolved import `{}`{}", n, p),
C
corentih 已提交
529
                None => "unresolved import".to_owned(),
530
            };
N
Nick Cameron 已提交
531
            struct_span_err!(resolver.session, span, E0432, "{}", msg)
C
corentih 已提交
532
        }
533
        ResolutionError::FailedToResolve(msg) => {
N
Nick Cameron 已提交
534
            struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg)
C
corentih 已提交
535
        }
536
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
N
Nick Cameron 已提交
537 538 539 540 541 542
            struct_span_err!(resolver.session,
                             span,
                             E0434,
                             "{}",
                             "can't capture dynamic environment in a fn item; use the || { ... } \
                              closure form instead")
C
corentih 已提交
543 544
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
N
Nick Cameron 已提交
545 546 547 548
            struct_span_err!(resolver.session,
                             span,
                             E0435,
                             "attempt to use a non-constant value in a constant")
C
corentih 已提交
549
        }
N
Nick Cameron 已提交
550
    }
551 552
}

N
Niko Matsakis 已提交
553
#[derive(Copy, Clone)]
554
struct BindingInfo {
555
    span: Span,
556
    binding_mode: BindingMode,
557 558 559
}

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

N
Niko Matsakis 已提交
562
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
563
enum PatternBindingMode {
564
    RefutableMode,
565
    LocalIrrefutableMode,
566
    ArgumentIrrefutableMode,
567 568
}

N
Niko Matsakis 已提交
569
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
570
pub enum Namespace {
571
    TypeNS,
C
corentih 已提交
572
    ValueNS,
573 574
}

B
Brian Anderson 已提交
575 576 577
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
578
#[derive(Clone)]
579
enum NamespaceResult<'a> {
T
Tim Chevalier 已提交
580 581 582
    /// 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.)
583
    UnknownResult,
B
Brian Anderson 已提交
584 585
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
586
    UnboundResult,
T
Tim Chevalier 已提交
587
    /// Means that resolve has determined that the name is bound in the Module
588
    /// argument, and specified by the NameBinding argument.
589
    BoundResult(Module<'a>, NameBinding<'a>),
590 591
}

592
impl<'a> NamespaceResult<'a> {
F
Felix S. Klock II 已提交
593
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
594
        match *self {
595
            UnknownResult => true,
C
corentih 已提交
596
            _ => false,
597 598
        }
    }
599 600 601
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
C
corentih 已提交
602
            _ => false,
603 604
        }
    }
605 606
}

607
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
608 609 610
    fn visit_nested_item(&mut self, item: hir::ItemId) {
        self.visit_item(self.ast_map.expect_item(item.id))
    }
611
    fn visit_item(&mut self, item: &Item) {
612
        execute_callback!(hir_map::Node::NodeItem(item), self);
A
Alex Crichton 已提交
613
        self.resolve_item(item);
614
    }
615
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
616
        self.resolve_arm(arm);
617
    }
618
    fn visit_block(&mut self, block: &Block) {
619
        execute_callback!(hir_map::Node::NodeBlock(block), self);
A
Alex Crichton 已提交
620
        self.resolve_block(block);
621
    }
622
    fn visit_expr(&mut self, expr: &Expr) {
623
        execute_callback!(hir_map::Node::NodeExpr(expr), self);
A
Alex Crichton 已提交
624
        self.resolve_expr(expr);
625
    }
626
    fn visit_local(&mut self, local: &Local) {
627
        execute_callback!(hir_map::Node::NodeLocal(&*local.pat), self);
A
Alex Crichton 已提交
628
        self.resolve_local(local);
629
    }
630
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
631
        self.resolve_type(ty);
632
    }
633 634 635
    fn visit_generics(&mut self, generics: &Generics) {
        self.resolve_generics(generics);
    }
C
corentih 已提交
636
    fn visit_poly_trait_ref(&mut self, tref: &hir::PolyTraitRef, m: &hir::TraitBoundModifier) {
637 638
        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 已提交
639 640
            Err(_) => {
                // error already reported
641
                self.record_def(tref.trait_ref.ref_id, err_path_resolution())
C
corentih 已提交
642
            }
643
        }
644
        intravisit::walk_poly_trait_ref(self, tref, m);
645
    }
C
corentih 已提交
646 647 648 649
    fn visit_variant(&mut self,
                     variant: &hir::Variant,
                     generics: &Generics,
                     item_id: ast::NodeId) {
650
        execute_callback!(hir_map::Node::NodeVariant(variant), self);
651 652 653
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
654
                this.visit_expr(dis_expr);
655 656 657
            });
        }

658
        // `intravisit::walk_variant` without the discriminant expression.
C
corentih 已提交
659 660 661 662 663
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
664
    }
665 666
    fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
        execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
667 668 669 670
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
C
corentih 已提交
671
            ForeignItemStatic(..) => NoTypeParameters,
672 673
        };
        self.with_type_parameter_rib(type_parameters, |this| {
674
            intravisit::walk_foreign_item(this, foreign_item);
675 676 677
        });
    }
    fn visit_fn(&mut self,
678
                function_kind: FnKind<'v>,
679 680 681 682 683
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
684
            FnKind::ItemFn(_, generics, _, _, _, _) => {
685 686 687
                self.visit_generics(generics);
                ItemRibKind
            }
688
            FnKind::Method(_, sig, _) => {
689 690
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
691 692
                MethodRibKind
            }
V
Vadim Petrochenkov 已提交
693
            FnKind::Closure => ClosureRibKind(node_id),
694 695 696
        };
        self.resolve_function(rib_kind, declaration, block);
    }
697
}
698

699 700
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
701
enum ResolveResult<T> {
C
corentih 已提交
702 703 704
    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.
705 706
}

707
impl<T> ResolveResult<T> {
708
    fn success(&self) -> bool {
C
corentih 已提交
709 710 711 712
        match *self {
            Success(_) => true,
            _ => false,
        }
713 714 715
    }
}

716 717 718 719
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
720
    TraitItem,
721
    StaticMethod(String),
722
    TraitMethod(String),
723 724
}

N
Niko Matsakis 已提交
725
#[derive(Copy, Clone)]
E
Erik Price 已提交
726
enum TypeParameters<'a> {
727
    NoTypeParameters,
C
corentih 已提交
728 729
    HasTypeParameters(// Type parameters.
                      &'a Generics,
730

C
corentih 已提交
731 732 733
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
734

C
corentih 已提交
735 736
                      // The kind of the rib used for type parameters.
                      RibKind),
737 738
}

739 740
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
741
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
742
enum RibKind {
743 744
    // No translation needs to be applied.
    NormalRibKind,
745

746 747
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
748
    ClosureRibKind(NodeId /* func id */),
749

750
    // We passed through an impl or trait and are now in one of its
751
    // methods. Allow references to ty params that impl or trait
752 753
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
754
    MethodRibKind,
755

756 757
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
758 759

    // We're in a constant item. Can't refer to dynamic stuff.
C
corentih 已提交
760
    ConstantItemRibKind,
761 762
}

N
Niko Matsakis 已提交
763
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
764
enum UseLexicalScopeFlag {
765
    DontUseLexicalScope,
C
corentih 已提交
766
    UseLexicalScope,
767 768
}

769
enum ModulePrefixResult<'a> {
770
    NoPrefixFound,
771
    PrefixFound(Module<'a>, usize),
772 773
}

774 775 776 777 778 779 780 781 782
#[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 已提交
783
#[derive(Copy, Clone, PartialEq)]
784
enum NameSearchType {
785 786 787 788
    /// 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
789 790
    /// expression, or a path pattern.
    PathSearch,
791 792
}

N
Niko Matsakis 已提交
793
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
794
enum BareIdentifierPatternResolution {
795
    FoundStructOrEnumVariant(Def, LastPrivate),
796
    FoundConst(Def, LastPrivate, Name),
C
corentih 已提交
797
    BareIdentifierPatternUnresolved,
798 799
}

800
/// One local scope.
J
Jorge Aparicio 已提交
801
#[derive(Debug)]
F
Felix S. Klock II 已提交
802
struct Rib {
803
    bindings: HashMap<Name, DefLike>,
804
    kind: RibKind,
B
Brian Anderson 已提交
805
}
806

807
impl Rib {
F
Felix S. Klock II 已提交
808
    fn new(kind: RibKind) -> Rib {
809
        Rib {
810
            bindings: HashMap::new(),
C
corentih 已提交
811
            kind: kind,
812
        }
813 814 815
    }
}

816 817 818
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
819
    def: Def,
820 821 822 823 824 825
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
826
            def: def,
827 828 829 830
        }
    }
}

831
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
832
#[derive(Clone,Debug)]
833
enum ParentLink<'a> {
834
    NoParentLink,
835 836
    ModuleParentLink(Module<'a>, Name),
    BlockParentLink(Module<'a>, NodeId),
837 838
}

839
/// One node in the tree of modules.
840 841
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
842
    def: Cell<Option<Def>>,
843
    is_public: bool,
844

845
    children: RefCell<HashMap<Name, NameBindings<'a>>>,
E
Eduard Burtescu 已提交
846
    imports: RefCell<Vec<ImportDirective>>,
847

848
    // The external module children of this node that were declared with
A
Alex Crichton 已提交
849
    // `extern crate`.
850
    external_module_children: RefCell<HashMap<Name, Module<'a>>>,
851

852 853 854 855 856 857 858 859 860 861 862 863 864 865
    // 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`.
866
    anonymous_children: RefCell<NodeMap<Module<'a>>>,
867 868

    // The status of resolving each import in this module.
869
    import_resolutions: RefCell<HashMap<Name, ImportResolutionPerNamespace<'a>>>,
870 871

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

874 875 876 877 878 879
    // 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>,

880
    // The index of the import we're resolving.
881
    resolved_import_count: Cell<usize>,
882 883 884 885

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

889 890 891 892 893
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
    fn new(parent_link: ParentLink<'a>, def: Option<Def>, external: bool, is_public: bool) -> Self {
        ModuleS {
894
            parent_link: parent_link,
895
            def: Cell::new(def),
896
            is_public: is_public,
897
            children: RefCell::new(HashMap::new()),
898
            imports: RefCell::new(Vec::new()),
899
            external_module_children: RefCell::new(HashMap::new()),
900
            anonymous_children: RefCell::new(NodeMap()),
901
            import_resolutions: RefCell::new(HashMap::new()),
902
            glob_count: Cell::new(0),
903 904
            pub_count: Cell::new(0),
            pub_glob_count: Cell::new(0),
905
            resolved_import_count: Cell::new(0),
906
            populated: Cell::new(!external),
907
        }
B
Brian Anderson 已提交
908 909
    }

910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
    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,
925
        }
B
Brian Anderson 已提交
926 927
    }

F
Felix S. Klock II 已提交
928
    fn all_imports_resolved(&self) -> bool {
929 930 931 932 933 934
        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()
        }
935 936
    }

V
Victor Berger 已提交
937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
    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);
    }
}

960
impl<'a> fmt::Debug for ModuleS<'a> {
961
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
C
corentih 已提交
962
        write!(f,
963 964
               "{:?}, {}",
               self.def,
C
corentih 已提交
965 966 967 968 969
               if self.is_public {
                   "public"
               } else {
                   "private"
               })
970 971 972
    }
}

973
bitflags! {
J
Jorge Aparicio 已提交
974
    #[derive(Debug)]
975
    flags DefModifiers: u8 {
V
Vadim Petrochenkov 已提交
976 977
        // Enum variants are always considered `PUBLIC`, this is needed for `use Enum::Variant`
        // or `use Enum::*` to work on private enums.
T
Fallout  
Tamir Duberstein 已提交
978 979
        const PUBLIC     = 1 << 0,
        const IMPORTABLE = 1 << 1,
V
Vadim Petrochenkov 已提交
980
        // Variants are considered `PUBLIC`, but some of them live in private enums.
981 982
        // We need to track them to prohibit reexports like `pub use PrivEnum::Variant`.
        const PRIVATE_VARIANT = 1 << 2,
983 984 985
    }
}

986
// Records a possibly-private value, type, or module definition.
987
#[derive(Debug)]
988
struct NsDef<'a> {
J
Jeffrey Seyfried 已提交
989
    modifiers: DefModifiers, // see note in ImportResolutionPerNamespace about how to use this
990
    def_or_module: DefOrModule<'a>,
991
    span: Option<Span>,
992 993
}

J
Jorge Aparicio 已提交
994
#[derive(Debug)]
995
enum DefOrModule<'a> {
996
    Def(Def),
997
    Module(Module<'a>),
998 999
}

1000 1001
impl<'a> NsDef<'a> {
    fn create_from_module(module: Module<'a>, span: Option<Span>) -> Self {
1002
        let modifiers = if module.is_public {
T
Fallout  
Tamir Duberstein 已提交
1003 1004 1005 1006
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
1007

1008
        NsDef { modifiers: modifiers, def_or_module: DefOrModule::Module(module), span: span }
1009 1010
    }

1011 1012 1013 1014
    fn create_from_def(def: Def, modifiers: DefModifiers, span: Option<Span>) -> Self {
        NsDef { modifiers: modifiers, def_or_module: DefOrModule::Def(def), span: span }
    }

1015
    fn module(&self) -> Option<Module<'a>> {
1016
        match self.def_or_module {
1017
            DefOrModule::Module(ref module) => Some(module),
1018
            DefOrModule::Def(_) => None,
1019 1020 1021
        }
    }

1022
    fn def(&self) -> Option<Def> {
1023 1024 1025
        match self.def_or_module {
            DefOrModule::Def(def) => Some(def),
            DefOrModule::Module(ref module) => module.def.get(),
1026
        }
1027
    }
1028
}
1029

1030 1031
// Records at most one definition that a name in a namespace is bound to
#[derive(Clone,Debug)]
1032
pub struct NameBinding<'a>(Rc<RefCell<Option<NsDef<'a>>>>);
1033

1034
impl<'a> NameBinding<'a> {
1035 1036
    fn new() -> Self {
        NameBinding(Rc::new(RefCell::new(None)))
1037 1038
    }

1039
    fn create_from_module(module: Module<'a>) -> Self {
1040
        NameBinding(Rc::new(RefCell::new(Some(NsDef::create_from_module(module, None)))))
1041 1042
    }

1043
    fn set(&self, ns_def: NsDef<'a>) {
1044
        *self.0.borrow_mut() = Some(ns_def);
1045 1046
    }

1047 1048 1049
    fn set_modifiers(&self, modifiers: DefModifiers) {
        if let Some(ref mut ns_def) = *self.0.borrow_mut() {
            ns_def.modifiers = modifiers
1050 1051 1052
        }
    }

1053
    fn borrow(&self) -> ::std::cell::Ref<Option<NsDef<'a>>> {
1054
        self.0.borrow()
1055 1056
    }

1057
    // Lifted versions of the NsDef methods and fields
1058 1059 1060
    fn def(&self) -> Option<Def> {
        self.borrow().as_ref().and_then(NsDef::def)
    }
1061
    fn module(&self) -> Option<Module<'a>> {
1062 1063 1064 1065 1066 1067 1068
        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))
1069 1070
    }

1071 1072
    fn defined(&self) -> bool {
        self.borrow().is_some()
1073 1074
    }

1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
    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()) }))
    }
1087 1088
}

1089 1090
// Records the definitions (at most one for each namespace) that a name is
// bound to.
1091
#[derive(Clone,Debug)]
1092 1093 1094
pub struct NameBindings<'a> {
    type_ns: NameBinding<'a>, // < Meaning in type namespace.
    value_ns: NameBinding<'a>, // < Meaning in value namespace.
1095 1096
}

1097 1098 1099
impl<'a> ::std::ops::Index<Namespace> for NameBindings<'a> {
    type Output = NameBinding<'a>;
    fn index(&self, namespace: Namespace) -> &NameBinding<'a> {
1100 1101
        match namespace { TypeNS => &self.type_ns, ValueNS => &self.value_ns }
    }
1102 1103
}

1104 1105
impl<'a> NameBindings<'a> {
    fn new() -> Self {
K
Kevin Butler 已提交
1106
        NameBindings {
1107 1108
            type_ns: NameBinding::new(),
            value_ns: NameBinding::new(),
1109 1110
        }
    }
K
Kevin Butler 已提交
1111

1112
    /// Creates a new module in this set of name bindings.
1113
    fn define_module(&self, module: Module<'a>, sp: Span) {
1114
        self.type_ns.set(NsDef::create_from_module(module, Some(sp)));
1115 1116
    }

1117
    /// Records a type definition.
1118
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
1119 1120
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
        self.type_ns.set(NsDef::create_from_def(def, modifiers, Some(sp)));
1121 1122
    }

1123
    /// Records a value definition.
1124
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
1125 1126
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
        self.value_ns.set(NsDef::create_from_def(def, modifiers, Some(sp)));
1127 1128 1129
    }
}

1130
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1131
struct PrimitiveTypeTable {
1132
    primitive_types: HashMap<Name, PrimTy>,
1133
}
1134

1135
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1136
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
        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 已提交
1154 1155 1156 1157

        table
    }

1158
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1159
        self.primitive_types.insert(token::intern(string), primitive_type);
1160 1161 1162
    }
}

1163
/// The main resolver class.
C
corentih 已提交
1164
pub struct Resolver<'a, 'tcx: 'a> {
E
Eduard Burtescu 已提交
1165
    session: &'a Session,
1166

1167
    ast_map: &'a hir_map::Map<'tcx>,
1168

1169
    graph_root: Module<'a>,
1170

1171
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1172

1173
    structs: FnvHashMap<DefId, Vec<Name>>,
1174

1175
    // The number of imports that are currently unresolved.
1176
    unresolved_imports: usize,
1177 1178

    // The module that represents the current item scope.
1179
    current_module: Module<'a>,
1180 1181

    // The current set of local scopes, for values.
1182
    // FIXME #4948: Reuse ribs to avoid allocation.
1183
    value_ribs: Vec<Rib>,
1184 1185

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

1188
    // The current set of local scopes, for labels.
1189
    label_ribs: Vec<Rib>,
1190

1191
    // The trait that the current context can refer to.
1192 1193 1194 1195
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1197
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1198
    primitive_type_table: PrimitiveTypeTable,
1199

J
Jonathan S 已提交
1200
    def_map: RefCell<DefMap>,
1201 1202
    freevars: FreevarMap,
    freevars_seen: NodeMap<NodeMap<usize>>,
1203
    export_map: ExportMap,
1204
    trait_map: TraitMap,
1205
    external_exports: ExternalExports,
1206

1207 1208 1209 1210 1211
    // 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,

1212 1213 1214 1215 1216
    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,

1217
    used_imports: HashSet<(NodeId, Namespace)>,
1218
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1219 1220

    // Callback function for intercepting walks
1221
    callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>,
G
Garming Sam 已提交
1222 1223 1224
    // The intention is that the callback modifies this flag.
    // Once set, the resolver falls out of the walk, preserving the ribs.
    resolved: bool,
1225 1226 1227 1228 1229 1230

    arenas: &'a ResolverArenas<'a>,
}

pub struct ResolverArenas<'a> {
    modules: arena::TypedArena<ModuleS<'a>>,
1231 1232
}

1233
#[derive(PartialEq)]
S
Steven Fackler 已提交
1234 1235
enum FallbackChecks {
    Everything,
C
corentih 已提交
1236
    OnlyTraitAndStatics,
S
Steven Fackler 已提交
1237 1238
}

1239 1240
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1241
           ast_map: &'a hir_map::Map<'tcx>,
1242 1243
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
C
corentih 已提交
1244
           -> Resolver<'a, 'tcx> {
1245
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
1246 1247
        let graph_root = ModuleS::new(NoParentLink, Some(DefMod(root_def_id)), false, true);
        let graph_root = arenas.modules.alloc(graph_root);
K
Kevin Butler 已提交
1248 1249 1250 1251

        Resolver {
            session: session,

1252 1253
            ast_map: ast_map,

K
Kevin Butler 已提交
1254 1255
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1256
            graph_root: graph_root,
K
Kevin Butler 已提交
1257

1258 1259
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1260 1261 1262

            unresolved_imports: 0,

1263
            current_module: graph_root,
1264 1265 1266
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1267 1268 1269 1270 1271 1272

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1273
            def_map: RefCell::new(NodeMap()),
1274 1275
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1276 1277
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1278
            used_imports: HashSet::new(),
1279
            used_crates: HashSet::new(),
1280
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1281 1282

            emit_errors: true,
1283 1284
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
G
Garming Sam 已提交
1285 1286 1287

            callback: None,
            resolved: false,
1288 1289 1290 1291 1292 1293 1294 1295

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
K
Kevin Butler 已提交
1296 1297
        }
    }
1298

1299 1300 1301 1302 1303 1304 1305 1306
    fn new_module(&self,
                  parent_link: ParentLink<'a>,
                  def: Option<Def>,
                  external: bool,
                  is_public: bool) -> Module<'a> {
        self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public))
    }

1307 1308 1309 1310 1311 1312
    #[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) {
1313
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1314 1315 1316 1317 1318 1319 1320 1321 1322
            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 {
1323 1324
        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
            self.ast_map.expect_item(node_id).name
1325
        } else {
1326
            self.session.cstore.item_name(did)
1327 1328 1329
        }
    }

1330
    /// Check that an external crate doesn't collide with items or other external crates.
1331
    fn check_for_conflicts_for_external_crate(&self, module: Module<'a>, name: Name, span: Span) {
1332
        if module.external_module_children.borrow().contains_key(&name) {
C
corentih 已提交
1333 1334 1335 1336 1337
            span_err!(self.session,
                      span,
                      E0259,
                      "an external crate named `{}` has already been imported into this module",
                      name);
1338
        }
1339 1340 1341 1342 1343 1344 1345 1346
        match module.children.borrow().get(&name) {
            Some(name_bindings) if name_bindings.type_ns.defined() => {
                resolve_error(self,
                              name_bindings.type_ns.span().unwrap_or(codemap::DUMMY_SP),
                              ResolutionError::NameConflictsWithExternCrate(name));
            }
            _ => {},
        }
1347 1348 1349 1350
    }

    /// Checks that the names of items don't collide with external crates.
    fn check_for_conflicts_between_external_crates_and_items(&self,
1351
                                                             module: Module<'a>,
1352 1353 1354
                                                             name: Name,
                                                             span: Span) {
        if module.external_module_children.borrow().contains_key(&name) {
1355
            resolve_error(self, span, ResolutionError::NameConflictsWithExternCrate(name));
1356
        }
1357 1358
    }

1359
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1360
    fn resolve_module_path_from_root(&mut self,
1361
                                     module_: Module<'a>,
1362
                                     module_path: &[Name],
1363
                                     index: usize,
1364 1365 1366
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
1367 1368 1369
                                     -> ResolveResult<(Module<'a>, LastPrivate)> {
        fn search_parent_externals<'a>(needle: Name, module: Module<'a>)
                                       -> Option<Module<'a>> {
1370
            match module.external_module_children.borrow().get(&needle) {
1371
                Some(_) => Some(module),
1372 1373
                None => match module.parent_link {
                    ModuleParentLink(ref parent, _) => {
1374
                        search_parent_externals(needle, parent)
1375
                    }
C
corentih 已提交
1376 1377
                    _ => None,
                },
1378
            }
1379 1380
        }

1381
        let mut search_module = module_;
1382
        let mut index = index;
A
Alex Crichton 已提交
1383
        let module_path_len = module_path.len();
1384
        let mut closest_private = lp;
1385 1386 1387 1388 1389

        // 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 已提交
1390
            let name = module_path[index];
1391
            match self.resolve_name_in_module(search_module,
1392
                                              name,
1393
                                              TypeNS,
1394 1395
                                              name_search_type,
                                              false) {
1396
                Failed(None) => {
1397
                    let segment_name = name.as_str();
1398
                    let module_name = module_to_string(search_module);
1399
                    let mut span = span;
1400
                    let msg = if "???" == &module_name[..] {
1401
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1402

C
corentih 已提交
1403
                        match search_parent_externals(name, &self.current_module) {
1404
                            Some(module) => {
1405 1406
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
C
corentih 已提交
1407
                                let current_mod_str = module_to_string(&*self.current_module);
1408 1409 1410 1411 1412 1413 1414

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

1415
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1416 1417
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1418
                        }
1419
                    } else {
C
corentih 已提交
1420
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1421
                    };
1422

1423
                    return Failed(Some((span, msg)));
1424
                }
1425
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1426
                Indeterminate => {
C
corentih 已提交
1427 1428 1429
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1430
                    return Indeterminate;
1431
                }
1432
                Success((target, used_proxy)) => {
1433 1434
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
1435 1436
                    if let Some(module_def) = target.binding.module() {
                        // track extern crates for unused_extern_crate lint
1437
                        if let Some(did) = module_def.def_id() {
1438 1439
                            self.used_crates.insert(did.krate);
                        }
1440

1441
                        search_module = module_def;
1442

1443 1444 1445
                        // Keep track of the closest private module used
                        // when resolving this import chain.
                        if !used_proxy && !search_module.is_public {
1446
                            if let Some(did) = search_module.def_id() {
1447
                                closest_private = LastMod(DependsOn(did));
1448 1449
                            }
                        }
1450 1451 1452
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1453 1454 1455 1456
                    }
                }
            }

T
Tim Chevalier 已提交
1457
            index += 1;
1458 1459
        }

1460
        return Success((search_module, closest_private));
1461 1462
    }

1463 1464
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1465 1466 1467
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1468
    fn resolve_module_path(&mut self,
1469
                           module_: Module<'a>,
1470
                           module_path: &[Name],
1471 1472 1473
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1474
                           -> ResolveResult<(Module<'a>, LastPrivate)> {
1475
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1476
        assert!(module_path_len > 0);
1477

1478
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1479 1480
               names_to_string(module_path),
               module_to_string(&*module_));
1481

1482
        // Resolve the module prefix, if any.
1483
        let module_prefix_result = self.resolve_module_prefix(module_, module_path);
1484

1485 1486
        let search_module;
        let start_index;
1487
        let last_private;
1488
        match module_prefix_result {
1489
            Failed(None) => {
1490
                let mpath = names_to_string(module_path);
1491
                let mpath = &mpath[..];
1492
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1493
                    Some(idx) => {
1494
                        let msg = format!("Could not find `{}` in `{}`",
C
corentih 已提交
1495 1496 1497 1498
                                          // idx +- 1 to account for the
                                          // colons on either side
                                          &mpath[idx + 1..],
                                          &mpath[..idx - 1]);
1499
                        return Failed(Some((span, msg)));
C
corentih 已提交
1500
                    }
1501
                    None => {
C
corentih 已提交
1502
                        return Failed(None);
1503
                    }
1504
                }
1505
            }
1506
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1507
            Indeterminate => {
C
corentih 已提交
1508
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1509
                return Indeterminate;
1510
            }
1511 1512 1513 1514 1515 1516 1517 1518
            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.
1519
                        search_module = self.graph_root;
1520
                        start_index = 0;
1521
                        last_private = LastMod(AllPublic);
1522 1523 1524 1525 1526
                    }
                    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 已提交
1527
                        match self.resolve_module_in_lexical_scope(module_, module_path[0]) {
1528
                            Failed(err) => return Failed(err),
1529
                            Indeterminate => {
C
corentih 已提交
1530
                                debug!("(resolving module path for import) indeterminate; bailing");
1531 1532 1533 1534 1535
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1536
                                last_private = LastMod(AllPublic);
1537 1538 1539 1540 1541
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1542
            Success(PrefixFound(ref containing_module, index)) => {
1543
                search_module = containing_module;
1544
                start_index = index;
1545
                last_private = LastMod(DependsOn(containing_module.def_id()
1546
                                                                  .unwrap()));
1547 1548 1549
            }
        }

1550 1551 1552 1553
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1554 1555
                                           name_search_type,
                                           last_private)
1556 1557
    }

1558 1559
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1560
    fn resolve_item_in_lexical_scope(&mut self,
1561
                                     module_: Module<'a>,
1562
                                     name: Name,
1563 1564
                                     namespace: Namespace,
                                     record_used: bool)
1565
                                     -> ResolveResult<(Target<'a>, bool)> {
C
corentih 已提交
1566
        debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
1567
               name,
1568
               namespace,
1569
               module_to_string(&*module_));
1570 1571 1572

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

1575
        match module_.children.borrow().get(&name) {
1576
            Some(name_bindings) if name_bindings[namespace].defined() => {
1577
                debug!("top name bindings succeeded");
1578
                return Success((Target::new(module_,
1579
                                            name_bindings[namespace].clone(),
1580
                                            Shadowable::Never),
C
corentih 已提交
1581 1582 1583 1584
                                false));
            }
            Some(_) | None => {
                // Not found; continue.
1585 1586 1587 1588 1589 1590 1591
            }
        }

        // 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.
1592
        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
1593
            match import_resolution[namespace].target.clone() {
1594 1595
                None => {
                    // Not found; continue.
C
corentih 已提交
1596 1597
                    debug!("(resolving item in lexical scope) found import resolution, but not \
                            in namespace {:?}",
1598 1599 1600
                           namespace);
                }
                Some(target) => {
C
corentih 已提交
1601
                    debug!("(resolving item in lexical scope) using import resolution");
1602
                    // track used imports and extern crates as well
1603
                    let id = import_resolution[namespace].id;
1604 1605 1606 1607 1608 1609
                    if record_used {
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
                            self.used_crates.insert(kid);
                        }
1610
                    }
1611
                    return Success((target, false));
1612 1613 1614 1615
                }
            }
        }

1616 1617
        // Search for external modules.
        if namespace == TypeNS {
1618 1619
            let children = module_.external_module_children.borrow();
            if let Some(module) = children.get(&name) {
1620
                let name_binding = NameBinding::create_from_module(module);
1621
                debug!("lower name bindings succeeded");
1622
                return Success((Target::new(module_, name_binding, Shadowable::Never),
1623
                                false));
1624 1625 1626
            }
        }

1627
        // Finally, proceed up the scope chain looking for parent modules.
1628
        let mut search_module = module_;
1629 1630
        loop {
            // Go to the next parent.
1631
            match search_module.parent_link {
B
Brian Anderson 已提交
1632
                NoParentLink => {
1633
                    // No more parents. This module was unresolved.
C
corentih 已提交
1634
                    debug!("(resolving item in lexical scope) unresolved module");
1635
                    return Failed(None);
1636
                }
1637
                ModuleParentLink(parent_module_node, _) => {
1638 1639 1640 1641
                    if search_module.is_normal() {
                        // We stop the search here.
                        debug!("(resolving item in lexical scope) unresolved module: not \
                                searching through module parents");
1642
                            return Failed(None);
1643
                    } else {
1644
                        search_module = parent_module_node;
1645 1646
                    }
                }
1647 1648
                BlockParentLink(parent_module_node, _) => {
                    search_module = parent_module_node;
1649 1650 1651 1652
                }
            }

            // Resolve the name in the parent module.
1653
            match self.resolve_name_in_module(search_module,
1654
                                              name,
1655
                                              namespace,
1656 1657
                                              PathSearch,
                                              true) {
1658
                Failed(Some((span, msg))) => {
1659
                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
C
corentih 已提交
1660
                }
1661
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1662
                Indeterminate => {
1663 1664 1665
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

C
corentih 已提交
1666
                    debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
B
Brian Anderson 已提交
1667
                    return Indeterminate;
1668
                }
1669
                Success((target, used_reexport)) => {
1670
                    // We found the module.
C
corentih 已提交
1671
                    debug!("(resolving item in lexical scope) found name in module, done");
1672
                    return Success((target, used_reexport));
1673 1674 1675 1676 1677
                }
            }
        }
    }

1678
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1679
    fn resolve_module_in_lexical_scope(&mut self,
1680
                                       module_: Module<'a>,
1681
                                       name: Name)
1682
                                       -> ResolveResult<Module<'a>> {
1683 1684
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1685
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS, true);
1686
        match resolve_result {
1687
            Success((target, _)) => {
1688 1689 1690 1691 1692 1693
                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);
1694 1695
                }
            }
B
Brian Anderson 已提交
1696
            Indeterminate => {
C
corentih 已提交
1697
                debug!("(resolving module in lexical scope) indeterminate; bailing");
B
Brian Anderson 已提交
1698
                return Indeterminate;
1699
            }
1700 1701 1702
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1703 1704 1705 1706
            }
        }
    }

1707
    /// Returns the nearest normal module parent of the given module.
1708
    fn get_nearest_normal_module_parent(&mut self, module_: Module<'a>) -> Option<Module<'a>> {
1709 1710
        let mut module_ = module_;
        loop {
1711
            match module_.parent_link {
1712 1713 1714
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
1715
                    let new_module = new_module;
1716 1717
                    if new_module.is_normal() {
                        return Some(new_module);
1718
                    }
1719
                    module_ = new_module;
1720 1721 1722 1723 1724
                }
            }
        }
    }

1725 1726
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1727
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Module<'a>) -> Module<'a> {
1728 1729 1730
        if module_.is_normal() {
            return module_;
        }
1731
        match self.get_nearest_normal_module_parent(module_) {
1732 1733
            None => module_,
            Some(new_module) => new_module,
1734 1735 1736
        }
    }

1737
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1738
    /// (b) some chain of `super::`.
1739
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1740
    fn resolve_module_prefix(&mut self,
1741
                             module_: Module<'a>,
1742
                             module_path: &[Name])
1743
                             -> ResolveResult<ModulePrefixResult<'a>> {
1744 1745
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1746 1747 1748 1749 1750 1751
        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_);
1752 1753

        // Now loop through all the `super`s we find.
1754
        while i < module_path.len() && "super" == module_path[i].as_str() {
1755
            debug!("(resolving module prefix) resolving `super` at {}",
1756
                   module_to_string(&*containing_module));
1757
            match self.get_nearest_normal_module_parent(containing_module) {
1758
                None => return Failed(None),
1759 1760 1761
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1762 1763 1764 1765
                }
            }
        }

1766
        debug!("(resolving module prefix) finished resolving prefix at {}",
1767
               module_to_string(&*containing_module));
1768 1769

        return Success(PrefixFound(containing_module, i));
1770 1771
    }

1772 1773 1774
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1775 1776 1777
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1778
    fn resolve_name_in_module(&mut self,
1779
                              module_: Module<'a>,
1780
                              name: Name,
1781
                              namespace: Namespace,
1782 1783
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1784
                              -> ResolveResult<(Target<'a>, bool)> {
1785
        debug!("(resolving name in module) resolving `{}` in `{}`",
1786
               name,
1787
               module_to_string(&*module_));
1788 1789

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

1792 1793
        let children = module_.children.borrow();
        match children.get(&name) {
1794
            Some(name_bindings) if name_bindings[namespace].defined() => {
1795
                debug!("(resolving name in module) found node as child");
1796
                return Success((Target::new(module_,
1797
                                            name_bindings[namespace].clone(),
1798
                                            Shadowable::Never),
C
corentih 已提交
1799
                                false));
1800 1801 1802
            }
            Some(_) | None => {
                // Continue.
1803 1804 1805
            }
        }

1806 1807 1808 1809
        // 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.
1810
        if name_search_type == PathSearch {
1811
            assert_eq!(module_.glob_count.get(), 0);
1812 1813
        }

1814
        // Check the list of resolved imports.
1815 1816
        let children = module_.import_resolutions.borrow();
        match children.get(&name) {
1817 1818
            Some(import_resolution) if allow_private_imports ||
                                       import_resolution[namespace].is_public => {
1819

1820 1821
                if import_resolution[namespace].is_public &&
                   import_resolution.outstanding_references != 0 {
C
corentih 已提交
1822
                    debug!("(resolving name in module) import unresolved; bailing out");
B
Brian Anderson 已提交
1823
                    return Indeterminate;
1824
                }
1825
                match import_resolution[namespace].target.clone() {
B
Brian Anderson 已提交
1826
                    None => {
C
corentih 已提交
1827
                        debug!("(resolving name in module) name found, but not in namespace {:?}",
P
Paul Stansifer 已提交
1828
                               namespace);
1829
                    }
1830
                    Some(target) => {
C
corentih 已提交
1831
                        debug!("(resolving name in module) resolved to import");
1832
                        // track used imports and extern crates as well
1833
                        let id = import_resolution[namespace].id;
1834 1835
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1836
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
1837
                            self.used_crates.insert(kid);
1838
                        }
1839
                        return Success((target, true));
1840
                    }
1841 1842
                }
            }
1843
            Some(..) | None => {} // Continue.
1844 1845 1846 1847
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1848 1849
            let children = module_.external_module_children.borrow();
            if let Some(module) = children.get(&name) {
1850 1851
                let name_binding = NameBinding::create_from_module(module);
                return Success((Target::new(module_, name_binding, Shadowable::Never),
1852
                                false));
1853 1854 1855 1856
            }
        }

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

1861
    fn report_unresolved_imports(&mut self, module_: Module<'a>) {
1862
        let index = module_.resolved_import_count.get();
1863 1864
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1865
        if index != import_count {
1866 1867 1868
            resolve_error(self,
                          (*imports)[index].span,
                          ResolutionError::UnresolvedImport(None));
1869 1870 1871
        }

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

1874
        for (_, child_node) in module_.children.borrow().iter() {
1875
            match child_node.type_ns.module() {
1876 1877 1878 1879 1880
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1881 1882 1883 1884
                }
            }
        }

1885
        for (_, module_) in module_.anonymous_children.borrow().iter() {
1886
            self.report_unresolved_imports(module_);
1887 1888 1889 1890 1891
        }
    }

    // AST resolution
    //
1892
    // We maintain a list of value ribs and type ribs.
1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
    //
    // 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 已提交
1908 1909
    fn with_scope<F>(&mut self, name: Option<Name>, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1910
    {
1911
        let orig_module = self.current_module;
1912 1913

        // Move down in the graph.
1914
        match name {
B
Brian Anderson 已提交
1915
            None => {
1916 1917
                // Nothing to do.
            }
B
Brian Anderson 已提交
1918
            Some(name) => {
1919
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1920

1921
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
1922
                    None => {
1923
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
1924
                               name,
1925
                               module_to_string(&*orig_module));
1926
                    }
B
Brian Anderson 已提交
1927
                    Some(name_bindings) => {
1928
                        match name_bindings.type_ns.module() {
B
Brian Anderson 已提交
1929
                            None => {
C
corentih 已提交
1930
                                debug!("!!! (with scope) didn't find module for `{}` in `{}`",
1931
                                       name,
1932
                                       module_to_string(&*orig_module));
1933
                            }
B
Brian Anderson 已提交
1934
                            Some(module_) => {
1935
                                self.current_module = module_;
1936 1937 1938 1939 1940 1941 1942
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
1943
        f(self);
1944 1945 1946 1947

        self.current_module = orig_module;
    }

S
Seo Sanghyeon 已提交
1948 1949
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1950 1951 1952 1953 1954 1955 1956 1957
    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 已提交
1958
                    return None;
1959 1960 1961
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1962
            if result.is_some() {
C
corentih 已提交
1963
                return result;
1964 1965 1966 1967 1968
            }
        }
        None
    }

1969
    fn resolve_crate(&mut self, krate: &hir::Crate) {
1970
        debug!("(resolving crate) starting");
1971

1972
        intravisit::walk_crate(self, krate);
1973 1974
    }

W
we 已提交
1975 1976
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
C
corentih 已提交
1977 1978 1979 1980
            span_err!(self.session,
                      span,
                      E0317,
                      "user-defined types or type parameters cannot shadow the primitive types");
W
we 已提交
1981 1982 1983
        }
    }

1984
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
1985
        let name = item.name;
1986

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

1989
        match item.node {
1990 1991 1992
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
1993 1994
                self.check_if_primitive_type_name(name, item.span);

C
corentih 已提交
1995
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1996
                                             |this| intravisit::walk_item(this, item));
1997
            }
1998
            ItemFn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1999
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
2000
                                             |this| intravisit::walk_item(this, item));
2001 2002
            }

F
Flavio Percoco 已提交
2003
            ItemDefaultImpl(_, ref trait_ref) => {
2004
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
2005
            }
C
corentih 已提交
2006
            ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
2007
                self.resolve_implementation(generics,
2008
                                            opt_trait_ref,
2009
                                            &**self_type,
2010
                                            item.id,
2011
                                            impl_items);
2012 2013
            }

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

2017 2018 2019 2020 2021
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
2022 2023
                    let local_def_id = this.ast_map.local_def_id(item.id);
                    this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
2024
                        this.visit_generics(generics);
2025
                        walk_list!(this, visit_ty_param_bound, bounds);
2026 2027

                        for trait_item in trait_items {
2028
                            match trait_item.node {
2029
                                hir::ConstTraitItem(_, ref default) => {
2030 2031 2032 2033 2034
                                    // 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| {
2035
                                            intravisit::walk_trait_item(this, trait_item)
2036 2037
                                        });
                                    } else {
2038
                                        intravisit::walk_trait_item(this, trait_item)
2039 2040
                                    }
                                }
2041
                                hir::MethodTraitItem(ref sig, _) => {
2042 2043 2044 2045 2046
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
2047
                                        intravisit::walk_trait_item(this, trait_item)
2048
                                    });
2049
                                }
2050
                                hir::TypeTraitItem(..) => {
V
Vadim Petrochenkov 已提交
2051
                                    this.check_if_primitive_type_name(trait_item.name,
2052
                                                                      trait_item.span);
2053
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
2054
                                        intravisit::walk_trait_item(this, trait_item)
2055
                                    });
2056 2057 2058 2059
                                }
                            };
                        }
                    });
2060
                });
2061 2062
            }

2063
            ItemMod(_) | ItemForeignMod(_) => {
2064
                self.with_scope(Some(name), |this| {
2065
                    intravisit::walk_item(this, item);
2066
                });
2067 2068
            }

2069
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2070
                self.with_constant_rib(|this| {
2071
                    intravisit::walk_item(this, item);
2072
                });
2073
            }
2074

W
we 已提交
2075 2076
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
2077
                let check_rename = |this: &Self, id, name| {
2078
                    match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
2079 2080
                        Some(DefEnum(..)) | Some(DefTyAlias(..)) | Some(DefStruct(..)) |
                        Some(DefTrait(..)) | None => {
2081
                            this.check_if_primitive_type_name(name, item.span);
W
we 已提交
2082 2083 2084
                        }
                        _ => {}
                    }
2085 2086 2087
                };

                match view_path.node {
2088 2089
                    hir::ViewPathSimple(name, _) => {
                        check_rename(self, item.id, name);
2090
                    }
2091
                    hir::ViewPathList(ref prefix, ref items) => {
2092
                        for item in items {
2093 2094
                            if let Some(name) = item.node.rename() {
                                check_rename(self, item.node.id(), name);
2095 2096 2097 2098 2099 2100 2101 2102
                            }
                        }

                        // 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 已提交
2103 2104
                                Some((def, lp)) =>
                                    self.record_def(item.id, PathResolution::new(def, lp, 0)),
2105 2106 2107 2108 2109
                                None => {
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
2110
                                    self.record_def(item.id, err_path_resolution());
2111
                                }
2112 2113 2114 2115
                            }
                        }
                    }
                    _ => {}
W
we 已提交
2116 2117 2118
                }
            }

2119
            ItemExternCrate(_) => {
2120
                // do nothing, these are just around to be encoded
2121
            }
2122 2123 2124
        }
    }

C
corentih 已提交
2125 2126
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2127
    {
2128
        match type_parameters {
2129
            HasTypeParameters(generics, space, rib_kind) => {
2130
                let mut function_type_rib = Rib::new(rib_kind);
2131
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2132
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2133
                    let name = type_parameter.name;
2134
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2135

2136
                    if seen_bindings.contains(&name) {
2137 2138
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
2139
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
2140
                    }
2141
                    seen_bindings.insert(name);
2142

2143
                    // plain insert (no renaming)
C
corentih 已提交
2144 2145 2146 2147 2148 2149 2150
                    function_type_rib.bindings
                                     .insert(name,
                                             DlDef(DefTyParam(space,
                                                              index as u32,
                                                              self.ast_map
                                                                  .local_def_id(type_parameter.id),
                                                              name)));
2151
                }
2152
                self.type_ribs.push(function_type_rib);
2153 2154
            }

B
Brian Anderson 已提交
2155
            NoTypeParameters => {
2156 2157 2158 2159
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2160
        f(self);
2161

2162
        match type_parameters {
C
corentih 已提交
2163 2164 2165 2166 2167 2168
            HasTypeParameters(..) => {
                if !self.resolved {
                    self.type_ribs.pop();
                }
            }
            NoTypeParameters => {}
2169 2170 2171
        }
    }

C
corentih 已提交
2172 2173
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2174
    {
2175
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2176
        f(self);
G
Garming Sam 已提交
2177 2178 2179
        if !self.resolved {
            self.label_ribs.pop();
        }
2180
    }
2181

C
corentih 已提交
2182 2183
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2184
    {
2185 2186
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2187
        f(self);
G
Garming Sam 已提交
2188 2189 2190 2191
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
2192 2193
    }

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

2198
        // Create a label rib for the function.
2199
        self.label_ribs.push(Rib::new(rib_kind));
2200

2201 2202 2203
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
C
corentih 已提交
2204
            self.resolve_pattern(&*argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
2205

2206
            self.visit_ty(&*argument.ty);
2207

2208 2209
            debug!("(resolving function) recorded argument");
        }
2210
        intravisit::walk_fn_ret_ty(self, &declaration.output);
2211

2212
        // Resolve the function body.
2213
        self.visit_block(block);
2214

2215
        debug!("(resolving function) leaving function");
2216

G
Garming Sam 已提交
2217 2218 2219 2220
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
2221 2222
    }

F
Felix S. Klock II 已提交
2223
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2224
                               id: NodeId,
2225
                               trait_path: &Path,
2226
                               path_depth: usize)
2227 2228 2229 2230 2231 2232
                               -> 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 {
N
Nick Cameron 已提交
2233 2234 2235 2236 2237
                let mut err =
                    resolve_struct_error(self,
                                  trait_path.span,
                                  ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
                                                                                      path_depth)));
2238 2239

                // If it's a typedef, give a note
2240
                if let DefTyAlias(..) = path_res.base_def {
N
Nick Cameron 已提交
2241 2242
                    err.span_note(trait_path.span,
                                  "`type` aliases cannot be used for traits");
2243
                }
N
Nick Cameron 已提交
2244
                err.emit();
2245 2246
                Err(())
            }
2247
        } else {
2248 2249
            resolve_error(self,
                          trait_path.span,
C
corentih 已提交
2250 2251
                          ResolutionError::UndeclaredTraitName(&*path_names_to_string(trait_path,
                                                                                      path_depth)));
2252
            Err(())
2253 2254 2255
        }
    }

2256
    fn resolve_generics(&mut self, generics: &Generics) {
2257
        for type_parameter in generics.ty_params.iter() {
2258
            self.check_if_primitive_type_name(type_parameter.name, type_parameter.span);
2259 2260
        }
        for predicate in &generics.where_clause.predicates {
2261
            match predicate {
2262 2263 2264
                &hir::WherePredicate::BoundPredicate(_) |
                &hir::WherePredicate::RegionPredicate(_) => {}
                &hir::WherePredicate::EqPredicate(ref eq_pred) => {
2265 2266 2267 2268
                    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 {
2269 2270
                        resolve_error(self,
                                      eq_pred.span,
2271
                                      ResolutionError::UndeclaredAssociatedType);
2272
                        self.record_def(eq_pred.id, err_path_resolution());
2273 2274
                    }
                }
2275 2276
            }
        }
2277
        intravisit::walk_generics(self, generics);
2278 2279
    }

2280 2281
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2282
    {
2283 2284 2285 2286 2287 2288 2289
        // 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 已提交
2290
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2291
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2292
    {
2293
        let mut new_val = None;
2294
        let mut new_id = None;
E
Eduard Burtescu 已提交
2295
        if let Some(trait_ref) = opt_trait_ref {
2296
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
2297 2298
                                                               &trait_ref.path,
                                                               0) {
2299 2300 2301 2302
                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());
2303 2304
            } else {
                self.record_def(trait_ref.ref_id, err_path_resolution());
2305
            }
2306
            intravisit::walk_trait_ref(self, trait_ref);
2307
        }
2308
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2309
        let result = f(self, new_id);
2310 2311 2312 2313
        self.current_trait_ref = original_trait_ref;
        result
    }

2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
    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 已提交
2324 2325 2326
        if !self.resolved {
            self.type_ribs.pop();
        }
2327 2328
    }

F
Felix S. Klock II 已提交
2329
    fn resolve_implementation(&mut self,
2330 2331 2332
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2333
                              item_id: NodeId,
2334
                              impl_items: &[ImplItem]) {
2335
        // If applicable, create a rib for the type parameters.
2336
        self.with_type_parameter_rib(HasTypeParameters(generics,
2337
                                                       TypeSpace,
2338
                                                       ItemRibKind),
2339
                                     |this| {
2340
            // Resolve the type parameters.
2341
            this.visit_generics(generics);
2342

2343
            // Resolve the trait reference, if necessary.
2344
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2345
                // Resolve the self type.
2346
                this.visit_ty(self_type);
2347

2348 2349 2350 2351
                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 {
2352
                                hir::ImplItemKind::Const(..) => {
2353
                                    // If this is a trait impl, ensure the const
2354
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2355
                                    this.check_trait_item(impl_item.name,
2356 2357
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2358
                                    this.with_constant_rib(|this| {
2359
                                        intravisit::walk_impl_item(this, impl_item);
2360 2361
                                    });
                                }
2362
                                hir::ImplItemKind::Method(ref sig, _) => {
2363 2364
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2365
                                    this.check_trait_item(impl_item.name,
2366 2367
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
2368 2369 2370 2371 2372 2373 2374 2375

                                    // 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| {
2376
                                        intravisit::walk_impl_item(this, impl_item);
2377 2378
                                    });
                                }
2379
                                hir::ImplItemKind::Type(ref ty) => {
2380
                                    // If this is a trait impl, ensure the type
2381
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2382
                                    this.check_trait_item(impl_item.name,
2383 2384
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2385

2386 2387
                                    this.visit_ty(ty);
                                }
2388
                            }
2389
                        }
2390
                    });
2391 2392
                });
            });
2393
        });
2394 2395
    }

2396
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
2397 2398 2399 2400
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2401
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2402
            if !self.trait_item_map.contains_key(&(name, did)) {
2403
                let path_str = path_names_to_string(&trait_ref.path, 0);
C
corentih 已提交
2404
                resolve_error(self, span, err(name, &*path_str));
2405 2406 2407 2408
            }
        }
    }

E
Eduard Burtescu 已提交
2409
    fn resolve_local(&mut self, local: &Local) {
2410
        // Resolve the type.
2411
        walk_list!(self, visit_ty, &local.ty);
2412

2413
        // Resolve the initializer.
2414
        walk_list!(self, visit_expr, &local.init);
2415 2416

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

J
John Clements 已提交
2420 2421 2422 2423
    // 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 已提交
2424
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2425
        let mut result = HashMap::new();
2426 2427
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = path1.node;
C
corentih 已提交
2428 2429 2430 2431 2432
            result.insert(name,
                          BindingInfo {
                              span: sp,
                              binding_mode: binding_mode,
                          });
2433
        });
2434
        return result;
2435 2436
    }

J
John Clements 已提交
2437 2438
    // 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 已提交
2439
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2440
        if arm.pats.is_empty() {
C
corentih 已提交
2441
            return;
2442
        }
2443
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2444
        for (i, p) in arm.pats.iter().enumerate() {
2445
            let map_i = self.binding_mode_map(&**p);
2446

2447
            for (&key, &binding_0) in &map_0 {
2448
                match map_i.get(&key) {
C
corentih 已提交
2449
                    None => {
2450
                        resolve_error(self,
C
corentih 已提交
2451 2452 2453 2454 2455 2456 2457 2458 2459 2460
                                      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));
                        }
2461
                    }
2462 2463 2464
                }
            }

2465
            for (&key, &binding) in &map_i {
2466
                if !map_0.contains_key(&key) {
2467 2468
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2469
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2470 2471 2472
                }
            }
        }
2473 2474
    }

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

2478
        let mut bindings_list = HashMap::new();
2479
        for pattern in &arm.pats {
2480
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2481 2482
        }

2483 2484 2485 2486
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2487
        walk_list!(self, visit_expr, &arm.guard);
2488
        self.visit_expr(&*arm.body);
2489

G
Garming Sam 已提交
2490 2491 2492
        if !self.resolved {
            self.value_ribs.pop();
        }
2493 2494
    }

E
Eduard Burtescu 已提交
2495
    fn resolve_block(&mut self, block: &Block) {
2496
        debug!("(resolving block) entering block");
2497
        self.value_ribs.push(Rib::new(NormalRibKind));
2498 2499

        // Move down in the graph, if there's an anonymous module rooted here.
2500
        let orig_module = self.current_module;
2501
        match orig_module.anonymous_children.borrow().get(&block.id) {
C
corentih 已提交
2502 2503 2504
            None => {
                // Nothing to do.
            }
E
Eduard Burtescu 已提交
2505
            Some(anonymous_module) => {
C
corentih 已提交
2506
                debug!("(resolving block) found anonymous module, moving down");
2507
                self.current_module = anonymous_module;
2508 2509 2510
            }
        }

2511 2512
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2513
        for statement in &block.stmts {
2514
            if let hir::StmtDecl(ref declaration, _) = statement.node {
2515 2516
                if let hir::DeclItem(i) = declaration.node {
                    let i = self.ast_map.expect_item(i.id);
2517 2518
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
C
corentih 已提交
2519 2520 2521 2522
                            span_err!(self.session,
                                      i.span,
                                      E0154,
                                      "imports are not allowed after non-item statements");
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

2534
        // Descend into the block.
2535
        intravisit::walk_block(self, block);
2536 2537

        // Move back up.
G
Garming Sam 已提交
2538
        if !self.resolved {
2539
            self.current_module = orig_module;
G
Garming Sam 已提交
2540 2541
            self.value_ribs.pop();
        }
2542
        debug!("(resolving block) leaving block");
2543 2544
    }

F
Felix S. Klock II 已提交
2545
    fn resolve_type(&mut self, ty: &Ty) {
2546
        match ty.node {
2547
            TyPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2548 2549 2550 2551 2552 2553 2554 2555
                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.
2556
                        intravisit::walk_ty(self, ty);
C
corentih 已提交
2557 2558 2559 2560
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2561 2562

                // This is a path in the type namespace. Walk through scopes
2563
                // looking for it.
2564
                match resolution {
B
Brian Anderson 已提交
2565
                    Some(def) => {
2566
                        // Write the result into the def map.
C
corentih 已提交
2567
                        debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2568
                               path_names_to_string(path, 0),
C
corentih 已提交
2569 2570
                               ty.id,
                               def);
2571
                        self.record_def(ty.id, def);
2572
                    }
B
Brian Anderson 已提交
2573
                    None => {
2574 2575
                        self.record_def(ty.id, err_path_resolution());

2576 2577 2578
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2579 2580 2581 2582
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2583
                        };
2584

2585
                        let self_type_name = special_idents::type_self.name;
C
corentih 已提交
2586 2587 2588 2589
                        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 已提交
2590
                        if is_invalid_self_type_name {
2591 2592
                            resolve_error(self,
                                          ty.span,
2593
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2594
                        } else {
2595 2596
                            resolve_error(self,
                                          ty.span,
2597
                                          ResolutionError::UseOfUndeclared(
2598 2599 2600 2601
                                                                    kind,
                                                                    &*path_names_to_string(path,
                                                                                           0))
                                         );
G
Guillaume Gomez 已提交
2602
                        }
2603 2604
                    }
                }
2605
            }
2606
            _ => {}
2607
        }
2608
        // Resolve embedded types.
2609
        intravisit::walk_ty(self, ty);
2610 2611
    }

F
Felix S. Klock II 已提交
2612
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2613
                       pattern: &Pat,
2614 2615 2616
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2617
                       bindings_list: &mut HashMap<Name, NodeId>) {
2618
        let pat_id = pattern.id;
2619
        walk_pat(pattern, |pattern| {
2620
            match pattern.node {
2621 2622
                PatIdent(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatIdent with no type parameters
2623 2624 2625 2626
                    // 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
2627 2628 2629 2630
                    // 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();
2631

2632
                    let ident = path1.node;
2633
                    let renamed = ident.name;
2634

2635 2636
                    match self.resolve_bare_identifier_pattern(ident.unhygienic_name,
                                                               pattern.span) {
2637
                        FoundStructOrEnumVariant(def, lp) if const_ok => {
C
corentih 已提交
2638
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2639
                                   renamed);
2640

C
corentih 已提交
2641 2642 2643 2644 2645 2646 2647 2648 2649
                            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,
                                            });
2650
                        }
A
Alex Crichton 已提交
2651
                        FoundStructOrEnumVariant(..) => {
2652
                            resolve_error(
2653
                                self,
2654
                                pattern.span,
2655
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2656 2657
                                    renamed)
                            );
2658
                            self.record_def(pattern.id, err_path_resolution());
2659
                        }
2660
                        FoundConst(def, lp, _) if const_ok => {
C
corentih 已提交
2661 2662 2663 2664 2665 2666 2667 2668 2669
                            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,
                                            });
2670
                        }
2671
                        FoundConst(def, _, name) => {
2672
                            resolve_error(
2673 2674
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2675 2676
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2677
                            );
2678
                            self.record_def(pattern.id, err_path_resolution());
2679
                        }
2680
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2681
                            debug!("(resolving pattern) binding `{}`", renamed);
2682

2683 2684
                            let def_id = self.ast_map.local_def_id(pattern.id);
                            let def = DefLocal(def_id, pattern.id);
2685 2686 2687 2688 2689

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

C
corentih 已提交
2690 2691 2692 2693 2694 2695
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: LastMod(AllPublic),
                                                depth: 0,
                                            });
2696 2697 2698 2699 2700 2701

                            // 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.)
2702 2703
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2704 2705
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2706
                                bindings_list.insert(renamed, pat_id);
2707
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2708
                               bindings_list.contains_key(&renamed) {
2709 2710
                                // Forbid duplicate bindings in the same
                                // parameter list.
2711
                                resolve_error(
2712 2713
                                    self,
                                    pattern.span,
2714
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2715
                                        &ident.name.as_str())
2716
                                );
C
corentih 已提交
2717
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2718 2719
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2720
                                resolve_error(
2721 2722
                                    self,
                                    pattern.span,
2723
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2724
                                        &ident.name.as_str())
2725
                                );
2726
                            }
2727 2728
                            // Else, not bound in the same pattern: do
                            // nothing.
2729 2730 2731 2732
                        }
                    }
                }

2733
                PatEnum(ref path, _) => {
2734
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752
                    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,
                    };
2753
                    if let Some(path_res) = resolution {
2754
                        match path_res.base_def {
2755 2756 2757 2758
                            DefStruct(..) if path_res.depth == 0 => {
                                self.record_def(pattern.id, path_res);
                            }
                            DefVariant(..) | DefConst(..) => {
2759 2760 2761
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
2762 2763
                                resolve_error(&self,
                                              path.span,
2764
                                              ResolutionError::StaticVariableReference);
2765
                                self.record_def(pattern.id, err_path_resolution());
2766
                            }
2767 2768 2769 2770
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2771
                                // be a `T::CONST` that typeck will resolve.
2772
                                if path_res.depth == 0 {
2773
                                    resolve_error(
2774
                                        self,
2775
                                        path.span,
2776
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2777 2778 2779 2780 2781 2782
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2783
                                    );
2784
                                    self.record_def(pattern.id, err_path_resolution());
2785
                                } else {
C
corentih 已提交
2786 2787 2788 2789 2790
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2791 2792
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2793 2794 2795 2796 2797
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2798
                        resolve_error(
2799 2800
                            self,
                            path.span,
2801
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2802
                                &path.segments.last().unwrap().identifier.name.as_str())
2803
                        );
2804
                        self.record_def(pattern.id, err_path_resolution());
2805
                    }
2806
                    intravisit::walk_path(self, path);
2807 2808 2809 2810
                }

                PatQPath(ref qself, ref path) => {
                    // Associated constants only.
C
corentih 已提交
2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826
                    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);
2827
                            intravisit::walk_pat(self, pattern);
C
corentih 已提交
2828 2829 2830 2831
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2832 2833 2834 2835 2836 2837 2838
                    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);
                            }
2839
                            _ => {
2840
                                resolve_error(
2841 2842
                                    self,
                                    path.span,
2843
                                    ResolutionError::NotAnAssociatedConst(
2844
                                        &path.segments.last().unwrap().identifier.name.as_str()
2845 2846
                                    )
                                );
2847
                                self.record_def(pattern.id, err_path_resolution());
2848
                            }
2849
                        }
2850
                    } else {
C
corentih 已提交
2851 2852 2853 2854 2855 2856 2857 2858
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2859
                        self.record_def(pattern.id, err_path_resolution());
2860
                    }
2861
                    intravisit::walk_pat(self, pattern);
2862 2863
                }

2864
                PatStruct(ref path, _, _) => {
2865
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2866
                        Some(definition) => {
2867 2868
                            self.record_def(pattern.id, definition);
                        }
2869
                        result => {
C
corentih 已提交
2870
                            debug!("(resolving pattern) didn't find struct def: {:?}", result);
2871 2872 2873
                            resolve_error(
                                self,
                                path.span,
2874
                                ResolutionError::DoesNotNameAStruct(
2875 2876
                                    &*path_names_to_string(path, 0))
                            );
2877
                            self.record_def(pattern.id, err_path_resolution());
2878 2879
                        }
                    }
2880
                    intravisit::walk_path(self, path);
2881 2882 2883
                }

                PatLit(_) | PatRange(..) => {
2884
                    intravisit::walk_pat(self, pattern);
2885 2886
                }

2887
                _ => {
2888 2889 2890
                    // Nothing to do.
                }
            }
2891
            true
2892
        });
2893 2894
    }

C
corentih 已提交
2895 2896 2897
    fn resolve_bare_identifier_pattern(&mut self,
                                       name: Name,
                                       span: Span)
E
Eduard Burtescu 已提交
2898
                                       -> BareIdentifierPatternResolution {
2899
        let module = self.current_module;
2900
        match self.resolve_item_in_lexical_scope(module, name, ValueNS, true) {
2901
            Success((target, _)) => {
C
corentih 已提交
2902 2903
                debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
                       name,
2904 2905
                       target.binding.borrow());
                match target.binding.def() {
B
Brian Anderson 已提交
2906
                    None => {
C
corentih 已提交
2907 2908
                        panic!("resolved name in the value namespace to a set of name bindings \
                                with no def?!");
2909
                    }
2910 2911 2912 2913 2914 2915 2916 2917
                    // 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);
2918
                    }
2919 2920 2921
                    Some(DefStatic(..)) => {
                        resolve_error(self, span, ResolutionError::StaticVariableReference);
                        return BareIdentifierPatternUnresolved;
2922
                    }
2923
                    _ => return BareIdentifierPatternUnresolved
2924 2925 2926
                }
            }

B
Brian Anderson 已提交
2927
            Indeterminate => {
S
Steve Klabnik 已提交
2928
                panic!("unexpected indeterminate result");
2929
            }
2930 2931 2932
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
2933
                        resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
2934
                    }
C
corentih 已提交
2935
                    None => (),
2936
                }
2937

C
corentih 已提交
2938
                debug!("(resolve bare identifier pattern) failed to find {}", name);
2939
                return BareIdentifierPatternUnresolved;
2940 2941 2942 2943
            }
        }
    }

2944 2945 2946
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2947
                                   maybe_qself: Option<&hir::QSelf>,
2948 2949 2950
                                   path: &Path,
                                   namespace: Namespace,
                                   check_ribs: bool)
C
corentih 已提交
2951
                                   -> AssocItemResolveResult {
2952 2953
        let max_assoc_types;

2954
        match maybe_qself {
2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965
            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();
            }
2966 2967 2968 2969 2970 2971 2972 2973 2974 2975
        }

        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 已提交
2976
                resolution = this.resolve_path(id, path, depth, TypeNS, true);
2977 2978 2979 2980 2981 2982 2983 2984 2985
            });
        }
        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

2986 2987
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
2988 2989
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
G
Garming Sam 已提交
2990 2991 2992 2993 2994
    pub fn resolve_path(&mut self,
                        id: NodeId,
                        path: &Path,
                        path_depth: usize,
                        namespace: Namespace,
C
corentih 已提交
2995 2996
                        check_ribs: bool)
                        -> Option<PathResolution> {
2997
        let span = path.span;
C
corentih 已提交
2998
        let segments = &path.segments[..path.segments.len() - path_depth];
2999

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

3002
        if path.global {
3003
            let def = self.resolve_crate_relative_path(span, segments, namespace);
3004
            return def.map(mk_res);
3005 3006
        }

3007
        // Try to find a path to an item in a module.
3008
        let last_ident = segments.last().unwrap().identifier;
N
Nick Cameron 已提交
3009
        if segments.len() <= 1 {
3010
            let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, true);
C
corentih 已提交
3011 3012 3013 3014
            return unqualified_def.and_then(|def| self.adjust_local_def(def, span))
                                  .map(|def| {
                                      PathResolution::new(def, LastMod(AllPublic), path_depth)
                                  });
N
Nick Cameron 已提交
3015
        }
3016

3017
        let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, false);
N
Nick Cameron 已提交
3018 3019
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
3020
            (Some((ref d, _)), Some(ref ud)) if *d == ud.def => {
N
Nick Cameron 已提交
3021 3022
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
3023 3024
                              id,
                              span,
N
Nick Cameron 已提交
3025 3026 3027
                              "unnecessary qualification".to_string());
            }
            _ => {}
3028
        }
N
Nick Cameron 已提交
3029 3030

        def.map(mk_res)
3031 3032
    }

3033
    // Resolve a single identifier
F
Felix S. Klock II 已提交
3034
    fn resolve_identifier(&mut self,
3035
                          identifier: hir::Ident,
3036
                          namespace: Namespace,
3037 3038
                          check_ribs: bool,
                          record_used: bool)
3039
                          -> Option<LocalDef> {
3040 3041 3042 3043
        // 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
3044
                                        .get(&identifier.unhygienic_name) {
3045
                return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
3046 3047 3048
            }
        }

3049
        if check_ribs {
C
corentih 已提交
3050
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, namespace) {
3051
                return Some(def);
3052 3053 3054
            }
        }

3055 3056
        let name = identifier.unhygienic_name;
        self.resolve_item_by_name_in_lexical_scope(name, namespace, record_used)
3057 3058 3059 3060
            .map(LocalDef::from_def)
    }

    // Resolve a local definition, potentially adjusting for closures.
3061
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
3062
        let ribs = match local_def.ribs {
C
corentih 已提交
3063 3064 3065
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
3066 3067 3068 3069
        };
        let mut def = local_def.def;
        match def {
            DefUpvar(..) => {
C
corentih 已提交
3070
                self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081
            }
            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 已提交
3082 3083 3084
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
3085 3086 3087 3088
                            if let Some(&index) = seen.get(&node_id) {
                                def = DefUpvar(node_def_id, node_id, index, function_id);
                                continue;
                            }
C
corentih 已提交
3089 3090 3091
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
3092
                            let depth = vec.len();
C
corentih 已提交
3093 3094 3095 3096
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
3097 3098 3099 3100 3101 3102 3103 3104

                            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 已提交
3105 3106 3107
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
3108 3109 3110 3111
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
3112 3113 3114
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145
                            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);
3146 3147
    }

3148
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3149
    fn resolve_module_relative_path(&mut self,
3150
                                    span: Span,
3151
                                    segments: &[hir::PathSegment],
3152 3153
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
C
corentih 已提交
3154 3155 3156 3157 3158 3159
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3160

3161
        let containing_module;
3162
        let last_private;
3163
        let current_module = self.current_module;
N
Nick Cameron 已提交
3164
        match self.resolve_module_path(current_module,
3165
                                       &module_path[..],
3166
                                       UseLexicalScope,
3167
                                       span,
3168
                                       PathSearch) {
3169 3170 3171 3172
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3173
                        let msg = format!("Use of undeclared type or module `{}`",
3174
                                          names_to_string(&module_path));
3175
                        (span, msg)
3176 3177
                    }
                };
3178

3179
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3180
                return None;
3181
            }
S
Steve Klabnik 已提交
3182
            Indeterminate => panic!("indeterminate unexpected"),
3183
            Success((resulting_module, resulting_last_private)) => {
3184
                containing_module = resulting_module;
3185
                last_private = resulting_last_private;
3186 3187 3188
            }
        }

3189
        let name = segments.last().unwrap().identifier.name;
3190
        let def = match self.resolve_name_in_module(containing_module,
3191 3192 3193 3194 3195 3196
                                                    name,
                                                    namespace,
                                                    NameSearchType::PathSearch,
                                                    false) {
            Success((Target { binding, .. }, _)) => {
                let (def, lp) = binding.def_and_lp();
3197
                (def, last_private.or(lp))
3198
            }
3199
            _ => return None,
3200
        };
3201
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id() {
3202
            self.used_crates.insert(kid);
3203
        }
3204
        return Some(def);
3205 3206
    }

3207 3208
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3209
    fn resolve_crate_relative_path(&mut self,
3210
                                   span: Span,
3211
                                   segments: &[hir::PathSegment],
3212
                                   namespace: Namespace)
C
corentih 已提交
3213 3214 3215 3216 3217 3218 3219
                                   -> Option<(Def, LastPrivate)> {
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
3220

3221
        let root_module = self.graph_root;
3222

3223
        let containing_module;
3224
        let last_private;
3225
        match self.resolve_module_path_from_root(root_module,
3226
                                                 &module_path[..],
3227
                                                 0,
3228
                                                 span,
3229
                                                 PathSearch,
3230
                                                 LastMod(AllPublic)) {
3231 3232 3233 3234 3235
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3236
                                          names_to_string(&module_path[..]));
3237
                        (span, msg)
3238 3239 3240
                    }
                };

3241
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
B
Brian Anderson 已提交
3242
                return None;
3243 3244
            }

B
Brian Anderson 已提交
3245
            Indeterminate => {
S
Steve Klabnik 已提交
3246
                panic!("indeterminate unexpected");
3247 3248
            }

3249
            Success((resulting_module, resulting_last_private)) => {
3250
                containing_module = resulting_module;
3251
                last_private = resulting_last_private;
3252 3253 3254
            }
        }

3255
        let name = segments.last().unwrap().identifier.name;
3256 3257 3258 3259 3260 3261 3262 3263
        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)))
3264
            }
3265
            _ => None,
3266 3267 3268
        }
    }

F
Felix S. Klock II 已提交
3269
    fn resolve_identifier_in_local_ribs(&mut self,
3270
                                        ident: hir::Ident,
3271 3272
                                        namespace: Namespace)
                                        -> Option<LocalDef> {
3273
        // Check the local set of ribs.
3274
        let (name, ribs) = match namespace {
3275 3276
            ValueNS => (ident.name, &self.value_ribs),
            TypeNS => (ident.unhygienic_name, &self.type_ribs),
3277
        };
3278

3279 3280 3281 3282 3283
        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 已提交
3284 3285 3286
                               name,
                               def,
                               i);
3287 3288
                        return Some(LocalDef {
                            ribs: Some((namespace, i)),
C
corentih 已提交
3289
                            def: def,
3290 3291 3292 3293
                        });
                    }
                    def_like => {
                        debug!("(resolving path in local ribs) resolved `{}` to pseudo-def {:?}",
C
corentih 已提交
3294 3295
                               name,
                               def_like);
3296 3297 3298
                        return None;
                    }
                }
3299 3300
            }
        }
3301 3302

        None
3303 3304
    }

3305 3306
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
3307 3308
                                             namespace: Namespace,
                                             record_used: bool)
C
corentih 已提交
3309
                                             -> Option<Def> {
3310
        // Check the items.
3311
        let module = self.current_module;
3312
        match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
3313
            Success((target, _)) => {
3314
                match target.binding.def() {
B
Brian Anderson 已提交
3315
                    None => {
3316 3317
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
C
corentih 已提交
3318 3319 3320
                        debug!("(resolving item path by identifier in lexical scope) failed to \
                                resolve {} after success...",
                               name);
3321
                        None
3322
                    }
B
Brian Anderson 已提交
3323
                    Some(def) => {
C
corentih 已提交
3324
                        debug!("(resolving item path in lexical scope) resolved `{}` to item",
3325
                               name);
3326 3327 3328
                        // 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.
3329
                        Some(def)
3330 3331 3332
                    }
                }
            }
B
Brian Anderson 已提交
3333
            Indeterminate => {
S
Steve Klabnik 已提交
3334
                panic!("unexpected indeterminate result");
3335
            }
3336
            Failed(err) => {
C
corentih 已提交
3337 3338
                debug!("(resolving item path by identifier in lexical scope) failed to resolve {}",
                       name);
N
Nick Cameron 已提交
3339 3340

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

3344
                None
3345 3346 3347 3348
            }
        }
    }

C
corentih 已提交
3349 3350
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
3351
    {
3352
        self.emit_errors = false;
A
Alex Crichton 已提交
3353
        let rs = f(self);
3354 3355 3356 3357
        self.emit_errors = true;
        rs
    }

3358
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
C
corentih 已提交
3359 3360 3361
        fn extract_path_and_node_id(t: &Ty,
                                    allow: FallbackChecks)
                                    -> Option<(Path, NodeId, FallbackChecks)> {
3362
            match t.node {
3363
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3364 3365
                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),
3366 3367 3368 3369 3370 3371 3372
                // 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,
            }
        }

3373 3374 3375 3376 3377
        fn get_module<'a, 'tcx>(this: &mut Resolver<'a, 'tcx>,
                                span: Span,
                                name_path: &[ast::Name])
                                -> Option<Module<'a>> {
            let root = this.current_module;
3378
            let last_name = name_path.last().unwrap();
3379

3380
            if name_path.len() == 1 {
3381
                match this.primitive_type_table.primitive_types.get(last_name) {
3382 3383
                    Some(_) => None,
                    None => {
3384
                        match this.current_module.children.borrow().get(last_name) {
3385
                            Some(child) => child.type_ns.module(),
C
corentih 已提交
3386
                            None => None,
3387 3388 3389 3390 3391
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
3392 3393 3394 3395
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
3396
                    Success((module, _)) => Some(module),
C
corentih 已提交
3397
                    _ => None,
3398 3399 3400 3401
                }
            }
        }

3402
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
3403 3404
            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
                let sig = match this.ast_map.get(node_id) {
3405 3406
                    hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                        hir::MethodTraitItem(ref sig, _) => sig,
C
corentih 已提交
3407
                        _ => return false,
3408
                    },
3409
                    hir_map::NodeImplItem(impl_item) => match impl_item.node {
3410
                        hir::ImplItemKind::Method(ref sig, _) => sig,
C
corentih 已提交
3411
                        _ => return false,
3412
                    },
C
corentih 已提交
3413
                    _ => return false,
3414
                };
3415
                sig.explicit_self.node == hir::SelfStatic
3416
            } else {
3417
                this.session.cstore.is_static_method(did)
3418 3419 3420
            }
        }

3421 3422 3423 3424
        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,
3425 3426 3427 3428
            },
            None => return NoSuggestion,
        };

3429 3430
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3431
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
3432 3433
                Some(DefEnum(did)) |
                Some(DefTyAlias(did)) |
3434
                Some(DefStruct(did)) |
3435
                Some(DefVariant(_, did)) => match self.structs.get(&did) {
3436 3437 3438 3439 3440
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3441
                    }
3442 3443 3444
                },
                _ => {} // Self type didn't resolve properly
            }
3445 3446
        }

3447
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3448 3449

        // Look for a method in the current self type's impl module.
3450 3451
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
3452
                if let Some(DefMethod(did)) = binding.value_ns.def() {
3453
                    if is_static_method(self, did) {
C
corentih 已提交
3454
                        return StaticMethod(path_names_to_string(&path, 0));
3455 3456 3457 3458 3459
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3460 3461
                    }
                }
3462
            }
3463 3464 3465
        }

        // Look for a method in the current trait.
3466 3467 3468
        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) {
3469
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3470 3471
                } else {
                    return TraitItem;
3472 3473 3474 3475 3476 3477 3478
                }
            }
        }

        NoSuggestion
    }

3479
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
3480
        if let Some(macro_name) = self.session.available_macros
3481
                                  .borrow().iter().find(|n| n.as_str() == name) {
3482 3483 3484
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

3485 3486 3487 3488
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
3489

3490 3491 3492
        if let Some(found) = find_best_match_for_name(names, name, None) {
            if name != &*found {
                return SuggestionType::Function(found);
3493
            }
3494
        } SuggestionType::NotFound
3495 3496
    }

E
Eduard Burtescu 已提交
3497
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3498 3499
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3500 3501 3502

        self.record_candidate_traits_for_expr_if_necessary(expr);

3503
        // Next, resolve the node.
3504
        match expr.node {
3505
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
3506 3507 3508 3509 3510 3511 3512 3513 3514 3515
                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);
3516
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
3517 3518 3519 3520
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
3521

3522 3523
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3524
                if let Some(path_res) = resolution {
3525
                    // Check if struct variant
3526 3527 3528 3529 3530 3531 3532
                    let is_struct_variant = if let DefVariant(_, variant_id) = path_res.base_def {
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
3533
                        let path_name = path_names_to_string(path, 0);
3534

N
Nick Cameron 已提交
3535 3536 3537
                        let mut err = resolve_struct_error(self,
                                        expr.span,
                                        ResolutionError::StructVariantUsedAsFunction(&*path_name));
3538

C
corentih 已提交
3539
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3540 3541
                                          path_name);
                        if self.emit_errors {
N
Nick Cameron 已提交
3542
                            err.fileline_help(expr.span, &msg);
3543
                        } else {
N
Nick Cameron 已提交
3544
                            err.span_help(expr.span, &msg);
3545
                        }
N
Nick Cameron 已提交
3546
                        err.emit();
3547
                        self.record_def(expr.id, err_path_resolution());
3548
                    } else {
3549
                        // Write the result into the def map.
3550
                        debug!("(resolving expr) resolved `{}`",
3551
                               path_names_to_string(path, 0));
3552

3553 3554
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3555
                        if path_res.depth != 0 {
3556
                            let method_name = path.segments.last().unwrap().identifier.name;
3557
                            let traits = self.get_traits_containing_item(method_name);
3558 3559 3560
                            self.trait_map.insert(expr.id, traits);
                        }

3561
                        self.record_def(expr.id, path_res);
3562
                    }
3563 3564 3565 3566 3567
                } 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.)
3568
                    let path_name = path_names_to_string(path, 0);
3569 3570 3571
                    let type_res = self.with_no_errors(|this| {
                        this.resolve_path(expr.id, path, 0, TypeNS, false)
                    });
3572 3573

                    self.record_def(expr.id, err_path_resolution());
3574
                    match type_res.map(|r| r.base_def) {
3575
                        Some(DefStruct(..)) => {
N
Nick Cameron 已提交
3576 3577 3578
                            let mut err = resolve_struct_error(self,
                                expr.span,
                                ResolutionError::StructVariantUsedAsFunction(&*path_name));
3579

C
corentih 已提交
3580 3581 3582
                            let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                              path_name);
                            if self.emit_errors {
N
Nick Cameron 已提交
3583
                                err.fileline_help(expr.span, &msg);
C
corentih 已提交
3584
                            } else {
N
Nick Cameron 已提交
3585
                                err.span_help(expr.span, &msg);
3586
                            }
N
Nick Cameron 已提交
3587
                            err.emit();
C
corentih 已提交
3588
                        }
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601
                        _ => {
                            // 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
                            });
3602

3603
                            if method_scope && special_names::self_.as_str() == &path_name[..] {
C
corentih 已提交
3604 3605 3606
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3607 3608 3609 3610 3611 3612
                            } 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
3613
                                        match self.find_best_match(&path_name) {
3614 3615 3616 3617 3618 3619
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
3620 3621 3622
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
C
corentih 已提交
3623
                                    TraitItem => format!("to call `self.{}`", path_name),
3624 3625
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
C
corentih 已提交
3626
                                        format!("to call `{}::{}`", path_str, path_name),
3627 3628
                                };

3629
                                let mut context =  UnresolvedNameContext::Other;
3630
                                if !msg.is_empty() {
3631 3632 3633 3634 3635 3636 3637
                                    msg = format!(". Did you mean {}?", msg);
                                } else {
                                    // we check if this a module and if so, we display a help
                                    // message
                                    let name_path = path.segments.iter()
                                                        .map(|seg| seg.identifier.name)
                                                        .collect::<Vec<_>>();
3638
                                    let current_module = self.current_module;
3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649

                                    match self.resolve_module_path(current_module,
                                                   &name_path[..],
                                                   UseLexicalScope,
                                                   expr.span,
                                                   PathSearch) {
                                        Success(_) => {
                                            context = UnresolvedNameContext::PathIsMod(expr.id);
                                        },
                                        _ => {},
                                    };
3650
                                }
3651

3652 3653
                                resolve_error(self,
                                              expr.span,
3654 3655
                                              ResolutionError::UnresolvedName(
                                                  &*path_name, &*msg, context));
3656
                            }
V
Vincent Belliard 已提交
3657
                        }
3658 3659 3660
                    }
                }

3661
                intravisit::walk_expr(self, expr);
3662 3663
            }

3664
            ExprStruct(ref path, _, _) => {
3665 3666 3667
                // 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.
3668
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3669
                    Some(definition) => self.record_def(expr.id, definition),
3670 3671
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3672

3673 3674
                        resolve_error(self,
                                      path.span,
3675
                                      ResolutionError::DoesNotNameAStruct(
3676 3677
                                                                &*path_names_to_string(path, 0))
                                     );
3678
                        self.record_def(expr.id, err_path_resolution());
3679 3680 3681
                    }
                }

3682
                intravisit::walk_expr(self, expr);
3683 3684
            }

P
Pythoner6 已提交
3685
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3686
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3687
                    let def_like = DlDef(DefLabel(expr.id));
3688

3689
                    {
3690
                        let rib = this.label_ribs.last_mut().unwrap();
3691
                        rib.bindings.insert(label.name, def_like);
3692
                    }
3693

3694
                    intravisit::walk_expr(this, expr);
3695
                })
3696 3697
            }

3698
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3699
                match self.search_label(label.node.name) {
3700
                    None => {
3701
                        self.record_def(expr.id, err_path_resolution());
3702
                        resolve_error(self,
3703 3704
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3705
                    }
3706
                    Some(DlDef(def @ DefLabel(_))) => {
3707
                        // Since this def is a label, it is never read.
C
corentih 已提交
3708 3709 3710 3711 3712 3713
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            last_private: LastMod(AllPublic),
                                            depth: 0,
                                        })
3714 3715
                    }
                    Some(_) => {
C
corentih 已提交
3716
                        self.session.span_bug(expr.span, "label wasn't mapped to a label def!")
3717 3718 3719 3720
                    }
                }
            }

B
Brian Anderson 已提交
3721
            _ => {
3722
                intravisit::walk_expr(self, expr);
3723 3724 3725 3726
            }
        }
    }

E
Eduard Burtescu 已提交
3727
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3728
        match expr.node {
3729
            ExprField(_, name) => {
3730 3731 3732 3733
                // 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.
3734
                let traits = self.get_traits_containing_item(name.node);
3735
                self.trait_map.insert(expr.id, traits);
3736
            }
3737
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3738
                debug!("(recording candidate traits for expr) recording traits for {}",
3739
                       expr.id);
3740
                let traits = self.get_traits_containing_item(name.node);
3741
                self.trait_map.insert(expr.id, traits);
3742
            }
3743
            _ => {
3744 3745 3746 3747 3748
                // Nothing to do.
            }
        }
    }

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

C
corentih 已提交
3752
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3753
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3754 3755
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3756 3757
            found_traits.push(trait_def_id);
        }
3758

3759
        let mut found_traits = Vec::new();
3760
        let mut search_module = self.current_module;
E
Eduard Burtescu 已提交
3761 3762
        loop {
            // Look for the current trait.
3763 3764
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3765
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3766
                        add_trait_info(&mut found_traits, trait_def_id, name);
3767 3768
                    }
                }
3769
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3770
            }
3771

E
Eduard Burtescu 已提交
3772
            // Look for trait children.
3773
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3774

E
Eduard Burtescu 已提交
3775
            {
3776
                for (_, child_names) in search_module.children.borrow().iter() {
3777
                    let def = match child_names.type_ns.def() {
3778
                        Some(def) => def,
C
corentih 已提交
3779
                        None => continue,
3780 3781
                    };
                    let trait_def_id = match def {
3782
                        DefTrait(trait_def_id) => trait_def_id,
3783 3784
                        _ => continue,
                    };
3785
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3786
                        add_trait_info(&mut found_traits, trait_def_id, name);
3787 3788
                    }
                }
E
Eduard Burtescu 已提交
3789
            }
3790

E
Eduard Burtescu 已提交
3791
            // Look for imports.
3792
            for (_, import) in search_module.import_resolutions.borrow().iter() {
3793
                let target = match import.type_ns.target {
E
Eduard Burtescu 已提交
3794
                    None => continue,
3795
                    Some(ref target) => target,
E
Eduard Burtescu 已提交
3796
                };
3797
                let did = match target.binding.def() {
3798
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3799 3800
                    Some(..) | None => continue,
                };
3801
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3802
                    add_trait_info(&mut found_traits, did, name);
3803
                    let id = import.type_ns.id;
3804 3805 3806
                    self.used_imports.insert((id, TypeNS));
                    let trait_name = self.get_trait_name(did);
                    self.record_import_use(id, trait_name);
3807
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
3808
                        self.used_crates.insert(kid);
3809
                    }
3810
                }
E
Eduard Burtescu 已提交
3811
            }
3812

3813
            match search_module.parent_link {
E
Eduard Burtescu 已提交
3814 3815
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
3816
                    search_module = parent_module;
3817
                }
E
Eduard Burtescu 已提交
3818
            }
3819 3820
        }

E
Eduard Burtescu 已提交
3821
        found_traits
3822 3823
    }

3824 3825
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
C
corentih 已提交
3826 3827 3828 3829
        assert!(match resolution.last_private {
                    LastImport{..} => false,
                    _ => true,
                },
3830
                "Import should only be used for `use` directives");
3831

3832 3833
        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 已提交
3834 3835 3836 3837
            self.session.span_bug(span,
                                  &format!("path resolved multiple times ({:?} before, {:?} now)",
                                           prev_res,
                                           resolution));
3838
        }
3839 3840
    }

F
Felix S. Klock II 已提交
3841
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3842 3843 3844
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3845
        match pat_binding_mode {
3846
            BindByValue(_) => {}
A
Alex Crichton 已提交
3847
            BindByRef(..) => {
3848 3849
                resolve_error(self,
                              pat.span,
3850
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3851 3852 3853 3854
            }
        }
    }

3855 3856 3857 3858 3859 3860 3861
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

K
Kiet Tran 已提交
3862
    #[allow(dead_code)]   // useful for debugging
3863
    fn dump_module(&mut self, module_: Module<'a>) {
3864
        debug!("Dump of module `{}`:", module_to_string(&*module_));
3865

3866
        debug!("Children:");
3867
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3868
        for (&name, _) in module_.children.borrow().iter() {
3869
            debug!("* {}", name);
3870 3871
        }

3872
        debug!("Import resolutions:");
3873
        let import_resolutions = module_.import_resolutions.borrow();
3874
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
3875
            let value_repr;
3876
            match import_resolution.value_ns.target {
C
corentih 已提交
3877 3878 3879
                None => {
                    value_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
3880
                Some(_) => {
R
Richo Healey 已提交
3881
                    value_repr = " value:?".to_string();
3882
                    // FIXME #4954
3883 3884 3885
                }
            }

N
Niko Matsakis 已提交
3886
            let type_repr;
3887
            match import_resolution.type_ns.target {
C
corentih 已提交
3888 3889 3890
                None => {
                    type_repr = "".to_string();
                }
E
Erick Tryzelaar 已提交
3891
                Some(_) => {
R
Richo Healey 已提交
3892
                    type_repr = " type:?".to_string();
3893
                    // FIXME #4954
3894 3895 3896
                }
            }

3897
            debug!("* {}:{}{}", name, value_repr, type_repr);
3898 3899 3900 3901
        }
    }
}

3902 3903 3904 3905 3906 3907 3908 3909 3910 3911

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("::")
        }
3912
        result.push_str(&name.as_str());
C
corentih 已提交
3913
    }
3914 3915 3916 3917
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3918
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3919 3920 3921 3922 3923 3924 3925
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

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

3929
    fn collect_mod<'a>(names: &mut Vec<ast::Name>, module: Module<'a>) {
3930 3931 3932 3933
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
3934
                collect_mod(names, module);
3935 3936 3937 3938
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
                names.push(special_idents::opaque.name);
3939
                collect_mod(names, module);
3940 3941 3942 3943 3944
            }
        }
    }
    collect_mod(&mut names, module);

3945
    if names.is_empty() {
3946 3947 3948 3949 3950
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3951 3952 3953 3954 3955 3956 3957 3958
fn err_path_resolution() -> PathResolution {
    PathResolution {
        base_def: DefErr,
        last_private: LastMod(AllPublic),
        depth: 0,
    }
}

3959

3960
pub struct CrateMap {
J
Jonathan S 已提交
3961
    pub def_map: RefCell<DefMap>,
3962
    pub freevars: FreevarMap,
3963
    pub export_map: ExportMap,
3964 3965
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
C
corentih 已提交
3966
    pub glob_map: Option<GlobMap>,
3967 3968
}

N
Niko Matsakis 已提交
3969
#[derive(PartialEq,Copy, Clone)]
3970 3971
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3972
    No,
3973 3974
}

3975
/// Entry point to crate resolution.
3976
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3977
                               ast_map: &'a hir_map::Map<'tcx>,
3978 3979
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3980
    let krate = ast_map.krate();
3981 3982
    let arenas = Resolver::arenas();
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
3983 3984 3985 3986 3987

    resolver.resolve_crate(krate);

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

3988
    CrateMap {
3989 3990
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3991
        export_map: resolver.export_map,
3992 3993
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
3994
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
3995 3996 3997 3998
            Some(resolver.glob_map)
        } else {
            None
        },
3999
    }
4000
}
4001

4002 4003 4004 4005 4006 4007 4008 4009
/// 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 已提交
4010
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
4011
                                 ast_map: &'a hir_map::Map<'tcx>,
G
Garming Sam 已提交
4012 4013
                                 krate: &'a Crate,
                                 make_glob_map: MakeGlobMap,
4014
                                 arenas: &'a ResolverArenas<'a>,
4015
                                 callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
G
Garming Sam 已提交
4016
                                 -> Resolver<'a, 'tcx> {
4017
    let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
G
Garming Sam 已提交
4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029

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

    resolver
}

4030
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }