lib.rs 149.3 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
#![cfg_attr(not(stage0), deny(warnings))]
19

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

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

S
Steven Fackler 已提交
34 35 36 37 38 39 40 41
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::ResolveResult::*;
use self::FallbackSuggestion::*;
use self::TypeParameters::*;
use self::RibKind::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
42
use self::AssocItemResolveResult::*;
S
Steven Fackler 已提交
43 44 45
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;

46
use rustc::dep_graph::DepNode;
47
use rustc::hir::map as hir_map;
48 49
use rustc::session::Session;
use rustc::lint;
50
use rustc::middle::cstore::CrateStore;
51 52 53
use rustc::hir::def::*;
use rustc::hir::def_id::DefId;
use rustc::hir::pat_util::pat_bindings;
54
use rustc::ty;
55
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
56 57
use rustc::hir::{Freevar, FreevarMap, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, FnvHashMap, FnvHashSet};
58

59
use syntax::ast::{self, FloatTy};
60
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
61
use syntax::attr::AttrMetaMethods;
62
use syntax::codemap::{self, Span, Pos};
N
Nick Cameron 已提交
63
use syntax::errors::DiagnosticBuilder;
64
use syntax::parse::token::{self, keywords};
65
use syntax::util::lev_distance::find_best_match_for_name;
66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use rustc::hir::intravisit::{self, FnKind, Visitor};
use rustc::hir;
use rustc::hir::{Arm, BindByRef, BindByValue, BindingMode, Block};
use rustc::hir::Crate;
use rustc::hir::{Expr, ExprAgain, ExprBreak, ExprCall, ExprField};
use rustc::hir::{ExprLoop, ExprWhile, ExprMethodCall};
use rustc::hir::{ExprPath, ExprStruct, FnDecl};
use rustc::hir::{ForeignItemFn, ForeignItemStatic, Generics};
use rustc::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use rustc::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl};
use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use rustc::hir::Local;
use rustc::hir::{Pat, PatKind, Path, PrimTy};
use rustc::hir::{PathSegment, PathParameters};
use rustc::hir::HirVec;
use rustc::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt};
83
use rustc::hir::{TyRptr, TyStr, TyUint, TyPath};
84

85
use std::collections::{HashMap, HashSet};
86
use std::cell::{Cell, RefCell};
87
use std::fmt;
88
use std::mem::replace;
89

90
use resolve_imports::{ImportDirective, NameResolution};
91

92 93
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
J
Jeffrey Seyfried 已提交
94
mod diagnostics;
95

A
Alex Crichton 已提交
96
mod check_unused;
97
mod build_reduced_graph;
98
mod resolve_imports;
99

100 101 102 103 104 105 106 107 108 109 110
// 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;
            }
        }
    )
}

111 112
enum SuggestionType {
    Macro(String),
113
    Function(token::InternedString),
114 115 116
    NotFound,
}

117
/// Candidates for a name resolution failure
J
Jeffrey Seyfried 已提交
118
struct SuggestedCandidates {
119 120 121 122
    name: String,
    candidates: Vec<Path>,
}

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

198
/// Context of where `ResolutionError::UnresolvedName` arose.
199
#[derive(Clone, PartialEq, Eq, Debug)]
J
Jeffrey Seyfried 已提交
200
enum UnresolvedNameContext {
201 202 203 204
    /// `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.
205
    PathIsMod(ast::NodeId),
206 207 208 209

    /// `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.)
210 211 212
    Other,
}

C
corentih 已提交
213 214 215
fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                       span: syntax::codemap::Span,
                                       resolution_error: ResolutionError<'b>) {
N
Nick Cameron 已提交
216
    resolve_struct_error(resolver, span, resolution_error).emit();
N
Nick Cameron 已提交
217 218 219 220 221
}

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 已提交
222
                                              -> DiagnosticBuilder<'a> {
223
    if !resolver.emit_errors {
N
Nick Cameron 已提交
224
        return resolver.session.diagnostic().struct_dummy();
225
    }
N
Nick Cameron 已提交
226

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

            match context {
436
                UnresolvedNameContext::Other => { } // no help available
437 438 439 440 441 442 443 444 445
                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}`",
J
Jonas Schievink 已提交
446
                                                   module = path,
447 448 449 450 451 452
                                                   ident = ident.node);
                            }
                            ExprMethodCall(ident, _, _) => {
                                help_msg = format!("To call a function from the \
                                                    `{module}` module, use \
                                                    `{module}::{ident}(..)`",
J
Jonas Schievink 已提交
453
                                                   module = path,
454 455
                                                   ident = ident.node);
                            }
456 457
                            ExprCall(_, _) => {
                                help_msg = format!("No function corresponds to `{module}(..)`",
J
Jonas Schievink 已提交
458
                                                   module = path);
459 460
                            }
                            _ => { } // no help available
461
                        }
462 463
                    } else {
                        help_msg = format!("Module `{module}` cannot be the value of an expression",
J
Jonas Schievink 已提交
464
                                           module = path);
465 466 467
                    }

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

N
Niko Matsakis 已提交
535
#[derive(Copy, Clone)]
536
struct BindingInfo {
537
    span: Span,
538
    binding_mode: BindingMode,
539 540 541
}

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

N
Niko Matsakis 已提交
544
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
545
enum PatternBindingMode {
546
    RefutableMode,
547
    LocalIrrefutableMode,
548
    ArgumentIrrefutableMode,
549 550
}

N
Niko Matsakis 已提交
551
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
552
pub enum Namespace {
553
    TypeNS,
C
corentih 已提交
554
    ValueNS,
555 556
}

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

608
        // `intravisit::walk_variant` without the discriminant expression.
C
corentih 已提交
609 610 611 612 613
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
614
    }
615 616
    fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
        execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
617 618 619 620
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
C
corentih 已提交
621
            ForeignItemStatic(..) => NoTypeParameters,
622 623
        };
        self.with_type_parameter_rib(type_parameters, |this| {
624
            intravisit::walk_foreign_item(this, foreign_item);
625 626 627
        });
    }
    fn visit_fn(&mut self,
628
                function_kind: FnKind<'v>,
629 630 631 632 633
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
634
            FnKind::ItemFn(_, generics, _, _, _, _, _) => {
635 636 637
                self.visit_generics(generics);
                ItemRibKind
            }
638
            FnKind::Method(_, sig, _, _) => {
639 640
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
641 642
                MethodRibKind
            }
643
            FnKind::Closure(_) => ClosureRibKind(node_id),
644 645 646
        };
        self.resolve_function(rib_kind, declaration, block);
    }
647
}
648

649
pub type ErrorMessage = Option<(Span, String)>;
650

651
#[derive(Clone, PartialEq, Eq)]
652
pub enum ResolveResult<T> {
C
corentih 已提交
653 654 655
    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.
656 657
}

658
impl<T> ResolveResult<T> {
659 660 661 662 663
    fn and_then<U, F: FnOnce(T) -> ResolveResult<U>>(self, f: F) -> ResolveResult<U> {
        match self {
            Failed(msg) => Failed(msg),
            Indeterminate => Indeterminate,
            Success(t) => f(t),
C
corentih 已提交
664
        }
665
    }
666 667 668 669 670 671 672

    fn success(self) -> Option<T> {
        match self {
            Success(t) => Some(t),
            _ => None,
        }
    }
673 674
}

675 676 677
enum FallbackSuggestion {
    NoSuggestion,
    Field,
678
    TraitItem,
679
    TraitMethod(String),
680 681
}

N
Niko Matsakis 已提交
682
#[derive(Copy, Clone)]
683
enum TypeParameters<'tcx, 'a> {
684
    NoTypeParameters,
C
corentih 已提交
685 686
    HasTypeParameters(// Type parameters.
                      &'a Generics,
687

C
corentih 已提交
688 689 690
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
691

C
corentih 已提交
692
                      // The kind of the rib used for type parameters.
693
                      RibKind<'tcx>),
694 695
}

696
// The rib kind controls the translation of local
697
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
698
#[derive(Copy, Clone, Debug)]
699
enum RibKind<'a> {
700 701
    // No translation needs to be applied.
    NormalRibKind,
702

703 704
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
705
    ClosureRibKind(NodeId /* func id */),
706

707
    // We passed through an impl or trait and are now in one of its
708
    // methods. Allow references to ty params that impl or trait
709 710
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
711
    MethodRibKind,
712

713 714
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
715 716

    // We're in a constant item. Can't refer to dynamic stuff.
C
corentih 已提交
717
    ConstantItemRibKind,
718

719 720
    // We passed through a module.
    ModuleRibKind(Module<'a>),
721 722
}

N
Niko Matsakis 已提交
723
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
724
enum UseLexicalScopeFlag {
725
    DontUseLexicalScope,
C
corentih 已提交
726
    UseLexicalScope,
727 728
}

729
enum ModulePrefixResult<'a> {
730
    NoPrefixFound,
731
    PrefixFound(Module<'a>, usize),
732 733
}

734 735 736 737 738 739 740 741 742
#[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 已提交
743
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
744
enum BareIdentifierPatternResolution {
J
Jeffrey Seyfried 已提交
745 746
    FoundStructOrEnumVariant(Def),
    FoundConst(Def, Name),
C
corentih 已提交
747
    BareIdentifierPatternUnresolved,
748 749
}

750
/// One local scope.
J
Jorge Aparicio 已提交
751
#[derive(Debug)]
752
struct Rib<'a> {
753
    bindings: HashMap<Name, Def>,
754
    kind: RibKind<'a>,
B
Brian Anderson 已提交
755
}
756

757 758
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
759
        Rib {
760
            bindings: HashMap::new(),
C
corentih 已提交
761
            kind: kind,
762
        }
763 764 765
    }
}

766 767 768
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
769
    def: Def,
770 771 772 773 774 775
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
776
            def: def,
777 778 779 780
        }
    }
}

781 782 783 784 785
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
    LocalDef(LocalDef),
}

786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
impl<'a> LexicalScopeBinding<'a> {
    fn local_def(self) -> LocalDef {
        match self {
            LexicalScopeBinding::LocalDef(local_def) => local_def,
            LexicalScopeBinding::Item(binding) => LocalDef::from_def(binding.def().unwrap()),
        }
    }

    fn def(self) -> Def {
        self.local_def().def
    }

    fn module(self) -> Option<Module<'a>> {
        match self {
            LexicalScopeBinding::Item(binding) => binding.module(),
            _ => None,
        }
    }
}

806
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
807
#[derive(Clone,Debug)]
808
enum ParentLink<'a> {
809
    NoParentLink,
810 811
    ModuleParentLink(Module<'a>, Name),
    BlockParentLink(Module<'a>, NodeId),
812 813
}

814
/// One node in the tree of modules.
815 816
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
J
Jeffrey Seyfried 已提交
817
    def: Option<Def>,
818

819 820 821
    // If the module is an extern crate, `def` is root of the external crate and `extern_crate_id`
    // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
    extern_crate_id: Option<NodeId>,
822

823
    resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
824
    unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
825

826
    prelude: RefCell<Option<Module<'a>>>,
827

828
    glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
829
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
830

J
Jeffrey Seyfried 已提交
831
    // Used to memoize the traits in this module for faster searches through all traits in scope.
832
    traits: RefCell<Option<Box<[(Name, &'a NameBinding<'a>)]>>>,
J
Jeffrey Seyfried 已提交
833

834 835 836
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
837
    populated: Cell<bool>,
838 839

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

842 843 844
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
845 846 847 848
    fn new(parent_link: ParentLink<'a>,
           def: Option<Def>,
           external: bool,
           arenas: &'a ResolverArenas<'a>) -> Self {
849
        ModuleS {
850
            parent_link: parent_link,
J
Jeffrey Seyfried 已提交
851
            def: def,
852
            extern_crate_id: None,
853
            resolutions: RefCell::new(HashMap::new()),
854
            unresolved_imports: RefCell::new(Vec::new()),
855
            prelude: RefCell::new(None),
856
            glob_importers: RefCell::new(Vec::new()),
857
            globs: RefCell::new((Vec::new())),
J
Jeffrey Seyfried 已提交
858
            traits: RefCell::new(None),
859
            populated: Cell::new(!external),
860
            arenas: arenas
861
        }
B
Brian Anderson 已提交
862 863
    }

864
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
865
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
866
            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
867 868 869
        }
    }

870
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
871
        self.def.as_ref().map(Def::def_id)
872 873
    }

874
    // `self` resolves to the first module ancestor that `is_normal`.
875
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
876
        match self.def {
877
            Some(Def::Mod(_)) => true,
878 879 880 881 882
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
883
        match self.def {
884
            Some(Def::Trait(_)) => true,
885
            _ => false,
886
        }
B
Brian Anderson 已提交
887
    }
V
Victor Berger 已提交
888 889
}

890
impl<'a> fmt::Debug for ModuleS<'a> {
891
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
892
        write!(f, "{:?}", self.def)
893 894 895
    }
}

896
// Records a possibly-private value, type, or module definition.
897
#[derive(Clone, Debug)]
898
pub struct NameBinding<'a> {
899
    kind: NameBindingKind<'a>,
900
    span: Span,
901
    vis: ty::Visibility,
902 903
}

904
#[derive(Clone, Debug)]
905
enum NameBindingKind<'a> {
906
    Def(Def),
907
    Module(Module<'a>),
908 909
    Import {
        binding: &'a NameBinding<'a>,
910
        directive: &'a ImportDirective<'a>,
911 912
        // Some(error) if using this imported name causes the import to be a privacy error
        privacy_error: Option<Box<PrivacyError<'a>>>,
913
    },
914 915
}

916 917 918
#[derive(Clone, Debug)]
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

919
impl<'a> NameBinding<'a> {
920
    fn module(&self) -> Option<Module<'a>> {
921 922 923 924
        match self.kind {
            NameBindingKind::Module(module) => Some(module),
            NameBindingKind::Def(_) => None,
            NameBindingKind::Import { binding, .. } => binding.module(),
925 926 927
        }
    }

928
    fn def(&self) -> Option<Def> {
929 930 931 932
        match self.kind {
            NameBindingKind::Def(def) => Some(def),
            NameBindingKind::Module(module) => module.def,
            NameBindingKind::Import { binding, .. } => binding.def(),
933
        }
934
    }
935

936 937 938 939 940 941 942 943 944 945 946 947 948 949
    fn is_pseudo_public(&self) -> bool {
        self.pseudo_vis() == ty::Visibility::Public
    }

    // We sometimes need to treat variants as `pub` for backwards compatibility
    fn pseudo_vis(&self) -> ty::Visibility {
        if self.is_variant() { ty::Visibility::Public } else { self.vis }
    }

    fn is_variant(&self) -> bool {
        match self.kind {
            NameBindingKind::Def(Def::Variant(..)) => true,
            _ => false,
        }
950 951
    }

952
    fn is_extern_crate(&self) -> bool {
953
        self.module().and_then(|module| module.extern_crate_id).is_some()
954
    }
955 956 957 958 959 960 961

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
962 963 964 965 966 967 968 969 970 971 972 973 974 975

    fn is_glob_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { directive, .. } => directive.is_glob(),
            _ => false,
        }
    }

    fn is_importable(&self) -> bool {
        match self.def().unwrap() {
            Def::AssociatedConst(..) | Def::Method(..) | Def::AssociatedTy(..) => false,
            _ => true,
        }
    }
976 977
}

978
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
979
struct PrimitiveTypeTable {
980
    primitive_types: HashMap<Name, PrimTy>,
981
}
982

983
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
984
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
985 986 987 988
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
989 990
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
991 992 993 994 995
        table.intern("isize", TyInt(IntTy::Is));
        table.intern("i8", TyInt(IntTy::I8));
        table.intern("i16", TyInt(IntTy::I16));
        table.intern("i32", TyInt(IntTy::I32));
        table.intern("i64", TyInt(IntTy::I64));
C
corentih 已提交
996
        table.intern("str", TyStr);
997 998 999 1000 1001
        table.intern("usize", TyUint(UintTy::Us));
        table.intern("u8", TyUint(UintTy::U8));
        table.intern("u16", TyUint(UintTy::U16));
        table.intern("u32", TyUint(UintTy::U32));
        table.intern("u64", TyUint(UintTy::U64));
K
Kevin Butler 已提交
1002 1003 1004 1005

        table
    }

1006
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1007
        self.primitive_types.insert(token::intern(string), primitive_type);
1008 1009 1010
    }
}

1011
/// The main resolver class.
C
corentih 已提交
1012
pub struct Resolver<'a, 'tcx: 'a> {
E
Eduard Burtescu 已提交
1013
    session: &'a Session,
1014

1015
    ast_map: &'a hir_map::Map<'tcx>,
1016

1017
    graph_root: Module<'a>,
1018

1019
    trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
1020

1021
    structs: FnvHashMap<DefId, Vec<Name>>,
1022

1023
    // The number of imports that are currently unresolved.
1024
    unresolved_imports: usize,
1025 1026

    // The module that represents the current item scope.
1027
    current_module: Module<'a>,
1028 1029

    // The current set of local scopes, for values.
1030
    // FIXME #4948: Reuse ribs to avoid allocation.
1031
    value_ribs: Vec<Rib<'a>>,
1032 1033

    // The current set of local scopes, for types.
1034
    type_ribs: Vec<Rib<'a>>,
1035

1036
    // The current set of local scopes, for labels.
1037
    label_ribs: Vec<Rib<'a>>,
1038

1039
    // The trait that the current context can refer to.
1040 1041 1042 1043
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1045
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1046
    primitive_type_table: PrimitiveTypeTable,
1047

J
Jonathan S 已提交
1048
    def_map: RefCell<DefMap>,
1049 1050
    freevars: FreevarMap,
    freevars_seen: NodeMap<NodeMap<usize>>,
1051
    export_map: ExportMap,
1052
    trait_map: TraitMap,
1053

1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
    // A map from nodes to modules, both normal (`mod`) modules and anonymous modules.
    // Anonymous modules 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`.
    module_map: NodeMap<Module<'a>>,

1070 1071 1072 1073 1074
    // 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,

1075 1076 1077 1078 1079
    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,

1080
    used_imports: HashSet<(NodeId, Namespace)>,
1081
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1082 1083

    // Callback function for intercepting walks
1084
    callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>,
G
Garming Sam 已提交
1085 1086 1087
    // The intention is that the callback modifies this flag.
    // Once set, the resolver falls out of the walk, preserving the ribs.
    resolved: bool,
1088
    privacy_errors: Vec<PrivacyError<'a>>,
1089 1090 1091 1092

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

J
Jeffrey Seyfried 已提交
1093
struct ResolverArenas<'a> {
1094
    modules: arena::TypedArena<ModuleS<'a>>,
1095
    local_modules: RefCell<Vec<Module<'a>>>,
1096
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1097
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1098
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1099 1100 1101
}

impl<'a> ResolverArenas<'a> {
1102
    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
1103 1104 1105 1106 1107 1108 1109 1110
        let module = self.modules.alloc(module);
        if module.def_id().map(|def_id| def_id.is_local()).unwrap_or(true) {
            self.local_modules.borrow_mut().push(module);
        }
        module
    }
    fn local_modules(&'a self) -> ::std::cell::Ref<'a, Vec<Module<'a>>> {
        self.local_modules.borrow()
1111 1112 1113 1114
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1115 1116
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1117 1118
        self.import_directives.alloc(import_directive)
    }
1119 1120 1121
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1122 1123
}

1124 1125 1126 1127
impl<'a, 'tcx> ty::NodeIdTree for Resolver<'a, 'tcx> {
    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
        let ancestor = self.ast_map.local_def_id(ancestor);
        let mut module = *self.module_map.get(&node).unwrap();
J
Jeffrey Seyfried 已提交
1128
        while module.def_id() != Some(ancestor) {
1129 1130 1131 1132 1133 1134
            let module_parent = match self.get_nearest_normal_module_parent(module) {
                Some(parent) => parent,
                None => return false,
            };
            module = module_parent;
        }
J
Jeffrey Seyfried 已提交
1135
        true
1136 1137 1138
    }
}

1139 1140
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1141
           ast_map: &'a hir_map::Map<'tcx>,
1142 1143
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
C
corentih 已提交
1144
           -> Resolver<'a, 'tcx> {
1145
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
1146
        let graph_root =
1147
            ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
1148
        let graph_root = arenas.alloc_module(graph_root);
1149 1150
        let mut module_map = NodeMap();
        module_map.insert(CRATE_NODE_ID, graph_root);
K
Kevin Butler 已提交
1151 1152 1153 1154

        Resolver {
            session: session,

1155 1156
            ast_map: ast_map,

K
Kevin Butler 已提交
1157 1158
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1159
            graph_root: graph_root,
K
Kevin Butler 已提交
1160

1161 1162
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1163 1164 1165

            unresolved_imports: 0,

1166
            current_module: graph_root,
1167 1168
            value_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
            type_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
1169
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1170 1171 1172 1173 1174 1175

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1176
            def_map: RefCell::new(NodeMap()),
1177 1178
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1179 1180
            export_map: NodeMap(),
            trait_map: NodeMap(),
1181
            module_map: module_map,
K
Kevin Butler 已提交
1182
            used_imports: HashSet::new(),
1183
            used_crates: HashSet::new(),
K
Kevin Butler 已提交
1184 1185

            emit_errors: true,
1186
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1187
            glob_map: NodeMap(),
G
Garming Sam 已提交
1188 1189 1190

            callback: None,
            resolved: false,
1191
            privacy_errors: Vec::new(),
1192 1193 1194 1195 1196 1197 1198 1199

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
1200
            local_modules: RefCell::new(Vec::new()),
1201
            name_bindings: arena::TypedArena::new(),
1202
            import_directives: arena::TypedArena::new(),
1203
            name_resolutions: arena::TypedArena::new(),
K
Kevin Butler 已提交
1204 1205
        }
    }
1206

1207 1208 1209
    fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool)
                  -> Module<'a> {
        self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas))
1210 1211
    }

1212
    fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId)
1213
                               -> Module<'a> {
1214
        let mut module = ModuleS::new(parent_link, Some(def), false, self.arenas);
1215
        module.extern_crate_id = Some(local_node_id);
1216 1217 1218
        self.arenas.modules.alloc(module)
    }

1219 1220 1221 1222
    fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec<Rib<'a>> {
        match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs }
    }

1223
    #[inline]
1224 1225 1226 1227 1228 1229
    fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
        // track extern crates for unused_extern_crate lint
        if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
            self.used_crates.insert(krate);
        }

1230 1231 1232
        let (directive, privacy_error) = match binding.kind {
            NameBindingKind::Import { directive, ref privacy_error, .. } =>
                (directive, privacy_error),
1233 1234 1235
            _ => return,
        };

1236
        self.used_imports.insert((directive.id, ns));
1237 1238 1239
        if let Some(error) = privacy_error.as_ref() {
            self.privacy_errors.push((**error).clone());
        }
1240

1241 1242 1243
        if !self.make_glob_map {
            return;
        }
1244 1245
        if self.glob_map.contains_key(&directive.id) {
            self.glob_map.get_mut(&directive.id).unwrap().insert(name);
1246 1247 1248
            return;
        }

1249
        let mut new_set = FnvHashSet();
1250
        new_set.insert(name);
1251
        self.glob_map.insert(directive.id, new_set);
1252 1253
    }

1254
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1255
    fn resolve_module_path_from_root(&mut self,
1256
                                     module_: Module<'a>,
1257
                                     module_path: &[Name],
1258
                                     index: usize,
J
Jeffrey Seyfried 已提交
1259 1260
                                     span: Span)
                                     -> ResolveResult<Module<'a>> {
1261
        fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
1262 1263
            match module.resolve_name(needle, TypeNS, false) {
                Success(binding) if binding.is_extern_crate() => Some(module),
1264
                _ => match module.parent_link {
1265
                    ModuleParentLink(ref parent, _) => {
1266
                        search_parent_externals(needle, parent)
1267
                    }
C
corentih 已提交
1268 1269
                    _ => None,
                },
1270
            }
1271 1272
        }

1273
        let mut search_module = module_;
1274
        let mut index = index;
A
Alex Crichton 已提交
1275
        let module_path_len = module_path.len();
1276 1277 1278 1279 1280

        // 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 已提交
1281
            let name = module_path[index];
1282
            match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
1283
                Failed(None) => {
1284
                    let segment_name = name.as_str();
1285
                    let module_name = module_to_string(search_module);
1286
                    let mut span = span;
1287
                    let msg = if "???" == &module_name {
1288
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1289

C
corentih 已提交
1290
                        match search_parent_externals(name, &self.current_module) {
1291
                            Some(module) => {
1292
                                let path_str = names_to_string(module_path);
J
Jonas Schievink 已提交
1293 1294
                                let target_mod_str = module_to_string(&module);
                                let current_mod_str = module_to_string(&self.current_module);
1295 1296 1297 1298 1299 1300 1301

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

1302
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1303 1304
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1305
                        }
1306
                    } else {
C
corentih 已提交
1307
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1308
                    };
1309

1310
                    return Failed(Some((span, msg)));
1311
                }
1312
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1313
                Indeterminate => {
C
corentih 已提交
1314 1315 1316
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1317
                    return Indeterminate;
1318
                }
1319
                Success(binding) => {
1320 1321
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
J
Jeffrey Seyfried 已提交
1322
                    if let Some(module_def) = binding.module() {
1323
                        self.check_privacy(name, binding, span);
1324 1325 1326 1327
                        search_module = module_def;
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1328 1329 1330 1331
                    }
                }
            }

T
Tim Chevalier 已提交
1332
            index += 1;
1333 1334
        }

J
Jeffrey Seyfried 已提交
1335
        return Success(search_module);
1336 1337
    }

1338 1339
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
F
Felix S. Klock II 已提交
1340
    fn resolve_module_path(&mut self,
1341
                           module_path: &[Name],
1342
                           use_lexical_scope: UseLexicalScopeFlag,
J
Jeffrey Seyfried 已提交
1343
                           span: Span)
J
Jeffrey Seyfried 已提交
1344
                           -> ResolveResult<Module<'a>> {
1345
        if module_path.len() == 0 {
J
Jeffrey Seyfried 已提交
1346
            return Success(self.graph_root) // Use the crate root
1347
        }
1348

1349
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1350
               names_to_string(module_path),
1351
               module_to_string(self.current_module));
1352

1353
        // Resolve the module prefix, if any.
1354
        let module_prefix_result = self.resolve_module_prefix(module_path, span);
1355

1356 1357
        let search_module;
        let start_index;
1358
        match module_prefix_result {
1359
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1360
            Indeterminate => {
C
corentih 已提交
1361
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1362
                return Indeterminate;
1363
            }
1364 1365 1366 1367 1368 1369 1370 1371
            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.
1372
                        search_module = self.graph_root;
1373 1374 1375 1376 1377 1378
                        start_index = 0;
                    }
                    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.
1379 1380 1381 1382 1383 1384 1385
                        let ident = hir::Ident::from_name(module_path[0]);
                        match self.resolve_ident_in_lexical_scope(ident, TypeNS, true)
                                  .and_then(LexicalScopeBinding::module) {
                            None => return Failed(None),
                            Some(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1386 1387 1388 1389 1390
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1391
            Success(PrefixFound(ref containing_module, index)) => {
1392
                search_module = containing_module;
1393
                start_index = index;
1394 1395 1396
            }
        }

1397 1398 1399
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
J
Jeffrey Seyfried 已提交
1400
                                           span)
1401 1402
    }

1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
    /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope.
    /// More specifically, we proceed up the hierarchy of scopes and return the binding for
    /// `ident` in the first scope that defines it (or None if no scopes define it).
    ///
    /// A block's items are above its local variables in the scope hierarchy, regardless of where
    /// the items are defined in the block. For example,
    /// ```rust
    /// fn f() {
    ///    g(); // Since there are no local variables in scope yet, this resolves to the item.
    ///    let g = || {};
    ///    fn g() {}
    ///    g(); // This resolves to the local variable `g` since it shadows the item.
    /// }
    /// ```
1417
    ///
1418 1419
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
1420 1421 1422 1423 1424 1425 1426
    fn resolve_ident_in_lexical_scope(&mut self,
                                      ident: hir::Ident,
                                      ns: Namespace,
                                      record_used: bool)
                                      -> Option<LexicalScopeBinding<'a>> {
        let name = match ns { ValueNS => ident.name, TypeNS => ident.unhygienic_name };

1427
        // Walk backwards up the ribs in scope.
1428 1429 1430 1431 1432 1433 1434
        for i in (0 .. self.get_ribs(ns).len()).rev() {
            if let Some(def) = self.get_ribs(ns)[i].bindings.get(&name).cloned() {
                // The ident resolves to a type parameter or local variable.
                return Some(LexicalScopeBinding::LocalDef(LocalDef {
                    ribs: Some((ns, i)),
                    def: def,
                }));
1435 1436
            }

1437 1438 1439 1440 1441 1442
            if let ModuleRibKind(module) = self.get_ribs(ns)[i].kind {
                let name = ident.unhygienic_name;
                let item = self.resolve_name_in_module(module, name, ns, true, record_used);
                if let Success(binding) = item {
                    // The ident resolves to an item.
                    return Some(LexicalScopeBinding::Item(binding));
1443
                }
1444

1445
                // We can only see through anonymous modules
1446
                if module.def.is_some() { return None; }
1447 1448
            }
        }
1449

1450 1451 1452
        None
    }

1453
    /// Returns the nearest normal module parent of the given module.
1454
    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
1455 1456
        let mut module_ = module_;
        loop {
1457
            match module_.parent_link {
1458 1459 1460
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
1461
                    let new_module = new_module;
1462 1463
                    if new_module.is_normal() {
                        return Some(new_module);
1464
                    }
1465
                    module_ = new_module;
1466 1467 1468 1469 1470
                }
            }
        }
    }

1471 1472
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1473
    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
1474 1475 1476
        if module_.is_normal() {
            return module_;
        }
1477
        match self.get_nearest_normal_module_parent(module_) {
1478 1479
            None => module_,
            Some(new_module) => new_module,
1480 1481 1482
        }
    }

1483
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1484
    /// (b) some chain of `super::`.
1485
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
1486
    fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
1487
                             -> ResolveResult<ModulePrefixResult<'a>> {
1488 1489
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1490 1491 1492 1493 1494
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
1495
        let module_ = self.current_module;
1496
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1497 1498

        // Now loop through all the `super`s we find.
1499
        while i < module_path.len() && "super" == module_path[i].as_str() {
1500
            debug!("(resolving module prefix) resolving `super` at {}",
J
Jonas Schievink 已提交
1501
                   module_to_string(&containing_module));
1502
            match self.get_nearest_normal_module_parent(containing_module) {
1503 1504 1505 1506
                None => {
                    let msg = "There are too many initial `super`s.".into();
                    return Failed(Some((span, msg)));
                }
1507 1508 1509
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1510 1511 1512 1513
                }
            }
        }

1514
        debug!("(resolving module prefix) finished resolving prefix at {}",
J
Jonas Schievink 已提交
1515
               module_to_string(&containing_module));
1516 1517

        return Success(PrefixFound(containing_module, i));
1518 1519
    }

1520
    /// Attempts to resolve the supplied name in the given module for the
J
Jeffrey Seyfried 已提交
1521
    /// given namespace. If successful, returns the binding corresponding to
1522
    /// the name.
F
Felix S. Klock II 已提交
1523
    fn resolve_name_in_module(&mut self,
1524
                              module: Module<'a>,
1525
                              name: Name,
1526
                              namespace: Namespace,
1527
                              use_lexical_scope: bool,
1528
                              record_used: bool)
1529
                              -> ResolveResult<&'a NameBinding<'a>> {
1530
        debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
1531

1532
        self.populate_module_if_necessary(module);
1533 1534 1535 1536 1537
        match use_lexical_scope {
            true => module.resolve_name_in_lexical_scope(name, namespace)
                          .map(Success).unwrap_or(Failed(None)),
            false => module.resolve_name(name, namespace, false),
        }.and_then(|binding| {
1538 1539
            if record_used {
                self.record_use(name, namespace, binding);
1540
            }
1541 1542
            Success(binding)
        })
1543 1544 1545 1546
    }

    // AST resolution
    //
1547
    // We maintain a list of value ribs and type ribs.
1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562
    //
    // 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.

1563
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1564
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1565
    {
1566 1567
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
1568 1569 1570 1571
            // Move down in the graph.
            let orig_module = ::std::mem::replace(&mut self.current_module, module);
            self.value_ribs.push(Rib::new(ModuleRibKind(module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(module)));
1572

1573
            f(self);
1574

1575 1576 1577 1578 1579 1580
            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
1581 1582
    }

S
Seo Sanghyeon 已提交
1583 1584
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1585
    fn search_label(&self, name: Name) -> Option<Def> {
1586 1587 1588 1589 1590 1591 1592
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1593
                    return None;
1594 1595 1596
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1597
            if result.is_some() {
C
corentih 已提交
1598
                return result;
1599 1600 1601 1602 1603
            }
        }
        None
    }

1604
    fn resolve_crate(&mut self, krate: &hir::Crate) {
1605
        debug!("(resolving crate) starting");
1606
        self.current_module = self.graph_root;
1607
        intravisit::walk_crate(self, krate);
1608 1609
    }

1610
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
1611
        let name = item.name;
1612

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

1615
        match item.node {
1616 1617 1618
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
C
corentih 已提交
1619
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1620
                                             |this| intravisit::walk_item(this, item));
1621
            }
1622
            ItemFn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1623
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
1624
                                             |this| intravisit::walk_item(this, item));
1625 1626
            }

F
Flavio Percoco 已提交
1627
            ItemDefaultImpl(_, ref trait_ref) => {
1628
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1629
            }
C
corentih 已提交
1630
            ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
1631
                self.resolve_implementation(generics,
1632
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1633
                                            &self_type,
1634
                                            item.id,
1635
                                            impl_items);
1636 1637
            }

N
Nick Cameron 已提交
1638
            ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
1639 1640 1641 1642 1643
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
1644
                    let local_def_id = this.ast_map.local_def_id(item.id);
1645
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1646
                        this.visit_generics(generics);
1647
                        walk_list!(this, visit_ty_param_bound, bounds);
1648 1649

                        for trait_item in trait_items {
1650
                            match trait_item.node {
1651
                                hir::ConstTraitItem(_, ref default) => {
1652 1653 1654 1655 1656
                                    // 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| {
1657
                                            intravisit::walk_trait_item(this, trait_item)
1658 1659
                                        });
                                    } else {
1660
                                        intravisit::walk_trait_item(this, trait_item)
1661 1662
                                    }
                                }
1663
                                hir::MethodTraitItem(ref sig, _) => {
1664 1665 1666 1667 1668
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
1669
                                        intravisit::walk_trait_item(this, trait_item)
1670
                                    });
1671
                                }
1672
                                hir::TypeTraitItem(..) => {
1673
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1674
                                        intravisit::walk_trait_item(this, trait_item)
1675
                                    });
1676 1677 1678 1679
                                }
                            };
                        }
                    });
1680
                });
1681 1682
            }

1683
            ItemMod(_) | ItemForeignMod(_) => {
1684
                self.with_scope(item.id, |this| {
1685
                    intravisit::walk_item(this, item);
1686
                });
1687 1688
            }

1689
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
1690
                self.with_constant_rib(|this| {
1691
                    intravisit::walk_item(this, item);
1692
                });
1693
            }
1694

W
we 已提交
1695
            ItemUse(ref view_path) => {
1696
                match view_path.node {
1697 1698 1699 1700 1701 1702
                    hir::ViewPathList(ref prefix, ref items) => {
                        // 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) {
1703 1704 1705 1706
                                Ok(binding) => {
                                    let def = binding.def().unwrap();
                                    self.record_def(item.id, PathResolution::new(def, 0));
                                }
1707 1708
                                Err(true) => self.record_def(item.id, err_path_resolution()),
                                Err(false) => {
1709 1710 1711 1712
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
1713
                                    self.record_def(item.id, err_path_resolution());
1714
                                }
1715 1716 1717 1718
                            }
                        }
                    }
                    _ => {}
W
we 已提交
1719 1720 1721
                }
            }

1722
            ItemExternCrate(_) => {
1723
                // do nothing, these are just around to be encoded
1724
            }
1725 1726 1727
        }
    }

1728
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1729
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1730
    {
1731
        match type_parameters {
1732
            HasTypeParameters(generics, space, rib_kind) => {
1733
                let mut function_type_rib = Rib::new(rib_kind);
1734
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
1735
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
1736
                    let name = type_parameter.name;
1737
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1738

1739
                    if seen_bindings.contains(&name) {
1740 1741
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
1742
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
1743
                    }
1744
                    seen_bindings.insert(name);
1745

1746
                    // plain insert (no renaming)
1747 1748 1749
                    let def_id = self.ast_map.local_def_id(type_parameter.id);
                    let def = Def::TyParam(space, index as u32, def_id, name);
                    function_type_rib.bindings.insert(name, def);
1750
                }
1751
                self.type_ribs.push(function_type_rib);
1752 1753
            }

B
Brian Anderson 已提交
1754
            NoTypeParameters => {
1755 1756 1757 1758
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1759
        f(self);
1760

1761
        match type_parameters {
C
corentih 已提交
1762 1763 1764 1765 1766 1767
            HasTypeParameters(..) => {
                if !self.resolved {
                    self.type_ribs.pop();
                }
            }
            NoTypeParameters => {}
1768 1769 1770
        }
    }

C
corentih 已提交
1771 1772
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1773
    {
1774
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1775
        f(self);
G
Garming Sam 已提交
1776 1777 1778
        if !self.resolved {
            self.label_ribs.pop();
        }
1779
    }
1780

C
corentih 已提交
1781 1782
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1783
    {
1784 1785
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1786
        f(self);
G
Garming Sam 已提交
1787 1788 1789 1790
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
1791 1792
    }

1793
    fn resolve_function(&mut self, rib_kind: RibKind<'a>, declaration: &FnDecl, block: &Block) {
1794
        // Create a value rib for the function.
1795
        self.value_ribs.push(Rib::new(rib_kind));
1796

1797
        // Create a label rib for the function.
1798
        self.label_ribs.push(Rib::new(rib_kind));
1799

1800 1801 1802
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
J
Jonas Schievink 已提交
1803
            self.resolve_pattern(&argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
1804

J
Jonas Schievink 已提交
1805
            self.visit_ty(&argument.ty);
1806

1807 1808
            debug!("(resolving function) recorded argument");
        }
1809
        intravisit::walk_fn_ret_ty(self, &declaration.output);
1810

1811
        // Resolve the function body.
1812
        self.visit_block(block);
1813

1814
        debug!("(resolving function) leaving function");
1815

G
Garming Sam 已提交
1816 1817 1818 1819
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
1820 1821
    }

F
Felix S. Klock II 已提交
1822
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
1823
                               id: NodeId,
1824
                               trait_path: &Path,
1825
                               path_depth: usize)
1826
                               -> Result<PathResolution, ()> {
1827
        self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
1828
            if let Def::Trait(_) = path_res.base_def {
1829 1830 1831
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
N
Nick Cameron 已提交
1832 1833 1834
                let mut err =
                    resolve_struct_error(self,
                                  trait_path.span,
J
Jonas Schievink 已提交
1835
                                  ResolutionError::IsNotATrait(&path_names_to_string(trait_path,
N
Nick Cameron 已提交
1836
                                                                                      path_depth)));
1837 1838

                // If it's a typedef, give a note
1839
                if let Def::TyAlias(..) = path_res.base_def {
V
vegai 已提交
1840
                    err.fileline_note(trait_path.span,
N
Nick Cameron 已提交
1841
                                  "`type` aliases cannot be used for traits");
1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853

                    let definition_site = {
                        let segments = &trait_path.segments;
                        if trait_path.global {
                            self.resolve_crate_relative_path(trait_path.span, segments, TypeNS)
                        } else {
                            self.resolve_module_relative_path(trait_path.span, segments, TypeNS)
                        }.map(|binding| binding.span).unwrap_or(codemap::DUMMY_SP)
                    };

                    if definition_site != codemap::DUMMY_SP {
                        err.span_note(definition_site, "type defined here");
V
vegai 已提交
1854
                    }
1855
                }
N
Nick Cameron 已提交
1856
                err.emit();
1857
                Err(true)
1858
            }
1859 1860
        }).map_err(|error_reported| {
            if error_reported { return }
1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882

            // find possible candidates
            let trait_name = trait_path.segments.last().unwrap().identifier.name;
            let candidates =
                self.lookup_candidates(
                    trait_name,
                    TypeNS,
                    |def| match def {
                        Def::Trait(_) => true,
                        _             => false,
                    },
                );

            // create error object
            let name = &path_names_to_string(trait_path, path_depth);
            let error =
                ResolutionError::UndeclaredTraitName(
                    name,
                    candidates,
                );

            resolve_error(self, trait_path.span, error);
1883
        })
1884 1885
    }

1886 1887
    fn resolve_generics(&mut self, generics: &Generics) {
        for predicate in &generics.where_clause.predicates {
1888
            match predicate {
1889 1890 1891
                &hir::WherePredicate::BoundPredicate(_) |
                &hir::WherePredicate::RegionPredicate(_) => {}
                &hir::WherePredicate::EqPredicate(ref eq_pred) => {
1892 1893 1894 1895 1896 1897 1898
                    self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS).and_then(|path_res| {
                        if let PathResolution { base_def: Def::TyParam(..), .. } = path_res {
                            Ok(self.record_def(eq_pred.id, path_res))
                        } else {
                            Err(false)
                        }
                    }).map_err(|error_reported| {
1899
                        self.record_def(eq_pred.id, err_path_resolution());
1900
                        if error_reported { return }
J
Jeffrey Seyfried 已提交
1901 1902
                        let error_variant = ResolutionError::UndeclaredAssociatedType;
                        resolve_error(self, eq_pred.span, error_variant);
1903
                    }).unwrap_or(());
1904
                }
1905 1906
            }
        }
1907
        intravisit::walk_generics(self, generics);
1908 1909
    }

1910 1911
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
1912
    {
1913 1914 1915 1916 1917 1918 1919
        // 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 已提交
1920
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
1921
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
1922
    {
1923
        let mut new_val = None;
1924
        let mut new_id = None;
E
Eduard Burtescu 已提交
1925
        if let Some(trait_ref) = opt_trait_ref {
1926
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
1927 1928
                                                               &trait_ref.path,
                                                               0) {
1929 1930 1931 1932
                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());
1933 1934
            } else {
                self.record_def(trait_ref.ref_id, err_path_resolution());
1935
            }
1936
            intravisit::walk_trait_ref(self, trait_ref);
1937
        }
1938
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
1939
        let result = f(self, new_id);
1940 1941 1942 1943
        self.current_trait_ref = original_trait_ref;
        result
    }

1944 1945 1946 1947 1948 1949
    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....)
1950
        self_type_rib.bindings.insert(keywords::SelfType.name(), self_def);
1951 1952
        self.type_ribs.push(self_type_rib);
        f(self);
G
Garming Sam 已提交
1953 1954 1955
        if !self.resolved {
            self.type_ribs.pop();
        }
1956 1957
    }

F
Felix S. Klock II 已提交
1958
    fn resolve_implementation(&mut self,
1959 1960 1961
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
1962
                              item_id: NodeId,
1963
                              impl_items: &[ImplItem]) {
1964
        // If applicable, create a rib for the type parameters.
1965
        self.with_type_parameter_rib(HasTypeParameters(generics,
1966
                                                       TypeSpace,
1967
                                                       ItemRibKind),
1968
                                     |this| {
1969
            // Resolve the type parameters.
1970
            this.visit_generics(generics);
1971

1972
            // Resolve the trait reference, if necessary.
1973
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
1974
                // Resolve the self type.
1975
                this.visit_ty(self_type);
1976

1977
                this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
1978 1979
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
1980
                            this.resolve_visibility(&impl_item.vis);
1981
                            match impl_item.node {
1982
                                hir::ImplItemKind::Const(..) => {
1983
                                    // If this is a trait impl, ensure the const
1984
                                    // exists in trait
V
Vadim Petrochenkov 已提交
1985
                                    this.check_trait_item(impl_item.name,
1986 1987
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
1988
                                    this.with_constant_rib(|this| {
1989
                                        intravisit::walk_impl_item(this, impl_item);
1990 1991
                                    });
                                }
1992
                                hir::ImplItemKind::Method(ref sig, _) => {
1993 1994
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
V
Vadim Petrochenkov 已提交
1995
                                    this.check_trait_item(impl_item.name,
1996 1997
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
1998 1999 2000 2001 2002 2003 2004 2005

                                    // 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| {
2006
                                        intravisit::walk_impl_item(this, impl_item);
2007 2008
                                    });
                                }
2009
                                hir::ImplItemKind::Type(ref ty) => {
2010
                                    // If this is a trait impl, ensure the type
2011
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2012
                                    this.check_trait_item(impl_item.name,
2013 2014
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2015

2016 2017
                                    this.visit_ty(ty);
                                }
2018
                            }
2019
                        }
2020
                    });
2021 2022
                });
            });
2023
        });
2024 2025
    }

2026
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
2027 2028 2029 2030
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2031
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2032
            if !self.trait_item_map.contains_key(&(name, did)) {
2033
                let path_str = path_names_to_string(&trait_ref.path, 0);
J
Jonas Schievink 已提交
2034
                resolve_error(self, span, err(name, &path_str));
2035 2036 2037 2038
            }
        }
    }

E
Eduard Burtescu 已提交
2039
    fn resolve_local(&mut self, local: &Local) {
2040
        // Resolve the type.
2041
        walk_list!(self, visit_ty, &local.ty);
2042

2043
        // Resolve the initializer.
2044
        walk_list!(self, visit_expr, &local.init);
2045 2046

        // Resolve the pattern.
J
Jonas Schievink 已提交
2047
        self.resolve_pattern(&local.pat, LocalIrrefutableMode, &mut HashMap::new());
2048 2049
    }

J
John Clements 已提交
2050 2051 2052 2053
    // 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 已提交
2054
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2055
        let mut result = HashMap::new();
2056 2057
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = path1.node;
C
corentih 已提交
2058 2059 2060 2061 2062
            result.insert(name,
                          BindingInfo {
                              span: sp,
                              binding_mode: binding_mode,
                          });
2063
        });
2064
        return result;
2065 2066
    }

J
John Clements 已提交
2067 2068
    // 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 已提交
2069
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2070
        if arm.pats.is_empty() {
C
corentih 已提交
2071
            return;
2072
        }
J
Jonas Schievink 已提交
2073
        let map_0 = self.binding_mode_map(&arm.pats[0]);
D
Daniel Micay 已提交
2074
        for (i, p) in arm.pats.iter().enumerate() {
J
Jonas Schievink 已提交
2075
            let map_i = self.binding_mode_map(&p);
2076

2077
            for (&key, &binding_0) in &map_0 {
2078
                match map_i.get(&key) {
C
corentih 已提交
2079
                    None => {
2080
                        resolve_error(self,
C
corentih 已提交
2081 2082 2083 2084 2085 2086 2087 2088 2089 2090
                                      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));
                        }
2091
                    }
2092 2093 2094
                }
            }

2095
            for (&key, &binding) in &map_i {
2096
                if !map_0.contains_key(&key) {
2097 2098
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2099
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2100 2101 2102
                }
            }
        }
2103 2104
    }

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

2108
        let mut bindings_list = HashMap::new();
2109
        for pattern in &arm.pats {
J
Jonas Schievink 已提交
2110
            self.resolve_pattern(&pattern, RefutableMode, &mut bindings_list);
2111 2112
        }

2113 2114 2115 2116
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2117
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2118
        self.visit_expr(&arm.body);
2119

G
Garming Sam 已提交
2120 2121 2122
        if !self.resolved {
            self.value_ribs.pop();
        }
2123 2124
    }

E
Eduard Burtescu 已提交
2125
    fn resolve_block(&mut self, block: &Block) {
2126
        debug!("(resolving block) entering block");
2127
        // Move down in the graph, if there's an anonymous module rooted here.
2128
        let orig_module = self.current_module;
2129
        let anonymous_module = self.module_map.get(&block.id).cloned(); // clones a reference
2130 2131 2132

        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
2133 2134
            self.value_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
2135 2136 2137
            self.current_module = anonymous_module;
        } else {
            self.value_ribs.push(Rib::new(NormalRibKind));
2138 2139 2140
        }

        // Descend into the block.
2141
        intravisit::walk_block(self, block);
2142 2143

        // Move back up.
G
Garming Sam 已提交
2144
        if !self.resolved {
2145
            self.current_module = orig_module;
G
Garming Sam 已提交
2146
            self.value_ribs.pop();
2147 2148 2149
            if let Some(_) = anonymous_module {
                self.type_ribs.pop();
            }
G
Garming Sam 已提交
2150
        }
2151
        debug!("(resolving block) leaving block");
2152 2153
    }

F
Felix S. Klock II 已提交
2154
    fn resolve_type(&mut self, ty: &Ty) {
2155
        match ty.node {
2156
            TyPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2157 2158 2159
                let resolution = match self.resolve_possibly_assoc_item(ty.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
J
Jeffrey Seyfried 已提交
2160
                                                                        TypeNS) {
C
corentih 已提交
2161 2162 2163
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        // Resolve embedded types.
2164
                        intravisit::walk_ty(self, ty);
C
corentih 已提交
2165 2166 2167 2168
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2169 2170

                // This is a path in the type namespace. Walk through scopes
2171
                // looking for it.
2172 2173 2174 2175 2176 2177 2178
                if let Some(def) = resolution {
                    // Write the result into the def map.
                    debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
                           path_names_to_string(path, 0), ty.id, def);
                    self.record_def(ty.id, def);
                } else {
                    self.record_def(ty.id, err_path_resolution());
2179

2180 2181 2182 2183
                    // Keep reporting some errors even if they're ignored above.
                    if let Err(true) = self.resolve_path(ty.id, path, 0, TypeNS) {
                        // `resolve_path` already reported the error
                    } else {
2184 2185 2186 2187
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2188
                        };
2189

C
corentih 已提交
2190 2191 2192
                        let is_invalid_self_type_name = path.segments.len() > 0 &&
                                                        maybe_qself.is_none() &&
                                                        path.segments[0].identifier.name ==
2193
                                                        keywords::SelfType.name();
G
Guillaume Gomez 已提交
2194
                        if is_invalid_self_type_name {
2195 2196
                            resolve_error(self,
                                          ty.span,
2197
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2198
                        } else {
2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
                            let segment = path.segments.last();
                            let segment = segment.expect("missing name in path");
                            let type_name = segment.identifier.name;

                            let candidates =
                                self.lookup_candidates(
                                    type_name,
                                    TypeNS,
                                    |def| match def {
                                        Def::Trait(_) |
                                        Def::Enum(_) |
                                        Def::Struct(_) |
                                        Def::TyAlias(_) => true,
                                        _               => false,
                                    },
                                );

                            // create error object
                            let name = &path_names_to_string(path, 0);
                            let error =
                                ResolutionError::UseOfUndeclared(
                                    kind,
                                    name,
                                    candidates,
                                );

                            resolve_error(self, ty.span, error);
G
Guillaume Gomez 已提交
2226
                        }
2227 2228
                    }
                }
2229
            }
2230
            _ => {}
2231
        }
2232
        // Resolve embedded types.
2233
        intravisit::walk_ty(self, ty);
2234 2235
    }

F
Felix S. Klock II 已提交
2236
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2237
                       pattern: &Pat,
2238 2239 2240
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2241
                       bindings_list: &mut HashMap<Name, NodeId>) {
2242
        let pat_id = pattern.id;
2243
        pattern.walk(|pattern| {
2244
            match pattern.node {
2245 2246
                PatKind::Ident(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatKind::Ident with no type parameters
2247 2248 2249 2250
                    // 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
2251 2252 2253 2254
                    // 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();
2255

2256
                    let ident = path1.node;
2257
                    let renamed = ident.name;
2258

2259
                    match self.resolve_bare_identifier_pattern(ident, pattern.span) {
J
Jeffrey Seyfried 已提交
2260
                        FoundStructOrEnumVariant(def) if const_ok => {
C
corentih 已提交
2261
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2262
                                   renamed);
2263

C
corentih 已提交
2264 2265 2266 2267 2268 2269 2270 2271
                            self.enforce_default_binding_mode(pattern,
                                                              binding_mode,
                                                              "an enum variant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2272
                        }
A
Alex Crichton 已提交
2273
                        FoundStructOrEnumVariant(..) => {
2274
                            resolve_error(
2275
                                self,
2276
                                pattern.span,
2277
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2278 2279
                                    renamed)
                            );
2280
                            self.record_def(pattern.id, err_path_resolution());
2281
                        }
J
Jeffrey Seyfried 已提交
2282
                        FoundConst(def, _) if const_ok => {
C
corentih 已提交
2283 2284 2285 2286 2287 2288 2289 2290
                            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,
                                                depth: 0,
                                            });
2291
                        }
J
Jeffrey Seyfried 已提交
2292
                        FoundConst(def, name) => {
2293
                            resolve_error(
2294 2295
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2296 2297
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2298
                            );
2299
                            self.record_def(pattern.id, err_path_resolution());
2300
                        }
2301
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2302
                            debug!("(resolving pattern) binding `{}`", renamed);
2303

2304
                            let def_id = self.ast_map.local_def_id(pattern.id);
2305
                            let def = Def::Local(def_id, pattern.id);
2306 2307 2308 2309 2310

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

C
corentih 已提交
2311 2312 2313 2314 2315
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2316 2317 2318 2319 2320 2321

                            // 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.)
2322 2323
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2324
                                let last_rib = this.value_ribs.last_mut().unwrap();
2325
                                last_rib.bindings.insert(renamed, def);
2326
                                bindings_list.insert(renamed, pat_id);
2327
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2328
                               bindings_list.contains_key(&renamed) {
2329 2330
                                // Forbid duplicate bindings in the same
                                // parameter list.
2331
                                resolve_error(
2332 2333
                                    self,
                                    pattern.span,
2334
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2335
                                        &ident.name.as_str())
2336
                                );
C
corentih 已提交
2337
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2338 2339
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2340
                                resolve_error(
2341 2342
                                    self,
                                    pattern.span,
2343
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2344
                                        &ident.name.as_str())
2345
                                );
2346
                            }
2347 2348
                            // Else, not bound in the same pattern: do
                            // nothing.
2349 2350 2351 2352
                        }
                    }
                }

2353
                PatKind::TupleStruct(ref path, _) | PatKind::Path(ref path) => {
2354
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2355 2356 2357
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            None,
                                                                            path,
J
Jeffrey Seyfried 已提交
2358
                                                                            ValueNS) {
C
corentih 已提交
2359
                        // The below shouldn't happen because all
2360
                        // qualified paths should be in PatKind::QPath.
C
corentih 已提交
2361
                        TypecheckRequired =>
2362 2363 2364 2365 2366
                            span_bug!(path.span,
                                      "resolve_possibly_assoc_item claimed that a path \
                                       in PatKind::Path or PatKind::TupleStruct \
                                       requires typecheck to resolve, but qualified \
                                       paths should be PatKind::QPath"),
C
corentih 已提交
2367 2368
                        ResolveAttempt(resolution) => resolution,
                    };
2369
                    if let Some(path_res) = resolution {
2370
                        match path_res.base_def {
2371
                            Def::Struct(..) if path_res.depth == 0 => {
2372 2373
                                self.record_def(pattern.id, path_res);
                            }
2374
                            Def::Variant(..) | Def::Const(..) => {
2375 2376
                                self.record_def(pattern.id, path_res);
                            }
2377
                            Def::Static(..) => {
2378 2379
                                resolve_error(&self,
                                              path.span,
2380
                                              ResolutionError::StaticVariableReference);
2381
                                self.record_def(pattern.id, err_path_resolution());
2382
                            }
2383 2384 2385 2386
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2387
                                // be a `T::CONST` that typeck will resolve.
2388
                                if path_res.depth == 0 {
2389
                                    resolve_error(
2390
                                        self,
2391
                                        path.span,
2392
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2393 2394 2395 2396 2397 2398
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2399
                                    );
2400
                                    self.record_def(pattern.id, err_path_resolution());
2401
                                } else {
C
corentih 已提交
2402 2403 2404 2405 2406
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2407 2408
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2409 2410 2411 2412
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
2413
                    } else if let Err(false) = self.resolve_path(pat_id, &path, 0, ValueNS) {
2414
                        resolve_error(
2415 2416
                            self,
                            path.span,
2417
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2418
                                &path.segments.last().unwrap().identifier.name.as_str())
2419
                        );
2420
                        self.record_def(pattern.id, err_path_resolution());
2421
                    }
2422
                    intravisit::walk_path(self, path);
2423 2424
                }

2425
                PatKind::QPath(ref qself, ref path) => {
2426
                    // Associated constants only.
C
corentih 已提交
2427 2428 2429
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            Some(qself),
                                                                            path,
J
Jeffrey Seyfried 已提交
2430
                                                                            ValueNS) {
C
corentih 已提交
2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441
                        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);
2442
                            intravisit::walk_pat(self, pattern);
C
corentih 已提交
2443 2444 2445 2446
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2447 2448 2449 2450
                    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.
2451
                            Def::AssociatedConst(..) => {
2452 2453
                                self.record_def(pattern.id, path_res);
                            }
2454
                            _ => {
2455
                                resolve_error(
2456 2457
                                    self,
                                    path.span,
2458
                                    ResolutionError::NotAnAssociatedConst(
2459
                                        &path.segments.last().unwrap().identifier.name.as_str()
2460 2461
                                    )
                                );
2462
                                self.record_def(pattern.id, err_path_resolution());
2463
                            }
2464
                        }
2465
                    } else {
C
corentih 已提交
2466 2467 2468 2469 2470 2471 2472 2473
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2474
                        self.record_def(pattern.id, err_path_resolution());
2475
                    }
2476
                    intravisit::walk_pat(self, pattern);
2477 2478
                }

2479
                PatKind::Struct(ref path, _, _) => {
J
Jeffrey Seyfried 已提交
2480
                    match self.resolve_path(pat_id, path, 0, TypeNS) {
2481
                        Ok(definition) => {
2482 2483
                            self.record_def(pattern.id, definition);
                        }
2484 2485
                        Err(true) => self.record_def(pattern.id, err_path_resolution()),
                        Err(false) => {
2486 2487 2488
                            resolve_error(
                                self,
                                path.span,
2489
                                ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
2490
                                    &path_names_to_string(path, 0))
2491
                            );
2492
                            self.record_def(pattern.id, err_path_resolution());
2493 2494
                        }
                    }
2495
                    intravisit::walk_path(self, path);
2496 2497
                }

2498
                PatKind::Lit(_) | PatKind::Range(..) => {
2499
                    intravisit::walk_pat(self, pattern);
2500 2501
                }

2502
                _ => {
2503 2504 2505
                    // Nothing to do.
                }
            }
2506
            true
2507
        });
2508 2509
    }

2510
    fn resolve_bare_identifier_pattern(&mut self, ident: hir::Ident, span: Span)
E
Eduard Burtescu 已提交
2511
                                       -> BareIdentifierPatternResolution {
2512 2513 2514 2515
        match self.resolve_ident_in_lexical_scope(ident, ValueNS, true)
                  .map(LexicalScopeBinding::def) {
            Some(def @ Def::Variant(..)) | Some(def @ Def::Struct(..)) => {
                FoundStructOrEnumVariant(def)
2516
            }
2517 2518
            Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
                FoundConst(def, ident.unhygienic_name)
2519
            }
2520 2521 2522 2523 2524
            Some(Def::Static(..)) => {
                resolve_error(self, span, ResolutionError::StaticVariableReference);
                BareIdentifierPatternUnresolved
            }
            _ => BareIdentifierPatternUnresolved,
2525 2526 2527
        }
    }

2528 2529 2530
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2531
                                   maybe_qself: Option<&hir::QSelf>,
2532
                                   path: &Path,
J
Jeffrey Seyfried 已提交
2533
                                   namespace: Namespace)
C
corentih 已提交
2534
                                   -> AssocItemResolveResult {
2535 2536
        let max_assoc_types;

2537
        match maybe_qself {
2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548
            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();
            }
2549 2550 2551
        }

        let mut resolution = self.with_no_errors(|this| {
2552
            this.resolve_path(id, path, 0, namespace).ok()
2553 2554 2555 2556 2557 2558
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
2559
                resolution = this.resolve_path(id, path, depth, TypeNS).ok();
2560 2561
            });
        }
2562
        if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
2563 2564 2565 2566 2567 2568
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

2569
    /// Skips `path_depth` trailing segments, which is also reflected in the
2570
    /// returned value. See `hir::def::PathResolution` for more info.
J
Jeffrey Seyfried 已提交
2571
    fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace)
2572
                    -> Result<PathResolution, bool /* true if an error was reported */ > {
2573
        let span = path.span;
C
corentih 已提交
2574
        let segments = &path.segments[..path.segments.len() - path_depth];
2575

J
Jeffrey Seyfried 已提交
2576
        let mk_res = |def| PathResolution::new(def, path_depth);
2577

2578
        if path.global {
2579 2580
            let binding = self.resolve_crate_relative_path(span, segments, namespace);
            return binding.map(|binding| mk_res(binding.def().unwrap()));
2581 2582
        }

2583
        // Try to find a path to an item in a module.
2584
        let last_ident = segments.last().unwrap().identifier;
V
Cleanup  
Vadim Petrochenkov 已提交
2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596
        // Resolve a single identifier with fallback to primitive types
        let resolve_identifier_with_fallback = |this: &mut Self, record_used| {
            let def = this.resolve_identifier(last_ident, namespace, record_used);
            match def {
                None | Some(LocalDef{def: Def::Mod(..), ..}) if namespace == TypeNS =>
                    this.primitive_type_table
                        .primitive_types
                        .get(&last_ident.unhygienic_name)
                        .map_or(def, |prim_ty| Some(LocalDef::from_def(Def::PrimTy(*prim_ty)))),
                _ => def
            }
        };
2597

2598 2599 2600 2601 2602 2603 2604
        if segments.len() == 1 {
            // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
            // don't report an error right away, but try to fallback to a primitive type.
            // So, we are still able to successfully resolve something like
            //
            // use std::u8; // bring module u8 in scope
            // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
V
Cleanup  
Vadim Petrochenkov 已提交
2605 2606
            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
            //                     // not to non-existent std::u8::max_value
2607 2608 2609 2610
            // }
            //
            // Such behavior is required for backward compatibility.
            // The same fallback is used when `a` resolves to nothing.
2611 2612
            let def = resolve_identifier_with_fallback(self, true).ok_or(false);
            return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res);
N
Nick Cameron 已提交
2613
        }
2614

V
Cleanup  
Vadim Petrochenkov 已提交
2615
        let unqualified_def = resolve_identifier_with_fallback(self, false);
2616 2617 2618
        let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
        match (qualified_binding, unqualified_def) {
            (Ok(binding), Some(ref ud)) if binding.def().unwrap() == ud.def => {
N
Nick Cameron 已提交
2619 2620
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
2621 2622
                              id,
                              span,
N
Nick Cameron 已提交
2623 2624 2625
                              "unnecessary qualification".to_string());
            }
            _ => {}
2626
        }
N
Nick Cameron 已提交
2627

2628
        qualified_binding.map(|binding| mk_res(binding.def().unwrap()))
2629 2630
    }

2631
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2632
    fn resolve_identifier(&mut self,
2633
                          identifier: hir::Ident,
2634
                          namespace: Namespace,
2635
                          record_used: bool)
2636
                          -> Option<LocalDef> {
2637
        if identifier.unhygienic_name == keywords::Invalid.name() {
2638
            return Some(LocalDef::from_def(Def::Err));
2639 2640
        }

2641 2642
        self.resolve_ident_in_lexical_scope(identifier, namespace, record_used)
            .map(LexicalScopeBinding::local_def)
2643 2644 2645
    }

    // Resolve a local definition, potentially adjusting for closures.
2646
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
2647
        let ribs = match local_def.ribs {
C
corentih 已提交
2648 2649 2650
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
2651 2652 2653
        };
        let mut def = local_def.def;
        match def {
2654
            Def::Upvar(..) => {
2655
                span_bug!(span, "unexpected {:?} in bindings", def)
2656
            }
2657
            Def::Local(_, node_id) => {
2658 2659
                for rib in ribs {
                    match rib.kind {
2660
                        NormalRibKind | ModuleRibKind(..) => {
2661 2662 2663 2664 2665 2666
                            // 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 已提交
2667 2668 2669
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2670
                            if let Some(&index) = seen.get(&node_id) {
2671
                                def = Def::Upvar(node_def_id, node_id, index, function_id);
2672 2673
                                continue;
                            }
C
corentih 已提交
2674 2675 2676
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2677
                            let depth = vec.len();
C
corentih 已提交
2678 2679 2680 2681
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2682

2683
                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
2684 2685 2686 2687 2688 2689
                            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 已提交
2690 2691 2692
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2693 2694 2695 2696
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2697 2698 2699
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2700 2701 2702 2703 2704
                            return None;
                        }
                    }
                }
            }
2705
            Def::TyParam(..) | Def::SelfTy(..) => {
2706 2707
                for rib in ribs {
                    match rib.kind {
2708
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) |
2709
                        ModuleRibKind(..) => {
2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731
                            // 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);
2732 2733
    }

2734
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
2735
    fn resolve_module_relative_path(&mut self,
2736
                                    span: Span,
2737
                                    segments: &[hir::PathSegment],
2738
                                    namespace: Namespace)
2739 2740
                                    -> Result<&'a NameBinding<'a>,
                                              bool /* true if an error was reported */> {
C
corentih 已提交
2741 2742 2743 2744 2745 2746
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2747

2748
        let containing_module;
2749
        match self.resolve_module_path(&module_path, UseLexicalScope, span) {
2750 2751 2752 2753
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
2754
                        let msg = format!("Use of undeclared type or module `{}`",
2755
                                          names_to_string(&module_path));
2756
                        (span, msg)
2757 2758
                    }
                };
2759

J
Jonas Schievink 已提交
2760
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2761
                return Err(true);
2762
            }
2763
            Indeterminate => return Err(false),
J
Jeffrey Seyfried 已提交
2764
            Success(resulting_module) => {
2765 2766 2767 2768
                containing_module = resulting_module;
            }
        }

2769
        let name = segments.last().unwrap().identifier.name;
2770
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2771
        result.success().map(|binding| {
2772
            self.check_privacy(name, binding, span);
2773
            binding
2774
        }).ok_or(false)
2775 2776
    }

2777 2778
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2779
    fn resolve_crate_relative_path(&mut self,
2780
                                   span: Span,
2781
                                   segments: &[hir::PathSegment],
2782
                                   namespace: Namespace)
2783 2784
                                   -> Result<&'a NameBinding<'a>,
                                             bool /* true if an error was reported */> {
C
corentih 已提交
2785 2786 2787 2788 2789 2790
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2791

2792
        let root_module = self.graph_root;
2793

2794
        let containing_module;
2795
        match self.resolve_module_path_from_root(root_module,
2796
                                                 &module_path,
2797
                                                 0,
J
Jeffrey Seyfried 已提交
2798
                                                 span) {
2799 2800 2801 2802 2803
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
2804
                                          names_to_string(&module_path));
2805
                        (span, msg)
2806 2807 2808
                    }
                };

J
Jonas Schievink 已提交
2809
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2810
                return Err(true);
2811 2812
            }

2813
            Indeterminate => return Err(false),
2814

J
Jeffrey Seyfried 已提交
2815
            Success(resulting_module) => {
2816 2817 2818 2819
                containing_module = resulting_module;
            }
        }

2820
        let name = segments.last().unwrap().identifier.name;
J
Jeffrey Seyfried 已提交
2821
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2822
        result.success().map(|binding| {
2823
            self.check_privacy(name, binding, span);
2824
            binding
2825
        }).ok_or(false)
2826 2827
    }

C
corentih 已提交
2828 2829
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2830
    {
2831
        self.emit_errors = false;
A
Alex Crichton 已提交
2832
        let rs = f(self);
2833 2834 2835 2836
        self.emit_errors = true;
        rs
    }

2837
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
2838
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
2839
            match t.node {
2840 2841
                TyPath(None, _) => Some(t.id),
                TyRptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
2842 2843 2844 2845 2846 2847 2848
                // 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,
            }
        }

2849
        if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
2850
            // Look for a field with the same name in the current self_type.
2851
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
2852 2853 2854 2855
                Some(Def::Enum(did)) |
                Some(Def::TyAlias(did)) |
                Some(Def::Struct(did)) |
                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
2856 2857 2858 2859 2860
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
2861
                    }
2862 2863 2864
                },
                _ => {} // Self type didn't resolve properly
            }
2865 2866 2867
        }

        // Look for a method in the current trait.
2868
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
2869 2870
            if let Some(&is_static_method) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method {
2871
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
2872 2873
                } else {
                    return TraitItem;
2874 2875 2876 2877 2878 2879 2880
                }
            }
        }

        NoSuggestion
    }

2881
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
2882
        if let Some(macro_name) = self.session.available_macros
2883
                                  .borrow().iter().find(|n| n.as_str() == name) {
2884 2885 2886
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

2887 2888 2889 2890
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
2891

2892
        if let Some(found) = find_best_match_for_name(names, name, None) {
J
Jonas Schievink 已提交
2893
            if name != found {
2894
                return SuggestionType::Function(found);
2895
            }
2896
        } SuggestionType::NotFound
2897 2898
    }

E
Eduard Burtescu 已提交
2899
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
2900 2901
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
2902 2903 2904

        self.record_candidate_traits_for_expr_if_necessary(expr);

2905
        // Next, resolve the node.
2906
        match expr.node {
2907
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2908 2909 2910
                let resolution = match self.resolve_possibly_assoc_item(expr.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
J
Jeffrey Seyfried 已提交
2911
                                                                        ValueNS) {
C
corentih 已提交
2912 2913 2914 2915 2916
                    // `<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);
2917
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
2918 2919 2920 2921
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2922

2923 2924
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
2925
                if let Some(path_res) = resolution {
2926
                    // Check if struct variant
2927
                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
2928 2929 2930 2931 2932 2933
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
2934
                        let path_name = path_names_to_string(path, 0);
2935

N
Nick Cameron 已提交
2936 2937
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
2938
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
2939

C
corentih 已提交
2940
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
2941 2942
                                          path_name);
                        if self.emit_errors {
N
Nick Cameron 已提交
2943
                            err.fileline_help(expr.span, &msg);
2944
                        } else {
N
Nick Cameron 已提交
2945
                            err.span_help(expr.span, &msg);
2946
                        }
N
Nick Cameron 已提交
2947
                        err.emit();
2948
                        self.record_def(expr.id, err_path_resolution());
2949
                    } else {
2950
                        // Write the result into the def map.
2951
                        debug!("(resolving expr) resolved `{}`",
2952
                               path_names_to_string(path, 0));
2953

2954 2955
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
2956
                        if path_res.depth != 0 {
2957
                            let method_name = path.segments.last().unwrap().identifier.name;
2958
                            let traits = self.get_traits_containing_item(method_name);
2959 2960 2961
                            self.trait_map.insert(expr.id, traits);
                        }

2962
                        self.record_def(expr.id, path_res);
2963
                    }
2964 2965 2966 2967 2968
                } 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.)
2969
                    let path_name = path_names_to_string(path, 0);
2970
                    let type_res = self.with_no_errors(|this| {
J
Jeffrey Seyfried 已提交
2971
                        this.resolve_path(expr.id, path, 0, TypeNS)
2972
                    });
2973 2974

                    self.record_def(expr.id, err_path_resolution());
2975

2976
                    if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
J
Jeffrey Seyfried 已提交
2977 2978
                        let error_variant =
                            ResolutionError::StructVariantUsedAsFunction(&path_name);
2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994
                        let mut err = resolve_struct_error(self, expr.span, error_variant);

                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                          path_name);

                        if self.emit_errors {
                            err.fileline_help(expr.span, &msg);
                        } else {
                            err.span_help(expr.span, &msg);
                        }
                        err.emit();
                    } else {
                        // Keep reporting some errors even if they're ignored above.
                        if let Err(true) = self.resolve_path(expr.id, path, 0, ValueNS) {
                            // `resolve_path` already reported the error
                        } else {
2995 2996 2997 2998 2999 3000 3001 3002 3003
                            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
                            });
3004

3005
                            if method_scope &&
3006
                                    &path_name[..] == keywords::SelfValue.name().as_str() {
C
corentih 已提交
3007 3008 3009
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3010 3011 3012 3013 3014 3015
                            } 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
3016
                                        match self.find_best_match(&path_name) {
3017 3018 3019 3020 3021 3022
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
3023 3024
                                    }
                                    Field => format!("`self.{}`", path_name),
C
corentih 已提交
3025
                                    TraitItem => format!("to call `self.{}`", path_name),
3026
                                    TraitMethod(path_str) =>
C
corentih 已提交
3027
                                        format!("to call `{}::{}`", path_str, path_name),
3028 3029
                                };

3030
                                let mut context =  UnresolvedNameContext::Other;
3031
                                if !msg.is_empty() {
3032 3033 3034 3035 3036 3037 3038 3039
                                    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<_>>();

3040
                                    match self.resolve_module_path(&name_path[..],
J
Jeffrey Seyfried 已提交
3041 3042
                                                                   UseLexicalScope,
                                                                   expr.span) {
3043 3044 3045 3046 3047
                                        Success(_) => {
                                            context = UnresolvedNameContext::PathIsMod(expr.id);
                                        },
                                        _ => {},
                                    };
3048
                                }
3049

3050 3051
                                resolve_error(self,
                                              expr.span,
3052
                                              ResolutionError::UnresolvedName(
J
Jonas Schievink 已提交
3053
                                                  &path_name, &msg, context));
3054
                            }
V
Vincent Belliard 已提交
3055
                        }
3056 3057 3058
                    }
                }

3059
                intravisit::walk_expr(self, expr);
3060 3061
            }

3062
            ExprStruct(ref path, _, _) => {
3063 3064 3065
                // 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.
J
Jeffrey Seyfried 已提交
3066
                match self.resolve_path(expr.id, path, 0, TypeNS) {
3067 3068 3069
                    Ok(definition) => self.record_def(expr.id, definition),
                    Err(true) => self.record_def(expr.id, err_path_resolution()),
                    Err(false) => {
3070
                        debug!("(resolving expression) didn't find struct def",);
3071

3072 3073
                        resolve_error(self,
                                      path.span,
3074
                                      ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
3075
                                                                &path_names_to_string(path, 0))
3076
                                     );
3077
                        self.record_def(expr.id, err_path_resolution());
3078 3079 3080
                    }
                }

3081
                intravisit::walk_expr(self, expr);
3082 3083
            }

P
Pythoner6 已提交
3084
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3085
                self.with_label_rib(|this| {
3086
                    let def = Def::Label(expr.id);
3087

3088
                    {
3089
                        let rib = this.label_ribs.last_mut().unwrap();
3090
                        rib.bindings.insert(label.name, def);
3091
                    }
3092

3093
                    intravisit::walk_expr(this, expr);
3094
                })
3095 3096
            }

3097
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3098
                match self.search_label(label.node.name) {
3099
                    None => {
3100
                        self.record_def(expr.id, err_path_resolution());
3101
                        resolve_error(self,
3102 3103
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3104
                    }
3105
                    Some(def @ Def::Label(_)) => {
3106
                        // Since this def is a label, it is never read.
C
corentih 已提交
3107 3108 3109 3110 3111
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            depth: 0,
                                        })
3112 3113
                    }
                    Some(_) => {
3114
                        span_bug!(expr.span, "label wasn't mapped to a label def!")
3115 3116 3117 3118
                    }
                }
            }

B
Brian Anderson 已提交
3119
            _ => {
3120
                intravisit::walk_expr(self, expr);
3121 3122 3123 3124
            }
        }
    }

E
Eduard Burtescu 已提交
3125
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3126
        match expr.node {
3127
            ExprField(_, name) => {
3128 3129 3130 3131
                // 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.
3132
                let traits = self.get_traits_containing_item(name.node);
3133
                self.trait_map.insert(expr.id, traits);
3134
            }
3135
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3136
                debug!("(recording candidate traits for expr) recording traits for {}",
3137
                       expr.id);
3138
                let traits = self.get_traits_containing_item(name.node);
3139
                self.trait_map.insert(expr.id, traits);
3140
            }
3141
            _ => {
3142 3143 3144 3145 3146
                // Nothing to do.
            }
        }
    }

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

C
corentih 已提交
3150
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3151
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3152 3153
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3154 3155
            found_traits.push(trait_def_id);
        }
3156

3157
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3158 3159 3160 3161
        // Look for the current trait.
        if let Some((trait_def_id, _)) = self.current_trait_ref {
            if self.trait_item_map.contains_key(&(name, trait_def_id)) {
                add_trait_info(&mut found_traits, trait_def_id, name);
E
Eduard Burtescu 已提交
3162
            }
J
Jeffrey Seyfried 已提交
3163
        }
3164

J
Jeffrey Seyfried 已提交
3165 3166
        let mut search_module = self.current_module;
        loop {
E
Eduard Burtescu 已提交
3167
            // Look for trait children.
J
Jeffrey Seyfried 已提交
3168 3169 3170 3171
            let mut search_in_module = |module: Module<'a>| {
                let mut traits = module.traits.borrow_mut();
                if traits.is_none() {
                    let mut collected_traits = Vec::new();
3172
                    module.for_each_child(|name, ns, binding| {
J
Jeffrey Seyfried 已提交
3173 3174
                        if ns != TypeNS { return }
                        if let Some(Def::Trait(_)) = binding.def() {
3175
                            collected_traits.push((name, binding));
J
Jeffrey Seyfried 已提交
3176 3177 3178
                        }
                    });
                    *traits = Some(collected_traits.into_boxed_slice());
3179
                }
J
Jeffrey Seyfried 已提交
3180

3181
                for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
J
Jeffrey Seyfried 已提交
3182 3183 3184 3185 3186 3187 3188
                    let trait_def_id = binding.def().unwrap().def_id();
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
                        add_trait_info(&mut found_traits, trait_def_id, name);
                        self.record_use(trait_name, TypeNS, binding);
                    }
                }
            };
3189
            search_in_module(search_module);
3190

3191
            match search_module.parent_link {
3192 3193 3194 3195
                NoParentLink | ModuleParentLink(..) => {
                    search_module.prelude.borrow().map(search_in_module);
                    break;
                }
E
Eduard Burtescu 已提交
3196
                BlockParentLink(parent_module, _) => {
3197
                    search_module = parent_module;
3198
                }
E
Eduard Burtescu 已提交
3199
            }
3200 3201
        }

E
Eduard Burtescu 已提交
3202
        found_traits
3203 3204
    }

3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224
    /// When name resolution fails, this method can be used to look up candidate
    /// entities with the expected name. It allows filtering them using the
    /// supplied predicate (which should be used to only accept the types of
    /// definitions expected e.g. traits). The lookup spans across all crates.
    ///
    /// NOTE: The method does not look into imports, but this is not a problem,
    /// since we report the definitions (thus, the de-aliased imports).
    fn lookup_candidates<FilterFn>(&mut self,
                                   lookup_name: Name,
                                   namespace: Namespace,
                                   filter_fn: FilterFn) -> SuggestedCandidates
        where FilterFn: Fn(Def) -> bool {

        let mut lookup_results = Vec::new();
        let mut worklist = Vec::new();
        worklist.push((self.graph_root, Vec::new(), false));

        while let Some((in_module,
                        path_segments,
                        in_module_is_extern)) = worklist.pop() {
3225
            self.populate_module_if_necessary(in_module);
3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241

            in_module.for_each_child(|name, ns, name_binding| {

                // avoid imports entirely
                if name_binding.is_import() { return; }

                // collect results based on the filter function
                if let Some(def) = name_binding.def() {
                    if name == lookup_name && ns == namespace && filter_fn(def) {
                        // create the path
                        let ident = hir::Ident::from_name(name);
                        let params = PathParameters::none();
                        let segment = PathSegment {
                            identifier: ident,
                            parameters: params,
                        };
3242
                        let span = name_binding.span;
3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257
                        let mut segms = path_segments.clone();
                        segms.push(segment);
                        let segms = HirVec::from_vec(segms);
                        let path = Path {
                            span: span,
                            global: true,
                            segments: segms,
                        };
                        // the entity is accessible in the following cases:
                        // 1. if it's defined in the same crate, it's always
                        // accessible (since private entities can be made public)
                        // 2. if it's defined in another crate, it's accessible
                        // only if both the module is public and the entity is
                        // declared as public (due to pruning, we don't explore
                        // outside crate private modules => no need to check this)
3258
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279
                            lookup_results.push(path);
                        }
                    }
                }

                // collect submodules to explore
                if let Some(module) = name_binding.module() {
                    // form the path
                    let path_segments = match module.parent_link {
                        NoParentLink => path_segments.clone(),
                        ModuleParentLink(_, name) => {
                            let mut paths = path_segments.clone();
                            let ident = hir::Ident::from_name(name);
                            let params = PathParameters::none();
                            let segm = PathSegment {
                                identifier: ident,
                                parameters: params,
                            };
                            paths.push(segm);
                            paths
                        }
3280
                        _ => bug!(),
3281 3282
                    };

3283
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3284
                        // add the module to the lookup
3285
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297
                        worklist.push((module, path_segments, is_extern));
                    }
                }
            })
        }

        SuggestedCandidates {
            name: lookup_name.as_str().to_string(),
            candidates: lookup_results,
        }
    }

3298 3299 3300 3301
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
        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);
3302 3303 3304 3305
            span_bug!(span,
                      "path resolved multiple times ({:?} before, {:?} now)",
                      prev_res,
                      resolution);
3306
        }
3307 3308
    }

F
Felix S. Klock II 已提交
3309
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3310 3311 3312
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3313
        match pat_binding_mode {
3314
            BindByValue(_) => {}
A
Alex Crichton 已提交
3315
            BindByRef(..) => {
3316 3317
                resolve_error(self,
                              pat.span,
3318
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3319 3320 3321
            }
        }
    }
3322

3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359
    fn resolve_visibility(&mut self, vis: &hir::Visibility) -> ty::Visibility {
        let (path, id) = match *vis {
            hir::Public => return ty::Visibility::Public,
            hir::Visibility::Crate => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
            hir::Visibility::Restricted { ref path, id } => (path, id),
            hir::Inherited => {
                let current_module =
                    self.get_nearest_normal_module_parent_or_self(self.current_module);
                let id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap();
                return ty::Visibility::Restricted(id);
            }
        };

        let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect();
        let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, path.span) {
            Success(module) => {
                let def = module.def.unwrap();
                let path_resolution = PathResolution { base_def: def, depth: 0 };
                self.def_map.borrow_mut().insert(id, path_resolution);
                ty::Visibility::Restricted(self.ast_map.as_local_node_id(def.def_id()).unwrap())
            }
            Failed(Some((span, msg))) => {
                self.session.span_err(span, &format!("failed to resolve module path. {}", msg));
                ty::Visibility::Public
            }
            _ => {
                self.session.span_err(path.span, "unresolved module path");
                ty::Visibility::Public
            }
        };
        if !self.is_accessible(vis) {
            let msg = format!("visibilities can only be restricted to ancestor modules");
            self.session.span_err(path.span, &msg);
        }
        vis
    }

3360 3361 3362
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
        let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
        let node_id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap();
3363
        vis.is_accessible_from(node_id, self)
3364 3365
    }

3366 3367
    fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
        if !self.is_accessible(binding.vis) {
3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387
            self.privacy_errors.push(PrivacyError(span, name, binding));
        }
    }

    fn report_privacy_errors(&self) {
        if self.privacy_errors.len() == 0 { return }
        let mut reported_spans = HashSet::new();
        for &PrivacyError(span, name, binding) in &self.privacy_errors {
            if !reported_spans.insert(span) { continue }
            if binding.is_extern_crate() {
                // Warn when using an inaccessible extern crate.
                let node_id = binding.module().unwrap().extern_crate_id.unwrap();
                let msg = format!("extern crate `{}` is private", name);
                self.session.add_lint(lint::builtin::INACCESSIBLE_EXTERN_CRATE, node_id, span, msg);
            } else {
                let def = binding.def().unwrap();
                self.session.span_err(span, &format!("{} `{}` is private", def.kind_name(), name));
            }
        }
    }
3388

3389 3390 3391 3392 3393 3394 3395
    fn report_conflict(&self,
                       parent: Module,
                       name: Name,
                       ns: Namespace,
                       binding: &NameBinding,
                       old_binding: &NameBinding) {
        // Error on the second of two conflicting names
3396
        if old_binding.span.lo > binding.span.lo {
3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411
            return self.report_conflict(parent, name, ns, old_binding, binding);
        }

        let container = match parent.def {
            Some(Def::Mod(_)) => "module",
            Some(Def::Trait(_)) => "trait",
            None => "block",
            _ => "enum",
        };

        let (participle, noun) = match old_binding.is_import() || old_binding.is_extern_crate() {
            true => ("imported", "import"),
            false => ("defined", "definition"),
        };

3412
        let span = binding.span;
3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436
        let msg = {
            let kind = match (ns, old_binding.module()) {
                (ValueNS, _) => "a value",
                (TypeNS, Some(module)) if module.extern_crate_id.is_some() => "an extern crate",
                (TypeNS, Some(module)) if module.is_normal() => "a module",
                (TypeNS, Some(module)) if module.is_trait() => "a trait",
                (TypeNS, _) => "a type",
            };
            format!("{} named `{}` has already been {} in this {}",
                    kind, name, participle, container)
        };

        let mut err = match (old_binding.is_extern_crate(), binding.is_extern_crate()) {
            (true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
            (true, _) | (_, true) if binding.is_import() || old_binding.is_import() =>
                struct_span_err!(self.session, span, E0254, "{}", msg),
            (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg),
            _ => match (old_binding.is_import(), binding.is_import()) {
                (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
                (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
                _ => struct_span_err!(self.session, span, E0255, "{}", msg),
            },
        };

3437 3438
        if old_binding.span != codemap::DUMMY_SP {
            err.span_note(old_binding.span, &format!("previous {} of `{}` here", noun, name));
3439 3440 3441 3442
        }
        err.emit();
    }
}
3443 3444 3445 3446 3447 3448 3449 3450 3451 3452

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("::")
        }
3453
        result.push_str(&name.as_str());
C
corentih 已提交
3454
    }
3455 3456 3457 3458
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3459
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3460 3461 3462 3463 3464 3465
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491
/// When an entity with a given name is not available in scope, we search for
/// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way
fn show_candidates(session: &mut DiagnosticBuilder,
                   span: syntax::codemap::Span,
                   candidates: &SuggestedCandidates) {

    let paths = &candidates.candidates;

    if paths.len() > 0 {
        // don't show more than MAX_CANDIDATES results, so
        // we're consistent with the trait suggestions
        const MAX_CANDIDATES: usize = 5;

        // we want consistent results across executions, but candidates are produced
        // by iterating through a hash map, so make sure they are ordered:
        let mut path_strings: Vec<_> = paths.into_iter()
                                            .map(|p| path_names_to_string(&p, 0))
                                            .collect();
        path_strings.sort();

        // behave differently based on how many candidates we have:
        if !paths.is_empty() {
            if paths.len() == 1 {
                session.fileline_help(
                    span,
T
tiehuis 已提交
3492
                    &format!("you can import it into scope: `use {};`.",
3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526
                        &path_strings[0]),
                );
            } else {
                session.fileline_help(span, "you can import several candidates \
                    into scope (`use ...;`):");
                let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1;

                for (idx, path_string) in path_strings.iter().enumerate() {
                    if idx == MAX_CANDIDATES - 1 && count > 1 {
                        session.fileline_help(
                            span,
                            &format!("  and {} other candidates", count).to_string(),
                        );
                        break;
                    } else {
                        session.fileline_help(
                            span,
                            &format!("  `{}`", path_string).to_string(),
                        );
                    }
                }
            }
        }
    } else {
        // nothing found:
        session.fileline_help(
            span,
            &format!("no candidates by the name of `{}` found in your \
            project; maybe you misspelled the name or forgot to import \
            an external crate?", candidates.name.to_string()),
        );
    };
}

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

3531
    fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
3532 3533 3534 3535
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
3536
                collect_mod(names, module);
3537 3538 3539
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
3540
                names.push(token::intern("<opaque>"));
3541
                collect_mod(names, module);
3542 3543 3544 3545 3546
            }
        }
    }
    collect_mod(&mut names, module);

3547
    if names.is_empty() {
3548 3549 3550 3551 3552
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3553 3554
fn err_path_resolution() -> PathResolution {
    PathResolution {
3555
        base_def: Def::Err,
3556 3557 3558 3559
        depth: 0,
    }
}

3560

3561
pub struct CrateMap {
J
Jonathan S 已提交
3562
    pub def_map: RefCell<DefMap>,
3563
    pub freevars: FreevarMap,
3564
    pub export_map: ExportMap,
3565
    pub trait_map: TraitMap,
C
corentih 已提交
3566
    pub glob_map: Option<GlobMap>,
3567 3568
}

N
Niko Matsakis 已提交
3569
#[derive(PartialEq,Copy, Clone)]
3570 3571
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3572
    No,
3573 3574
}

3575
/// Entry point to crate resolution.
3576
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3577
                               ast_map: &'a hir_map::Map<'tcx>,
3578 3579
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3580 3581 3582 3583 3584 3585 3586 3587 3588
    // Currently, we ignore the name resolution data structures for
    // the purposes of dependency tracking. Instead we will run name
    // resolution and include its output in the hash of each item,
    // much like we do for macro expansion. In other words, the hash
    // reflects not just its contents but the results of name
    // resolution on those contents. Hopefully we'll push this back at
    // some point.
    let _task = ast_map.dep_graph.in_task(DepNode::Resolve);

3589
    let krate = ast_map.krate();
3590 3591
    let arenas = Resolver::arenas();
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
3592 3593 3594 3595

    resolver.resolve_crate(krate);

    check_unused::check_crate(&mut resolver, krate);
3596
    resolver.report_privacy_errors();
3597

3598
    CrateMap {
3599 3600
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3601
        export_map: resolver.export_map,
3602
        trait_map: resolver.trait_map,
3603
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
3604 3605 3606 3607
            Some(resolver.glob_map)
        } else {
            None
        },
3608
    }
3609
}
3610

3611 3612 3613 3614 3615 3616 3617 3618
/// 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.
J
Jeffrey Seyfried 已提交
3619 3620 3621 3622 3623 3624 3625
fn create_resolver<'a, 'tcx>(session: &'a Session,
                             ast_map: &'a hir_map::Map<'tcx>,
                             krate: &'a Crate,
                             make_glob_map: MakeGlobMap,
                             arenas: &'a ResolverArenas<'a>,
                             callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
                             -> Resolver<'a, 'tcx> {
3626
    let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
G
Garming Sam 已提交
3627 3628 3629

    resolver.callback = callback;

J
Jeffrey Seyfried 已提交
3630
    resolver.build_reduced_graph(krate);
G
Garming Sam 已提交
3631 3632 3633 3634 3635 3636

    resolve_imports::resolve_imports(&mut resolver);

    resolver
}

3637
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }