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

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

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

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

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

46 47
use rustc::hir::map::Definitions;
use rustc::hir::{PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
48 49
use rustc::session::Session;
use rustc::lint;
50 51
use rustc::hir::def::*;
use rustc::hir::def_id::DefId;
52
use rustc::ty;
53
use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace};
S
Seo Sanghyeon 已提交
54 55
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
56

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

65 66 67 68 69 70
use syntax::visit::{self, FnKind, Visitor};
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
use syntax::ast::{Local, Pat, PatKind, Path};
use syntax::ast::{PathSegment, PathParameters, TraitItemKind, TraitRef, Ty, TyKind};
71

72
use std::collections::{HashMap, HashSet};
73
use std::cell::{Cell, RefCell};
74
use std::fmt;
75
use std::mem::replace;
76

77
use resolve_imports::{ImportDirective, NameResolution};
78

79 80
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
J
Jeffrey Seyfried 已提交
81
mod diagnostics;
82

A
Alex Crichton 已提交
83
mod check_unused;
84
mod build_reduced_graph;
85
mod resolve_imports;
86

87 88
enum SuggestionType {
    Macro(String),
89
    Function(token::InternedString),
90 91 92
    NotFound,
}

93
/// Candidates for a name resolution failure
J
Jeffrey Seyfried 已提交
94
struct SuggestedCandidates {
95 96 97 98
    name: String,
    candidates: Vec<Path>,
}

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

174
/// Context of where `ResolutionError::UnresolvedName` arose.
175
#[derive(Clone, PartialEq, Eq, Debug)]
176 177
enum UnresolvedNameContext<'a> {
    /// `PathIsMod(parent)` indicates that a given path, used in
178
    /// expression context, actually resolved to a module rather than
179 180 181
    /// a value. The optional expression attached to the variant is the
    /// the parent of the erroneous path expression.
    PathIsMod(Option<&'a Expr>),
182 183 184 185

    /// `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.)
186 187 188
    Other,
}

189 190 191
fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                                 span: syntax::codemap::Span,
                                 resolution_error: ResolutionError<'c>) {
N
Nick Cameron 已提交
192
    resolve_struct_error(resolver, span, resolution_error).emit();
N
Nick Cameron 已提交
193 194
}

195 196 197 198
fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                                        span: syntax::codemap::Span,
                                        resolution_error: ResolutionError<'c>)
                                        -> DiagnosticBuilder<'a> {
199
    if !resolver.emit_errors {
N
Nick Cameron 已提交
200
        return resolver.session.diagnostic().struct_dummy();
201
    }
N
Nick Cameron 已提交
202

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

            match context {
413
                UnresolvedNameContext::Other => { } // no help available
414
                UnresolvedNameContext::PathIsMod(parent) => {
415
                    err.help(&match parent.map(|parent| &parent.node) {
416
                        Some(&ExprKind::Field(_, ident)) => {
417 418 419 420
                            format!("To reference an item from the `{module}` module, \
                                     use `{module}::{ident}`",
                                    module = path,
                                    ident = ident.node)
421
                        }
422
                        Some(&ExprKind::MethodCall(ident, _, _)) => {
423 424 425 426 427 428 429 430 431 432
                            format!("To call a function from the `{module}` module, \
                                     use `{module}::{ident}(..)`",
                                    module = path,
                                    ident = ident.node)
                        }
                        _ => {
                            format!("Module `{module}` cannot be used as an expression",
                                    module = path)
                        }
                    });
433 434
                }
            }
N
Nick Cameron 已提交
435
            err
C
corentih 已提交
436
        }
437
        ResolutionError::UndeclaredLabel(name) => {
N
Nick Cameron 已提交
438 439 440 441 442
            struct_span_err!(resolver.session,
                             span,
                             E0426,
                             "use of undeclared label `{}`",
                             name)
C
corentih 已提交
443
        }
444
        ResolutionError::CannotUseRefBindingModeWith(descr) => {
N
Nick Cameron 已提交
445 446 447 448 449
            struct_span_err!(resolver.session,
                             span,
                             E0427,
                             "cannot use `ref` binding mode with {}",
                             descr)
C
corentih 已提交
450
        }
451
        ResolutionError::SelfImportsOnlyAllowedWithin => {
N
Nick Cameron 已提交
452 453 454 455 456
            struct_span_err!(resolver.session,
                             span,
                             E0429,
                             "{}",
                             "`self` imports are only allowed within a { } list")
C
corentih 已提交
457
        }
458
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
N
Nick Cameron 已提交
459 460 461 462
            struct_span_err!(resolver.session,
                             span,
                             E0430,
                             "`self` import can only appear once in the list")
C
corentih 已提交
463
        }
464
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
N
Nick Cameron 已提交
465 466 467 468 469
            struct_span_err!(resolver.session,
                             span,
                             E0431,
                             "`self` import can only appear in an import list with a \
                              non-empty prefix")
470
        }
471
        ResolutionError::UnresolvedImport(name) => {
472
            let msg = match name {
473
                Some((n, p)) => format!("unresolved import `{}`{}", n, p),
C
corentih 已提交
474
                None => "unresolved import".to_owned(),
475
            };
N
Nick Cameron 已提交
476
            struct_span_err!(resolver.session, span, E0432, "{}", msg)
C
corentih 已提交
477
        }
478
        ResolutionError::FailedToResolve(msg) => {
N
Nick Cameron 已提交
479
            struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg)
C
corentih 已提交
480
        }
481
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
N
Nick Cameron 已提交
482 483 484 485 486 487
            struct_span_err!(resolver.session,
                             span,
                             E0434,
                             "{}",
                             "can't capture dynamic environment in a fn item; use the || { ... } \
                              closure form instead")
C
corentih 已提交
488 489
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
N
Nick Cameron 已提交
490 491 492 493
            struct_span_err!(resolver.session,
                             span,
                             E0435,
                             "attempt to use a non-constant value in a constant")
C
corentih 已提交
494
        }
N
Nick Cameron 已提交
495
    }
496 497
}

N
Niko Matsakis 已提交
498
#[derive(Copy, Clone)]
499
struct BindingInfo {
500
    span: Span,
501
    binding_mode: BindingMode,
502 503 504
}

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

N
Niko Matsakis 已提交
507
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
508
enum PatternBindingMode {
509
    RefutableMode,
510
    LocalIrrefutableMode,
511
    ArgumentIrrefutableMode,
512 513
}

N
Niko Matsakis 已提交
514
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
515
pub enum Namespace {
516
    TypeNS,
C
corentih 已提交
517
    ValueNS,
518 519
}

520
impl<'a, 'v> Visitor<'v> for Resolver<'a> {
521
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
522
        self.resolve_item(item);
523
    }
524
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
525
        self.resolve_arm(arm);
526
    }
527
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
528
        self.resolve_block(block);
529
    }
530
    fn visit_expr(&mut self, expr: &Expr) {
531
        self.resolve_expr(expr, None);
532
    }
533
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
534
        self.resolve_local(local);
535
    }
536
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
537
        self.resolve_type(ty);
538
    }
539 540 541
    fn visit_generics(&mut self, generics: &Generics) {
        self.resolve_generics(generics);
    }
542
    fn visit_poly_trait_ref(&mut self, tref: &ast::PolyTraitRef, m: &ast::TraitBoundModifier) {
543 544
        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 已提交
545 546
            Err(_) => {
                // error already reported
547
                self.record_def(tref.trait_ref.ref_id, err_path_resolution())
C
corentih 已提交
548
            }
549
        }
550
        visit::walk_poly_trait_ref(self, tref, m);
551
    }
C
corentih 已提交
552
    fn visit_variant(&mut self,
553
                     variant: &ast::Variant,
C
corentih 已提交
554 555
                     generics: &Generics,
                     item_id: ast::NodeId) {
556 557 558
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
559
                this.visit_expr(dis_expr);
560 561 562
            });
        }

563
        // `visit::walk_variant` without the discriminant expression.
C
corentih 已提交
564 565 566 567 568
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
569
    }
570
    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
571
        let type_parameters = match foreign_item.node {
572
            ForeignItemKind::Fn(_, ref generics) => {
573 574
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
575
            ForeignItemKind::Static(..) => NoTypeParameters,
576 577
        };
        self.with_type_parameter_rib(type_parameters, |this| {
578
            visit::walk_foreign_item(this, foreign_item);
579 580 581
        });
    }
    fn visit_fn(&mut self,
582
                function_kind: FnKind<'v>,
583 584 585 586 587
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
588
            FnKind::ItemFn(_, generics, _, _, _, _) => {
589 590 591
                self.visit_generics(generics);
                ItemRibKind
            }
592
            FnKind::Method(_, sig, _) => {
593 594
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
595 596
                MethodRibKind
            }
597
            FnKind::Closure => ClosureRibKind(node_id),
598 599 600
        };
        self.resolve_function(rib_kind, declaration, block);
    }
601
}
602

603
pub type ErrorMessage = Option<(Span, String)>;
604

605
#[derive(Clone, PartialEq, Eq)]
606
pub enum ResolveResult<T> {
C
corentih 已提交
607 608 609
    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.
610 611
}

612
impl<T> ResolveResult<T> {
613 614 615 616 617
    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 已提交
618
        }
619
    }
620 621 622 623 624 625 626

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

629 630 631
enum FallbackSuggestion {
    NoSuggestion,
    Field,
632
    TraitItem,
633
    TraitMethod(String),
634 635
}

N
Niko Matsakis 已提交
636
#[derive(Copy, Clone)]
637
enum TypeParameters<'a, 'b> {
638
    NoTypeParameters,
C
corentih 已提交
639
    HasTypeParameters(// Type parameters.
640
                      &'b Generics,
641

C
corentih 已提交
642 643 644
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
645

C
corentih 已提交
646
                      // The kind of the rib used for type parameters.
647
                      RibKind<'a>),
648 649
}

650
// The rib kind controls the translation of local
651
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
652
#[derive(Copy, Clone, Debug)]
653
enum RibKind<'a> {
654 655
    // No translation needs to be applied.
    NormalRibKind,
656

657 658
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
659
    ClosureRibKind(NodeId /* func id */),
660

661
    // We passed through an impl or trait and are now in one of its
662
    // methods. Allow references to ty params that impl or trait
663 664
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
665
    MethodRibKind,
666

667 668
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
669 670

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

673 674
    // We passed through a module.
    ModuleRibKind(Module<'a>),
675 676
}

N
Niko Matsakis 已提交
677
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
678
enum UseLexicalScopeFlag {
679
    DontUseLexicalScope,
C
corentih 已提交
680
    UseLexicalScope,
681 682
}

683
enum ModulePrefixResult<'a> {
684
    NoPrefixFound,
685
    PrefixFound(Module<'a>, usize),
686 687
}

688 689 690 691 692 693 694 695 696
#[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 已提交
697
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
698
enum BareIdentifierPatternResolution {
J
Jeffrey Seyfried 已提交
699 700
    FoundStructOrEnumVariant(Def),
    FoundConst(Def, Name),
C
corentih 已提交
701
    BareIdentifierPatternUnresolved,
702 703
}

704
/// One local scope.
J
Jorge Aparicio 已提交
705
#[derive(Debug)]
706
struct Rib<'a> {
707
    bindings: HashMap<Name, Def>,
708
    kind: RibKind<'a>,
B
Brian Anderson 已提交
709
}
710

711 712
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
713
        Rib {
714
            bindings: HashMap::new(),
C
corentih 已提交
715
            kind: kind,
716
        }
717 718 719
    }
}

720 721 722
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
723
    def: Def,
724 725 726 727 728 729
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
730
            def: def,
731 732 733 734
        }
    }
}

735 736 737 738 739
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
    LocalDef(LocalDef),
}

740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
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 module(self) -> Option<Module<'a>> {
        match self {
            LexicalScopeBinding::Item(binding) => binding.module(),
            _ => None,
        }
    }
}

756
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
757
#[derive(Clone,Debug)]
758
enum ParentLink<'a> {
759
    NoParentLink,
760 761
    ModuleParentLink(Module<'a>, Name),
    BlockParentLink(Module<'a>, NodeId),
762 763
}

764
/// One node in the tree of modules.
765 766
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
J
Jeffrey Seyfried 已提交
767
    def: Option<Def>,
768

769 770 771
    // 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>,
772

773
    resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
774
    unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
775

776
    prelude: RefCell<Option<Module<'a>>>,
777

778
    glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
779
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
780

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

784 785 786
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
787
    populated: Cell<bool>,
788 789

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

792 793 794
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
795 796 797 798
    fn new(parent_link: ParentLink<'a>,
           def: Option<Def>,
           external: bool,
           arenas: &'a ResolverArenas<'a>) -> Self {
799
        ModuleS {
800
            parent_link: parent_link,
J
Jeffrey Seyfried 已提交
801
            def: def,
802
            extern_crate_id: None,
803
            resolutions: RefCell::new(HashMap::new()),
804
            unresolved_imports: RefCell::new(Vec::new()),
805
            prelude: RefCell::new(None),
806
            glob_importers: RefCell::new(Vec::new()),
807
            globs: RefCell::new((Vec::new())),
J
Jeffrey Seyfried 已提交
808
            traits: RefCell::new(None),
809
            populated: Cell::new(!external),
810
            arenas: arenas
811
        }
B
Brian Anderson 已提交
812 813
    }

814
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
815
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
816
            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
817 818 819
        }
    }

820
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
821
        self.def.as_ref().map(Def::def_id)
822 823
    }

824
    // `self` resolves to the first module ancestor that `is_normal`.
825
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
826
        match self.def {
827
            Some(Def::Mod(_)) => true,
828 829 830 831 832
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
833
        match self.def {
834
            Some(Def::Trait(_)) => true,
835
            _ => false,
836
        }
B
Brian Anderson 已提交
837
    }
V
Victor Berger 已提交
838 839
}

840
impl<'a> fmt::Debug for ModuleS<'a> {
841
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
842
        write!(f, "{:?}", self.def)
843 844 845
    }
}

846
// Records a possibly-private value, type, or module definition.
847
#[derive(Clone, Debug)]
848
pub struct NameBinding<'a> {
849
    kind: NameBindingKind<'a>,
850
    span: Span,
851
    vis: ty::Visibility,
852 853
}

854
#[derive(Clone, Debug)]
855
enum NameBindingKind<'a> {
856
    Def(Def),
857
    Module(Module<'a>),
858 859
    Import {
        binding: &'a NameBinding<'a>,
860
        directive: &'a ImportDirective<'a>,
861 862
        // Some(error) if using this imported name causes the import to be a privacy error
        privacy_error: Option<Box<PrivacyError<'a>>>,
863
    },
864 865
}

866 867 868
#[derive(Clone, Debug)]
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

869
impl<'a> NameBinding<'a> {
870
    fn module(&self) -> Option<Module<'a>> {
871 872 873 874
        match self.kind {
            NameBindingKind::Module(module) => Some(module),
            NameBindingKind::Def(_) => None,
            NameBindingKind::Import { binding, .. } => binding.module(),
875 876 877
        }
    }

878
    fn def(&self) -> Option<Def> {
879 880 881 882
        match self.kind {
            NameBindingKind::Def(def) => Some(def),
            NameBindingKind::Module(module) => module.def,
            NameBindingKind::Import { binding, .. } => binding.def(),
883
        }
884
    }
885

886 887 888 889 890 891 892 893 894 895 896 897 898 899
    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,
        }
900 901
    }

902
    fn is_extern_crate(&self) -> bool {
903
        self.module().and_then(|module| module.extern_crate_id).is_some()
904
    }
905 906 907 908 909 910 911

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
912 913 914 915 916 917 918 919 920 921 922 923 924 925

    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,
        }
    }
926 927
}

928
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
929
struct PrimitiveTypeTable {
930
    primitive_types: HashMap<Name, PrimTy>,
931
}
932

933
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
934
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
935 936 937 938
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
939 940
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
941 942 943 944 945
        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 已提交
946
        table.intern("str", TyStr);
947 948 949 950 951
        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 已提交
952 953 954 955

        table
    }

956
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
957
        self.primitive_types.insert(token::intern(string), primitive_type);
958 959 960
    }
}

961
/// The main resolver class.
962
pub struct Resolver<'a> {
E
Eduard Burtescu 已提交
963
    session: &'a Session,
964

965
    definitions: &'a Definitions,
966

967
    graph_root: Module<'a>,
968

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

971
    structs: FnvHashMap<DefId, Vec<Name>>,
972

973
    // The number of imports that are currently unresolved.
974
    unresolved_imports: usize,
975 976

    // The module that represents the current item scope.
977
    current_module: Module<'a>,
978 979

    // The current set of local scopes, for values.
980
    // FIXME #4948: Reuse ribs to avoid allocation.
981
    value_ribs: Vec<Rib<'a>>,
982 983

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

986
    // The current set of local scopes, for labels.
987
    label_ribs: Vec<Rib<'a>>,
988

989
    // The trait that the current context can refer to.
990 991 992 993
    current_trait_ref: Option<(DefId, TraitRef)>,

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

995
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
996
    primitive_type_table: PrimitiveTypeTable,
997

998 999
    pub def_map: DefMap,
    pub freevars: FreevarMap,
1000
    freevars_seen: NodeMap<NodeMap<usize>>,
1001 1002
    pub export_map: ExportMap,
    pub trait_map: TraitMap,
1003

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
    // A map from nodes to modules, both normal (`mod`) modules and anonymous modules.
    // Anonymous modules are pseudo-modules that are implicitly created around items
    // contained within blocks.
    //
    // For example, if we have this:
    //
    //  fn f() {
    //      fn g() {
    //          ...
    //      }
    //  }
    //
    // There will be an anonymous module created around `g` with the ID of the
    // entry block for `f`.
    module_map: NodeMap<Module<'a>>,

1020 1021 1022 1023 1024
    // 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,

1025
    pub make_glob_map: bool,
1026 1027
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
1028
    pub glob_map: GlobMap,
1029

1030
    used_imports: HashSet<(NodeId, Namespace)>,
1031
    used_crates: HashSet<CrateNum>,
1032
    pub maybe_unused_trait_imports: NodeSet,
G
Garming Sam 已提交
1033

1034
    privacy_errors: Vec<PrivacyError<'a>>,
1035 1036 1037 1038

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

J
Jeffrey Seyfried 已提交
1039
struct ResolverArenas<'a> {
1040
    modules: arena::TypedArena<ModuleS<'a>>,
1041
    local_modules: RefCell<Vec<Module<'a>>>,
1042
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1043
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1044
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1045 1046 1047
}

impl<'a> ResolverArenas<'a> {
1048
    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
1049 1050 1051 1052 1053 1054 1055 1056
        let module = self.modules.alloc(module);
        if module.def_id().map(|def_id| def_id.is_local()).unwrap_or(true) {
            self.local_modules.borrow_mut().push(module);
        }
        module
    }
    fn local_modules(&'a self) -> ::std::cell::Ref<'a, Vec<Module<'a>>> {
        self.local_modules.borrow()
1057 1058 1059 1060
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1061 1062
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1063 1064
        self.import_directives.alloc(import_directive)
    }
1065 1066 1067
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1068 1069
}

1070
impl<'a> ty::NodeIdTree for Resolver<'a> {
1071
    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
1072
        let ancestor = self.definitions.local_def_id(ancestor);
1073
        let mut module = *self.module_map.get(&node).unwrap();
J
Jeffrey Seyfried 已提交
1074
        while module.def_id() != Some(ancestor) {
1075 1076 1077 1078 1079 1080
            let module_parent = match self.get_nearest_normal_module_parent(module) {
                Some(parent) => parent,
                None => return false,
            };
            module = module_parent;
        }
J
Jeffrey Seyfried 已提交
1081
        true
1082 1083 1084
    }
}

1085
impl<'a> Resolver<'a> {
1086
    fn new(session: &'a Session,
1087
           definitions: &'a Definitions,
1088 1089
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
1090 1091
           -> Resolver<'a> {
        let root_def_id = definitions.local_def_id(CRATE_NODE_ID);
1092
        let graph_root =
1093
            ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
1094
        let graph_root = arenas.alloc_module(graph_root);
1095 1096
        let mut module_map = NodeMap();
        module_map.insert(CRATE_NODE_ID, graph_root);
K
Kevin Butler 已提交
1097 1098 1099 1100

        Resolver {
            session: session,

1101
            definitions: definitions,
1102

K
Kevin Butler 已提交
1103 1104
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1105
            graph_root: graph_root,
K
Kevin Butler 已提交
1106

1107 1108
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1109 1110 1111

            unresolved_imports: 0,

1112
            current_module: graph_root,
1113 1114
            value_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
            type_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
1115
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1116 1117 1118 1119 1120 1121

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1122
            def_map: NodeMap(),
1123 1124
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1125 1126
            export_map: NodeMap(),
            trait_map: NodeMap(),
1127
            module_map: module_map,
K
Kevin Butler 已提交
1128 1129

            emit_errors: true,
1130
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1131
            glob_map: NodeMap(),
G
Garming Sam 已提交
1132

S
Seo Sanghyeon 已提交
1133 1134 1135 1136
            used_imports: HashSet::new(),
            used_crates: HashSet::new(),
            maybe_unused_trait_imports: NodeSet(),

1137
            privacy_errors: Vec::new(),
1138 1139 1140 1141 1142 1143 1144 1145

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
1146
            local_modules: RefCell::new(Vec::new()),
1147
            name_bindings: arena::TypedArena::new(),
1148
            import_directives: arena::TypedArena::new(),
1149
            name_resolutions: arena::TypedArena::new(),
K
Kevin Butler 已提交
1150 1151
        }
    }
1152

1153 1154 1155
    fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool)
                  -> Module<'a> {
        self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas))
1156 1157
    }

1158
    fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId)
1159
                               -> Module<'a> {
1160
        let mut module = ModuleS::new(parent_link, Some(def), false, self.arenas);
1161
        module.extern_crate_id = Some(local_node_id);
1162 1163 1164
        self.arenas.modules.alloc(module)
    }

1165 1166 1167 1168
    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 }
    }

1169
    #[inline]
S
Seo Sanghyeon 已提交
1170
    fn record_use(&mut self, name: Name, binding: &'a NameBinding<'a>) {
1171 1172 1173 1174 1175
        // 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);
        }

1176 1177 1178
        let (directive, privacy_error) = match binding.kind {
            NameBindingKind::Import { directive, ref privacy_error, .. } =>
                (directive, privacy_error),
1179 1180 1181
            _ => return,
        };

1182 1183 1184
        if let Some(error) = privacy_error.as_ref() {
            self.privacy_errors.push((**error).clone());
        }
1185

1186 1187 1188
        if !self.make_glob_map {
            return;
        }
1189 1190
        if self.glob_map.contains_key(&directive.id) {
            self.glob_map.get_mut(&directive.id).unwrap().insert(name);
1191 1192 1193
            return;
        }

1194
        let mut new_set = FnvHashSet();
1195
        new_set.insert(name);
1196
        self.glob_map.insert(directive.id, new_set);
1197 1198
    }

1199
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1200
    fn resolve_module_path_from_root(&mut self,
1201
                                     module_: Module<'a>,
1202
                                     module_path: &[Name],
1203
                                     index: usize,
J
Jeffrey Seyfried 已提交
1204 1205
                                     span: Span)
                                     -> ResolveResult<Module<'a>> {
1206
        fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
1207 1208
            match module.resolve_name(needle, TypeNS, false) {
                Success(binding) if binding.is_extern_crate() => Some(module),
1209
                _ => match module.parent_link {
1210
                    ModuleParentLink(ref parent, _) => {
1211
                        search_parent_externals(needle, parent)
1212
                    }
C
corentih 已提交
1213 1214
                    _ => None,
                },
1215
            }
1216 1217
        }

1218
        let mut search_module = module_;
1219
        let mut index = index;
A
Alex Crichton 已提交
1220
        let module_path_len = module_path.len();
1221 1222 1223 1224 1225

        // 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 已提交
1226
            let name = module_path[index];
1227
            match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
1228
                Failed(None) => {
1229
                    let segment_name = name.as_str();
1230
                    let module_name = module_to_string(search_module);
1231
                    let mut span = span;
1232
                    let msg = if "???" == &module_name {
1233
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1234

C
corentih 已提交
1235
                        match search_parent_externals(name, &self.current_module) {
1236
                            Some(module) => {
1237
                                let path_str = names_to_string(module_path);
J
Jonas Schievink 已提交
1238 1239
                                let target_mod_str = module_to_string(&module);
                                let current_mod_str = module_to_string(&self.current_module);
1240 1241 1242 1243 1244 1245 1246

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

1247
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1248 1249
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1250
                        }
1251
                    } else {
C
corentih 已提交
1252
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1253
                    };
1254

1255
                    return Failed(Some((span, msg)));
1256
                }
1257
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1258
                Indeterminate => {
C
corentih 已提交
1259 1260 1261
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1262
                    return Indeterminate;
1263
                }
1264
                Success(binding) => {
1265 1266
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
J
Jeffrey Seyfried 已提交
1267
                    if let Some(module_def) = binding.module() {
1268
                        self.check_privacy(name, binding, span);
1269 1270 1271 1272
                        search_module = module_def;
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1273 1274 1275 1276
                    }
                }
            }

T
Tim Chevalier 已提交
1277
            index += 1;
1278 1279
        }

J
Jeffrey Seyfried 已提交
1280
        return Success(search_module);
1281 1282
    }

1283 1284
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
F
Felix S. Klock II 已提交
1285
    fn resolve_module_path(&mut self,
1286
                           module_path: &[Name],
1287
                           use_lexical_scope: UseLexicalScopeFlag,
J
Jeffrey Seyfried 已提交
1288
                           span: Span)
J
Jeffrey Seyfried 已提交
1289
                           -> ResolveResult<Module<'a>> {
1290
        if module_path.len() == 0 {
J
Jeffrey Seyfried 已提交
1291
            return Success(self.graph_root) // Use the crate root
1292
        }
1293

1294
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1295
               names_to_string(module_path),
1296
               module_to_string(self.current_module));
1297

1298
        // Resolve the module prefix, if any.
1299
        let module_prefix_result = self.resolve_module_prefix(module_path, span);
1300

1301 1302
        let search_module;
        let start_index;
1303
        match module_prefix_result {
1304
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1305
            Indeterminate => {
C
corentih 已提交
1306
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1307
                return Indeterminate;
1308
            }
1309 1310 1311 1312 1313 1314 1315 1316
            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.
1317
                        search_module = self.graph_root;
1318 1319 1320 1321 1322 1323
                        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.
1324
                        let ident = ast::Ident::with_empty_ctxt(module_path[0]);
1325 1326 1327 1328 1329 1330
                        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;
1331 1332 1333 1334 1335
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1336
            Success(PrefixFound(ref containing_module, index)) => {
1337
                search_module = containing_module;
1338
                start_index = index;
1339 1340 1341
            }
        }

1342 1343 1344
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
J
Jeffrey Seyfried 已提交
1345
                                           span)
1346 1347
    }

1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
    /// 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.
    /// }
    /// ```
1362
    ///
1363 1364
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
1365
    fn resolve_ident_in_lexical_scope(&mut self,
1366
                                      ident: ast::Ident,
1367 1368 1369
                                      ns: Namespace,
                                      record_used: bool)
                                      -> Option<LexicalScopeBinding<'a>> {
1370
        let name = match ns { ValueNS => mtwt::resolve(ident), TypeNS => ident.name };
1371

1372
        // Walk backwards up the ribs in scope.
1373 1374 1375 1376 1377 1378 1379
        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,
                }));
1380 1381
            }

1382
            if let ModuleRibKind(module) = self.get_ribs(ns)[i].kind {
1383
                let name = ident.name;
1384 1385 1386 1387
                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));
1388
                }
1389

1390
                // We can only see through anonymous modules
1391
                if module.def.is_some() { return None; }
1392 1393
            }
        }
1394

1395 1396 1397
        None
    }

1398
    /// Returns the nearest normal module parent of the given module.
1399
    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
1400 1401
        let mut module_ = module_;
        loop {
1402
            match module_.parent_link {
1403 1404 1405
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
1406
                    let new_module = new_module;
1407 1408
                    if new_module.is_normal() {
                        return Some(new_module);
1409
                    }
1410
                    module_ = new_module;
1411 1412 1413 1414 1415
                }
            }
        }
    }

1416 1417
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1418
    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
1419 1420 1421
        if module_.is_normal() {
            return module_;
        }
1422
        match self.get_nearest_normal_module_parent(module_) {
1423 1424
            None => module_,
            Some(new_module) => new_module,
1425 1426 1427
        }
    }

1428
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1429
    /// (b) some chain of `super::`.
1430
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
1431
    fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
1432
                             -> ResolveResult<ModulePrefixResult<'a>> {
1433 1434
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1435 1436 1437 1438 1439
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
1440
        let module_ = self.current_module;
1441
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1442 1443

        // Now loop through all the `super`s we find.
1444
        while i < module_path.len() && "super" == module_path[i].as_str() {
1445
            debug!("(resolving module prefix) resolving `super` at {}",
J
Jonas Schievink 已提交
1446
                   module_to_string(&containing_module));
1447
            match self.get_nearest_normal_module_parent(containing_module) {
1448 1449 1450 1451
                None => {
                    let msg = "There are too many initial `super`s.".into();
                    return Failed(Some((span, msg)));
                }
1452 1453 1454
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1455 1456 1457 1458
                }
            }
        }

1459
        debug!("(resolving module prefix) finished resolving prefix at {}",
J
Jonas Schievink 已提交
1460
               module_to_string(&containing_module));
1461 1462

        return Success(PrefixFound(containing_module, i));
1463 1464
    }

1465
    /// Attempts to resolve the supplied name in the given module for the
J
Jeffrey Seyfried 已提交
1466
    /// given namespace. If successful, returns the binding corresponding to
1467
    /// the name.
F
Felix S. Klock II 已提交
1468
    fn resolve_name_in_module(&mut self,
1469
                              module: Module<'a>,
1470
                              name: Name,
1471
                              namespace: Namespace,
1472
                              use_lexical_scope: bool,
1473
                              record_used: bool)
1474
                              -> ResolveResult<&'a NameBinding<'a>> {
1475
        debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
1476

1477
        self.populate_module_if_necessary(module);
1478 1479 1480 1481 1482
        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| {
1483
            if record_used {
S
Seo Sanghyeon 已提交
1484 1485 1486 1487
                if let NameBindingKind::Import { directive, .. } = binding.kind {
                    self.used_imports.insert((directive.id, namespace));
                }
                self.record_use(name, binding);
1488
            }
1489 1490
            Success(binding)
        })
1491 1492 1493 1494
    }

    // AST resolution
    //
1495
    // We maintain a list of value ribs and type ribs.
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
    //
    // 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.

1511
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1512
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1513
    {
1514 1515
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
1516 1517 1518 1519
            // 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)));
1520

1521
            f(self);
1522

1523 1524 1525 1526 1527 1528
            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
1529 1530
    }

S
Seo Sanghyeon 已提交
1531 1532
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1533
    fn search_label(&self, name: Name) -> Option<Def> {
1534 1535 1536 1537 1538 1539 1540
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1541
                    return None;
1542 1543 1544
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1545
            if result.is_some() {
C
corentih 已提交
1546
                return result;
1547 1548 1549 1550 1551
            }
        }
        None
    }

1552
    fn resolve_crate(&mut self, krate: &Crate) {
1553
        debug!("(resolving crate) starting");
1554
        self.current_module = self.graph_root;
1555
        visit::walk_crate(self, krate);
1556 1557
    }

1558
    fn resolve_item(&mut self, item: &Item) {
1559
        let name = item.ident.name;
1560

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

1563
        match item.node {
1564 1565 1566
            ItemKind::Enum(_, ref generics) |
            ItemKind::Ty(_, ref generics) |
            ItemKind::Struct(_, ref generics) => {
C
corentih 已提交
1567
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1568
                                             |this| visit::walk_item(this, item));
1569
            }
1570
            ItemKind::Fn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1571
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
1572
                                             |this| visit::walk_item(this, item));
1573 1574
            }

1575
            ItemKind::DefaultImpl(_, ref trait_ref) => {
1576
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1577
            }
1578
            ItemKind::Impl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
1579
                self.resolve_implementation(generics,
1580
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1581
                                            &self_type,
1582
                                            item.id,
1583
                                            impl_items),
1584

1585
            ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
1586 1587 1588 1589 1590
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
1591
                    let local_def_id = this.definitions.local_def_id(item.id);
1592
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1593
                        this.visit_generics(generics);
1594
                        walk_list!(this, visit_ty_param_bound, bounds);
1595 1596

                        for trait_item in trait_items {
1597
                            match trait_item.node {
1598
                                TraitItemKind::Const(_, ref default) => {
1599 1600 1601 1602 1603
                                    // 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| {
1604
                                            visit::walk_trait_item(this, trait_item)
1605 1606
                                        });
                                    } else {
1607
                                        visit::walk_trait_item(this, trait_item)
1608 1609
                                    }
                                }
1610
                                TraitItemKind::Method(ref sig, _) => {
1611 1612 1613 1614 1615
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
1616
                                        visit::walk_trait_item(this, trait_item)
1617
                                    });
1618
                                }
1619
                                TraitItemKind::Type(..) => {
1620
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1621
                                        visit::walk_trait_item(this, trait_item)
1622
                                    });
1623 1624 1625 1626
                                }
                            };
                        }
                    });
1627
                });
1628 1629
            }

1630
            ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
1631
                self.with_scope(item.id, |this| {
1632
                    visit::walk_item(this, item);
1633
                });
1634 1635
            }

1636
            ItemKind::Const(..) | ItemKind::Static(..) => {
A
Alex Crichton 已提交
1637
                self.with_constant_rib(|this| {
1638
                    visit::walk_item(this, item);
1639
                });
1640
            }
1641

1642
            ItemKind::Use(ref view_path) => {
1643
                match view_path.node {
1644
                    ast::ViewPathList(ref prefix, ref items) => {
1645 1646 1647 1648 1649
                        // 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) {
1650 1651 1652 1653
                                Ok(binding) => {
                                    let def = binding.def().unwrap();
                                    self.record_def(item.id, PathResolution::new(def, 0));
                                }
1654 1655
                                Err(true) => self.record_def(item.id, err_path_resolution()),
                                Err(false) => {
1656 1657 1658 1659
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
1660
                                    self.record_def(item.id, err_path_resolution());
1661
                                }
1662 1663 1664 1665
                            }
                        }
                    }
                    _ => {}
W
we 已提交
1666 1667 1668
                }
            }

1669
            ItemKind::ExternCrate(_) => {
1670
                // do nothing, these are just around to be encoded
1671
            }
1672 1673

            ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
1674 1675 1676
        }
    }

1677
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1678
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1679
    {
1680
        match type_parameters {
1681
            HasTypeParameters(generics, space, rib_kind) => {
1682
                let mut function_type_rib = Rib::new(rib_kind);
1683
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
1684
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
1685
                    let name = type_parameter.ident.name;
1686
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1687

1688
                    if seen_bindings.contains(&name) {
1689 1690
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
1691
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
1692
                    }
1693
                    seen_bindings.insert(name);
1694

1695
                    // plain insert (no renaming)
1696
                    let def_id = self.definitions.local_def_id(type_parameter.id);
1697 1698
                    let def = Def::TyParam(space, index as u32, def_id, name);
                    function_type_rib.bindings.insert(name, def);
1699
                }
1700
                self.type_ribs.push(function_type_rib);
1701 1702
            }

B
Brian Anderson 已提交
1703
            NoTypeParameters => {
1704 1705 1706 1707
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1708
        f(self);
1709

J
Jeffrey Seyfried 已提交
1710 1711
        if let HasTypeParameters(..) = type_parameters {
            self.type_ribs.pop();
1712 1713 1714
        }
    }

C
corentih 已提交
1715 1716
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1717
    {
1718
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1719
        f(self);
J
Jeffrey Seyfried 已提交
1720
        self.label_ribs.pop();
1721
    }
1722

C
corentih 已提交
1723 1724
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1725
    {
1726 1727
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1728
        f(self);
J
Jeffrey Seyfried 已提交
1729 1730
        self.type_ribs.pop();
        self.value_ribs.pop();
1731 1732
    }

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

1737
        // Create a label rib for the function.
1738
        self.label_ribs.push(Rib::new(rib_kind));
1739

1740 1741 1742
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
J
Jonas Schievink 已提交
1743
            self.resolve_pattern(&argument.pat, ArgumentIrrefutableMode, &mut bindings_list);
1744

J
Jonas Schievink 已提交
1745
            self.visit_ty(&argument.ty);
1746

1747 1748
            debug!("(resolving function) recorded argument");
        }
1749
        visit::walk_fn_ret_ty(self, &declaration.output);
1750

1751
        // Resolve the function body.
1752
        self.visit_block(block);
1753

1754
        debug!("(resolving function) leaving function");
1755

J
Jeffrey Seyfried 已提交
1756 1757
        self.label_ribs.pop();
        self.value_ribs.pop();
1758 1759
    }

F
Felix S. Klock II 已提交
1760
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
1761
                               id: NodeId,
1762
                               trait_path: &Path,
1763
                               path_depth: usize)
1764
                               -> Result<PathResolution, ()> {
1765
        self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
1766
            if let Def::Trait(_) = path_res.base_def {
1767 1768 1769
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
N
Nick Cameron 已提交
1770 1771 1772
                let mut err =
                    resolve_struct_error(self,
                                  trait_path.span,
J
Jonas Schievink 已提交
1773
                                  ResolutionError::IsNotATrait(&path_names_to_string(trait_path,
N
Nick Cameron 已提交
1774
                                                                                      path_depth)));
1775 1776

                // If it's a typedef, give a note
1777
                if let Def::TyAlias(..) = path_res.base_def {
N
Niko Matsakis 已提交
1778
                    err.note("`type` aliases cannot be used for traits");
1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790

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

                    if definition_site != codemap::DUMMY_SP {
                        err.span_note(definition_site, "type defined here");
V
vegai 已提交
1791
                    }
1792
                }
N
Nick Cameron 已提交
1793
                err.emit();
1794
                Err(true)
1795
            }
1796 1797
        }).map_err(|error_reported| {
            if error_reported { return }
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819

            // 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);
1820
        })
1821 1822
    }

1823 1824
    fn resolve_generics(&mut self, generics: &Generics) {
        for predicate in &generics.where_clause.predicates {
1825
            match predicate {
1826 1827 1828
                &ast::WherePredicate::BoundPredicate(_) |
                &ast::WherePredicate::RegionPredicate(_) => {}
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
1829 1830 1831 1832 1833 1834 1835
                    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| {
1836
                        self.record_def(eq_pred.id, err_path_resolution());
1837
                        if error_reported { return }
J
Jeffrey Seyfried 已提交
1838 1839
                        let error_variant = ResolutionError::UndeclaredAssociatedType;
                        resolve_error(self, eq_pred.span, error_variant);
1840
                    }).unwrap_or(());
1841
                }
1842 1843
            }
        }
1844
        visit::walk_generics(self, generics);
1845 1846
    }

1847 1848
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
1849
    {
1850 1851 1852 1853 1854 1855 1856
        // 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 已提交
1857
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
1858
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
1859
    {
1860
        let mut new_val = None;
1861
        let mut new_id = None;
E
Eduard Burtescu 已提交
1862
        if let Some(trait_ref) = opt_trait_ref {
1863
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
1864 1865
                                                               &trait_ref.path,
                                                               0) {
1866 1867 1868 1869
                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());
1870 1871
            } else {
                self.record_def(trait_ref.ref_id, err_path_resolution());
1872
            }
1873
            visit::walk_trait_ref(self, trait_ref);
1874
        }
1875
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
1876
        let result = f(self, new_id);
1877 1878 1879 1880
        self.current_trait_ref = original_trait_ref;
        result
    }

1881 1882 1883 1884 1885 1886
    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....)
1887
        self_type_rib.bindings.insert(keywords::SelfType.name(), self_def);
1888 1889
        self.type_ribs.push(self_type_rib);
        f(self);
J
Jeffrey Seyfried 已提交
1890
        self.type_ribs.pop();
1891 1892
    }

F
Felix S. Klock II 已提交
1893
    fn resolve_implementation(&mut self,
1894 1895 1896
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
1897
                              item_id: NodeId,
1898
                              impl_items: &[ImplItem]) {
1899
        // If applicable, create a rib for the type parameters.
1900
        self.with_type_parameter_rib(HasTypeParameters(generics,
1901
                                                       TypeSpace,
1902
                                                       ItemRibKind),
1903
                                     |this| {
1904
            // Resolve the type parameters.
1905
            this.visit_generics(generics);
1906

1907
            // Resolve the trait reference, if necessary.
1908
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
1909
                // Resolve the self type.
1910
                this.visit_ty(self_type);
1911

1912
                this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
1913 1914
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
1915
                            this.resolve_visibility(&impl_item.vis);
1916
                            match impl_item.node {
1917
                                ImplItemKind::Const(..) => {
1918
                                    // If this is a trait impl, ensure the const
1919
                                    // exists in trait
1920
                                    this.check_trait_item(impl_item.ident.name,
1921 1922
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
1923
                                    this.with_constant_rib(|this| {
1924
                                        visit::walk_impl_item(this, impl_item);
1925 1926
                                    });
                                }
1927
                                ImplItemKind::Method(ref sig, _) => {
1928 1929
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
1930
                                    this.check_trait_item(impl_item.ident.name,
1931 1932
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
1933 1934 1935 1936 1937 1938 1939 1940

                                    // 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| {
1941
                                        visit::walk_impl_item(this, impl_item);
1942 1943
                                    });
                                }
1944
                                ImplItemKind::Type(ref ty) => {
1945
                                    // If this is a trait impl, ensure the type
1946
                                    // exists in trait
1947
                                    this.check_trait_item(impl_item.ident.name,
1948 1949
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
1950

1951 1952
                                    this.visit_ty(ty);
                                }
1953
                                ImplItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
1954
                            }
1955
                        }
1956
                    });
1957 1958
                });
            });
1959
        });
1960 1961
    }

1962
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
1963 1964 1965 1966
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
1967
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
1968
            if !self.trait_item_map.contains_key(&(name, did)) {
1969
                let path_str = path_names_to_string(&trait_ref.path, 0);
J
Jonas Schievink 已提交
1970
                resolve_error(self, span, err(name, &path_str));
1971 1972 1973 1974
            }
        }
    }

E
Eduard Burtescu 已提交
1975
    fn resolve_local(&mut self, local: &Local) {
1976
        // Resolve the type.
1977
        walk_list!(self, visit_ty, &local.ty);
1978

1979
        // Resolve the initializer.
1980
        walk_list!(self, visit_expr, &local.init);
1981 1982

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

J
John Clements 已提交
1986 1987 1988 1989
    // 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 已提交
1990
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
        let mut binding_map = HashMap::new();

        pat.walk(&mut |pat| {
            if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
                if sub_pat.is_some() || match self.def_map.get(&pat.id) {
                    Some(&PathResolution { base_def: Def::Local(..), .. }) => true,
                    _ => false,
                } {
                    let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
                    binding_map.insert(mtwt::resolve(ident.node), binding_info);
                }
            }
            true
2004
        });
2005 2006

        binding_map
2007 2008
    }

J
John Clements 已提交
2009 2010
    // 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 已提交
2011
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2012
        if arm.pats.is_empty() {
C
corentih 已提交
2013
            return;
2014
        }
J
Jonas Schievink 已提交
2015
        let map_0 = self.binding_mode_map(&arm.pats[0]);
D
Daniel Micay 已提交
2016
        for (i, p) in arm.pats.iter().enumerate() {
J
Jonas Schievink 已提交
2017
            let map_i = self.binding_mode_map(&p);
2018

2019
            for (&key, &binding_0) in &map_0 {
2020
                match map_i.get(&key) {
C
corentih 已提交
2021
                    None => {
2022
                        resolve_error(self,
C
corentih 已提交
2023 2024 2025 2026 2027 2028 2029 2030 2031 2032
                                      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));
                        }
2033
                    }
2034 2035 2036
                }
            }

2037
            for (&key, &binding) in &map_i {
2038
                if !map_0.contains_key(&key) {
2039 2040
                    resolve_error(self,
                                  binding.span,
C
corentih 已提交
2041
                                  ResolutionError::VariableNotBoundInParentPattern(key, i + 1));
2042 2043 2044
                }
            }
        }
2045 2046
    }

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

2050
        let mut bindings_list = HashMap::new();
2051
        for pattern in &arm.pats {
J
Jonas Schievink 已提交
2052
            self.resolve_pattern(&pattern, RefutableMode, &mut bindings_list);
2053 2054
        }

2055 2056 2057 2058
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2059
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2060
        self.visit_expr(&arm.body);
2061

J
Jeffrey Seyfried 已提交
2062
        self.value_ribs.pop();
2063 2064
    }

E
Eduard Burtescu 已提交
2065
    fn resolve_block(&mut self, block: &Block) {
2066
        debug!("(resolving block) entering block");
2067
        // Move down in the graph, if there's an anonymous module rooted here.
2068
        let orig_module = self.current_module;
2069
        let anonymous_module = self.module_map.get(&block.id).cloned(); // clones a reference
2070 2071 2072

        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
2073 2074
            self.value_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(anonymous_module)));
2075 2076 2077
            self.current_module = anonymous_module;
        } else {
            self.value_ribs.push(Rib::new(NormalRibKind));
2078 2079 2080
        }

        // Descend into the block.
2081
        visit::walk_block(self, block);
2082 2083

        // Move back up.
J
Jeffrey Seyfried 已提交
2084 2085 2086 2087
        self.current_module = orig_module;
        self.value_ribs.pop();
        if let Some(_) = anonymous_module {
            self.type_ribs.pop();
G
Garming Sam 已提交
2088
        }
2089
        debug!("(resolving block) leaving block");
2090 2091
    }

F
Felix S. Klock II 已提交
2092
    fn resolve_type(&mut self, ty: &Ty) {
2093
        match ty.node {
2094
            TyKind::Path(ref maybe_qself, ref path) => {
C
corentih 已提交
2095 2096 2097
                let resolution = match self.resolve_possibly_assoc_item(ty.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
J
Jeffrey Seyfried 已提交
2098
                                                                        TypeNS) {
C
corentih 已提交
2099 2100 2101
                    // `<T>::a::b::c` is resolved by typeck alone.
                    TypecheckRequired => {
                        // Resolve embedded types.
2102
                        visit::walk_ty(self, ty);
C
corentih 已提交
2103 2104 2105 2106
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2107 2108

                // This is a path in the type namespace. Walk through scopes
2109
                // looking for it.
2110 2111 2112 2113 2114 2115 2116
                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());
2117

2118 2119 2120 2121
                    // 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 {
2122 2123 2124 2125
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2126
                        };
2127

C
corentih 已提交
2128 2129 2130
                        let is_invalid_self_type_name = path.segments.len() > 0 &&
                                                        maybe_qself.is_none() &&
                                                        path.segments[0].identifier.name ==
2131
                                                        keywords::SelfType.name();
G
Guillaume Gomez 已提交
2132
                        if is_invalid_self_type_name {
2133 2134
                            resolve_error(self,
                                          ty.span,
2135
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2136
                        } else {
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
                            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 已提交
2164
                        }
2165 2166
                    }
                }
2167
            }
2168
            _ => {}
2169
        }
2170
        // Resolve embedded types.
2171
        visit::walk_ty(self, ty);
2172 2173
    }

F
Felix S. Klock II 已提交
2174
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2175
                       pattern: &Pat,
2176 2177 2178
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2179
                       bindings_list: &mut HashMap<Name, NodeId>) {
2180
        let pat_id = pattern.id;
2181
        pattern.walk(&mut |pattern| {
2182
            match pattern.node {
2183 2184
                PatKind::Ident(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatKind::Ident with no type parameters
2185 2186 2187 2188
                    // 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
2189 2190 2191 2192
                    // 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();
2193

2194
                    let ident = path1.node;
2195
                    let renamed = mtwt::resolve(ident);
2196

2197
                    match self.resolve_bare_identifier_pattern(ident, pattern.span) {
J
Jeffrey Seyfried 已提交
2198
                        FoundStructOrEnumVariant(def) if const_ok => {
C
corentih 已提交
2199
                            debug!("(resolving pattern) resolving `{}` to struct or enum variant",
2200
                                   renamed);
2201

C
corentih 已提交
2202 2203 2204 2205 2206 2207 2208 2209
                            self.enforce_default_binding_mode(pattern,
                                                              binding_mode,
                                                              "an enum variant");
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2210
                        }
A
Alex Crichton 已提交
2211
                        FoundStructOrEnumVariant(..) => {
2212
                            resolve_error(
2213
                                self,
2214
                                pattern.span,
2215
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2216 2217
                                    renamed)
                            );
2218
                            self.record_def(pattern.id, err_path_resolution());
2219
                        }
J
Jeffrey Seyfried 已提交
2220
                        FoundConst(def, _) if const_ok => {
C
corentih 已提交
2221 2222 2223 2224 2225 2226 2227 2228
                            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,
                                            });
2229
                        }
2230
                        FoundConst(_, name) => {
2231
                            resolve_error(
2232 2233
                                self,
                                pattern.span,
2234
                                ResolutionError::ConstantForIrrefutableBinding(name)
2235
                            );
2236
                            self.record_def(pattern.id, err_path_resolution());
2237
                        }
2238
                        BareIdentifierPatternUnresolved => {
C
corentih 已提交
2239
                            debug!("(resolving pattern) binding `{}`", renamed);
2240

2241
                            let def_id = self.definitions.local_def_id(pattern.id);
2242
                            let def = Def::Local(def_id, pattern.id);
2243 2244 2245 2246 2247

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

C
corentih 已提交
2248 2249 2250 2251 2252
                            self.record_def(pattern.id,
                                            PathResolution {
                                                base_def: def,
                                                depth: 0,
                                            });
2253 2254 2255 2256 2257 2258

                            // 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.)
2259 2260
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2261
                                let last_rib = this.value_ribs.last_mut().unwrap();
2262
                                last_rib.bindings.insert(renamed, def);
2263
                                bindings_list.insert(renamed, pat_id);
2264
                            } else if mode == ArgumentIrrefutableMode &&
C
corentih 已提交
2265
                               bindings_list.contains_key(&renamed) {
2266 2267
                                // Forbid duplicate bindings in the same
                                // parameter list.
2268
                                resolve_error(
2269 2270
                                    self,
                                    pattern.span,
2271
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2272
                                        &ident.name.as_str())
2273
                                );
C
corentih 已提交
2274
                            } else if bindings_list.get(&renamed) == Some(&pat_id) {
2275 2276
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2277
                                resolve_error(
2278 2279
                                    self,
                                    pattern.span,
2280
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2281
                                        &ident.name.as_str())
2282
                                );
2283
                            }
2284 2285
                            // Else, not bound in the same pattern: do
                            // nothing.
2286 2287 2288 2289
                        }
                    }
                }

2290
                PatKind::TupleStruct(ref path, _) | PatKind::Path(ref path) => {
2291
                    // This must be an enum variant, struct or const.
C
corentih 已提交
2292 2293 2294
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            None,
                                                                            path,
J
Jeffrey Seyfried 已提交
2295
                                                                            ValueNS) {
C
corentih 已提交
2296
                        // The below shouldn't happen because all
2297
                        // qualified paths should be in PatKind::QPath.
C
corentih 已提交
2298
                        TypecheckRequired =>
2299 2300 2301 2302 2303
                            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 已提交
2304 2305
                        ResolveAttempt(resolution) => resolution,
                    };
2306
                    if let Some(path_res) = resolution {
2307
                        match path_res.base_def {
2308
                            Def::Struct(..) if path_res.depth == 0 => {
2309 2310
                                self.record_def(pattern.id, path_res);
                            }
2311
                            Def::Variant(..) | Def::Const(..) => {
2312 2313
                                self.record_def(pattern.id, path_res);
                            }
2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
                            Def::Static(..) => {
                                let segments = &path.segments;
                                let binding = if path.global {
                                    self.resolve_crate_relative_path(path.span, segments, ValueNS)
                                } else {
                                    self.resolve_module_relative_path(path.span, segments, ValueNS)
                                }.unwrap();

                                let error = ResolutionError::StaticVariableReference(binding);
                                resolve_error(self, path.span, error);
2324
                                self.record_def(pattern.id, err_path_resolution());
2325
                            }
2326 2327 2328 2329
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2330
                                // be a `T::CONST` that typeck will resolve.
2331
                                if path_res.depth == 0 {
2332
                                    resolve_error(
2333
                                        self,
2334
                                        path.span,
2335
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2336 2337 2338 2339 2340 2341
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2342
                                    );
2343
                                    self.record_def(pattern.id, err_path_resolution());
2344
                                } else {
C
corentih 已提交
2345 2346 2347 2348 2349
                                    let const_name = path.segments
                                                         .last()
                                                         .unwrap()
                                                         .identifier
                                                         .name;
2350 2351
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2352 2353 2354 2355
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
2356
                    } else if let Err(false) = self.resolve_path(pat_id, &path, 0, ValueNS) {
2357
                        resolve_error(
2358 2359
                            self,
                            path.span,
2360
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2361
                                &path.segments.last().unwrap().identifier.name.as_str())
2362
                        );
2363
                        self.record_def(pattern.id, err_path_resolution());
2364
                    }
2365
                    visit::walk_path(self, path);
2366 2367
                }

2368
                PatKind::QPath(ref qself, ref path) => {
2369
                    // Associated constants only.
C
corentih 已提交
2370 2371 2372
                    let resolution = match self.resolve_possibly_assoc_item(pat_id,
                                                                            Some(qself),
                                                                            path,
J
Jeffrey Seyfried 已提交
2373
                                                                            ValueNS) {
C
corentih 已提交
2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384
                        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);
2385
                            visit::walk_pat(self, pattern);
C
corentih 已提交
2386 2387 2388 2389
                            return true;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2390 2391 2392 2393
                    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.
2394
                            Def::AssociatedConst(..) => {
2395 2396
                                self.record_def(pattern.id, path_res);
                            }
2397
                            _ => {
2398
                                resolve_error(
2399 2400
                                    self,
                                    path.span,
2401
                                    ResolutionError::NotAnAssociatedConst(
2402
                                        &path.segments.last().unwrap().identifier.name.as_str()
2403 2404
                                    )
                                );
2405
                                self.record_def(pattern.id, err_path_resolution());
2406
                            }
2407
                        }
2408
                    } else {
C
corentih 已提交
2409 2410 2411 2412 2413 2414 2415 2416
                        resolve_error(self,
                                      path.span,
                                      ResolutionError::UnresolvedAssociatedConst(&path.segments
                                                                                      .last()
                                                                                      .unwrap()
                                                                                      .identifier
                                                                                      .name
                                                                                      .as_str()));
2417
                        self.record_def(pattern.id, err_path_resolution());
2418
                    }
2419
                    visit::walk_pat(self, pattern);
2420 2421
                }

2422
                PatKind::Struct(ref path, _, _) => {
J
Jeffrey Seyfried 已提交
2423
                    match self.resolve_path(pat_id, path, 0, TypeNS) {
2424
                        Ok(definition) => {
2425 2426
                            self.record_def(pattern.id, definition);
                        }
2427 2428
                        Err(true) => self.record_def(pattern.id, err_path_resolution()),
                        Err(false) => {
2429 2430 2431
                            resolve_error(
                                self,
                                path.span,
2432
                                ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
2433
                                    &path_names_to_string(path, 0))
2434
                            );
2435
                            self.record_def(pattern.id, err_path_resolution());
2436 2437
                        }
                    }
2438
                    visit::walk_path(self, path);
2439 2440
                }

2441
                PatKind::Lit(_) | PatKind::Range(..) => {
2442
                    visit::walk_pat(self, pattern);
2443 2444
                }

2445
                _ => {
2446 2447 2448
                    // Nothing to do.
                }
            }
2449
            true
2450
        });
2451 2452
    }

2453
    fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span)
E
Eduard Burtescu 已提交
2454
                                       -> BareIdentifierPatternResolution {
2455 2456 2457 2458 2459 2460 2461 2462
        let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) {
            Some(LexicalScopeBinding::Item(binding)) => binding,
            _ => return BareIdentifierPatternUnresolved,
        };
        let def = binding.def().unwrap();

        match def {
            Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def),
2463
            Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.name),
2464 2465 2466
            Def::Static(..) => {
                let error = ResolutionError::StaticVariableReference(binding);
                resolve_error(self, span, error);
2467 2468 2469
                BareIdentifierPatternUnresolved
            }
            _ => BareIdentifierPatternUnresolved,
2470 2471 2472
        }
    }

2473 2474 2475
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2476
                                   maybe_qself: Option<&ast::QSelf>,
2477
                                   path: &Path,
J
Jeffrey Seyfried 已提交
2478
                                   namespace: Namespace)
C
corentih 已提交
2479
                                   -> AssocItemResolveResult {
2480 2481
        let max_assoc_types;

2482
        match maybe_qself {
2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493
            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();
            }
2494 2495 2496
        }

        let mut resolution = self.with_no_errors(|this| {
2497
            this.resolve_path(id, path, 0, namespace).ok()
2498 2499 2500 2501 2502 2503
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
2504
                resolution = this.resolve_path(id, path, depth, TypeNS).ok();
2505 2506
            });
        }
2507
        if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
2508 2509 2510 2511 2512 2513
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

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

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

2523
        if path.global {
2524 2525
            let binding = self.resolve_crate_relative_path(span, segments, namespace);
            return binding.map(|binding| mk_res(binding.def().unwrap()));
2526 2527
        }

2528
        // Try to find a path to an item in a module.
2529
        let last_ident = segments.last().unwrap().identifier;
V
Cleanup  
Vadim Petrochenkov 已提交
2530 2531 2532 2533 2534 2535 2536
        // 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
2537
                        .get(&last_ident.name)
V
Cleanup  
Vadim Petrochenkov 已提交
2538 2539 2540 2541
                        .map_or(def, |prim_ty| Some(LocalDef::from_def(Def::PrimTy(*prim_ty)))),
                _ => def
            }
        };
2542

2543 2544 2545 2546 2547 2548 2549
        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 已提交
2550 2551
            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
            //                     // not to non-existent std::u8::max_value
2552 2553 2554 2555
            // }
            //
            // Such behavior is required for backward compatibility.
            // The same fallback is used when `a` resolves to nothing.
2556 2557
            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 已提交
2558
        }
2559

V
Cleanup  
Vadim Petrochenkov 已提交
2560
        let unqualified_def = resolve_identifier_with_fallback(self, false);
2561 2562 2563
        let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
        match (qualified_binding, unqualified_def) {
            (Ok(binding), Some(ref ud)) if binding.def().unwrap() == ud.def => {
N
Nick Cameron 已提交
2564 2565
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
2566 2567
                              id,
                              span,
N
Nick Cameron 已提交
2568 2569 2570
                              "unnecessary qualification".to_string());
            }
            _ => {}
2571
        }
N
Nick Cameron 已提交
2572

2573
        qualified_binding.map(|binding| mk_res(binding.def().unwrap()))
2574 2575
    }

2576
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2577
    fn resolve_identifier(&mut self,
2578
                          identifier: ast::Ident,
2579
                          namespace: Namespace,
2580
                          record_used: bool)
2581
                          -> Option<LocalDef> {
2582
        if identifier.name == keywords::Invalid.name() {
2583
            return Some(LocalDef::from_def(Def::Err));
2584 2585
        }

2586 2587
        self.resolve_ident_in_lexical_scope(identifier, namespace, record_used)
            .map(LexicalScopeBinding::local_def)
2588 2589 2590
    }

    // Resolve a local definition, potentially adjusting for closures.
2591
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
2592
        let ribs = match local_def.ribs {
C
corentih 已提交
2593 2594 2595
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
2596 2597 2598
        };
        let mut def = local_def.def;
        match def {
2599
            Def::Upvar(..) => {
2600
                span_bug!(span, "unexpected {:?} in bindings", def)
2601
            }
2602
            Def::Local(_, node_id) => {
2603 2604
                for rib in ribs {
                    match rib.kind {
2605
                        NormalRibKind | ModuleRibKind(..) => {
2606 2607 2608 2609
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;
2610
                            let node_def_id = self.definitions.local_def_id(node_id);
2611

C
corentih 已提交
2612 2613 2614
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2615
                            if let Some(&index) = seen.get(&node_id) {
2616
                                def = Def::Upvar(node_def_id, node_id, index, function_id);
2617 2618
                                continue;
                            }
C
corentih 已提交
2619 2620 2621
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2622
                            let depth = vec.len();
C
corentih 已提交
2623 2624 2625 2626
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2627

2628
                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
2629 2630 2631 2632 2633 2634
                            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 已提交
2635 2636 2637
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2638 2639 2640 2641
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2642 2643 2644
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2645 2646 2647 2648 2649
                            return None;
                        }
                    }
                }
            }
2650
            Def::TyParam(..) | Def::SelfTy(..) => {
2651 2652
                for rib in ribs {
                    match rib.kind {
2653
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) |
2654
                        ModuleRibKind(..) => {
2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676
                            // 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);
2677 2678
    }

2679
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
2680
    fn resolve_module_relative_path(&mut self,
2681
                                    span: Span,
2682
                                    segments: &[ast::PathSegment],
2683
                                    namespace: Namespace)
2684 2685
                                    -> Result<&'a NameBinding<'a>,
                                              bool /* true if an error was reported */> {
C
corentih 已提交
2686 2687 2688 2689 2690 2691
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2692

2693
        let containing_module;
2694
        match self.resolve_module_path(&module_path, UseLexicalScope, span) {
2695 2696 2697 2698
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
2699
                        let msg = format!("Use of undeclared type or module `{}`",
2700
                                          names_to_string(&module_path));
2701
                        (span, msg)
2702 2703
                    }
                };
2704

J
Jonas Schievink 已提交
2705
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2706
                return Err(true);
2707
            }
2708
            Indeterminate => return Err(false),
J
Jeffrey Seyfried 已提交
2709
            Success(resulting_module) => {
2710 2711 2712 2713
                containing_module = resulting_module;
            }
        }

2714
        let name = segments.last().unwrap().identifier.name;
2715
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2716
        result.success().map(|binding| {
2717
            self.check_privacy(name, binding, span);
2718
            binding
2719
        }).ok_or(false)
2720 2721
    }

2722 2723
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
2724
    fn resolve_crate_relative_path(&mut self,
2725
                                   span: Span,
2726
                                   segments: &[ast::PathSegment],
2727
                                   namespace: Namespace)
2728 2729
                                   -> Result<&'a NameBinding<'a>,
                                             bool /* true if an error was reported */> {
C
corentih 已提交
2730 2731 2732 2733 2734 2735
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2736

2737
        let root_module = self.graph_root;
2738

2739
        let containing_module;
2740
        match self.resolve_module_path_from_root(root_module,
2741
                                                 &module_path,
2742
                                                 0,
J
Jeffrey Seyfried 已提交
2743
                                                 span) {
2744 2745 2746 2747 2748
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
2749
                                          names_to_string(&module_path));
2750
                        (span, msg)
2751 2752 2753
                    }
                };

J
Jonas Schievink 已提交
2754
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2755
                return Err(true);
2756 2757
            }

2758
            Indeterminate => return Err(false),
2759

J
Jeffrey Seyfried 已提交
2760
            Success(resulting_module) => {
2761 2762 2763 2764
                containing_module = resulting_module;
            }
        }

2765
        let name = segments.last().unwrap().identifier.name;
J
Jeffrey Seyfried 已提交
2766
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2767
        result.success().map(|binding| {
2768
            self.check_privacy(name, binding, span);
2769
            binding
2770
        }).ok_or(false)
2771 2772
    }

C
corentih 已提交
2773 2774
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2775
    {
2776
        self.emit_errors = false;
A
Alex Crichton 已提交
2777
        let rs = f(self);
2778 2779 2780 2781
        self.emit_errors = true;
        rs
    }

2782
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
2783
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
2784
            match t.node {
2785 2786
                TyKind::Path(None, _) => Some(t.id),
                TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
2787 2788 2789 2790 2791 2792 2793
                // 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,
            }
        }

2794
        if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
2795
            // Look for a field with the same name in the current self_type.
2796
            match self.def_map.get(&node_id).map(|d| d.full_def()) {
2797 2798 2799 2800
                Some(Def::Enum(did)) |
                Some(Def::TyAlias(did)) |
                Some(Def::Struct(did)) |
                Some(Def::Variant(_, did)) => match self.structs.get(&did) {
2801 2802 2803 2804 2805
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
2806
                    }
2807 2808 2809
                },
                _ => {} // Self type didn't resolve properly
            }
2810 2811 2812
        }

        // Look for a method in the current trait.
2813
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
2814 2815
            if let Some(&is_static_method) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method {
2816
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
2817 2818
                } else {
                    return TraitItem;
2819 2820 2821 2822 2823 2824 2825
                }
            }
        }

        NoSuggestion
    }

2826
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
2827
        if let Some(macro_name) = self.session.available_macros
2828
                                  .borrow().iter().find(|n| n.as_str() == name) {
2829 2830 2831
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

2832 2833 2834 2835
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
2836

2837
        if let Some(found) = find_best_match_for_name(names, name, None) {
J
Jonas Schievink 已提交
2838
            if name != found {
2839
                return SuggestionType::Function(found);
2840
            }
2841
        } SuggestionType::NotFound
2842 2843
    }

2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855
    fn resolve_labeled_block(&mut self, label: Option<ast::Ident>, id: NodeId, block: &Block) {
        if let Some(label) = label {
            let (label, def) = (mtwt::resolve(label), Def::Label(id));
            self.with_label_rib(|this| {
                this.label_ribs.last_mut().unwrap().bindings.insert(label, def);
                this.visit_block(block);
            });
        } else {
            self.visit_block(block);
        }
    }

2856
    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
P
Patrick Walton 已提交
2857 2858
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
2859 2860 2861

        self.record_candidate_traits_for_expr_if_necessary(expr);

2862
        // Next, resolve the node.
2863
        match expr.node {
2864
            ExprKind::Path(ref maybe_qself, ref path) => {
C
corentih 已提交
2865 2866 2867
                let resolution = match self.resolve_possibly_assoc_item(expr.id,
                                                                        maybe_qself.as_ref(),
                                                                        path,
J
Jeffrey Seyfried 已提交
2868
                                                                        ValueNS) {
C
corentih 已提交
2869 2870 2871 2872 2873
                    // `<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);
2874
                        visit::walk_expr(self, expr);
C
corentih 已提交
2875 2876 2877 2878
                        return;
                    }
                    ResolveAttempt(resolution) => resolution,
                };
2879

2880 2881
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
2882
                if let Some(path_res) = resolution {
2883
                    // Check if struct variant
2884
                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
2885 2886 2887 2888 2889 2890
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
2891
                        let path_name = path_names_to_string(path, 0);
2892

N
Nick Cameron 已提交
2893 2894
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
2895
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
2896

C
corentih 已提交
2897
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
2898 2899
                                          path_name);
                        if self.emit_errors {
2900
                            err.help(&msg);
2901
                        } else {
N
Nick Cameron 已提交
2902
                            err.span_help(expr.span, &msg);
2903
                        }
N
Nick Cameron 已提交
2904
                        err.emit();
2905
                        self.record_def(expr.id, err_path_resolution());
2906
                    } else {
2907
                        // Write the result into the def map.
2908
                        debug!("(resolving expr) resolved `{}`",
2909
                               path_names_to_string(path, 0));
2910

2911 2912
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
2913
                        if path_res.depth != 0 {
2914
                            let method_name = path.segments.last().unwrap().identifier.name;
2915
                            let traits = self.get_traits_containing_item(method_name);
2916 2917 2918
                            self.trait_map.insert(expr.id, traits);
                        }

2919
                        self.record_def(expr.id, path_res);
2920
                    }
2921 2922 2923 2924 2925
                } 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.)
2926
                    let path_name = path_names_to_string(path, 0);
2927
                    let type_res = self.with_no_errors(|this| {
J
Jeffrey Seyfried 已提交
2928
                        this.resolve_path(expr.id, path, 0, TypeNS)
2929
                    });
2930 2931

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

2933
                    if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
J
Jeffrey Seyfried 已提交
2934 2935
                        let error_variant =
                            ResolutionError::StructVariantUsedAsFunction(&path_name);
2936 2937 2938 2939 2940 2941
                        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 {
2942
                            err.help(&msg);
2943 2944 2945 2946 2947 2948 2949 2950 2951
                        } 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 {
2952 2953 2954 2955 2956 2957 2958 2959 2960
                            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
                            });
2961

2962
                            if method_scope &&
2963
                                    &path_name[..] == keywords::SelfValue.name().as_str() {
C
corentih 已提交
2964 2965 2966
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
2967 2968 2969 2970 2971 2972
                            } 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
2973
                                        match self.find_best_match(&path_name) {
2974 2975 2976 2977 2978 2979
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
                                        }
2980 2981
                                    }
                                    Field => format!("`self.{}`", path_name),
C
corentih 已提交
2982
                                    TraitItem => format!("to call `self.{}`", path_name),
2983
                                    TraitMethod(path_str) =>
C
corentih 已提交
2984
                                        format!("to call `{}::{}`", path_str, path_name),
2985 2986
                                };

2987
                                let mut context =  UnresolvedNameContext::Other;
2988
                                if !msg.is_empty() {
2989 2990 2991 2992 2993 2994 2995 2996
                                    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<_>>();

2997
                                    match self.resolve_module_path(&name_path[..],
J
Jeffrey Seyfried 已提交
2998 2999
                                                                   UseLexicalScope,
                                                                   expr.span) {
3000
                                        Success(_) => {
3001
                                            context = UnresolvedNameContext::PathIsMod(parent);
3002 3003 3004
                                        },
                                        _ => {},
                                    };
3005
                                }
3006

3007 3008
                                resolve_error(self,
                                              expr.span,
3009
                                              ResolutionError::UnresolvedName(
J
Jonas Schievink 已提交
3010
                                                  &path_name, &msg, context));
3011
                            }
V
Vincent Belliard 已提交
3012
                        }
3013 3014 3015
                    }
                }

3016
                visit::walk_expr(self, expr);
3017 3018
            }

3019
            ExprKind::Struct(ref path, _, _) => {
3020 3021 3022
                // 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 已提交
3023
                match self.resolve_path(expr.id, path, 0, TypeNS) {
3024 3025 3026
                    Ok(definition) => self.record_def(expr.id, definition),
                    Err(true) => self.record_def(expr.id, err_path_resolution()),
                    Err(false) => {
3027
                        debug!("(resolving expression) didn't find struct def",);
3028

3029 3030
                        resolve_error(self,
                                      path.span,
3031
                                      ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
3032
                                                                &path_names_to_string(path, 0))
3033
                                     );
3034
                        self.record_def(expr.id, err_path_resolution());
3035 3036 3037
                    }
                }

3038
                visit::walk_expr(self, expr);
3039 3040
            }

3041
            ExprKind::Loop(_, Some(label)) | ExprKind::While(_, _, Some(label)) => {
3042
                self.with_label_rib(|this| {
3043
                    let def = Def::Label(expr.id);
3044

3045
                    {
3046
                        let rib = this.label_ribs.last_mut().unwrap();
3047
                        rib.bindings.insert(mtwt::resolve(label), def);
3048
                    }
3049

3050
                    visit::walk_expr(this, expr);
3051
                })
3052 3053
            }

3054 3055
            ExprKind::Break(Some(label)) | ExprKind::Again(Some(label)) => {
                match self.search_label(mtwt::resolve(label.node)) {
3056
                    None => {
3057
                        self.record_def(expr.id, err_path_resolution());
3058
                        resolve_error(self,
3059 3060
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
3061
                    }
3062
                    Some(def @ Def::Label(_)) => {
3063
                        // Since this def is a label, it is never read.
C
corentih 已提交
3064 3065 3066 3067 3068
                        self.record_def(expr.id,
                                        PathResolution {
                                            base_def: def,
                                            depth: 0,
                                        })
3069 3070
                    }
                    Some(_) => {
3071
                        span_bug!(expr.span, "label wasn't mapped to a label def!")
3072 3073 3074
                    }
                }
            }
3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107

            ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => {
                self.visit_expr(subexpression);

                self.value_ribs.push(Rib::new(NormalRibKind));
                self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new());
                self.visit_block(if_block);
                self.value_ribs.pop();

                optional_else.as_ref().map(|expr| self.visit_expr(expr));
            }

            ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => {
                self.visit_expr(subexpression);
                self.value_ribs.push(Rib::new(NormalRibKind));
                self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new());

                self.resolve_labeled_block(label, expr.id, block);

                self.value_ribs.pop();
            }

            ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => {
                self.visit_expr(subexpression);
                self.value_ribs.push(Rib::new(NormalRibKind));
                self.resolve_pattern(pattern, LocalIrrefutableMode, &mut HashMap::new());

                self.resolve_labeled_block(label, expr.id, block);

                self.value_ribs.pop();
            }

            ExprKind::Field(ref subexpression, _) => {
3108 3109
                self.resolve_expr(subexpression, Some(expr));
            }
3110
            ExprKind::MethodCall(_, ref types, ref arguments) => {
3111 3112 3113 3114 3115 3116 3117 3118 3119
                let mut arguments = arguments.iter();
                self.resolve_expr(arguments.next().unwrap(), Some(expr));
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
                for ty in types.iter() {
                    self.visit_ty(ty);
                }
            }
3120

B
Brian Anderson 已提交
3121
            _ => {
3122
                visit::walk_expr(self, expr);
3123 3124 3125 3126
            }
        }
    }

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

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

S
Seo Sanghyeon 已提交
3152 3153 3154 3155
        fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
                          trait_def_id: DefId,
                          import_id: Option<NodeId>,
                          name: Name) {
3156
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3157 3158
                   trait_def_id,
                   name);
S
Seo Sanghyeon 已提交
3159 3160 3161 3162
            found_traits.push(TraitCandidate {
                def_id: trait_def_id,
                import_id: import_id,
            });
E
Eduard Burtescu 已提交
3163
        }
3164

3165
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3166 3167 3168
        // 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)) {
S
Seo Sanghyeon 已提交
3169
                add_trait_info(&mut found_traits, trait_def_id, None, name);
E
Eduard Burtescu 已提交
3170
            }
J
Jeffrey Seyfried 已提交
3171
        }
3172

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

3189
                for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
J
Jeffrey Seyfried 已提交
3190 3191
                    let trait_def_id = binding.def().unwrap().def_id();
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
S
Seo Sanghyeon 已提交
3192 3193 3194 3195 3196 3197 3198 3199
                        let mut import_id = None;
                        if let NameBindingKind::Import { directive, .. } = binding.kind {
                            let id = directive.id;
                            self.maybe_unused_trait_imports.insert(id);
                            import_id = Some(id);
                        }
                        add_trait_info(&mut found_traits, trait_def_id, import_id, name);
                        self.record_use(trait_name, binding);
J
Jeffrey Seyfried 已提交
3200 3201 3202
                    }
                }
            };
3203
            search_in_module(search_module);
3204

3205
            match search_module.parent_link {
3206 3207 3208 3209
                NoParentLink | ModuleParentLink(..) => {
                    search_module.prelude.borrow().map(search_in_module);
                    break;
                }
E
Eduard Burtescu 已提交
3210
                BlockParentLink(parent_module, _) => {
3211
                    search_module = parent_module;
3212
                }
E
Eduard Burtescu 已提交
3213
            }
3214 3215
        }

E
Eduard Burtescu 已提交
3216
        found_traits
3217 3218
    }

3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238
    /// 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() {
3239
            self.populate_module_if_necessary(in_module);
3240 3241 3242 3243 3244 3245 3246 3247 3248 3249

            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
3250
                        let ident = ast::Ident::with_empty_ctxt(name);
3251 3252 3253 3254 3255
                        let params = PathParameters::none();
                        let segment = PathSegment {
                            identifier: ident,
                            parameters: params,
                        };
3256
                        let span = name_binding.span;
3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270
                        let mut segms = path_segments.clone();
                        segms.push(segment);
                        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)
3271
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283
                            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();
3284
                            let ident = ast::Ident::with_empty_ctxt(name);
3285 3286 3287 3288 3289 3290 3291 3292
                            let params = PathParameters::none();
                            let segm = PathSegment {
                                identifier: ident,
                                parameters: params,
                            };
                            paths.push(segm);
                            paths
                        }
3293
                        _ => bug!(),
3294 3295
                    };

3296
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3297
                        // add the module to the lookup
3298
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310
                        worklist.push((module, path_segments, is_extern));
                    }
                }
            })
        }

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

3311 3312
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
3313
        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
3314
            panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
3315
        }
3316 3317
    }

F
Felix S. Klock II 已提交
3318
    fn enforce_default_binding_mode(&mut self,
C
corentih 已提交
3319 3320 3321
                                    pat: &Pat,
                                    pat_binding_mode: BindingMode,
                                    descr: &str) {
3322
        match pat_binding_mode {
3323 3324
            BindingMode::ByValue(_) => {}
            BindingMode::ByRef(..) => {
3325 3326
                resolve_error(self,
                              pat.span,
3327
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3328 3329 3330
            }
        }
    }
3331

3332
    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
3333
        let (path, id) = match *vis {
3334 3335 3336 3337
            ast::Visibility::Public => return ty::Visibility::Public,
            ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
            ast::Visibility::Restricted { ref path, id } => (path, id),
            ast::Visibility::Inherited => {
3338 3339
                let current_module =
                    self.get_nearest_normal_module_parent_or_self(self.current_module);
3340 3341
                let id =
                    self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
3342 3343 3344 3345 3346 3347 3348 3349 3350
                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 };
3351
                self.def_map.insert(id, path_resolution);
3352
                ty::Visibility::Restricted(self.definitions.as_local_node_id(def.def_id()).unwrap())
3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369
            }
            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
    }

3370 3371
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
        let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
3372
        let node_id = self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
3373
        vis.is_accessible_from(node_id, self)
3374 3375
    }

3376 3377
    fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
        if !self.is_accessible(binding.vis) {
3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397
            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));
            }
        }
    }
3398

3399 3400 3401 3402 3403 3404 3405
    fn report_conflict(&self,
                       parent: Module,
                       name: Name,
                       ns: Namespace,
                       binding: &NameBinding,
                       old_binding: &NameBinding) {
        // Error on the second of two conflicting names
3406
        if old_binding.span.lo > binding.span.lo {
3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421
            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"),
        };

3422
        let span = binding.span;
3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446
        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),
            },
        };

3447 3448
        if old_binding.span != codemap::DUMMY_SP {
            err.span_note(old_binding.span, &format!("previous {} of `{}` here", noun, name));
3449 3450 3451 3452
        }
        err.emit();
    }
}
3453 3454 3455 3456 3457 3458 3459 3460 3461 3462

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("::")
        }
3463
        result.push_str(&name.as_str());
C
corentih 已提交
3464
    }
3465 3466 3467 3468
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3469
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3470 3471 3472 3473 3474 3475
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498
/// 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,
                   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 {
3499
                session.help(
T
tiehuis 已提交
3500
                    &format!("you can import it into scope: `use {};`.",
3501 3502 3503
                        &path_strings[0]),
                );
            } else {
3504
                session.help("you can import several candidates \
3505 3506 3507 3508 3509
                    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 {
3510
                        session.help(
3511 3512 3513 3514
                            &format!("  and {} other candidates", count).to_string(),
                        );
                        break;
                    } else {
3515
                        session.help(
3516 3517 3518 3519 3520 3521 3522 3523
                            &format!("  `{}`", path_string).to_string(),
                        );
                    }
                }
            }
        }
    } else {
        // nothing found:
3524
        session.help(
3525 3526 3527 3528 3529 3530 3531
            &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()),
        );
    };
}

3532
/// A somewhat inefficient routine to obtain the name of a module.
3533
fn module_to_string(module: Module) -> String {
3534 3535
    let mut names = Vec::new();

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

3552
    if names.is_empty() {
3553 3554 3555 3556 3557
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3558 3559
fn err_path_resolution() -> PathResolution {
    PathResolution {
3560
        base_def: Def::Err,
3561 3562 3563 3564
        depth: 0,
    }
}

3565

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

3572
/// Entry point to crate resolution.
3573
pub fn resolve_crate<'a, 'b>(resolver: &'b mut Resolver<'a>, krate: &'b Crate) {
3574 3575 3576 3577 3578 3579 3580 3581
    // 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.

3582 3583
    resolver.build_reduced_graph(krate);
    resolve_imports::resolve_imports(resolver);
3584 3585
    resolver.resolve_crate(krate);

3586
    check_unused::check_crate(resolver, krate);
3587
    resolver.report_privacy_errors();
3588
}
3589

3590 3591 3592 3593 3594 3595 3596 3597 3598
pub fn with_resolver<'a, T, F>(session: &'a Session,
                               definitions: &'a Definitions,
                               make_glob_map: MakeGlobMap,
                               f: F) -> T
    where F: for<'b> FnOnce(Resolver<'b>) -> T,
{
    let arenas = Resolver::arenas();
    let resolver = Resolver::new(session, definitions, make_glob_map, &arenas);
    f(resolver)
G
Garming Sam 已提交
3599 3600
}

3601
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }