lib.rs 156.7 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)]
A
Alex Crichton 已提交
21
#![feature(rustc_diagnostic_macros)]
22
#![feature(rustc_private)]
A
Alex Crichton 已提交
23
#![feature(staged_api)]
24

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

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

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

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

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

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

94
use resolve_imports::{ImportDirective, NameResolution};
95

96 97 98 99
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

A
Alex Crichton 已提交
100
mod check_unused;
101
mod build_reduced_graph;
102
mod resolve_imports;
103

104 105 106 107 108 109 110 111 112 113 114
// 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;
            }
        }
    )
}

115 116
enum SuggestionType {
    Macro(String),
117
    Function(token::InternedString),
118 119 120
    NotFound,
}

121 122 123 124 125 126
/// Candidates for a name resolution failure
pub struct SuggestedCandidates {
    name: String,
    candidates: Vec<Path>,
}

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

204
/// Context of where `ResolutionError::UnresolvedName` arose.
205 206
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum UnresolvedNameContext {
207 208 209 210
    /// `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.
211
    PathIsMod(ast::NodeId),
212 213 214 215

    /// `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.)
216 217 218
    Other,
}

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

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 已提交
228
                                              -> DiagnosticBuilder<'a> {
229
    if !resolver.emit_errors {
N
Nick Cameron 已提交
230
        return resolver.session.diagnostic().struct_dummy();
231
    }
N
Nick Cameron 已提交
232

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

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

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

N
Niko Matsakis 已提交
548
#[derive(Copy, Clone)]
549
struct BindingInfo {
550
    span: Span,
551
    binding_mode: BindingMode,
552 553 554
}

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

N
Niko Matsakis 已提交
557
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
558
enum PatternBindingMode {
559
    RefutableMode,
560
    LocalIrrefutableMode,
561
    ArgumentIrrefutableMode,
562 563
}

N
Niko Matsakis 已提交
564
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
565
pub enum Namespace {
566
    TypeNS,
C
corentih 已提交
567
    ValueNS,
568 569
}

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

621
        // `intravisit::walk_variant` without the discriminant expression.
C
corentih 已提交
622 623 624 625 626
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
627
    }
628 629
    fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) {
        execute_callback!(hir_map::Node::NodeForeignItem(foreign_item), self);
630 631 632 633
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
C
corentih 已提交
634
            ForeignItemStatic(..) => NoTypeParameters,
635 636
        };
        self.with_type_parameter_rib(type_parameters, |this| {
637
            intravisit::walk_foreign_item(this, foreign_item);
638 639 640
        });
    }
    fn visit_fn(&mut self,
641
                function_kind: FnKind<'v>,
642 643 644 645 646
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
647
            FnKind::ItemFn(_, generics, _, _, _, _) => {
648 649 650
                self.visit_generics(generics);
                ItemRibKind
            }
651
            FnKind::Method(_, sig, _) => {
652 653
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
654 655
                MethodRibKind
            }
V
Vadim Petrochenkov 已提交
656
            FnKind::Closure => ClosureRibKind(node_id),
657 658 659
        };
        self.resolve_function(rib_kind, declaration, block);
    }
660
}
661

662
pub type ErrorMessage = Option<(Span, String)>;
663

664
#[derive(Clone, PartialEq, Eq)]
665
pub enum ResolveResult<T> {
C
corentih 已提交
666 667 668
    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.
669 670
}

671
impl<T> ResolveResult<T> {
672 673 674 675 676
    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 已提交
677
        }
678
    }
679 680 681 682 683 684 685

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

688 689 690 691
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
692
    TraitItem,
693
    StaticMethod(String),
694
    TraitMethod(String),
695 696
}

N
Niko Matsakis 已提交
697
#[derive(Copy, Clone)]
698
enum TypeParameters<'tcx, 'a> {
699
    NoTypeParameters,
C
corentih 已提交
700 701
    HasTypeParameters(// Type parameters.
                      &'a Generics,
702

C
corentih 已提交
703 704 705
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
706

C
corentih 已提交
707
                      // The kind of the rib used for type parameters.
708
                      RibKind<'tcx>),
709 710
}

711
// The rib kind controls the translation of local
712
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
713
#[derive(Copy, Clone, Debug)]
714
enum RibKind<'a> {
715 716
    // No translation needs to be applied.
    NormalRibKind,
717

718 719
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
720
    ClosureRibKind(NodeId /* func id */),
721

722
    // We passed through an impl or trait and are now in one of its
723
    // methods. Allow references to ty params that impl or trait
724 725
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
726
    MethodRibKind,
727

728 729
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
730 731

    // We're in a constant item. Can't refer to dynamic stuff.
C
corentih 已提交
732
    ConstantItemRibKind,
733 734 735

    // We passed through an anonymous module.
    AnonymousModuleRibKind(Module<'a>),
736 737
}

N
Niko Matsakis 已提交
738
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
739
enum UseLexicalScopeFlag {
740
    DontUseLexicalScope,
C
corentih 已提交
741
    UseLexicalScope,
742 743
}

744
enum ModulePrefixResult<'a> {
745
    NoPrefixFound,
746
    PrefixFound(Module<'a>, usize),
747 748
}

749 750 751 752 753 754 755 756 757
#[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 已提交
758
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
759
enum BareIdentifierPatternResolution {
760
    FoundStructOrEnumVariant(Def, LastPrivate),
761
    FoundConst(Def, LastPrivate, Name),
C
corentih 已提交
762
    BareIdentifierPatternUnresolved,
763 764
}

765
/// One local scope.
J
Jorge Aparicio 已提交
766
#[derive(Debug)]
767
struct Rib<'a> {
768
    bindings: HashMap<Name, DefLike>,
769
    kind: RibKind<'a>,
B
Brian Anderson 已提交
770
}
771

772 773
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
774
        Rib {
775
            bindings: HashMap::new(),
C
corentih 已提交
776
            kind: kind,
777
        }
778 779 780
    }
}

781 782 783
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
784
    def: Def,
785 786 787 788 789 790
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
791
            def: def,
792 793 794 795
        }
    }
}

796
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
797
#[derive(Clone,Debug)]
798
enum ParentLink<'a> {
799
    NoParentLink,
800 801
    ModuleParentLink(Module<'a>, Name),
    BlockParentLink(Module<'a>, NodeId),
802 803
}

804
/// One node in the tree of modules.
805 806
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
J
Jeffrey Seyfried 已提交
807
    def: Option<Def>,
808
    is_public: bool,
809
    is_extern_crate: bool,
810

811
    resolutions: RefCell<HashMap<(Name, Namespace), NameResolution<'a>>>,
812
    unresolved_imports: RefCell<Vec<ImportDirective>>,
813

814 815 816
    // The module children of this node, including normal modules and anonymous modules.
    // Anonymous children are pseudo-modules that are implicitly created around items
    // contained within blocks.
817 818 819 820 821 822 823 824 825 826 827
    //
    // 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`.
828
    module_children: RefCell<NodeMap<Module<'a>>>,
829

830 831
    shadowed_traits: RefCell<Vec<&'a NameBinding<'a>>>,

832
    // The number of unresolved globs that this module exports.
833
    glob_count: Cell<usize>,
834

835 836 837 838 839 840
    // The number of unresolved pub imports (both regular and globs) in this module
    pub_count: Cell<usize>,

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

841 842 843
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
844
    populated: Cell<bool>,
845 846
}

847 848 849
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
850

851 852
    fn new(parent_link: ParentLink<'a>, def: Option<Def>, external: bool, is_public: bool) -> Self {
        ModuleS {
853
            parent_link: parent_link,
J
Jeffrey Seyfried 已提交
854
            def: def,
855
            is_public: is_public,
856
            is_extern_crate: false,
857
            resolutions: RefCell::new(HashMap::new()),
858
            unresolved_imports: RefCell::new(Vec::new()),
859
            module_children: RefCell::new(NodeMap()),
860
            shadowed_traits: RefCell::new(Vec::new()),
861
            glob_count: Cell::new(0),
862 863
            pub_count: Cell::new(0),
            pub_glob_count: Cell::new(0),
864
            populated: Cell::new(!external),
865
        }
B
Brian Anderson 已提交
866 867
    }

868 869 870 871 872
    fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: bool)
                    -> ResolveResult<&'a NameBinding<'a>> {
        let glob_count =
            if allow_private_imports { self.glob_count.get() } else { self.pub_glob_count.get() };

873
        self.resolutions.borrow().get(&(name, ns)).cloned().unwrap_or_default().result(glob_count)
874 875 876 877
            .and_then(|binding| {
                let allowed = allow_private_imports || !binding.is_import() || binding.is_public();
                if allowed { Success(binding) } else { Failed(None) }
            })
878 879
    }

880
    // Define the name or return the existing binding if there is a collision.
881
    fn try_define_child(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>)
882
                        -> Result<(), &'a NameBinding<'a>> {
883
        let mut children = self.resolutions.borrow_mut();
884 885 886 887 888 889 890 891 892 893 894 895
        let resolution = children.entry((name, ns)).or_insert_with(Default::default);

        // FIXME #31379: We can use methods from imported traits shadowed by non-import items
        if let Some(old_binding) = resolution.binding {
            if !old_binding.is_import() && binding.is_import() {
                if let Some(Def::Trait(_)) = binding.def() {
                    self.shadowed_traits.borrow_mut().push(binding);
                }
            }
        }

        resolution.try_define(binding)
896 897
    }

898
    fn increment_outstanding_references_for(&self, name: Name, ns: Namespace) {
899
        let mut children = self.resolutions.borrow_mut();
900
        children.entry((name, ns)).or_insert_with(Default::default).outstanding_references += 1;
901 902 903
    }

    fn decrement_outstanding_references_for(&self, name: Name, ns: Namespace) {
904
        match self.resolutions.borrow_mut().get_mut(&(name, ns)).unwrap().outstanding_references {
905 906 907 908 909
            0 => panic!("No more outstanding references!"),
            ref mut outstanding_references => { *outstanding_references -= 1; }
        }
    }

910
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
911
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
912 913 914 915
            name_resolution.binding.map(|binding| f(name, ns, binding));
        }
    }

916
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
917
        self.def.as_ref().map(Def::def_id)
918 919 920
    }

    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
921
        match self.def {
922
            Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
923 924 925 926 927
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
928
        match self.def {
929
            Some(Def::Trait(_)) => true,
930
            _ => false,
931
        }
B
Brian Anderson 已提交
932 933
    }

V
Victor Berger 已提交
934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
    pub fn inc_glob_count(&self) {
        self.glob_count.set(self.glob_count.get() + 1);
    }
    pub fn dec_glob_count(&self) {
        assert!(self.glob_count.get() > 0);
        self.glob_count.set(self.glob_count.get() - 1);
    }
    pub fn inc_pub_count(&self) {
        self.pub_count.set(self.pub_count.get() + 1);
    }
    pub fn dec_pub_count(&self) {
        assert!(self.pub_count.get() > 0);
        self.pub_count.set(self.pub_count.get() - 1);
    }
    pub fn inc_pub_glob_count(&self) {
        self.pub_glob_count.set(self.pub_glob_count.get() + 1);
    }
    pub fn dec_pub_glob_count(&self) {
        assert!(self.pub_glob_count.get() > 0);
        self.pub_glob_count.set(self.pub_glob_count.get() - 1);
    }
}

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

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

985
// Records a possibly-private value, type, or module definition.
986
#[derive(Debug)]
987
pub struct NameBinding<'a> {
988 989
    modifiers: DefModifiers,
    kind: NameBindingKind<'a>,
990
    span: Option<Span>,
991 992
}

993 994
#[derive(Debug)]
enum NameBindingKind<'a> {
995
    Def(Def),
996
    Module(Module<'a>),
997 998 999 1000
    Import {
        binding: &'a NameBinding<'a>,
        id: NodeId,
    },
1001 1002
}

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

1011
        NameBinding { modifiers: modifiers, kind: NameBindingKind::Module(module), span: span }
1012 1013
    }

1014
    fn module(&self) -> Option<Module<'a>> {
1015 1016 1017 1018
        match self.kind {
            NameBindingKind::Module(module) => Some(module),
            NameBindingKind::Def(_) => None,
            NameBindingKind::Import { binding, .. } => binding.module(),
1019 1020 1021
        }
    }

1022
    fn def(&self) -> Option<Def> {
1023 1024 1025 1026
        match self.kind {
            NameBindingKind::Def(def) => Some(def),
            NameBindingKind::Module(module) => module.def,
            NameBindingKind::Import { binding, .. } => binding.def(),
1027
        }
1028
    }
1029

1030
    fn defined_with(&self, modifiers: DefModifiers) -> bool {
1031
        self.modifiers.contains(modifiers)
1032 1033 1034 1035 1036 1037 1038 1039
    }

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

    fn def_and_lp(&self) -> (Def, LastPrivate) {
        let def = self.def().unwrap();
1040
        if let Def::Err = def { return (def, LastMod(AllPublic)) }
1041 1042
        (def, LastMod(if self.is_public() { AllPublic } else { DependsOn(def.def_id()) }))
    }
1043 1044 1045 1046

    fn is_extern_crate(&self) -> bool {
        self.module().map(|module| module.is_extern_crate).unwrap_or(false)
    }
1047 1048 1049 1050 1051 1052 1053

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
1054 1055
}

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

1061
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1062
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
1063 1064 1065 1066
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
1067 1068
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
1069 1070 1071 1072 1073
        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 已提交
1074
        table.intern("str", TyStr);
1075 1076 1077 1078 1079
        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 已提交
1080 1081 1082 1083

        table
    }

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

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

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

1095
    graph_root: Module<'a>,
1096

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

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

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

    // The module that represents the current item scope.
1105
    current_module: Module<'a>,
1106 1107

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

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

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

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

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

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

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

1133 1134 1135 1136 1137
    // Whether or not to print error messages. Can be set to true
    // when getting additional info for error message suggestions,
    // so as to avoid printing duplicate errors
    emit_errors: bool,

1138 1139 1140 1141 1142
    make_glob_map: bool,
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
    glob_map: GlobMap,

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

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

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

pub struct ResolverArenas<'a> {
    modules: arena::TypedArena<ModuleS<'a>>,
1157
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1158 1159
}

1160
#[derive(PartialEq)]
S
Steven Fackler 已提交
1161 1162
enum FallbackChecks {
    Everything,
C
corentih 已提交
1163
    OnlyTraitAndStatics,
S
Steven Fackler 已提交
1164 1165
}

1166 1167
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1168
           ast_map: &'a hir_map::Map<'tcx>,
1169 1170
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
C
corentih 已提交
1171
           -> Resolver<'a, 'tcx> {
1172
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
1173
        let graph_root = ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, true);
1174
        let graph_root = arenas.modules.alloc(graph_root);
K
Kevin Butler 已提交
1175 1176 1177 1178

        Resolver {
            session: session,

1179 1180
            ast_map: ast_map,

K
Kevin Butler 已提交
1181 1182
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1183
            graph_root: graph_root,
K
Kevin Butler 已提交
1184

1185 1186
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1187 1188 1189

            unresolved_imports: 0,

1190
            current_module: graph_root,
1191 1192 1193
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1194 1195 1196 1197 1198 1199

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1200
            def_map: RefCell::new(NodeMap()),
1201 1202
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1203 1204
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1205
            used_imports: HashSet::new(),
1206
            used_crates: HashSet::new(),
1207
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1208 1209

            emit_errors: true,
1210 1211
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
G
Garming Sam 已提交
1212 1213 1214

            callback: None,
            resolved: false,
1215 1216 1217 1218 1219 1220 1221 1222

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
1223
            name_bindings: arena::TypedArena::new(),
K
Kevin Butler 已提交
1224 1225
        }
    }
1226

1227 1228 1229 1230 1231 1232 1233 1234
    fn new_module(&self,
                  parent_link: ParentLink<'a>,
                  def: Option<Def>,
                  external: bool,
                  is_public: bool) -> Module<'a> {
        self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public))
    }

1235 1236 1237 1238
    fn new_name_binding(&self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.arenas.name_bindings.alloc(name_binding)
    }

1239 1240 1241 1242 1243 1244
    fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def) -> Module<'a> {
        let mut module = ModuleS::new(parent_link, Some(def), false, true);
        module.is_extern_crate = true;
        self.arenas.modules.alloc(module)
    }

1245 1246 1247 1248
    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 }
    }

1249
    #[inline]
1250 1251 1252 1253 1254 1255
    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);
        }

1256 1257 1258 1259 1260
        let import_id = match binding.kind {
            NameBindingKind::Import { id, .. } => id,
            _ => return,
        };

1261 1262
        self.used_imports.insert((import_id, ns));

1263 1264 1265 1266
        if !self.make_glob_map {
            return;
        }
        if self.glob_map.contains_key(&import_id) {
1267
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1268 1269 1270 1271 1272 1273 1274 1275 1276
            return;
        }

        let mut new_set = HashSet::new();
        new_set.insert(name);
        self.glob_map.insert(import_id, new_set);
    }

    fn get_trait_name(&self, did: DefId) -> Name {
1277 1278
        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
            self.ast_map.expect_item(node_id).name
1279
        } else {
1280
            self.session.cstore.item_name(did)
1281 1282 1283
        }
    }

1284
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1285
    fn resolve_module_path_from_root(&mut self,
1286
                                     module_: Module<'a>,
1287
                                     module_path: &[Name],
1288
                                     index: usize,
1289 1290
                                     span: Span,
                                     lp: LastPrivate)
1291
                                     -> ResolveResult<(Module<'a>, LastPrivate)> {
1292
        fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
1293 1294
            match module.resolve_name(needle, TypeNS, false) {
                Success(binding) if binding.is_extern_crate() => Some(module),
1295
                _ => match module.parent_link {
1296
                    ModuleParentLink(ref parent, _) => {
1297
                        search_parent_externals(needle, parent)
1298
                    }
C
corentih 已提交
1299 1300
                    _ => None,
                },
1301
            }
1302 1303
        }

1304
        let mut search_module = module_;
1305
        let mut index = index;
A
Alex Crichton 已提交
1306
        let module_path_len = module_path.len();
1307
        let mut closest_private = lp;
1308 1309 1310 1311 1312

        // 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 已提交
1313
            let name = module_path[index];
1314
            match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
1315
                Failed(None) => {
1316
                    let segment_name = name.as_str();
1317
                    let module_name = module_to_string(search_module);
1318
                    let mut span = span;
1319
                    let msg = if "???" == &module_name {
1320
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1321

C
corentih 已提交
1322
                        match search_parent_externals(name, &self.current_module) {
1323
                            Some(module) => {
1324
                                let path_str = names_to_string(module_path);
J
Jonas Schievink 已提交
1325 1326
                                let target_mod_str = module_to_string(&module);
                                let current_mod_str = module_to_string(&self.current_module);
1327 1328 1329 1330 1331 1332 1333

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

1334
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1335 1336
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1337
                        }
1338
                    } else {
C
corentih 已提交
1339
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1340
                    };
1341

1342
                    return Failed(Some((span, msg)));
1343
                }
1344
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1345
                Indeterminate => {
C
corentih 已提交
1346 1347 1348
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1349
                    return Indeterminate;
1350
                }
1351
                Success(binding) => {
1352 1353
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
J
Jeffrey Seyfried 已提交
1354
                    if let Some(module_def) = binding.module() {
1355
                        search_module = module_def;
1356

1357 1358
                        // Keep track of the closest private module used
                        // when resolving this import chain.
1359
                        if !binding.is_public() {
1360
                            if let Some(did) = search_module.def_id() {
1361
                                closest_private = LastMod(DependsOn(did));
1362 1363
                            }
                        }
1364 1365 1366
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1367 1368 1369 1370
                    }
                }
            }

T
Tim Chevalier 已提交
1371
            index += 1;
1372 1373
        }

1374
        return Success((search_module, closest_private));
1375 1376
    }

1377 1378
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1379 1380 1381
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1382
    fn resolve_module_path(&mut self,
1383
                           module_: Module<'a>,
1384
                           module_path: &[Name],
1385
                           use_lexical_scope: UseLexicalScopeFlag,
J
Jeffrey Seyfried 已提交
1386
                           span: Span)
1387
                           -> ResolveResult<(Module<'a>, LastPrivate)> {
1388 1389 1390
        if module_path.len() == 0 {
            return Success((self.graph_root, LastMod(AllPublic))) // Use the crate root
        }
1391

1392
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1393
               names_to_string(module_path),
J
Jonas Schievink 已提交
1394
               module_to_string(&module_));
1395

1396
        // Resolve the module prefix, if any.
1397
        let module_prefix_result = self.resolve_module_prefix(module_, module_path);
1398

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

1470 1471 1472 1473
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1474
                                           last_private)
1475 1476
    }

1477 1478
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1479
    fn resolve_item_in_lexical_scope(&mut self,
1480
                                     module_: Module<'a>,
1481
                                     name: Name,
1482 1483
                                     namespace: Namespace,
                                     record_used: bool)
1484
                                     -> ResolveResult<&'a NameBinding<'a>> {
C
corentih 已提交
1485
        debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
1486
               name,
1487
               namespace,
J
Jonas Schievink 已提交
1488
               module_to_string(&module_));
1489

1490 1491 1492 1493 1494 1495
        // Proceed up the scope chain looking for parent modules.
        let mut search_module = module_;
        loop {
            // Resolve the name in the parent module.
            match self.resolve_name_in_module(search_module, name, namespace, true, record_used) {
                Failed(Some((span, msg))) => {
J
Jonas Schievink 已提交
1496
                    resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
1497 1498 1499 1500 1501
                }
                Failed(None) => (), // Continue up the search chain.
                Indeterminate => {
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.
1502

1503 1504
                    debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
                    return Indeterminate;
1505
                }
1506
                Success(binding) => {
1507 1508
                    // We found the module.
                    debug!("(resolving item in lexical scope) found name in module, done");
1509
                    return Success(binding);
1510 1511 1512 1513
                }
            }

            // Go to the next parent.
1514
            match search_module.parent_link {
B
Brian Anderson 已提交
1515
                NoParentLink => {
1516
                    // No more parents. This module was unresolved.
1517
                    debug!("(resolving item in lexical scope) unresolved module: no parent module");
1518
                    return Failed(None);
1519
                }
1520
                ModuleParentLink(parent_module_node, _) => {
1521 1522 1523 1524
                    if search_module.is_normal() {
                        // We stop the search here.
                        debug!("(resolving item in lexical scope) unresolved module: not \
                                searching through module parents");
1525
                            return Failed(None);
1526
                    } else {
1527
                        search_module = parent_module_node;
1528 1529
                    }
                }
1530 1531
                BlockParentLink(parent_module_node, _) => {
                    search_module = parent_module_node;
1532 1533 1534 1535 1536
                }
            }
        }
    }

1537
    /// Returns the nearest normal module parent of the given module.
1538
    fn get_nearest_normal_module_parent(&mut self, module_: Module<'a>) -> Option<Module<'a>> {
1539 1540
        let mut module_ = module_;
        loop {
1541
            match module_.parent_link {
1542 1543 1544
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
1545
                    let new_module = new_module;
1546 1547
                    if new_module.is_normal() {
                        return Some(new_module);
1548
                    }
1549
                    module_ = new_module;
1550 1551 1552 1553 1554
                }
            }
        }
    }

1555 1556
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1557
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Module<'a>) -> Module<'a> {
1558 1559 1560
        if module_.is_normal() {
            return module_;
        }
1561
        match self.get_nearest_normal_module_parent(module_) {
1562 1563
            None => module_,
            Some(new_module) => new_module,
1564 1565 1566
        }
    }

1567
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1568
    /// (b) some chain of `super::`.
1569
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1570
    fn resolve_module_prefix(&mut self,
1571
                             module_: Module<'a>,
1572
                             module_path: &[Name])
1573
                             -> ResolveResult<ModulePrefixResult<'a>> {
1574 1575
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1576 1577 1578 1579 1580 1581
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1582 1583

        // Now loop through all the `super`s we find.
1584
        while i < module_path.len() && "super" == module_path[i].as_str() {
1585
            debug!("(resolving module prefix) resolving `super` at {}",
J
Jonas Schievink 已提交
1586
                   module_to_string(&containing_module));
1587
            match self.get_nearest_normal_module_parent(containing_module) {
1588
                None => return Failed(None),
1589 1590 1591
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1592 1593 1594 1595
                }
            }
        }

1596
        debug!("(resolving module prefix) finished resolving prefix at {}",
J
Jonas Schievink 已提交
1597
               module_to_string(&containing_module));
1598 1599

        return Success(PrefixFound(containing_module, i));
1600 1601
    }

1602
    /// Attempts to resolve the supplied name in the given module for the
J
Jeffrey Seyfried 已提交
1603
    /// given namespace. If successful, returns the binding corresponding to
1604
    /// the name.
F
Felix S. Klock II 已提交
1605
    fn resolve_name_in_module(&mut self,
1606
                              module: Module<'a>,
1607
                              name: Name,
1608
                              namespace: Namespace,
1609 1610
                              allow_private_imports: bool,
                              record_used: bool)
1611
                              -> ResolveResult<&'a NameBinding<'a>> {
1612
        debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
1613

1614 1615 1616 1617
        build_reduced_graph::populate_module_if_necessary(self, module);
        module.resolve_name(name, namespace, allow_private_imports).and_then(|binding| {
            if record_used {
                self.record_use(name, namespace, binding);
1618
            }
1619 1620
            Success(binding)
        })
1621 1622
    }

1623
    fn report_unresolved_imports(&mut self, module_: Module<'a>) {
1624 1625 1626
        for import in module_.unresolved_imports.borrow().iter() {
            resolve_error(self, import.span, ResolutionError::UnresolvedImport(None));
            break;
1627 1628 1629
        }

        // Descend into children and anonymous children.
1630
        for (_, module_) in module_.module_children.borrow().iter() {
1631
            self.report_unresolved_imports(module_);
1632 1633 1634 1635 1636
        }
    }

    // AST resolution
    //
1637
    // We maintain a list of value ribs and type ribs.
1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652
    //
    // 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.

1653
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1654
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1655
    {
1656
        let orig_module = self.current_module;
1657 1658

        // Move down in the graph.
1659 1660
        if let Some(module) = orig_module.module_children.borrow().get(&id) {
            self.current_module = module;
1661 1662
        }

A
Alex Crichton 已提交
1663
        f(self);
1664 1665 1666 1667

        self.current_module = orig_module;
    }

S
Seo Sanghyeon 已提交
1668 1669
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1670 1671 1672 1673 1674 1675 1676 1677
    fn search_label(&self, name: Name) -> Option<DefLike> {
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1678
                    return None;
1679 1680 1681
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1682
            if result.is_some() {
C
corentih 已提交
1683
                return result;
1684 1685 1686 1687 1688
            }
        }
        None
    }

1689
    fn resolve_crate(&mut self, krate: &hir::Crate) {
1690
        debug!("(resolving crate) starting");
1691

1692
        intravisit::walk_crate(self, krate);
1693 1694
    }

W
we 已提交
1695 1696
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
C
corentih 已提交
1697 1698 1699 1700
            span_err!(self.session,
                      span,
                      E0317,
                      "user-defined types or type parameters cannot shadow the primitive types");
W
we 已提交
1701 1702 1703
        }
    }

1704
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
1705
        let name = item.name;
1706

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

1709
        match item.node {
1710 1711 1712
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
1713 1714
                self.check_if_primitive_type_name(name, item.span);

C
corentih 已提交
1715
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1716
                                             |this| intravisit::walk_item(this, item));
1717
            }
1718
            ItemFn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1719
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
1720
                                             |this| intravisit::walk_item(this, item));
1721 1722
            }

F
Flavio Percoco 已提交
1723
            ItemDefaultImpl(_, ref trait_ref) => {
1724
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1725
            }
C
corentih 已提交
1726
            ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
1727
                self.resolve_implementation(generics,
1728
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1729
                                            &self_type,
1730
                                            item.id,
1731
                                            impl_items);
1732 1733
            }

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

1737 1738 1739 1740 1741
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
1742
                    let local_def_id = this.ast_map.local_def_id(item.id);
1743
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1744
                        this.visit_generics(generics);
1745
                        walk_list!(this, visit_ty_param_bound, bounds);
1746 1747

                        for trait_item in trait_items {
1748
                            match trait_item.node {
1749
                                hir::ConstTraitItem(_, ref default) => {
1750 1751 1752 1753 1754
                                    // 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| {
1755
                                            intravisit::walk_trait_item(this, trait_item)
1756 1757
                                        });
                                    } else {
1758
                                        intravisit::walk_trait_item(this, trait_item)
1759 1760
                                    }
                                }
1761
                                hir::MethodTraitItem(ref sig, _) => {
1762 1763 1764 1765 1766
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
1767
                                        intravisit::walk_trait_item(this, trait_item)
1768
                                    });
1769
                                }
1770
                                hir::TypeTraitItem(..) => {
V
Vadim Petrochenkov 已提交
1771
                                    this.check_if_primitive_type_name(trait_item.name,
1772
                                                                      trait_item.span);
1773
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1774
                                        intravisit::walk_trait_item(this, trait_item)
1775
                                    });
1776 1777 1778 1779
                                }
                            };
                        }
                    });
1780
                });
1781 1782
            }

1783
            ItemMod(_) | ItemForeignMod(_) => {
1784
                self.with_scope(item.id, |this| {
1785
                    intravisit::walk_item(this, item);
1786
                });
1787 1788
            }

1789
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
1790
                self.with_constant_rib(|this| {
1791
                    intravisit::walk_item(this, item);
1792
                });
1793
            }
1794

W
we 已提交
1795 1796
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
1797
                let check_rename = |this: &Self, id, name| {
1798
                    match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
1799 1800
                        Some(Def::Enum(..)) | Some(Def::TyAlias(..)) | Some(Def::Struct(..)) |
                        Some(Def::Trait(..)) | None => {
1801
                            this.check_if_primitive_type_name(name, item.span);
W
we 已提交
1802 1803 1804
                        }
                        _ => {}
                    }
1805 1806 1807
                };

                match view_path.node {
1808 1809
                    hir::ViewPathSimple(name, _) => {
                        check_rename(self, item.id, name);
1810
                    }
1811
                    hir::ViewPathList(ref prefix, ref items) => {
1812
                        for item in items {
1813 1814
                            if let Some(name) = item.node.rename() {
                                check_rename(self, item.node.id(), name);
1815 1816 1817 1818 1819 1820 1821 1822
                            }
                        }

                        // Resolve prefix of an import with empty braces (issue #28388)
                        if items.is_empty() && !prefix.segments.is_empty() {
                            match self.resolve_crate_relative_path(prefix.span,
                                                                   &prefix.segments,
                                                                   TypeNS) {
C
corentih 已提交
1823 1824
                                Some((def, lp)) =>
                                    self.record_def(item.id, PathResolution::new(def, lp, 0)),
1825 1826 1827 1828 1829
                                None => {
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
1830
                                    self.record_def(item.id, err_path_resolution());
1831
                                }
1832 1833 1834 1835
                            }
                        }
                    }
                    _ => {}
W
we 已提交
1836 1837 1838
                }
            }

1839
            ItemExternCrate(_) => {
1840
                // do nothing, these are just around to be encoded
1841
            }
1842 1843 1844
        }
    }

1845
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1846
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1847
    {
1848
        match type_parameters {
1849
            HasTypeParameters(generics, space, rib_kind) => {
1850
                let mut function_type_rib = Rib::new(rib_kind);
1851
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
1852
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
1853
                    let name = type_parameter.name;
1854
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1855

1856
                    if seen_bindings.contains(&name) {
1857 1858
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
1859
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
1860
                    }
1861
                    seen_bindings.insert(name);
1862

1863
                    // plain insert (no renaming)
C
corentih 已提交
1864 1865
                    function_type_rib.bindings
                                     .insert(name,
1866
                                             DlDef(Def::TyParam(space,
C
corentih 已提交
1867 1868 1869 1870
                                                              index as u32,
                                                              self.ast_map
                                                                  .local_def_id(type_parameter.id),
                                                              name)));
1871
                }
1872
                self.type_ribs.push(function_type_rib);
1873 1874
            }

B
Brian Anderson 已提交
1875
            NoTypeParameters => {
1876 1877 1878 1879
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1880
        f(self);
1881

1882
        match type_parameters {
C
corentih 已提交
1883 1884 1885 1886 1887 1888
            HasTypeParameters(..) => {
                if !self.resolved {
                    self.type_ribs.pop();
                }
            }
            NoTypeParameters => {}
1889 1890 1891
        }
    }

C
corentih 已提交
1892 1893
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1894
    {
1895
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1896
        f(self);
G
Garming Sam 已提交
1897 1898 1899
        if !self.resolved {
            self.label_ribs.pop();
        }
1900
    }
1901

C
corentih 已提交
1902 1903
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1904
    {
1905 1906
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1907
        f(self);
G
Garming Sam 已提交
1908 1909 1910 1911
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
1912 1913
    }

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

1918
        // Create a label rib for the function.
1919
        self.label_ribs.push(Rib::new(rib_kind));
1920

1921 1922 1923
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
J
Jonas Schievink 已提交
1924
            self.resolve_pattern(&argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
1925

J
Jonas Schievink 已提交
1926
            self.visit_ty(&argument.ty);
1927

1928 1929
            debug!("(resolving function) recorded argument");
        }
1930
        intravisit::walk_fn_ret_ty(self, &declaration.output);
1931

1932
        // Resolve the function body.
1933
        self.visit_block(block);
1934

1935
        debug!("(resolving function) leaving function");
1936

G
Garming Sam 已提交
1937 1938 1939 1940
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
1941 1942
    }

F
Felix S. Klock II 已提交
1943
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
1944
                               id: NodeId,
1945
                               trait_path: &Path,
1946
                               path_depth: usize)
1947 1948
                               -> Result<PathResolution, ()> {
        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
1949
            if let Def::Trait(_) = path_res.base_def {
1950 1951 1952
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
N
Nick Cameron 已提交
1953 1954 1955
                let mut err =
                    resolve_struct_error(self,
                                  trait_path.span,
J
Jonas Schievink 已提交
1956
                                  ResolutionError::IsNotATrait(&path_names_to_string(trait_path,
N
Nick Cameron 已提交
1957
                                                                                      path_depth)));
1958 1959

                // If it's a typedef, give a note
1960
                if let Def::TyAlias(..) = path_res.base_def {
N
Nick Cameron 已提交
1961 1962
                    err.span_note(trait_path.span,
                                  "`type` aliases cannot be used for traits");
1963
                }
N
Nick Cameron 已提交
1964
                err.emit();
1965 1966
                Err(())
            }
1967
        } else {
1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989

            // 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);
1990
            Err(())
1991 1992 1993
        }
    }

1994
    fn resolve_generics(&mut self, generics: &Generics) {
1995
        for type_parameter in generics.ty_params.iter() {
1996
            self.check_if_primitive_type_name(type_parameter.name, type_parameter.span);
1997 1998
        }
        for predicate in &generics.where_clause.predicates {
1999
            match predicate {
2000 2001 2002
                &hir::WherePredicate::BoundPredicate(_) |
                &hir::WherePredicate::RegionPredicate(_) => {}
                &hir::WherePredicate::EqPredicate(ref eq_pred) => {
2003
                    let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
2004
                    if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res {
2005 2006
                        self.record_def(eq_pred.id, path_res.unwrap());
                    } else {
2007 2008
                        resolve_error(self,
                                      eq_pred.span,
2009
                                      ResolutionError::UndeclaredAssociatedType);
2010
                        self.record_def(eq_pred.id, err_path_resolution());
2011 2012
                    }
                }
2013 2014
            }
        }
2015
        intravisit::walk_generics(self, generics);
2016 2017
    }

2018 2019
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2020
    {
2021 2022 2023 2024 2025 2026 2027
        // 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 已提交
2028
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2029
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2030
    {
2031
        let mut new_val = None;
2032
        let mut new_id = None;
E
Eduard Burtescu 已提交
2033
        if let Some(trait_ref) = opt_trait_ref {
2034
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
2035 2036
                                                               &trait_ref.path,
                                                               0) {
2037 2038 2039 2040
                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());
2041 2042
            } else {
                self.record_def(trait_ref.ref_id, err_path_resolution());
2043
            }
2044
            intravisit::walk_trait_ref(self, trait_ref);
2045
        }
2046
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2047
        let result = f(self, new_id);
2048 2049 2050 2051
        self.current_trait_ref = original_trait_ref;
        result
    }

2052 2053 2054 2055 2056 2057 2058 2059 2060 2061
    fn with_self_rib<F>(&mut self, self_def: Def, f: F)
        where F: FnOnce(&mut Resolver)
    {
        let mut self_type_rib = Rib::new(NormalRibKind);

        // plain insert (no renaming, types are not currently hygienic....)
        let name = special_names::type_self;
        self_type_rib.bindings.insert(name, DlDef(self_def));
        self.type_ribs.push(self_type_rib);
        f(self);
G
Garming Sam 已提交
2062 2063 2064
        if !self.resolved {
            self.type_ribs.pop();
        }
2065 2066
    }

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

2081
            // Resolve the trait reference, if necessary.
2082
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2083
                // Resolve the self type.
2084
                this.visit_ty(self_type);
2085

2086
                this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
2087 2088 2089
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
                            match impl_item.node {
2090
                                hir::ImplItemKind::Const(..) => {
2091
                                    // If this is a trait impl, ensure the const
2092
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2093
                                    this.check_trait_item(impl_item.name,
2094 2095
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2096
                                    this.with_constant_rib(|this| {
2097
                                        intravisit::walk_impl_item(this, impl_item);
2098 2099
                                    });
                                }
2100
                                hir::ImplItemKind::Method(ref sig, _) => {
2101 2102
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2103
                                    this.check_trait_item(impl_item.name,
2104 2105
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
2106 2107 2108 2109 2110 2111 2112 2113

                                    // 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| {
2114
                                        intravisit::walk_impl_item(this, impl_item);
2115 2116
                                    });
                                }
2117
                                hir::ImplItemKind::Type(ref ty) => {
2118
                                    // If this is a trait impl, ensure the type
2119
                                    // exists in trait
V
Vadim Petrochenkov 已提交
2120
                                    this.check_trait_item(impl_item.name,
2121 2122
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2123

2124 2125
                                    this.visit_ty(ty);
                                }
2126
                            }
2127
                        }
2128
                    });
2129 2130
                });
            });
2131
        });
2132 2133
    }

2134
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
2135 2136 2137 2138
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2139
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2140
            if !self.trait_item_map.contains_key(&(name, did)) {
2141
                let path_str = path_names_to_string(&trait_ref.path, 0);
J
Jonas Schievink 已提交
2142
                resolve_error(self, span, err(name, &path_str));
2143 2144 2145 2146
            }
        }
    }

E
Eduard Burtescu 已提交
2147
    fn resolve_local(&mut self, local: &Local) {
2148
        // Resolve the type.
2149
        walk_list!(self, visit_ty, &local.ty);
2150

2151
        // Resolve the initializer.
2152
        walk_list!(self, visit_expr, &local.init);
2153 2154

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

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

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

2185
            for (&key, &binding_0) in &map_0 {
2186
                match map_i.get(&key) {
C
corentih 已提交
2187
                    None => {
2188
                        resolve_error(self,
C
corentih 已提交
2189 2190 2191 2192 2193 2194 2195 2196 2197 2198
                                      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));
                        }
2199
                    }
2200 2201 2202
                }
            }

2203
            for (&key, &binding) in &map_i {
2204
                if !map_0.contains_key(&key) {
2205 2206
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2207
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2208 2209 2210
                }
            }
        }
2211 2212
    }

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

2216
        let mut bindings_list = HashMap::new();
2217
        for pattern in &arm.pats {
J
Jonas Schievink 已提交
2218
            self.resolve_pattern(&pattern, RefutableMode, &mut bindings_list);
2219 2220
        }

2221 2222 2223 2224
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2225
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2226
        self.visit_expr(&arm.body);
2227

G
Garming Sam 已提交
2228 2229 2230
        if !self.resolved {
            self.value_ribs.pop();
        }
2231 2232
    }

E
Eduard Burtescu 已提交
2233
    fn resolve_block(&mut self, block: &Block) {
2234
        debug!("(resolving block) entering block");
2235
        // Move down in the graph, if there's an anonymous module rooted here.
2236
        let orig_module = self.current_module;
2237
        let anonymous_module =
2238
            orig_module.module_children.borrow().get(&block.id).map(|module| *module);
2239 2240 2241 2242 2243 2244 2245 2246

        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
            self.value_ribs.push(Rib::new(AnonymousModuleRibKind(anonymous_module)));
            self.type_ribs.push(Rib::new(AnonymousModuleRibKind(anonymous_module)));
            self.current_module = anonymous_module;
        } else {
            self.value_ribs.push(Rib::new(NormalRibKind));
2247 2248 2249
        }

        // Descend into the block.
2250
        intravisit::walk_block(self, block);
2251 2252

        // Move back up.
G
Garming Sam 已提交
2253
        if !self.resolved {
2254
            self.current_module = orig_module;
G
Garming Sam 已提交
2255
            self.value_ribs.pop();
2256 2257 2258
            if let Some(_) = anonymous_module {
                self.type_ribs.pop();
            }
G
Garming Sam 已提交
2259
        }
2260
        debug!("(resolving block) leaving block");
2261 2262
    }

F
Felix S. Klock II 已提交
2263
    fn resolve_type(&mut self, ty: &Ty) {
2264
        match ty.node {
2265
            TyPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2266 2267 2268 2269 2270 2271 2272 2273
                let resolution = match self.resolve_possibly_assoc_item(ty.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
                                                                        TypeNS,
                                                                        true) {
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        // Resolve embedded types.
2274
                        intravisit::walk_ty(self, ty);
C
corentih 已提交
2275 2276 2277 2278
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2279 2280

                // This is a path in the type namespace. Walk through scopes
2281
                // looking for it.
2282
                match resolution {
B
Brian Anderson 已提交
2283
                    Some(def) => {
2284
                        // Write the result into the def map.
C
corentih 已提交
2285
                        debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
2286
                               path_names_to_string(path, 0),
C
corentih 已提交
2287 2288
                               ty.id,
                               def);
2289
                        self.record_def(ty.id, def);
2290
                    }
B
Brian Anderson 已提交
2291
                    None => {
2292 2293
                        self.record_def(ty.id, err_path_resolution());

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

2297 2298 2299 2300
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2301
                        };
2302

2303
                        let self_type_name = special_idents::type_self.name;
C
corentih 已提交
2304 2305 2306 2307
                        let is_invalid_self_type_name = path.segments.len() > 0 &&
                                                        maybe_qself.is_none() &&
                                                        path.segments[0].identifier.name ==
                                                        self_type_name;
G
Guillaume Gomez 已提交
2308
                        if is_invalid_self_type_name {
2309 2310
                            resolve_error(self,
                                          ty.span,
2311
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2312
                        } else {
2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339
                            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 已提交
2340
                        }
2341 2342
                    }
                }
2343
            }
2344
            _ => {}
2345
        }
2346
        // Resolve embedded types.
2347
        intravisit::walk_ty(self, ty);
2348 2349
    }

F
Felix S. Klock II 已提交
2350
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2351
                       pattern: &Pat,
2352 2353 2354
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2355
                       bindings_list: &mut HashMap<Name, NodeId>) {
2356
        let pat_id = pattern.id;
2357
        walk_pat(pattern, |pattern| {
2358
            match pattern.node {
2359 2360
                PatKind::Ident(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatKind::Ident with no type parameters
2361 2362 2363 2364
                    // 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
2365 2366 2367 2368
                    // 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();
2369

2370
                    let ident = path1.node;
2371
                    let renamed = ident.name;
2372

2373 2374
                    match self.resolve_bare_identifier_pattern(ident.unhygienic_name,
                                                               pattern.span) {
2375
                        FoundStructOrEnumVariant(def, lp) if const_ok => {
C
corentih 已提交
2376
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2377
                                   renamed);
2378

C
corentih 已提交
2379 2380 2381 2382 2383 2384 2385 2386 2387
                            self.enforce_default_binding_mode(pattern,
                                                              binding_mode,
                                                              "an enum variant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: lp,
                                                depth: 0,
                                            });
2388
                        }
A
Alex Crichton 已提交
2389
                        FoundStructOrEnumVariant(..) => {
2390
                            resolve_error(
2391
                                self,
2392
                                pattern.span,
2393
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2394 2395
                                    renamed)
                            );
2396
                            self.record_def(pattern.id, err_path_resolution());
2397
                        }
2398
                        FoundConst(def, lp, _) if const_ok => {
C
corentih 已提交
2399 2400 2401 2402 2403 2404 2405 2406 2407
                            debug!("(resolving pattern) resolving `{}` to constant", renamed);

                            self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: lp,
                                                depth: 0,
                                            });
2408
                        }
2409
                        FoundConst(def, _, name) => {
2410
                            resolve_error(
2411 2412
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2413 2414
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2415
                            );
2416
                            self.record_def(pattern.id, err_path_resolution());
2417
                        }
2418
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2419
                            debug!("(resolving pattern) binding `{}`", renamed);
2420

2421
                            let def_id = self.ast_map.local_def_id(pattern.id);
2422
                            let def = Def::Local(def_id, pattern.id);
2423 2424 2425 2426 2427

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

C
corentih 已提交
2428 2429 2430 2431 2432 2433
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                last_private: LastMod(AllPublic),
                                                depth: 0,
                                            });
2434 2435 2436 2437 2438 2439

                            // 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.)
2440 2441
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2442 2443
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2444
                                bindings_list.insert(renamed, pat_id);
2445
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2446
                               bindings_list.contains_key(&renamed) {
2447 2448
                                // Forbid duplicate bindings in the same
                                // parameter list.
2449
                                resolve_error(
2450 2451
                                    self,
                                    pattern.span,
2452
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2453
                                        &ident.name.as_str())
2454
                                );
C
corentih 已提交
2455
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2456 2457
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2458
                                resolve_error(
2459 2460
                                    self,
                                    pattern.span,
2461
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2462
                                        &ident.name.as_str())
2463
                                );
2464
                            }
2465 2466
                            // Else, not bound in the same pattern: do
                            // nothing.
2467 2468 2469 2470
                        }
                    }
                }

2471
                PatKind::TupleStruct(ref path, _) | PatKind::Path(ref path) => {
2472
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2473 2474 2475 2476 2477 2478
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            None,
                                                                            path,
                                                                            ValueNS,
                                                                            false) {
                        // The below shouldn't happen because all
2479
                        // qualified paths should be in PatKind::QPath.
C
corentih 已提交
2480 2481
                        TypecheckRequired =>
                            self.session.span_bug(path.span,
2482 2483 2484 2485
                                                  "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 已提交
2486 2487
                        ResolveAttempt(resolution) => resolution,
                    };
2488
                    if let Some(path_res) = resolution {
2489
                        match path_res.base_def {
2490
                            Def::Struct(..) if path_res.depth == 0 => {
2491 2492
                                self.record_def(pattern.id, path_res);
                            }
2493
                            Def::Variant(..) | Def::Const(..) => {
2494 2495
                                self.record_def(pattern.id, path_res);
                            }
2496
                            Def::Static(..) => {
2497 2498
                                resolve_error(&self,
                                              path.span,
2499
                                              ResolutionError::StaticVariableReference);
2500
                                self.record_def(pattern.id, err_path_resolution());
2501
                            }
2502 2503 2504 2505
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2506
                                // be a `T::CONST` that typeck will resolve.
2507
                                if path_res.depth == 0 {
2508
                                    resolve_error(
2509
                                        self,
2510
                                        path.span,
2511
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2512 2513 2514 2515 2516 2517
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2518
                                    );
2519
                                    self.record_def(pattern.id, err_path_resolution());
2520
                                } else {
C
corentih 已提交
2521 2522 2523 2524 2525
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2526 2527
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2528 2529 2530 2531 2532
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2533
                        resolve_error(
2534 2535
                            self,
                            path.span,
2536
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2537
                                &path.segments.last().unwrap().identifier.name.as_str())
2538
                        );
2539
                        self.record_def(pattern.id, err_path_resolution());
2540
                    }
2541
                    intravisit::walk_path(self, path);
2542 2543
                }

2544
                PatKind::QPath(ref qself, ref path) => {
2545
                    // Associated constants only.
C
corentih 已提交
2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            Some(qself),
                                                                            path,
                                                                            ValueNS,
                                                                            false) {
                        TypecheckRequired => {
                            // All `<T>::CONST` should end up here, and will
                            // require use of the trait map to resolve
                            // during typechecking.
                            let const_name = path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name;
                            let traits = self.get_traits_containing_item(const_name);
                            self.trait_map.insert(pattern.id, traits);
2562
                            intravisit::walk_pat(self, pattern);
C
corentih 已提交
2563 2564 2565 2566
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2567 2568 2569 2570
                    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.
2571
                            Def::AssociatedConst(..) => {
2572 2573
                                self.record_def(pattern.id, path_res);
                            }
2574
                            _ => {
2575
                                resolve_error(
2576 2577
                                    self,
                                    path.span,
2578
                                    ResolutionError::NotAnAssociatedConst(
2579
                                        &path.segments.last().unwrap().identifier.name.as_str()
2580 2581
                                    )
                                );
2582
                                self.record_def(pattern.id, err_path_resolution());
2583
                            }
2584
                        }
2585
                    } else {
C
corentih 已提交
2586 2587 2588 2589 2590 2591 2592 2593
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2594
                        self.record_def(pattern.id, err_path_resolution());
2595
                    }
2596
                    intravisit::walk_pat(self, pattern);
2597 2598
                }

2599
                PatKind::Struct(ref path, _, _) => {
2600
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2601
                        Some(definition) => {
2602 2603
                            self.record_def(pattern.id, definition);
                        }
2604
                        result => {
C
corentih 已提交
2605
                            debug!("(resolving pattern) didn't find struct def: {:?}", result);
2606 2607 2608
                            resolve_error(
                                self,
                                path.span,
2609
                                ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
2610
                                    &path_names_to_string(path, 0))
2611
                            );
2612
                            self.record_def(pattern.id, err_path_resolution());
2613 2614
                        }
                    }
2615
                    intravisit::walk_path(self, path);
2616 2617
                }

2618
                PatKind::Lit(_) | PatKind::Range(..) => {
2619
                    intravisit::walk_pat(self, pattern);
2620 2621
                }

2622
                _ => {
2623 2624 2625
                    // Nothing to do.
                }
            }
2626
            true
2627
        });
2628 2629
    }

C
corentih 已提交
2630 2631 2632
    fn resolve_bare_identifier_pattern(&mut self,
                                       name: Name,
                                       span: Span)
E
Eduard Burtescu 已提交
2633
                                       -> BareIdentifierPatternResolution {
2634
        let module = self.current_module;
2635
        match self.resolve_item_in_lexical_scope(module, name, ValueNS, true) {
2636
            Success(binding) => {
C
corentih 已提交
2637 2638
                debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
                       name,
2639
                       binding);
J
Jeffrey Seyfried 已提交
2640
                match binding.def() {
B
Brian Anderson 已提交
2641
                    None => {
C
corentih 已提交
2642 2643
                        panic!("resolved name in the value namespace to a set of name bindings \
                                with no def?!");
2644
                    }
2645 2646 2647
                    // For the two success cases, this lookup can be
                    // considered as not having a private component because
                    // the lookup happened only within the current module.
2648
                    Some(def @ Def::Variant(..)) | Some(def @ Def::Struct(..)) => {
2649 2650
                        return FoundStructOrEnumVariant(def, LastMod(AllPublic));
                    }
2651
                    Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
2652
                        return FoundConst(def, LastMod(AllPublic), name);
2653
                    }
2654
                    Some(Def::Static(..)) => {
2655 2656
                        resolve_error(self, span, ResolutionError::StaticVariableReference);
                        return BareIdentifierPatternUnresolved;
2657
                    }
2658
                    _ => return BareIdentifierPatternUnresolved
2659 2660 2661
                }
            }

2662
            Indeterminate => return BareIdentifierPatternUnresolved,
2663 2664 2665
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
J
Jonas Schievink 已提交
2666
                        resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2667
                    }
C
corentih 已提交
2668
                    None => (),
2669
                }
2670

C
corentih 已提交
2671
                debug!("(resolve bare identifier pattern) failed to find {}", name);
2672
                return BareIdentifierPatternUnresolved;
2673 2674 2675 2676
            }
        }
    }

2677 2678 2679
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2680
                                   maybe_qself: Option<&hir::QSelf>,
2681 2682 2683
                                   path: &Path,
                                   namespace: Namespace,
                                   check_ribs: bool)
C
corentih 已提交
2684
                                   -> AssocItemResolveResult {
2685 2686
        let max_assoc_types;

2687
        match maybe_qself {
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698
            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();
            }
2699 2700 2701 2702 2703 2704 2705 2706 2707 2708
        }

        let mut resolution = self.with_no_errors(|this| {
            this.resolve_path(id, path, 0, namespace, check_ribs)
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
C
corentih 已提交
2709
                resolution = this.resolve_path(id, path, depth, TypeNS, true);
2710 2711
            });
        }
2712
        if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
2713 2714 2715 2716 2717 2718
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

2719 2720
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
2721 2722
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
G
Garming Sam 已提交
2723 2724 2725 2726 2727
    pub fn resolve_path(&mut self,
                        id: NodeId,
                        path: &Path,
                        path_depth: usize,
                        namespace: Namespace,
C
corentih 已提交
2728 2729
                        check_ribs: bool)
                        -> Option<PathResolution> {
2730
        let span = path.span;
C
corentih 已提交
2731
        let segments = &path.segments[..path.segments.len() - path_depth];
2732

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

2735
        if path.global {
2736
            let def = self.resolve_crate_relative_path(span, segments, namespace);
2737
            return def.map(mk_res);
2738 2739
        }

2740
        // Try to find a path to an item in a module.
2741
        let last_ident = segments.last().unwrap().identifier;
N
Nick Cameron 已提交
2742
        if segments.len() <= 1 {
2743
            let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, true);
C
corentih 已提交
2744 2745 2746 2747
            return unqualified_def.and_then(|def| self.adjust_local_def(def, span))
                                  .map(|def| {
                                      PathResolution::new(def, LastMod(AllPublic), path_depth)
                                  });
N
Nick Cameron 已提交
2748
        }
2749

2750
        let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, false);
N
Nick Cameron 已提交
2751 2752
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
2753
            (Some((ref d, _)), Some(ref ud)) if *d == ud.def => {
N
Nick Cameron 已提交
2754 2755
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
2756 2757
                              id,
                              span,
N
Nick Cameron 已提交
2758 2759 2760
                              "unnecessary qualification".to_string());
            }
            _ => {}
2761
        }
N
Nick Cameron 已提交
2762 2763

        def.map(mk_res)
2764 2765
    }

2766
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2767
    fn resolve_identifier(&mut self,
2768
                          identifier: hir::Ident,
2769
                          namespace: Namespace,
2770 2771
                          check_ribs: bool,
                          record_used: bool)
2772
                          -> Option<LocalDef> {
2773
        if identifier.name == special_idents::invalid.name {
2774
            return Some(LocalDef::from_def(Def::Err));
2775 2776
        }

2777 2778 2779 2780
        // First, check to see whether the name is a primitive type.
        if namespace == TypeNS {
            if let Some(&prim_ty) = self.primitive_type_table
                                        .primitive_types
2781
                                        .get(&identifier.unhygienic_name) {
2782
                return Some(LocalDef::from_def(Def::PrimTy(prim_ty)));
2783 2784 2785
            }
        }

2786
        if check_ribs {
C
corentih 已提交
2787
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier, namespace) {
2788
                return Some(def);
2789 2790 2791
            }
        }

2792 2793
        // Check the items.
        let module = self.current_module;
2794
        let name = identifier.unhygienic_name;
2795
        match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
2796
            Success(binding) => binding.def().map(LocalDef::from_def),
2797
            Failed(Some((span, msg))) => {
J
Jonas Schievink 已提交
2798
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2799 2800 2801 2802
                None
            }
            _ => None,
        }
2803 2804 2805
    }

    // Resolve a local definition, potentially adjusting for closures.
2806
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
2807
        let ribs = match local_def.ribs {
C
corentih 已提交
2808 2809 2810
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
2811 2812 2813
        };
        let mut def = local_def.def;
        match def {
2814
            Def::Upvar(..) => {
C
corentih 已提交
2815
                self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
2816
            }
2817
            Def::Local(_, node_id) => {
2818 2819
                for rib in ribs {
                    match rib.kind {
2820
                        NormalRibKind | AnonymousModuleRibKind(..) => {
2821 2822 2823 2824 2825 2826
                            // 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 已提交
2827 2828 2829
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2830
                            if let Some(&index) = seen.get(&node_id) {
2831
                                def = Def::Upvar(node_def_id, node_id, index, function_id);
2832 2833
                                continue;
                            }
C
corentih 已提交
2834 2835 2836
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2837
                            let depth = vec.len();
C
corentih 已提交
2838 2839 2840 2841
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2842

2843
                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
2844 2845 2846 2847 2848 2849
                            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 已提交
2850 2851 2852
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2853 2854 2855 2856
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2857 2858 2859
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2860 2861 2862 2863 2864
                            return None;
                        }
                    }
                }
            }
2865
            Def::TyParam(..) | Def::SelfTy(..) => {
2866 2867
                for rib in ribs {
                    match rib.kind {
2868 2869
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) |
                        AnonymousModuleRibKind(..) => {
2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891
                            // 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);
2892 2893
    }

2894
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
2895
    fn resolve_module_relative_path(&mut self,
2896
                                    span: Span,
2897
                                    segments: &[hir::PathSegment],
2898 2899
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
C
corentih 已提交
2900 2901 2902 2903 2904 2905
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2906

2907
        let containing_module;
2908
        let last_private;
2909
        let current_module = self.current_module;
J
Jeffrey Seyfried 已提交
2910
        match self.resolve_module_path(current_module, &module_path, UseLexicalScope, span) {
2911 2912 2913 2914
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
2915
                        let msg = format!("Use of undeclared type or module `{}`",
2916
                                          names_to_string(&module_path));
2917
                        (span, msg)
2918 2919
                    }
                };
2920

J
Jonas Schievink 已提交
2921
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2922
                return None;
2923
            }
2924
            Indeterminate => return None,
2925
            Success((resulting_module, resulting_last_private)) => {
2926
                containing_module = resulting_module;
2927
                last_private = resulting_last_private;
2928 2929 2930
            }
        }

2931
        let name = segments.last().unwrap().identifier.name;
2932 2933
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
        let def = match result {
2934
            Success(binding) => {
2935
                let (def, lp) = binding.def_and_lp();
2936
                (def, last_private.or(lp))
2937
            }
2938
            _ => return None,
2939 2940
        };
        return Some(def);
2941 2942
    }

2943 2944
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2945
    fn resolve_crate_relative_path(&mut self,
2946
                                   span: Span,
2947
                                   segments: &[hir::PathSegment],
2948
                                   namespace: Namespace)
C
corentih 已提交
2949 2950 2951 2952 2953 2954 2955
                                   -> Option<(Def, LastPrivate)> {
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2956

2957
        let root_module = self.graph_root;
2958

2959
        let containing_module;
2960
        let last_private;
2961
        match self.resolve_module_path_from_root(root_module,
2962
                                                 &module_path,
2963
                                                 0,
2964
                                                 span,
2965
                                                 LastMod(AllPublic)) {
2966 2967 2968 2969 2970
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
2971
                                          names_to_string(&module_path));
2972
                        (span, msg)
2973 2974 2975
                    }
                };

J
Jonas Schievink 已提交
2976
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
B
Brian Anderson 已提交
2977
                return None;
2978 2979
            }

2980
            Indeterminate => return None,
2981

2982
            Success((resulting_module, resulting_last_private)) => {
2983
                containing_module = resulting_module;
2984
                last_private = resulting_last_private;
2985 2986 2987
            }
        }

2988
        let name = segments.last().unwrap().identifier.name;
2989
        match self.resolve_name_in_module(containing_module, name, namespace, false, true) {
2990
            Success(binding) => {
2991 2992
                let (def, lp) = binding.def_and_lp();
                Some((def, last_private.or(lp)))
2993
            }
2994
            _ => None,
2995 2996 2997
        }
    }

F
Felix S. Klock II 已提交
2998
    fn resolve_identifier_in_local_ribs(&mut self,
2999
                                        ident: hir::Ident,
3000 3001
                                        namespace: Namespace)
                                        -> Option<LocalDef> {
3002
        // Check the local set of ribs.
3003
        let name = match namespace { ValueNS => ident.name, TypeNS => ident.unhygienic_name };
3004

3005 3006
        for i in (0 .. self.get_ribs(namespace).len()).rev() {
            if let Some(def_like) = self.get_ribs(namespace)[i].bindings.get(&name).cloned() {
3007 3008 3009
                match def_like {
                    DlDef(def) => {
                        debug!("(resolving path in local ribs) resolved `{}` to {:?} at {}",
C
corentih 已提交
3010 3011 3012
                               name,
                               def,
                               i);
3013 3014
                        return Some(LocalDef {
                            ribs: Some((namespace, i)),
C
corentih 已提交
3015
                            def: def,
3016 3017 3018 3019
                        });
                    }
                    def_like => {
                        debug!("(resolving path in local ribs) resolved `{}` to pseudo-def {:?}",
C
corentih 已提交
3020 3021
                               name,
                               def_like);
3022 3023 3024
                        return None;
                    }
                }
3025
            }
3026 3027

            if let AnonymousModuleRibKind(module) = self.get_ribs(namespace)[i].kind {
3028 3029 3030 3031 3032
                if let Success(binding) = self.resolve_name_in_module(module,
                                                                      ident.unhygienic_name,
                                                                      namespace,
                                                                      true,
                                                                      true) {
J
Jeffrey Seyfried 已提交
3033
                    if let Some(def) = binding.def() {
3034 3035 3036 3037
                        return Some(LocalDef::from_def(def));
                    }
                }
            }
3038
        }
3039 3040

        None
3041 3042
    }

C
corentih 已提交
3043 3044
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
3045
    {
3046
        self.emit_errors = false;
A
Alex Crichton 已提交
3047
        let rs = f(self);
3048 3049 3050 3051
        self.emit_errors = true;
        rs
    }

3052
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
C
corentih 已提交
3053 3054 3055
        fn extract_path_and_node_id(t: &Ty,
                                    allow: FallbackChecks)
                                    -> Option<(Path, NodeId, FallbackChecks)> {
3056
            match t.node {
3057
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
J
Jonas Schievink 已提交
3058 3059
                TyPtr(ref mut_ty) => extract_path_and_node_id(&mut_ty.ty, OnlyTraitAndStatics),
                TyRptr(_, ref mut_ty) => extract_path_and_node_id(&mut_ty.ty, allow),
3060 3061 3062 3063 3064 3065 3066
                // 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,
            }
        }

3067 3068 3069 3070 3071
        fn get_module<'a, 'tcx>(this: &mut Resolver<'a, 'tcx>,
                                span: Span,
                                name_path: &[ast::Name])
                                -> Option<Module<'a>> {
            let root = this.current_module;
3072
            let last_name = name_path.last().unwrap();
3073

3074
            if name_path.len() == 1 {
3075
                match this.primitive_type_table.primitive_types.get(last_name) {
3076
                    Some(_) => None,
3077
                    None => this.current_module.resolve_name(*last_name, TypeNS, true).success()
3078
                                               .and_then(NameBinding::module)
3079 3080
                }
            } else {
J
Jeffrey Seyfried 已提交
3081
                match this.resolve_module_path(root, &name_path, UseLexicalScope, span) {
3082
                    Success((module, _)) => Some(module),
C
corentih 已提交
3083
                    _ => None,
3084 3085 3086 3087
                }
            }
        }

3088
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
3089 3090
            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
                let sig = match this.ast_map.get(node_id) {
3091 3092
                    hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                        hir::MethodTraitItem(ref sig, _) => sig,
C
corentih 已提交
3093
                        _ => return false,
3094
                    },
3095
                    hir_map::NodeImplItem(impl_item) => match impl_item.node {
3096
                        hir::ImplItemKind::Method(ref sig, _) => sig,
C
corentih 已提交
3097
                        _ => return false,
3098
                    },
C
corentih 已提交
3099
                    _ => return false,
3100
                };
3101
                sig.explicit_self.node == hir::SelfStatic
3102
            } else {
3103
                this.session.cstore.is_static_method(did)
3104 3105 3106
            }
        }

3107 3108 3109 3110
        let (path, node_id, allowed) = match self.current_self_type {
            Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
                Some(x) => x,
                None => return NoSuggestion,
3111 3112 3113 3114
            },
            None => return NoSuggestion,
        };

3115 3116
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3117
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
3118 3119 3120 3121
                Some(Def::Enum(did)) |
                Some(Def::TyAlias(did)) |
                Some(Def::Struct(did)) |
                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
3122 3123 3124 3125 3126
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3127
                    }
3128 3129 3130
                },
                _ => {} // Self type didn't resolve properly
            }
3131 3132
        }

3133
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3134 3135

        // Look for a method in the current self type's impl module.
3136
        if let Some(module) = get_module(self, path.span, &name_path) {
3137
            if let Success(binding) = module.resolve_name(name, ValueNS, true) {
3138
                if let Some(Def::Method(did)) = binding.def() {
3139
                    if is_static_method(self, did) {
C
corentih 已提交
3140
                        return StaticMethod(path_names_to_string(&path, 0));
3141 3142 3143 3144 3145
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3146 3147
                    }
                }
3148
            }
3149 3150 3151
        }

        // Look for a method in the current trait.
3152 3153 3154
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
            if let Some(&did) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method(self, did) {
3155
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3156 3157
                } else {
                    return TraitItem;
3158 3159 3160 3161 3162 3163 3164
                }
            }
        }

        NoSuggestion
    }

3165
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
3166
        if let Some(macro_name) = self.session.available_macros
3167
                                  .borrow().iter().find(|n| n.as_str() == name) {
3168 3169 3170
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

3171 3172 3173 3174
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
3175

3176
        if let Some(found) = find_best_match_for_name(names, name, None) {
J
Jonas Schievink 已提交
3177
            if name != found {
3178
                return SuggestionType::Function(found);
3179
            }
3180
        } SuggestionType::NotFound
3181 3182
    }

E
Eduard Burtescu 已提交
3183
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3184 3185
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3186 3187 3188

        self.record_candidate_traits_for_expr_if_necessary(expr);

3189
        // Next, resolve the node.
3190
        match expr.node {
3191
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
3192 3193 3194 3195 3196 3197 3198 3199 3200 3201
                let resolution = match self.resolve_possibly_assoc_item(expr.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
                                                                        ValueNS,
                                                                        true) {
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        let method_name = path.segments.last().unwrap().identifier.name;
                        let traits = self.get_traits_containing_item(method_name);
                        self.trait_map.insert(expr.id, traits);
3202
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
3203 3204 3205 3206
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
3207

3208 3209
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3210
                if let Some(path_res) = resolution {
3211
                    // Check if struct variant
3212
                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
3213 3214 3215 3216 3217 3218
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
3219
                        let path_name = path_names_to_string(path, 0);
3220

N
Nick Cameron 已提交
3221 3222
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
3223
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
3224

C
corentih 已提交
3225
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3226 3227
                                          path_name);
                        if self.emit_errors {
N
Nick Cameron 已提交
3228
                            err.fileline_help(expr.span, &msg);
3229
                        } else {
N
Nick Cameron 已提交
3230
                            err.span_help(expr.span, &msg);
3231
                        }
N
Nick Cameron 已提交
3232
                        err.emit();
3233
                        self.record_def(expr.id, err_path_resolution());
3234
                    } else {
3235
                        // Write the result into the def map.
3236
                        debug!("(resolving expr) resolved `{}`",
3237
                               path_names_to_string(path, 0));
3238

3239 3240
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3241
                        if path_res.depth != 0 {
3242
                            let method_name = path.segments.last().unwrap().identifier.name;
3243
                            let traits = self.get_traits_containing_item(method_name);
3244 3245 3246
                            self.trait_map.insert(expr.id, traits);
                        }

3247
                        self.record_def(expr.id, path_res);
3248
                    }
3249 3250 3251 3252 3253
                } 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.)
3254
                    let path_name = path_names_to_string(path, 0);
3255 3256 3257
                    let type_res = self.with_no_errors(|this| {
                        this.resolve_path(expr.id, path, 0, TypeNS, false)
                    });
3258 3259

                    self.record_def(expr.id, err_path_resolution());
3260
                    match type_res.map(|r| r.base_def) {
3261
                        Some(Def::Struct(..)) => {
N
Nick Cameron 已提交
3262 3263
                            let mut err = resolve_struct_error(self,
                                expr.span,
J
Jonas Schievink 已提交
3264
                                ResolutionError::StructVariantUsedAsFunction(&path_name));
3265

C
corentih 已提交
3266 3267 3268
                            let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                              path_name);
                            if self.emit_errors {
N
Nick Cameron 已提交
3269
                                err.fileline_help(expr.span, &msg);
C
corentih 已提交
3270
                            } else {
N
Nick Cameron 已提交
3271
                                err.span_help(expr.span, &msg);
3272
                            }
N
Nick Cameron 已提交
3273
                            err.emit();
C
corentih 已提交
3274
                        }
3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287
                        _ => {
                            // Keep reporting some errors even if they're ignored above.
                            self.resolve_path(expr.id, path, 0, ValueNS, true);

                            let mut method_scope = false;
                            self.value_ribs.iter().rev().all(|rib| {
                                method_scope = match rib.kind {
                                    MethodRibKind => true,
                                    ItemRibKind | ConstantItemRibKind => false,
                                    _ => return true, // Keep advancing
                                };
                                false // Stop advancing
                            });
3288

3289
                            if method_scope && special_names::self_.as_str() == &path_name[..] {
C
corentih 已提交
3290 3291 3292
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3293 3294 3295 3296 3297 3298
                            } 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
3299
                                        match self.find_best_match(&path_name) {
3300 3301 3302 3303 3304 3305
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
3306 3307 3308
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
C
corentih 已提交
3309
                                    TraitItem => format!("to call `self.{}`", path_name),
3310 3311
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
C
corentih 已提交
3312
                                        format!("to call `{}::{}`", path_str, path_name),
3313 3314
                                };

3315
                                let mut context =  UnresolvedNameContext::Other;
3316
                                if !msg.is_empty() {
3317 3318 3319 3320 3321 3322 3323
                                    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<_>>();
3324
                                    let current_module = self.current_module;
3325 3326

                                    match self.resolve_module_path(current_module,
J
Jeffrey Seyfried 已提交
3327 3328 3329
                                                                   &name_path[..],
                                                                   UseLexicalScope,
                                                                   expr.span) {
3330 3331 3332 3333 3334
                                        Success(_) => {
                                            context = UnresolvedNameContext::PathIsMod(expr.id);
                                        },
                                        _ => {},
                                    };
3335
                                }
3336

3337 3338
                                resolve_error(self,
                                              expr.span,
3339
                                              ResolutionError::UnresolvedName(
J
Jonas Schievink 已提交
3340
                                                  &path_name, &msg, context));
3341
                            }
V
Vincent Belliard 已提交
3342
                        }
3343 3344 3345
                    }
                }

3346
                intravisit::walk_expr(self, expr);
3347 3348
            }

3349
            ExprStruct(ref path, _, _) => {
3350 3351 3352
                // 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.
3353
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3354
                    Some(definition) => self.record_def(expr.id, definition),
3355 3356
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3357

3358 3359
                        resolve_error(self,
                                      path.span,
3360
                                      ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
3361
                                                                &path_names_to_string(path, 0))
3362
                                     );
3363
                        self.record_def(expr.id, err_path_resolution());
3364 3365 3366
                    }
                }

3367
                intravisit::walk_expr(self, expr);
3368 3369
            }

P
Pythoner6 已提交
3370
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3371
                self.with_label_rib(|this| {
3372
                    let def_like = DlDef(Def::Label(expr.id));
3373

3374
                    {
3375
                        let rib = this.label_ribs.last_mut().unwrap();
3376
                        rib.bindings.insert(label.name, def_like);
3377
                    }
3378

3379
                    intravisit::walk_expr(this, expr);
3380
                })
3381 3382
            }

3383
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3384
                match self.search_label(label.node.name) {
3385
                    None => {
3386
                        self.record_def(expr.id, err_path_resolution());
3387
                        resolve_error(self,
3388 3389
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3390
                    }
3391
                    Some(DlDef(def @ Def::Label(_))) => {
3392
                        // Since this def is a label, it is never read.
C
corentih 已提交
3393 3394 3395 3396 3397 3398
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            last_private: LastMod(AllPublic),
                                            depth: 0,
                                        })
3399 3400
                    }
                    Some(_) => {
C
corentih 已提交
3401
                        self.session.span_bug(expr.span, "label wasn't mapped to a label def!")
3402 3403 3404 3405
                    }
                }
            }

B
Brian Anderson 已提交
3406
            _ => {
3407
                intravisit::walk_expr(self, expr);
3408 3409 3410 3411
            }
        }
    }

E
Eduard Burtescu 已提交
3412
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3413
        match expr.node {
3414
            ExprField(_, name) => {
3415 3416 3417 3418
                // 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.
3419
                let traits = self.get_traits_containing_item(name.node);
3420
                self.trait_map.insert(expr.id, traits);
3421
            }
3422
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3423
                debug!("(recording candidate traits for expr) recording traits for {}",
3424
                       expr.id);
3425
                let traits = self.get_traits_containing_item(name.node);
3426
                self.trait_map.insert(expr.id, traits);
3427
            }
3428
            _ => {
3429 3430 3431 3432 3433
                // Nothing to do.
            }
        }
    }

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

C
corentih 已提交
3437
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3438
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3439 3440
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3441 3442
            found_traits.push(trait_def_id);
        }
3443

3444
        let mut found_traits = Vec::new();
3445
        let mut search_module = self.current_module;
E
Eduard Burtescu 已提交
3446 3447
        loop {
            // Look for the current trait.
3448 3449
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3450
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3451
                        add_trait_info(&mut found_traits, trait_def_id, name);
3452 3453
                    }
                }
3454
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3455
            }
3456

E
Eduard Burtescu 已提交
3457
            // Look for trait children.
3458
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3459

3460 3461
            search_module.for_each_child(|_, ns, name_binding| {
                if ns != TypeNS { return }
3462 3463
                let trait_def_id = match name_binding.def() {
                    Some(Def::Trait(trait_def_id)) => trait_def_id,
3464
                    Some(..) | None => return,
3465 3466 3467
                };
                if self.trait_item_map.contains_key(&(name, trait_def_id)) {
                    add_trait_info(&mut found_traits, trait_def_id, name);
3468 3469
                    let trait_name = self.get_trait_name(trait_def_id);
                    self.record_use(trait_name, TypeNS, name_binding);
3470
                }
3471
            });
3472

3473 3474 3475 3476 3477 3478 3479 3480 3481 3482
            // Look for shadowed traits.
            for binding in search_module.shadowed_traits.borrow().iter() {
                let did = binding.def().unwrap().def_id();
                if self.trait_item_map.contains_key(&(name, did)) {
                    add_trait_info(&mut found_traits, did, name);
                    let trait_name = self.get_trait_name(did);
                    self.record_use(trait_name, TypeNS, binding);
                }
            }

3483
            match search_module.parent_link {
E
Eduard Burtescu 已提交
3484 3485
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
3486
                    search_module = parent_module;
3487
                }
E
Eduard Burtescu 已提交
3488
            }
3489 3490
        }

E
Eduard Burtescu 已提交
3491
        found_traits
3492 3493
    }

3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586
    /// 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() {
            build_reduced_graph::populate_module_if_necessary(self, &in_module);

            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,
                        };
                        let span = name_binding.span.unwrap_or(syntax::codemap::DUMMY_SP);
                        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)
                        if !in_module_is_extern || name_binding.is_public() {
                            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
                        }
                        _ => unreachable!(),
                    };

                    if !in_module_is_extern || name_binding.is_public() {
                        // add the module to the lookup
                        let is_extern = in_module_is_extern || module.is_extern_crate;
                        worklist.push((module, path_segments, is_extern));
                    }
                }
            })
        }

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

3587 3588
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
C
corentih 已提交
3589 3590 3591 3592
        assert!(match resolution.last_private {
                    LastImport{..} => false,
                    _ => true,
                },
3593
                "Import should only be used for `use` directives");
3594

3595 3596
        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
C
corentih 已提交
3597 3598 3599 3600
            self.session.span_bug(span,
                                  &format!("path resolved multiple times ({:?} before, {:?} now)",
                                           prev_res,
                                           resolution));
3601
        }
3602 3603
    }

F
Felix S. Klock II 已提交
3604
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3605 3606 3607
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3608
        match pat_binding_mode {
3609
            BindByValue(_) => {}
A
Alex Crichton 已提交
3610
            BindByRef(..) => {
3611 3612
                resolve_error(self,
                              pat.span,
3613
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3614 3615 3616
            }
        }
    }
3617 3618
}

3619 3620 3621 3622 3623 3624 3625 3626 3627 3628

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("::")
        }
3629
        result.push_str(&name.as_str());
C
corentih 已提交
3630
    }
3631 3632 3633 3634
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3635
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3636 3637 3638 3639 3640 3641
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702
/// 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,
                    &format!("you can to import it into scope: `use {};`.",
                        &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()),
        );
    };
}

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

3707
    fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
3708 3709 3710 3711
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
3712
                collect_mod(names, module);
3713 3714 3715 3716
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
                names.push(special_idents::opaque.name);
3717
                collect_mod(names, module);
3718 3719 3720 3721 3722
            }
        }
    }
    collect_mod(&mut names, module);

3723
    if names.is_empty() {
3724 3725 3726 3727 3728
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3729 3730
fn err_path_resolution() -> PathResolution {
    PathResolution {
3731
        base_def: Def::Err,
3732 3733 3734 3735 3736
        last_private: LastMod(AllPublic),
        depth: 0,
    }
}

3737

3738
pub struct CrateMap {
J
Jonathan S 已提交
3739
    pub def_map: RefCell<DefMap>,
3740
    pub freevars: FreevarMap,
3741
    pub export_map: ExportMap,
3742 3743
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
C
corentih 已提交
3744
    pub glob_map: Option<GlobMap>,
3745 3746
}

N
Niko Matsakis 已提交
3747
#[derive(PartialEq,Copy, Clone)]
3748 3749
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3750
    No,
3751 3752
}

3753
/// Entry point to crate resolution.
3754
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3755
                               ast_map: &'a hir_map::Map<'tcx>,
3756 3757
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3758 3759 3760 3761 3762 3763 3764 3765 3766
    // 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);

3767
    let krate = ast_map.krate();
3768 3769
    let arenas = Resolver::arenas();
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
3770 3771 3772 3773 3774

    resolver.resolve_crate(krate);

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

3775
    CrateMap {
3776 3777
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3778
        export_map: resolver.export_map,
3779 3780
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
3781
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
3782 3783 3784 3785
            Some(resolver.glob_map)
        } else {
            None
        },
3786
    }
3787
}
3788

3789 3790 3791 3792 3793 3794 3795 3796
/// Builds a name resolution walker to be used within this module,
/// or used externally, with an optional callback function.
///
/// The callback takes a &mut bool which allows callbacks to end a
/// walk when set to true, passing through the rest of the walk, while
/// preserving the ribs + current module. This allows resolve_path
/// calls to be made with the correct scope info. The node in the
/// callback corresponds to the current node in the walk.
G
Garming Sam 已提交
3797
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
3798
                                 ast_map: &'a hir_map::Map<'tcx>,
G
Garming Sam 已提交
3799 3800
                                 krate: &'a Crate,
                                 make_glob_map: MakeGlobMap,
3801
                                 arenas: &'a ResolverArenas<'a>,
3802
                                 callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
G
Garming Sam 已提交
3803
                                 -> Resolver<'a, 'tcx> {
3804
    let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
G
Garming Sam 已提交
3805 3806 3807 3808 3809 3810 3811 3812 3813 3814

    resolver.callback = callback;

    build_reduced_graph::build_reduced_graph(&mut resolver, krate);

    resolve_imports::resolve_imports(&mut resolver);

    resolver
}

3815
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }