lib.rs 150.9 KB
Newer Older
1
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

11
#![crate_name = "rustc_resolve"]
12
#![unstable(feature = "rustc_private", issue = "27812")]
13 14
#![crate_type = "dylib"]
#![crate_type = "rlib"]
15
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
16
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
17
      html_root_url = "https://doc.rust-lang.org/nightly/")]
18
#![cfg_attr(not(stage0), deny(warnings))]
19

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

659
impl<T> ResolveResult<T> {
660 661 662 663 664
    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 已提交
665
        }
666
    }
667 668 669 670 671 672 673

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

676 677 678 679
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
680
    TraitItem,
681
    StaticMethod(String),
682
    TraitMethod(String),
683 684
}

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

C
corentih 已提交
691 692 693
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
694

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

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

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

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

716 717
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
718 719

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

722 723
    // We passed through a module.
    ModuleRibKind(Module<'a>),
724 725
}

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

732
enum ModulePrefixResult<'a> {
733
    NoPrefixFound,
734
    PrefixFound(Module<'a>, usize),
735 736
}

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

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

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

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

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

784 785 786 787 788
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
    LocalDef(LocalDef),
}

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

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

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

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

817
/// One node in the tree of modules.
818 819
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
J
Jeffrey Seyfried 已提交
820
    def: Option<Def>,
821
    vis: ty::Visibility,
822

823 824 825
    // If the module is an extern crate, `def` is root of the external crate and `extern_crate_id`
    // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
    extern_crate_id: Option<NodeId>,
826

827
    resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
828
    unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
829

830 831 832
    // 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.
833 834 835 836 837 838 839 840 841 842 843
    //
    // 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`.
844
    module_children: RefCell<NodeMap<Module<'a>>>,
845

846
    prelude: RefCell<Option<Module<'a>>>,
847

848
    glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
849
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
850

851 852 853
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
854
    populated: Cell<bool>,
855 856

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

859 860 861
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
862 863 864
    fn new(parent_link: ParentLink<'a>,
           def: Option<Def>,
           external: bool,
865
           vis: ty::Visibility,
866
           arenas: &'a ResolverArenas<'a>) -> Self {
867
        ModuleS {
868
            parent_link: parent_link,
J
Jeffrey Seyfried 已提交
869
            def: def,
870
            vis: vis,
871
            extern_crate_id: None,
872
            resolutions: RefCell::new(HashMap::new()),
873
            unresolved_imports: RefCell::new(Vec::new()),
874
            module_children: RefCell::new(NodeMap()),
875
            prelude: RefCell::new(None),
876
            glob_importers: RefCell::new(Vec::new()),
877
            globs: RefCell::new((Vec::new())),
878
            populated: Cell::new(!external),
879
            arenas: arenas
880
        }
B
Brian Anderson 已提交
881 882
    }

883
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
884
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
885
            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
886 887 888
        }
    }

889
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
890
        self.def.as_ref().map(Def::def_id)
891 892
    }

893
    // `self` resolves to the first module ancestor that `is_normal`.
894
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
895
        match self.def {
896
            Some(Def::Mod(_)) => true,
897 898 899 900 901
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
902
        match self.def {
903
            Some(Def::Trait(_)) => true,
904
            _ => false,
905
        }
B
Brian Anderson 已提交
906
    }
V
Victor Berger 已提交
907 908
}

909
impl<'a> fmt::Debug for ModuleS<'a> {
910
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
911
        write!(f, "{:?}, {:?}", self.def, self.vis)
912 913 914
    }
}

915
// Records a possibly-private value, type, or module definition.
916
#[derive(Clone, Debug)]
917
pub struct NameBinding<'a> {
918
    kind: NameBindingKind<'a>,
919
    span: Option<Span>,
920
    vis: ty::Visibility,
921 922
}

923
#[derive(Clone, Debug)]
924
enum NameBindingKind<'a> {
925
    Def(Def),
926
    Module(Module<'a>),
927 928
    Import {
        binding: &'a NameBinding<'a>,
929
        directive: &'a ImportDirective<'a>,
930 931
        // Some(error) if using this imported name causes the import to be a privacy error
        privacy_error: Option<Box<PrivacyError<'a>>>,
932
    },
933 934
}

935 936 937
#[derive(Clone, Debug)]
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

938
impl<'a> NameBinding<'a> {
939
    fn create_from_module(module: Module<'a>, span: Option<Span>) -> Self {
940 941 942 943 944
        NameBinding {
            kind: NameBindingKind::Module(module),
            span: span,
            vis: module.vis,
        }
945 946
    }

947
    fn module(&self) -> Option<Module<'a>> {
948 949 950 951
        match self.kind {
            NameBindingKind::Module(module) => Some(module),
            NameBindingKind::Def(_) => None,
            NameBindingKind::Import { binding, .. } => binding.module(),
952 953 954
        }
    }

955
    fn def(&self) -> Option<Def> {
956 957 958 959
        match self.kind {
            NameBindingKind::Def(def) => Some(def),
            NameBindingKind::Module(module) => module.def,
            NameBindingKind::Import { binding, .. } => binding.def(),
960
        }
961
    }
962

963 964 965 966 967 968 969 970 971 972 973 974 975 976
    fn is_pseudo_public(&self) -> bool {
        self.pseudo_vis() == ty::Visibility::Public
    }

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

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

979
    fn is_extern_crate(&self) -> bool {
980
        self.module().and_then(|module| module.extern_crate_id).is_some()
981
    }
982 983 984 985 986 987 988

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002

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

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

1005
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1006
struct PrimitiveTypeTable {
1007
    primitive_types: HashMap<Name, PrimTy>,
1008
}
1009

1010
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1011
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
1012 1013 1014 1015
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
1016 1017
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
1018 1019 1020 1021 1022
        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 已提交
1023
        table.intern("str", TyStr);
1024 1025 1026 1027 1028
        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 已提交
1029 1030 1031 1032

        table
    }

1033
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1034
        self.primitive_types.insert(token::intern(string), primitive_type);
1035 1036 1037
    }
}

1038
/// The main resolver class.
C
corentih 已提交
1039
pub struct Resolver<'a, 'tcx: 'a> {
E
Eduard Burtescu 已提交
1040
    session: &'a Session,
1041

1042
    ast_map: &'a hir_map::Map<'tcx>,
1043

1044
    graph_root: Module<'a>,
1045

1046
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1047

1048
    structs: FnvHashMap<DefId, Vec<Name>>,
1049

1050
    // The number of imports that are currently unresolved.
1051
    unresolved_imports: usize,
1052 1053

    // The module that represents the current item scope.
1054
    current_module: Module<'a>,
1055 1056

    // The current set of local scopes, for values.
1057
    // FIXME #4948: Reuse ribs to avoid allocation.
1058
    value_ribs: Vec<Rib<'a>>,
1059 1060

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

1063
    // The current set of local scopes, for labels.
1064
    label_ribs: Vec<Rib<'a>>,
1065

1066
    // The trait that the current context can refer to.
1067 1068 1069 1070
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1072
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1073
    primitive_type_table: PrimitiveTypeTable,
1074

J
Jonathan S 已提交
1075
    def_map: RefCell<DefMap>,
1076 1077
    freevars: FreevarMap,
    freevars_seen: NodeMap<NodeMap<usize>>,
1078
    export_map: ExportMap,
1079
    trait_map: TraitMap,
1080

1081 1082 1083 1084 1085
    // 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,

1086 1087 1088 1089 1090
    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,

1091
    used_imports: HashSet<(NodeId, Namespace)>,
1092
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1093 1094

    // Callback function for intercepting walks
1095
    callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>,
G
Garming Sam 已提交
1096 1097 1098
    // The intention is that the callback modifies this flag.
    // Once set, the resolver falls out of the walk, preserving the ribs.
    resolved: bool,
1099
    privacy_errors: Vec<PrivacyError<'a>>,
1100 1101 1102 1103

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

J
Jeffrey Seyfried 已提交
1104
struct ResolverArenas<'a> {
1105
    modules: arena::TypedArena<ModuleS<'a>>,
1106
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1107
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1108
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1109 1110 1111
}

impl<'a> ResolverArenas<'a> {
1112 1113 1114 1115 1116 1117
    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
        self.modules.alloc(module)
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1118 1119
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1120 1121
        self.import_directives.alloc(import_directive)
    }
1122 1123 1124
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1125 1126
}

1127
#[derive(PartialEq)]
S
Steven Fackler 已提交
1128 1129
enum FallbackChecks {
    Everything,
C
corentih 已提交
1130
    OnlyTraitAndStatics,
S
Steven Fackler 已提交
1131 1132
}

1133 1134
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
1135
           ast_map: &'a hir_map::Map<'tcx>,
1136 1137
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
C
corentih 已提交
1138
           -> Resolver<'a, 'tcx> {
1139
        let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
1140
        let vis = ty::Visibility::Public;
1141
        let graph_root =
1142
            ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, vis, arenas);
1143
        let graph_root = arenas.alloc_module(graph_root);
K
Kevin Butler 已提交
1144 1145 1146 1147

        Resolver {
            session: session,

1148 1149
            ast_map: ast_map,

K
Kevin Butler 已提交
1150 1151
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1152
            graph_root: graph_root,
K
Kevin Butler 已提交
1153

1154 1155
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1156 1157 1158

            unresolved_imports: 0,

1159
            current_module: graph_root,
1160 1161
            value_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
            type_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
1162
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1163 1164 1165 1166 1167 1168

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1169
            def_map: RefCell::new(NodeMap()),
1170 1171
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1172 1173
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1174
            used_imports: HashSet::new(),
1175
            used_crates: HashSet::new(),
K
Kevin Butler 已提交
1176 1177

            emit_errors: true,
1178
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1179
            glob_map: NodeMap(),
G
Garming Sam 已提交
1180 1181 1182

            callback: None,
            resolved: false,
1183
            privacy_errors: Vec::new(),
1184 1185 1186 1187 1188 1189 1190 1191

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
1192
            name_bindings: arena::TypedArena::new(),
1193
            import_directives: arena::TypedArena::new(),
1194
            name_resolutions: arena::TypedArena::new(),
K
Kevin Butler 已提交
1195 1196
        }
    }
1197

1198 1199 1200 1201
    fn new_module(&self,
                  parent_link: ParentLink<'a>,
                  def: Option<Def>,
                  external: bool,
1202 1203
                  vis: ty::Visibility) -> Module<'a> {
        self.arenas.alloc_module(ModuleS::new(parent_link, def, external, vis, self.arenas))
1204 1205
    }

1206 1207 1208
    fn new_extern_crate_module(&self,
                               parent_link: ParentLink<'a>,
                               def: Def,
1209
                               vis: ty::Visibility,
1210
                               local_node_id: NodeId)
1211
                               -> Module<'a> {
1212
        let mut module = ModuleS::new(parent_link, Some(def), false, vis, self.arenas);
1213
        module.extern_crate_id = Some(local_node_id);
1214 1215 1216
        self.arenas.modules.alloc(module)
    }

1217 1218 1219 1220
    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 }
    }

1221
    #[inline]
1222 1223 1224 1225 1226 1227
    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);
        }

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

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

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

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

    fn get_trait_name(&self, did: DefId) -> Name {
1253 1254
        if let Some(node_id) = self.ast_map.as_local_node_id(did) {
            self.ast_map.expect_item(node_id).name
1255
        } else {
1256
            self.session.cstore.item_name(did)
1257 1258 1259
        }
    }

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

1279
        let mut search_module = module_;
1280
        let mut index = index;
A
Alex Crichton 已提交
1281
        let module_path_len = module_path.len();
1282 1283 1284 1285 1286

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

C
corentih 已提交
1296
                        match search_parent_externals(name, &self.current_module) {
1297
                            Some(module) => {
1298
                                let path_str = names_to_string(module_path);
J
Jonas Schievink 已提交
1299 1300
                                let target_mod_str = module_to_string(&module);
                                let current_mod_str = module_to_string(&self.current_module);
1301 1302 1303 1304 1305 1306 1307

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

1308
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1309 1310
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1311
                        }
1312
                    } else {
C
corentih 已提交
1313
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1314
                    };
1315

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

T
Tim Chevalier 已提交
1338
            index += 1;
1339 1340
        }

J
Jeffrey Seyfried 已提交
1341
        return Success(search_module);
1342 1343
    }

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

1355
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1356
               names_to_string(module_path),
1357
               module_to_string(self.current_module));
1358

1359
        // Resolve the module prefix, if any.
1360
        let module_prefix_result = self.resolve_module_prefix(module_path, span);
1361

1362 1363
        let search_module;
        let start_index;
1364
        match module_prefix_result {
1365
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1366
            Indeterminate => {
C
corentih 已提交
1367
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1368
                return Indeterminate;
1369
            }
1370 1371 1372 1373 1374 1375 1376 1377
            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.
1378
                        search_module = self.graph_root;
1379 1380 1381 1382 1383 1384
                        start_index = 0;
                    }
                    UseLexicalScope => {
                        // This is not a crate-relative path. We resolve the
                        // first component of the path in the current lexical
                        // scope and then proceed to resolve below that.
1385 1386 1387 1388 1389 1390 1391
                        let ident = hir::Ident::from_name(module_path[0]);
                        match self.resolve_ident_in_lexical_scope(ident, TypeNS, true)
                                  .and_then(LexicalScopeBinding::module) {
                            None => return Failed(None),
                            Some(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1392 1393 1394 1395 1396
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1397
            Success(PrefixFound(ref containing_module, index)) => {
1398
                search_module = containing_module;
1399
                start_index = index;
1400 1401 1402
            }
        }

1403 1404 1405
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
J
Jeffrey Seyfried 已提交
1406
                                           span)
1407 1408
    }

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

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

1443 1444 1445 1446 1447 1448
            if let ModuleRibKind(module) = self.get_ribs(ns)[i].kind {
                let name = ident.unhygienic_name;
                let item = self.resolve_name_in_module(module, name, ns, true, record_used);
                if let Success(binding) = item {
                    // The ident resolves to an item.
                    return Some(LexicalScopeBinding::Item(binding));
1449
                }
1450

1451
                // We can only see through anonymous modules
1452
                if module.def.is_some() { return None; }
1453 1454
            }
        }
1455

1456 1457 1458
        None
    }

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

1477 1478
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1479
    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
1480 1481 1482
        if module_.is_normal() {
            return module_;
        }
1483
        match self.get_nearest_normal_module_parent(module_) {
1484 1485
            None => module_,
            Some(new_module) => new_module,
1486 1487 1488
        }
    }

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

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

1520
        debug!("(resolving module prefix) finished resolving prefix at {}",
J
Jonas Schievink 已提交
1521
               module_to_string(&containing_module));
1522 1523

        return Success(PrefixFound(containing_module, i));
1524 1525
    }

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

1538
        self.populate_module_if_necessary(module);
1539 1540 1541 1542 1543
        match use_lexical_scope {
            true => module.resolve_name_in_lexical_scope(name, namespace)
                          .map(Success).unwrap_or(Failed(None)),
            false => module.resolve_name(name, namespace, false),
        }.and_then(|binding| {
1544 1545
            if record_used {
                self.record_use(name, namespace, binding);
1546
            }
1547 1548
            Success(binding)
        })
1549 1550 1551 1552
    }

    // AST resolution
    //
1553
    // We maintain a list of value ribs and type ribs.
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
    //
    // 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.

1569
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1570
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1571
    {
1572 1573 1574 1575 1576
        if let Some(module) = self.current_module.module_children.borrow().get(&id) {
            // Move down in the graph.
            let orig_module = ::std::mem::replace(&mut self.current_module, module);
            self.value_ribs.push(Rib::new(ModuleRibKind(module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(module)));
1577

1578
            f(self);
1579

1580 1581 1582 1583 1584 1585
            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
1586 1587
    }

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

1609
    fn resolve_crate(&mut self, krate: &hir::Crate) {
1610
        debug!("(resolving crate) starting");
1611
        self.current_module = self.graph_root;
1612
        intravisit::walk_crate(self, krate);
1613 1614
    }

1615
    fn resolve_item(&mut self, item: &Item) {
V
Vadim Petrochenkov 已提交
1616
        let name = item.name;
1617

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

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

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

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

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

1688
            ItemMod(_) | ItemForeignMod(_) => {
1689
                self.with_scope(item.id, |this| {
1690
                    intravisit::walk_item(this, item);
1691
                });
1692 1693
            }

1694
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
1695
                self.with_constant_rib(|this| {
1696
                    intravisit::walk_item(this, item);
1697
                });
1698
            }
1699

W
we 已提交
1700
            ItemUse(ref view_path) => {
1701
                match view_path.node {
1702 1703 1704 1705 1706 1707
                    hir::ViewPathList(ref prefix, ref items) => {
                        // Resolve prefix of an import with empty braces (issue #28388)
                        if items.is_empty() && !prefix.segments.is_empty() {
                            match self.resolve_crate_relative_path(prefix.span,
                                                                   &prefix.segments,
                                                                   TypeNS) {
1708
                                Ok(def) =>
J
Jeffrey Seyfried 已提交
1709
                                    self.record_def(item.id, PathResolution::new(def, 0)),
1710 1711
                                Err(true) => self.record_def(item.id, err_path_resolution()),
                                Err(false) => {
1712 1713 1714 1715
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
1716
                                    self.record_def(item.id, err_path_resolution());
1717
                                }
1718 1719 1720 1721
                            }
                        }
                    }
                    _ => {}
W
we 已提交
1722 1723 1724
                }
            }

1725
            ItemExternCrate(_) => {
1726
                // do nothing, these are just around to be encoded
1727
            }
1728 1729 1730
        }
    }

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

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

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

B
Brian Anderson 已提交
1757
            NoTypeParameters => {
1758 1759 1760 1761
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1762
        f(self);
1763

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

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

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

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

1800
        // Create a label rib for the function.
1801
        self.label_ribs.push(Rib::new(rib_kind));
1802

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

J
Jonas Schievink 已提交
1808
            self.visit_ty(&argument.ty);
1809

1810 1811
            debug!("(resolving function) recorded argument");
        }
1812
        intravisit::walk_fn_ret_ty(self, &declaration.output);
1813

1814
        // Resolve the function body.
1815
        self.visit_block(block);
1816

1817
        debug!("(resolving function) leaving function");
1818

G
Garming Sam 已提交
1819 1820 1821 1822
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
1823 1824
    }

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

                // If it's a typedef, give a note
V
vegai 已提交
1842
                if let Def::TyAlias(did) = path_res.base_def {
V
vegai 已提交
1843
                    err.fileline_note(trait_path.span,
N
Nick Cameron 已提交
1844
                                  "`type` aliases cannot be used for traits");
V
vegai 已提交
1845 1846 1847
                    if let Some(sp) = self.ast_map.span_if_local(did) {
                        err.span_note(sp, "type defined here");
                    }
1848
                }
N
Nick Cameron 已提交
1849
                err.emit();
1850
                Err(true)
1851
            }
1852 1853
        }).map_err(|error_reported| {
            if error_reported { return }
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875

            // 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);
1876
        })
1877 1878
    }

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

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

1937 1938 1939 1940 1941 1942 1943
    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;
1944
        self_type_rib.bindings.insert(name, self_def);
1945 1946
        self.type_ribs.push(self_type_rib);
        f(self);
G
Garming Sam 已提交
1947 1948 1949
        if !self.resolved {
            self.type_ribs.pop();
        }
1950 1951
    }

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

1966
            // Resolve the trait reference, if necessary.
1967
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
1968
                // Resolve the self type.
1969
                this.visit_ty(self_type);
1970

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

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

2010 2011
                                    this.visit_ty(ty);
                                }
2012
                            }
2013
                        }
2014
                    });
2015 2016
                });
            });
2017
        });
2018 2019
    }

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

E
Eduard Burtescu 已提交
2033
    fn resolve_local(&mut self, local: &Local) {
2034
        // Resolve the type.
2035
        walk_list!(self, visit_ty, &local.ty);
2036

2037
        // Resolve the initializer.
2038
        walk_list!(self, visit_expr, &local.init);
2039 2040

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

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

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

2071
            for (&key, &binding_0) in &map_0 {
2072
                match map_i.get(&key) {
C
corentih 已提交
2073
                    None => {
2074
                        resolve_error(self,
C
corentih 已提交
2075 2076 2077 2078 2079 2080 2081 2082 2083 2084
                                      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));
                        }
2085
                    }
2086 2087 2088
                }
            }

2089
            for (&key, &binding) in &map_i {
2090
                if !map_0.contains_key(&key) {
2091 2092
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2093
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2094 2095 2096
                }
            }
        }
2097 2098
    }

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

2102
        let mut bindings_list = HashMap::new();
2103
        for pattern in &arm.pats {
J
Jonas Schievink 已提交
2104
            self.resolve_pattern(&pattern, RefutableMode, &mut bindings_list);
2105 2106
        }

2107 2108 2109 2110
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2111
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2112
        self.visit_expr(&arm.body);
2113

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

E
Eduard Burtescu 已提交
2119
    fn resolve_block(&mut self, block: &Block) {
2120
        debug!("(resolving block) entering block");
2121
        // Move down in the graph, if there's an anonymous module rooted here.
2122
        let orig_module = self.current_module;
2123
        let anonymous_module =
2124
            orig_module.module_children.borrow().get(&block.id).map(|module| *module);
2125 2126 2127

        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
2128 2129
            self.value_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
2130 2131 2132
            self.current_module = anonymous_module;
        } else {
            self.value_ribs.push(Rib::new(NormalRibKind));
2133 2134 2135
        }

        // Descend into the block.
2136
        intravisit::walk_block(self, block);
2137 2138

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

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

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

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

2185
                        let self_type_name = special_idents::type_self.name;
C
corentih 已提交
2186 2187 2188 2189
                        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 已提交
2190
                        if is_invalid_self_type_name {
2191 2192
                            resolve_error(self,
                                          ty.span,
2193
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2194
                        } else {
2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
                            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 已提交
2222
                        }
2223 2224
                    }
                }
2225
            }
2226
            _ => {}
2227
        }
2228
        // Resolve embedded types.
2229
        intravisit::walk_ty(self, ty);
2230 2231
    }

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

2252
                    let ident = path1.node;
2253
                    let renamed = ident.name;
2254

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

C
corentih 已提交
2260 2261 2262 2263 2264 2265 2266 2267
                            self.enforce_default_binding_mode(pattern,
                                                              binding_mode,
                                                              "an enum variant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2268
                        }
A
Alex Crichton 已提交
2269
                        FoundStructOrEnumVariant(..) => {
2270
                            resolve_error(
2271
                                self,
2272
                                pattern.span,
2273
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2274 2275
                                    renamed)
                            );
2276
                            self.record_def(pattern.id, err_path_resolution());
2277
                        }
J
Jeffrey Seyfried 已提交
2278
                        FoundConst(def, _) if const_ok => {
C
corentih 已提交
2279 2280 2281 2282 2283 2284 2285 2286
                            debug!("(resolving pattern) resolving `{}` to constant", renamed);

                            self.enforce_default_binding_mode(pattern, binding_mode, "a constant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2287
                        }
J
Jeffrey Seyfried 已提交
2288
                        FoundConst(def, name) => {
2289
                            resolve_error(
2290 2291
                                self,
                                pattern.span,
M
Manish Goregaokar 已提交
2292 2293
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
                                                                                    name)
2294
                            );
2295
                            self.record_def(pattern.id, err_path_resolution());
2296
                        }
2297
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2298
                            debug!("(resolving pattern) binding `{}`", renamed);
2299

2300
                            let def_id = self.ast_map.local_def_id(pattern.id);
2301
                            let def = Def::Local(def_id, pattern.id);
2302 2303 2304 2305 2306

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

C
corentih 已提交
2307 2308 2309 2310 2311
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2312 2313 2314 2315 2316 2317

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

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

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

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

2494
                PatKind::Lit(_) | PatKind::Range(..) => {
2495
                    intravisit::walk_pat(self, pattern);
2496 2497
                }

2498
                _ => {
2499 2500 2501
                    // Nothing to do.
                }
            }
2502
            true
2503
        });
2504 2505
    }

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

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

2533
        match maybe_qself {
2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544
            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();
            }
2545 2546 2547
        }

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

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

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

2574
        if path.global {
2575
            let def = self.resolve_crate_relative_path(span, segments, namespace);
2576
            return def.map(mk_res);
2577 2578
        }

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

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

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

        def.map(mk_res)
2625 2626
    }

2627
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2628
    fn resolve_identifier(&mut self,
2629
                          identifier: hir::Ident,
2630
                          namespace: Namespace,
2631
                          record_used: bool)
2632
                          -> Option<LocalDef> {
2633
        if identifier.name == special_idents::invalid.name {
2634
            return Some(LocalDef::from_def(Def::Err));
2635 2636
        }

2637 2638
        self.resolve_ident_in_lexical_scope(identifier, namespace, record_used)
            .map(LexicalScopeBinding::local_def)
2639 2640 2641
    }

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

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

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

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

J
Jonas Schievink 已提交
2755
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2756
                return Err(true);
2757
            }
2758
            Indeterminate => return Err(false),
J
Jeffrey Seyfried 已提交
2759
            Success(resulting_module) => {
2760 2761 2762 2763
                containing_module = resulting_module;
            }
        }

2764
        let name = segments.last().unwrap().identifier.name;
2765
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2766
        result.success().map(|binding| {
2767
            self.check_privacy(name, binding, span);
2768
            binding.def().unwrap()
2769
        }).ok_or(false)
2770 2771
    }

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

2786
        let root_module = self.graph_root;
2787

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

J
Jonas Schievink 已提交
2803
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2804
                return Err(true);
2805 2806
            }

2807
            Indeterminate => return Err(false),
2808

J
Jeffrey Seyfried 已提交
2809
            Success(resulting_module) => {
2810 2811 2812 2813
                containing_module = resulting_module;
            }
        }

2814
        let name = segments.last().unwrap().identifier.name;
J
Jeffrey Seyfried 已提交
2815
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2816
        result.success().map(|binding| {
2817
            self.check_privacy(name, binding, span);
2818
            binding.def().unwrap()
2819
        }).ok_or(false)
2820 2821
    }

C
corentih 已提交
2822 2823
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2824
    {
2825
        self.emit_errors = false;
A
Alex Crichton 已提交
2826
        let rs = f(self);
2827 2828 2829 2830
        self.emit_errors = true;
        rs
    }

2831
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
C
corentih 已提交
2832 2833 2834
        fn extract_path_and_node_id(t: &Ty,
                                    allow: FallbackChecks)
                                    -> Option<(Path, NodeId, FallbackChecks)> {
2835
            match t.node {
2836
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
J
Jonas Schievink 已提交
2837 2838
                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),
2839 2840 2841 2842 2843 2844 2845
                // 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,
            }
        }

2846 2847 2848 2849
        fn get_module<'a, 'tcx>(this: &mut Resolver<'a, 'tcx>,
                                span: Span,
                                name_path: &[ast::Name])
                                -> Option<Module<'a>> {
2850
            let last_name = name_path.last().unwrap();
2851

2852
            if name_path.len() == 1 {
2853
                match this.primitive_type_table.primitive_types.get(last_name) {
2854
                    Some(_) => None,
2855
                    None => this.current_module.resolve_name_in_lexical_scope(*last_name, TypeNS)
2856
                                               .and_then(NameBinding::module)
2857 2858
                }
            } else {
2859
                this.resolve_module_path(&name_path, UseLexicalScope, span).success()
2860 2861 2862
            }
        }

2863
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
2864 2865
            if let Some(node_id) = this.ast_map.as_local_node_id(did) {
                let sig = match this.ast_map.get(node_id) {
2866 2867
                    hir_map::NodeTraitItem(trait_item) => match trait_item.node {
                        hir::MethodTraitItem(ref sig, _) => sig,
C
corentih 已提交
2868
                        _ => return false,
2869
                    },
2870
                    hir_map::NodeImplItem(impl_item) => match impl_item.node {
2871
                        hir::ImplItemKind::Method(ref sig, _) => sig,
C
corentih 已提交
2872
                        _ => return false,
2873
                    },
C
corentih 已提交
2874
                    _ => return false,
2875
                };
2876
                sig.explicit_self.node == hir::SelfStatic
2877
            } else {
2878
                this.session.cstore.is_static_method(did)
2879 2880 2881
            }
        }

2882 2883 2884 2885
        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,
2886 2887 2888 2889
            },
            None => return NoSuggestion,
        };

2890 2891
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
2892
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
2893 2894 2895 2896
                Some(Def::Enum(did)) |
                Some(Def::TyAlias(did)) |
                Some(Def::Struct(did)) |
                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
2897 2898 2899 2900 2901
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
2902
                    }
2903 2904 2905
                },
                _ => {} // Self type didn't resolve properly
            }
2906 2907
        }

2908
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
2909 2910

        // Look for a method in the current self type's impl module.
2911
        if let Some(module) = get_module(self, path.span, &name_path) {
2912
            if let Some(binding) = module.resolve_name_in_lexical_scope(name, ValueNS) {
2913
                if let Some(Def::Method(did)) = binding.def() {
2914
                    if is_static_method(self, did) {
C
corentih 已提交
2915
                        return StaticMethod(path_names_to_string(&path, 0));
2916 2917 2918 2919 2920
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
2921 2922
                    }
                }
2923
            }
2924 2925 2926
        }

        // Look for a method in the current trait.
2927 2928 2929
        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) {
2930
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
2931 2932
                } else {
                    return TraitItem;
2933 2934 2935 2936 2937 2938 2939
                }
            }
        }

        NoSuggestion
    }

2940
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
2941
        if let Some(macro_name) = self.session.available_macros
2942
                                  .borrow().iter().find(|n| n.as_str() == name) {
2943 2944 2945
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

2946 2947 2948 2949
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
2950

2951
        if let Some(found) = find_best_match_for_name(names, name, None) {
J
Jonas Schievink 已提交
2952
            if name != found {
2953
                return SuggestionType::Function(found);
2954
            }
2955
        } SuggestionType::NotFound
2956 2957
    }

E
Eduard Burtescu 已提交
2958
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
2959 2960
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
2961 2962 2963

        self.record_candidate_traits_for_expr_if_necessary(expr);

2964
        // Next, resolve the node.
2965
        match expr.node {
2966
            ExprPath(ref maybe_qself, ref path) => {
C
corentih 已提交
2967 2968 2969
                let resolution = match self.resolve_possibly_assoc_item(expr.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
J
Jeffrey Seyfried 已提交
2970
                                                                        ValueNS) {
C
corentih 已提交
2971 2972 2973 2974 2975
                    // `<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);
2976
                        intravisit::walk_expr(self, expr);
C
corentih 已提交
2977 2978 2979 2980
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2981

2982 2983
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
2984
                if let Some(path_res) = resolution {
2985
                    // Check if struct variant
2986
                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
2987 2988 2989 2990 2991 2992
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
2993
                        let path_name = path_names_to_string(path, 0);
2994

N
Nick Cameron 已提交
2995 2996
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
2997
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
2998

C
corentih 已提交
2999
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
3000 3001
                                          path_name);
                        if self.emit_errors {
N
Nick Cameron 已提交
3002
                            err.fileline_help(expr.span, &msg);
3003
                        } else {
N
Nick Cameron 已提交
3004
                            err.span_help(expr.span, &msg);
3005
                        }
N
Nick Cameron 已提交
3006
                        err.emit();
3007
                        self.record_def(expr.id, err_path_resolution());
3008
                    } else {
3009
                        // Write the result into the def map.
3010
                        debug!("(resolving expr) resolved `{}`",
3011
                               path_names_to_string(path, 0));
3012

3013 3014
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3015
                        if path_res.depth != 0 {
3016
                            let method_name = path.segments.last().unwrap().identifier.name;
3017
                            let traits = self.get_traits_containing_item(method_name);
3018 3019 3020
                            self.trait_map.insert(expr.id, traits);
                        }

3021
                        self.record_def(expr.id, path_res);
3022
                    }
3023 3024 3025 3026 3027
                } 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.)
3028
                    let path_name = path_names_to_string(path, 0);
3029
                    let type_res = self.with_no_errors(|this| {
J
Jeffrey Seyfried 已提交
3030
                        this.resolve_path(expr.id, path, 0, TypeNS)
3031
                    });
3032 3033

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

3035
                    if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
J
Jeffrey Seyfried 已提交
3036 3037
                        let error_variant =
                            ResolutionError::StructVariantUsedAsFunction(&path_name);
3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053
                        let mut err = resolve_struct_error(self, expr.span, error_variant);

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

                        if self.emit_errors {
                            err.fileline_help(expr.span, &msg);
                        } else {
                            err.span_help(expr.span, &msg);
                        }
                        err.emit();
                    } else {
                        // Keep reporting some errors even if they're ignored above.
                        if let Err(true) = self.resolve_path(expr.id, path, 0, ValueNS) {
                            // `resolve_path` already reported the error
                        } else {
3054 3055 3056 3057 3058 3059 3060 3061 3062
                            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
                            });
3063

3064
                            if method_scope && special_names::self_.as_str() == &path_name[..] {
C
corentih 已提交
3065 3066 3067
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
3068 3069 3070 3071 3072 3073
                            } 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
3074
                                        match self.find_best_match(&path_name) {
3075 3076 3077 3078 3079 3080
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
3081 3082 3083
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
C
corentih 已提交
3084
                                    TraitItem => format!("to call `self.{}`", path_name),
3085 3086
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
C
corentih 已提交
3087
                                        format!("to call `{}::{}`", path_str, path_name),
3088 3089
                                };

3090
                                let mut context =  UnresolvedNameContext::Other;
3091
                                if !msg.is_empty() {
3092 3093 3094 3095 3096 3097 3098 3099
                                    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<_>>();

3100
                                    match self.resolve_module_path(&name_path[..],
J
Jeffrey Seyfried 已提交
3101 3102
                                                                   UseLexicalScope,
                                                                   expr.span) {
3103 3104 3105 3106 3107
                                        Success(_) => {
                                            context = UnresolvedNameContext::PathIsMod(expr.id);
                                        },
                                        _ => {},
                                    };
3108
                                }
3109

3110 3111
                                resolve_error(self,
                                              expr.span,
3112
                                              ResolutionError::UnresolvedName(
J
Jonas Schievink 已提交
3113
                                                  &path_name, &msg, context));
3114
                            }
V
Vincent Belliard 已提交
3115
                        }
3116 3117 3118
                    }
                }

3119
                intravisit::walk_expr(self, expr);
3120 3121
            }

3122
            ExprStruct(ref path, _, _) => {
3123 3124 3125
                // Resolve the path to the structure it goes to. We don't
                // check to ensure that the path is actually a structure; that
                // is checked later during typeck.
J
Jeffrey Seyfried 已提交
3126
                match self.resolve_path(expr.id, path, 0, TypeNS) {
3127 3128 3129
                    Ok(definition) => self.record_def(expr.id, definition),
                    Err(true) => self.record_def(expr.id, err_path_resolution()),
                    Err(false) => {
3130
                        debug!("(resolving expression) didn't find struct def",);
3131

3132 3133
                        resolve_error(self,
                                      path.span,
3134
                                      ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
3135
                                                                &path_names_to_string(path, 0))
3136
                                     );
3137
                        self.record_def(expr.id, err_path_resolution());
3138 3139 3140
                    }
                }

3141
                intravisit::walk_expr(self, expr);
3142 3143
            }

P
Pythoner6 已提交
3144
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3145
                self.with_label_rib(|this| {
3146
                    let def = Def::Label(expr.id);
3147

3148
                    {
3149
                        let rib = this.label_ribs.last_mut().unwrap();
3150
                        rib.bindings.insert(label.name, def);
3151
                    }
3152

3153
                    intravisit::walk_expr(this, expr);
3154
                })
3155 3156
            }

3157
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3158
                match self.search_label(label.node.name) {
3159
                    None => {
3160
                        self.record_def(expr.id, err_path_resolution());
3161
                        resolve_error(self,
3162 3163
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3164
                    }
3165
                    Some(def @ Def::Label(_)) => {
3166
                        // Since this def is a label, it is never read.
C
corentih 已提交
3167 3168 3169 3170 3171
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            depth: 0,
                                        })
3172 3173
                    }
                    Some(_) => {
3174
                        span_bug!(expr.span, "label wasn't mapped to a label def!")
3175 3176 3177 3178
                    }
                }
            }

B
Brian Anderson 已提交
3179
            _ => {
3180
                intravisit::walk_expr(self, expr);
3181 3182 3183 3184
            }
        }
    }

E
Eduard Burtescu 已提交
3185
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3186
        match expr.node {
3187
            ExprField(_, name) => {
3188 3189 3190 3191
                // 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.
3192
                let traits = self.get_traits_containing_item(name.node);
3193
                self.trait_map.insert(expr.id, traits);
3194
            }
3195
            ExprMethodCall(name, _, _) => {
C
corentih 已提交
3196
                debug!("(recording candidate traits for expr) recording traits for {}",
3197
                       expr.id);
3198
                let traits = self.get_traits_containing_item(name.node);
3199
                self.trait_map.insert(expr.id, traits);
3200
            }
3201
            _ => {
3202 3203 3204 3205 3206
                // Nothing to do.
            }
        }
    }

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

C
corentih 已提交
3210
        fn add_trait_info(found_traits: &mut Vec<DefId>, trait_def_id: DefId, name: Name) {
3211
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3212 3213
                   trait_def_id,
                   name);
E
Eduard Burtescu 已提交
3214 3215
            found_traits.push(trait_def_id);
        }
3216

3217
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3218 3219 3220 3221
        // Look for the current trait.
        if let Some((trait_def_id, _)) = self.current_trait_ref {
            if self.trait_item_map.contains_key(&(name, trait_def_id)) {
                add_trait_info(&mut found_traits, trait_def_id, name);
E
Eduard Burtescu 已提交
3222
            }
J
Jeffrey Seyfried 已提交
3223
        }
3224

J
Jeffrey Seyfried 已提交
3225 3226
        let mut search_module = self.current_module;
        loop {
E
Eduard Burtescu 已提交
3227
            // Look for trait children.
3228
            let mut search_in_module = |module: Module<'a>| module.for_each_child(|_, ns, binding| {
3229
                if ns != TypeNS { return }
3230
                let trait_def_id = match binding.def() {
3231
                    Some(Def::Trait(trait_def_id)) => trait_def_id,
3232
                    Some(..) | None => return,
3233 3234 3235
                };
                if self.trait_item_map.contains_key(&(name, trait_def_id)) {
                    add_trait_info(&mut found_traits, trait_def_id, name);
3236
                    let trait_name = self.get_trait_name(trait_def_id);
3237 3238
                    self.record_use(trait_name, TypeNS, binding);
                }
3239 3240
            });
            search_in_module(search_module);
3241

3242
            match search_module.parent_link {
3243 3244 3245 3246
                NoParentLink | ModuleParentLink(..) => {
                    search_module.prelude.borrow().map(search_in_module);
                    break;
                }
E
Eduard Burtescu 已提交
3247
                BlockParentLink(parent_module, _) => {
3248
                    search_module = parent_module;
3249
                }
E
Eduard Burtescu 已提交
3250
            }
3251 3252
        }

E
Eduard Burtescu 已提交
3253
        found_traits
3254 3255
    }

3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275
    /// 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() {
3276
            self.populate_module_if_necessary(in_module);
3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308

            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)
3309
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330
                            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
                        }
3331
                        _ => bug!(),
3332 3333
                    };

3334
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3335
                        // add the module to the lookup
3336
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348
                        worklist.push((module, path_segments, is_extern));
                    }
                }
            })
        }

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

3349 3350 3351 3352
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
3353 3354 3355 3356
            span_bug!(span,
                      "path resolved multiple times ({:?} before, {:?} now)",
                      prev_res,
                      resolution);
3357
        }
3358 3359
    }

F
Felix S. Klock II 已提交
3360
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3361 3362 3363
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3364
        match pat_binding_mode {
3365
            BindByValue(_) => {}
A
Alex Crichton 已提交
3366
            BindByRef(..) => {
3367 3368
                resolve_error(self,
                              pat.span,
3369
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3370 3371 3372
            }
        }
    }
3373

3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410
    fn resolve_visibility(&mut self, vis: &hir::Visibility) -> ty::Visibility {
        let (path, id) = match *vis {
            hir::Public => return ty::Visibility::Public,
            hir::Visibility::Crate => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
            hir::Visibility::Restricted { ref path, id } => (path, id),
            hir::Inherited => {
                let current_module =
                    self.get_nearest_normal_module_parent_or_self(self.current_module);
                let id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap();
                return ty::Visibility::Restricted(id);
            }
        };

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

3411 3412 3413 3414
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
        let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
        let node_id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap();
        vis.is_accessible_from(node_id, &self.ast_map)
3415 3416
    }

3417 3418
    fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
        if !self.is_accessible(binding.vis) {
3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438
            self.privacy_errors.push(PrivacyError(span, name, binding));
        }
    }

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

3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494
    fn report_conflict(&self,
                       parent: Module,
                       name: Name,
                       ns: Namespace,
                       binding: &NameBinding,
                       old_binding: &NameBinding) {
        // Error on the second of two conflicting names
        if old_binding.span.unwrap().lo > binding.span.unwrap().lo {
            return self.report_conflict(parent, name, ns, old_binding, binding);
        }

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

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

        let span = binding.span.unwrap();
        let msg = {
            let kind = match (ns, old_binding.module()) {
                (ValueNS, _) => "a value",
                (TypeNS, Some(module)) if module.extern_crate_id.is_some() => "an extern crate",
                (TypeNS, Some(module)) if module.is_normal() => "a module",
                (TypeNS, Some(module)) if module.is_trait() => "a trait",
                (TypeNS, _) => "a type",
            };
            format!("{} named `{}` has already been {} in this {}",
                    kind, name, participle, container)
        };

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

        let span = old_binding.span.unwrap();
        if span != codemap::DUMMY_SP {
            err.span_note(span, &format!("previous {} of `{}` here", noun, name));
        }
        err.emit();
    }
}
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504

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("::")
        }
3505
        result.push_str(&name.as_str());
C
corentih 已提交
3506
    }
3507 3508 3509 3510
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3511
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3512 3513 3514 3515 3516 3517
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

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
/// When an entity with a given name is not available in scope, we search for
/// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way
fn show_candidates(session: &mut DiagnosticBuilder,
                   span: syntax::codemap::Span,
                   candidates: &SuggestedCandidates) {

    let paths = &candidates.candidates;

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

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

        // behave differently based on how many candidates we have:
        if !paths.is_empty() {
            if paths.len() == 1 {
                session.fileline_help(
                    span,
T
tiehuis 已提交
3544
                    &format!("you can import it into scope: `use {};`.",
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
                        &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()),
        );
    };
}

3579
/// A somewhat inefficient routine to obtain the name of a module.
3580
fn module_to_string(module: Module) -> String {
3581 3582
    let mut names = Vec::new();

3583
    fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
3584 3585 3586 3587
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
3588
                collect_mod(names, module);
3589 3590 3591 3592
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
                names.push(special_idents::opaque.name);
3593
                collect_mod(names, module);
3594 3595 3596 3597 3598
            }
        }
    }
    collect_mod(&mut names, module);

3599
    if names.is_empty() {
3600 3601 3602 3603 3604
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3605 3606
fn err_path_resolution() -> PathResolution {
    PathResolution {
3607
        base_def: Def::Err,
3608 3609 3610 3611
        depth: 0,
    }
}

3612

3613
pub struct CrateMap {
J
Jonathan S 已提交
3614
    pub def_map: RefCell<DefMap>,
3615
    pub freevars: FreevarMap,
3616
    pub export_map: ExportMap,
3617
    pub trait_map: TraitMap,
C
corentih 已提交
3618
    pub glob_map: Option<GlobMap>,
3619 3620
}

N
Niko Matsakis 已提交
3621
#[derive(PartialEq,Copy, Clone)]
3622 3623
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3624
    No,
3625 3626
}

3627
/// Entry point to crate resolution.
3628
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3629
                               ast_map: &'a hir_map::Map<'tcx>,
3630 3631
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3632 3633 3634 3635 3636 3637 3638 3639 3640
    // 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);

3641
    let krate = ast_map.krate();
3642 3643
    let arenas = Resolver::arenas();
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
3644 3645 3646 3647

    resolver.resolve_crate(krate);

    check_unused::check_crate(&mut resolver, krate);
3648
    resolver.report_privacy_errors();
3649

3650
    CrateMap {
3651 3652
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3653
        export_map: resolver.export_map,
3654
        trait_map: resolver.trait_map,
3655
        glob_map: if resolver.make_glob_map {
C
corentih 已提交
3656 3657 3658 3659
            Some(resolver.glob_map)
        } else {
            None
        },
3660
    }
3661
}
3662

3663 3664 3665 3666 3667 3668 3669 3670
/// Builds a name resolution walker to be used within this module,
/// or used externally, with an optional callback function.
///
/// The callback takes a &mut bool which allows callbacks to end a
/// walk when set to true, passing through the rest of the walk, while
/// preserving the ribs + current module. This allows resolve_path
/// calls to be made with the correct scope info. The node in the
/// callback corresponds to the current node in the walk.
J
Jeffrey Seyfried 已提交
3671 3672 3673 3674 3675 3676 3677
fn create_resolver<'a, 'tcx>(session: &'a Session,
                             ast_map: &'a hir_map::Map<'tcx>,
                             krate: &'a Crate,
                             make_glob_map: MakeGlobMap,
                             arenas: &'a ResolverArenas<'a>,
                             callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
                             -> Resolver<'a, 'tcx> {
3678
    let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
G
Garming Sam 已提交
3679 3680 3681

    resolver.callback = callback;

J
Jeffrey Seyfried 已提交
3682
    resolver.build_reduced_graph(krate);
G
Garming Sam 已提交
3683 3684 3685 3686 3687 3688

    resolve_imports::resolve_imports(&mut resolver);

    resolver
}

3689
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }