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

11
#![crate_name = "rustc_resolve"]
12
#![unstable(feature = "rustc_private", issue = "27812")]
13 14
#![crate_type = "dylib"]
#![crate_type = "rlib"]
15
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
16
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
17
      html_root_url = "https://doc.rust-lang.org/nightly/")]
18
#![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 31
extern crate syntax_pos;
extern crate rustc_errors as errors;
32
extern crate arena;
C
corentih 已提交
33
#[macro_use]
34 35
extern crate rustc;

S
Steven Fackler 已提交
36 37 38 39 40
use self::Namespace::*;
use self::FallbackSuggestion::*;
use self::TypeParameters::*;
use self::RibKind::*;

41
use rustc::hir::map::{Definitions, DefCollector};
42
use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
43
use rustc::middle::cstore::CrateLoader;
44 45
use rustc::session::Session;
use rustc::lint;
46
use rustc::hir::def::*;
47
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
48
use rustc::ty;
S
Seo Sanghyeon 已提交
49
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
50
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet};
51

J
Jeffrey Seyfried 已提交
52
use syntax::ext::hygiene::{Mark, SyntaxContext};
53
use syntax::ast::{self, FloatTy};
J
Jeffrey Seyfried 已提交
54
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, Ident, SpannedIdent, IntTy, UintTy};
J
Jeffrey Seyfried 已提交
55
use syntax::ext::base::SyntaxExtension;
J
Jeffrey Seyfried 已提交
56
use syntax::ext::base::Determinacy::{Determined, Undetermined};
57
use syntax::symbol::{Symbol, keywords};
58
use syntax::util::lev_distance::find_best_match_for_name;
59

60
use syntax::visit::{self, FnKind, Visitor};
61
use syntax::attr;
62 63 64
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
65 66
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind};
67

68
use syntax_pos::{Span, DUMMY_SP};
69 70
use errors::DiagnosticBuilder;

71
use std::cell::{Cell, RefCell};
72
use std::fmt;
73
use std::mem::replace;
74
use std::rc::Rc;
75

76
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
J
Jeffrey Seyfried 已提交
77
use macros::{InvocationData, LegacyBinding, LegacyScope};
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

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

88 89
enum SuggestionType {
    Macro(String),
90
    Function(Symbol),
91 92 93
    NotFound,
}

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

J
Jeffrey Seyfried 已提交
100
enum ResolutionError<'a> {
101
    /// error E0401: can't use type parameters from outer function
102
    TypeParametersFromOuterFunction,
103
    /// error E0402: cannot use an outer type parameter in this context
104
    OuterTypeParameterContext,
105
    /// error E0403: the name is already used for a type parameter in this type parameter list
C
Chris Stankus 已提交
106
    NameAlreadyUsedInTypeParameterList(Name, &'a Span),
107
    /// error E0404: is not a trait
108
    IsNotATrait(&'a str, &'a str),
109
    /// error E0405: use of undeclared trait name
110
    UndeclaredTraitName(&'a str, SuggestedCandidates),
111
    /// error E0407: method is not a member of trait
112
    MethodNotMemberOfTrait(Name, &'a str),
113 114 115 116
    /// 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),
M
Manish Goregaokar 已提交
117 118
    /// error E0408: variable `{}` from pattern #{} is not bound in pattern #{}
    VariableNotBoundInPattern(Name, usize, usize),
119
    /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
M
Mikhail Modin 已提交
120
    VariableBoundWithDifferentMode(Name, usize, Span),
121
    /// error E0411: use of `Self` outside of an impl or trait
122
    SelfUsedOutsideImplOrTrait,
123
    /// error E0412: use of undeclared
124
    UseOfUndeclared(&'a str, &'a str, SuggestedCandidates),
125
    /// error E0415: identifier is bound more than once in this parameter list
126
    IdentifierBoundMoreThanOnceInParameterList(&'a str),
127
    /// error E0416: identifier is bound more than once in the same pattern
128
    IdentifierBoundMoreThanOnceInSamePattern(&'a str),
129
    /// error E0423: is a struct variant name, but this expression uses it like a function name
130
    StructVariantUsedAsFunction(&'a str),
131
    /// error E0424: `self` is not available in a static method
132
    SelfNotAvailableInStaticMethod,
133
    /// error E0425: unresolved name
134 135 136 137 138
    UnresolvedName {
        path: &'a str,
        message: &'a str,
        context: UnresolvedNameContext<'a>,
        is_static_method: bool,
G
ggomez 已提交
139 140
        is_field: bool,
        def: Def,
141
    },
142
    /// error E0426: use of undeclared label
143
    UndeclaredLabel(&'a str),
144
    /// error E0429: `self` imports are only allowed within a { } list
145
    SelfImportsOnlyAllowedWithin,
146
    /// error E0430: `self` import can only appear once in the list
147
    SelfImportCanOnlyAppearOnceInTheList,
148
    /// error E0431: `self` import can only appear in an import list with a non-empty prefix
149
    SelfImportOnlyInImportListWithNonEmptyPrefix,
150
    /// error E0432: unresolved import
151
    UnresolvedImport(Option<(&'a str, &'a str)>),
152
    /// error E0433: failed to resolve
153
    FailedToResolve(&'a str),
154
    /// error E0434: can't capture dynamic environment in a fn item
155
    CannotCaptureDynamicEnvironmentInFnItem,
156
    /// error E0435: attempt to use a non-constant value in a constant
157
    AttemptToUseNonConstantValueInConstant,
158
    /// error E0530: X bindings cannot shadow Ys
159
    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
160
    /// error E0531: unresolved pattern path kind `name`
161
    PatPathUnresolved(&'a str, &'a Path),
162
    /// error E0532: expected pattern path kind, found another pattern path kind
163
    PatPathUnexpected(&'a str, &'a str, &'a Path),
164 165
}

166
/// Context of where `ResolutionError::UnresolvedName` arose.
167
#[derive(Clone, PartialEq, Eq, Debug)]
168 169
enum UnresolvedNameContext<'a> {
    /// `PathIsMod(parent)` indicates that a given path, used in
170
    /// expression context, actually resolved to a module rather than
171 172 173
    /// a value. The optional expression attached to the variant is the
    /// the parent of the erroneous path expression.
    PathIsMod(Option<&'a Expr>),
174 175 176 177

    /// `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.)
178 179 180
    Other,
}

181
fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
182
                                 span: syntax_pos::Span,
183
                                 resolution_error: ResolutionError<'c>) {
N
Nick Cameron 已提交
184
    resolve_struct_error(resolver, span, resolution_error).emit();
N
Nick Cameron 已提交
185 186
}

187
fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
188
                                        span: syntax_pos::Span,
189 190
                                        resolution_error: ResolutionError<'c>)
                                        -> DiagnosticBuilder<'a> {
N
Nick Cameron 已提交
191
    match resolution_error {
192
        ResolutionError::TypeParametersFromOuterFunction => {
193 194 195 196 197
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0401,
                                           "can't use type parameters from outer function; \
                                           try using a local type parameter instead");
198
            err.span_label(span, &format!("use of type variable from outer function"));
199
            err
C
corentih 已提交
200
        }
201
        ResolutionError::OuterTypeParameterContext => {
N
Nick Cameron 已提交
202 203 204 205
            struct_span_err!(resolver.session,
                             span,
                             E0402,
                             "cannot use an outer type parameter in this context")
C
corentih 已提交
206
        }
C
Chris Stankus 已提交
207 208 209 210 211 212 213 214 215 216 217
        ResolutionError::NameAlreadyUsedInTypeParameterList(name, first_use_span) => {
             let mut err = struct_span_err!(resolver.session,
                                            span,
                                            E0403,
                                            "the name `{}` is already used for a type parameter \
                                            in this type parameter list",
                                            name);
             err.span_label(span, &format!("already used"));
             err.span_label(first_use_span.clone(), &format!("first use of `{}`", name));
             err

C
corentih 已提交
218
        }
219
        ResolutionError::IsNotATrait(name, kind_name) => {
R
Ryan Scott 已提交
220 221 222 223 224
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0404,
                                           "`{}` is not a trait",
                                           name);
225
            err.span_label(span, &format!("expected trait, found {}", kind_name));
R
Ryan Scott 已提交
226
            err
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.span_label(span, &format!("`{}` is not in scope", name));
236
            err
C
corentih 已提交
237
        }
238
        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
C
crypto-universe 已提交
239 240 241 242 243 244
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0407,
                                           "method `{}` is not a member of trait `{}`",
                                           method,
                                           trait_);
245
            err.span_label(span, &format!("not a member of trait `{}`", trait_));
C
crypto-universe 已提交
246
            err
C
corentih 已提交
247
        }
248
        ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
S
Shyam Sundar B 已提交
249
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
250 251 252 253
                             span,
                             E0437,
                             "type `{}` is not a member of trait `{}`",
                             type_,
S
Shyam Sundar B 已提交
254
                             trait_);
255
            err.span_label(span, &format!("not a member of trait `{}`", trait_));
S
Shyam Sundar B 已提交
256
            err
C
corentih 已提交
257
        }
258
        ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
S
Shyam Sundar B 已提交
259
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
260 261 262 263
                             span,
                             E0438,
                             "const `{}` is not a member of trait `{}`",
                             const_,
S
Shyam Sundar B 已提交
264
                             trait_);
265
            err.span_label(span, &format!("not a member of trait `{}`", trait_));
S
Shyam Sundar B 已提交
266
            err
C
corentih 已提交
267
        }
M
Manish Goregaokar 已提交
268
        ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => {
269
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
270 271
                             span,
                             E0408,
M
Manish Goregaokar 已提交
272
                             "variable `{}` from pattern #{} is not bound in pattern #{}",
N
Nick Cameron 已提交
273
                             variable_name,
M
Manish Goregaokar 已提交
274
                             from,
275 276 277
                             to);
            err.span_label(span, &format!("pattern doesn't bind `{}`", variable_name));
            err
C
corentih 已提交
278
        }
M
Mikhail Modin 已提交
279 280 281 282
        ResolutionError::VariableBoundWithDifferentMode(variable_name,
                                                        pattern_number,
                                                        first_binding_span) => {
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
283 284 285 286 287
                             span,
                             E0409,
                             "variable `{}` is bound with different mode in pattern #{} than in \
                              pattern #1",
                             variable_name,
M
Mikhail Modin 已提交
288 289 290 291
                             pattern_number);
            err.span_label(span, &format!("bound in different ways"));
            err.span_label(first_binding_span, &format!("first binding"));
            err
C
corentih 已提交
292
        }
293
        ResolutionError::SelfUsedOutsideImplOrTrait => {
294 295 296 297
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0411,
                                           "use of `Self` outside of an impl or trait");
J
Jonathan Turner 已提交
298
            err.span_label(span, &format!("used outside of impl or trait"));
299
            err
C
corentih 已提交
300
        }
301 302 303 304 305 306 307
        ResolutionError::UseOfUndeclared(kind, name, candidates) => {
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0412,
                                           "{} `{}` is undefined or not in scope",
                                           kind,
                                           name);
308
            show_candidates(&mut err, &candidates);
309
            err.span_label(span, &format!("undefined or not in scope"));
310
            err
C
corentih 已提交
311
        }
312
        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
313
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
314 315 316
                             span,
                             E0415,
                             "identifier `{}` is bound more than once in this parameter list",
317
                             identifier);
318
            err.span_label(span, &format!("used as parameter more than once"));
319
            err
C
corentih 已提交
320
        }
321
        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
322
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
323 324 325
                             span,
                             E0416,
                             "identifier `{}` is bound more than once in the same pattern",
326
                             identifier);
327
            err.span_label(span, &format!("used in a pattern more than once"));
328
            err
C
corentih 已提交
329
        }
330
        ResolutionError::StructVariantUsedAsFunction(path_name) => {
K
Knight 已提交
331
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
332 333 334 335
                             span,
                             E0423,
                             "`{}` is the name of a struct or struct variant, but this expression \
                             uses it like a function name",
K
Knight 已提交
336 337 338
                             path_name);
            err.span_label(span, &format!("struct called like a function"));
            err
C
corentih 已提交
339
        }
340
        ResolutionError::SelfNotAvailableInStaticMethod => {
341
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
342 343
                             span,
                             E0424,
344 345 346 347
                             "`self` is not available in a static method");
            err.span_label(span, &format!("not available in static method"));
            err.note(&format!("maybe a `self` argument is missing?"));
            err
C
corentih 已提交
348
        }
349
        ResolutionError::UnresolvedName { path, message: msg, context, is_static_method,
G
ggomez 已提交
350
                                          is_field, def } => {
N
Nick Cameron 已提交
351 352 353
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0425,
J
Jonathan Turner 已提交
354 355 356 357 358 359 360 361
                                           "unresolved name `{}`",
                                           path);
            if msg != "" {
                err.span_label(span, &msg);
            } else {
                err.span_label(span, &format!("unresolved name"));
            }

362
            match context {
363 364 365 366 367 368
                UnresolvedNameContext::Other => {
                    if msg.is_empty() && is_static_method && is_field {
                        err.help("this is an associated function, you don't have access to \
                                  this type's fields or methods");
                    }
                }
369
                UnresolvedNameContext::PathIsMod(parent) => {
370
                    err.help(&match parent.map(|parent| &parent.node) {
371
                        Some(&ExprKind::Field(_, ident)) => {
G
ggomez 已提交
372
                            format!("to reference an item from the `{module}` module, \
373 374 375
                                     use `{module}::{ident}`",
                                    module = path,
                                    ident = ident.node)
376
                        }
V
Vadim Petrochenkov 已提交
377
                        Some(&ExprKind::MethodCall(ident, ..)) => {
G
ggomez 已提交
378
                            format!("to call a function from the `{module}` module, \
379 380 381 382 383
                                     use `{module}::{ident}(..)`",
                                    module = path,
                                    ident = ident.node)
                        }
                        _ => {
G
ggomez 已提交
384 385
                            format!("{def} `{module}` cannot be used as an expression",
                                    def = def.kind_name(),
386 387 388
                                    module = path)
                        }
                    });
389 390
                }
            }
N
Nick Cameron 已提交
391
            err
C
corentih 已提交
392
        }
393
        ResolutionError::UndeclaredLabel(name) => {
C
crypto-universe 已提交
394 395 396 397 398 399 400
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0426,
                                           "use of undeclared label `{}`",
                                           name);
            err.span_label(span, &format!("undeclared label `{}`",&name));
            err
C
corentih 已提交
401
        }
402
        ResolutionError::SelfImportsOnlyAllowedWithin => {
N
Nick Cameron 已提交
403 404 405 406 407
            struct_span_err!(resolver.session,
                             span,
                             E0429,
                             "{}",
                             "`self` imports are only allowed within a { } list")
C
corentih 已提交
408
        }
409
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
N
Nick Cameron 已提交
410 411 412 413
            struct_span_err!(resolver.session,
                             span,
                             E0430,
                             "`self` import can only appear once in the list")
C
corentih 已提交
414
        }
415
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
N
Nick Cameron 已提交
416 417 418 419 420
            struct_span_err!(resolver.session,
                             span,
                             E0431,
                             "`self` import can only appear in an import list with a \
                              non-empty prefix")
421
        }
422
        ResolutionError::UnresolvedImport(name) => {
423
            let msg = match name {
K
Knight 已提交
424
                Some((n, _)) => format!("unresolved import `{}`", n),
C
corentih 已提交
425
                None => "unresolved import".to_owned(),
426
            };
K
Knight 已提交
427 428 429 430 431
            let mut err = struct_span_err!(resolver.session, span, E0432, "{}", msg);
            if let Some((_, p)) = name {
                err.span_label(span, &p);
            }
            err
C
corentih 已提交
432
        }
433
        ResolutionError::FailedToResolve(msg) => {
J
Jonathan Turner 已提交
434 435
            let mut err = struct_span_err!(resolver.session, span, E0433,
                                           "failed to resolve. {}", msg);
436 437
            err.span_label(span, &msg);
            err
C
corentih 已提交
438
        }
439
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
N
Nick Cameron 已提交
440 441 442 443 444 445
            struct_span_err!(resolver.session,
                             span,
                             E0434,
                             "{}",
                             "can't capture dynamic environment in a fn item; use the || { ... } \
                              closure form instead")
C
corentih 已提交
446 447
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
S
Shyam Sundar B 已提交
448
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
449 450
                             span,
                             E0435,
S
Shyam Sundar B 已提交
451 452 453
                             "attempt to use a non-constant value in a constant");
            err.span_label(span, &format!("non-constant used with constant"));
            err
C
corentih 已提交
454
        }
455
        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
456
            let shadows_what = PathResolution::new(binding.def()).kind_name();
457 458
            let mut err = struct_span_err!(resolver.session,
                                           span,
459
                                           E0530,
460 461
                                           "{}s cannot shadow {}s", what_binding, shadows_what);
            err.span_label(span, &format!("cannot be named the same as a {}", shadows_what));
462 463 464
            let participle = if binding.is_import() { "imported" } else { "defined" };
            let msg = &format!("a {} `{}` is {} here", shadows_what, name, participle);
            err.span_label(binding.span, msg);
465 466 467 468 469
            err
        }
        ResolutionError::PatPathUnresolved(expected_what, path) => {
            struct_span_err!(resolver.session,
                             span,
470
                             E0531,
471 472
                             "unresolved {} `{}`",
                             expected_what,
473
                             path)
474 475 476 477
        }
        ResolutionError::PatPathUnexpected(expected_what, found_what, path) => {
            struct_span_err!(resolver.session,
                             span,
478
                             E0532,
479 480 481
                             "expected {}, found {} `{}`",
                             expected_what,
                             found_what,
482
                             path)
483
        }
N
Nick Cameron 已提交
484
    }
485 486
}

N
Niko Matsakis 已提交
487
#[derive(Copy, Clone)]
488
struct BindingInfo {
489
    span: Span,
490
    binding_mode: BindingMode,
491 492 493
}

// Map from the name in a pattern to its binding mode.
494
type BindingMap = FxHashMap<Ident, BindingInfo>;
495

496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum PatternSource {
    Match,
    IfLet,
    WhileLet,
    Let,
    For,
    FnParam,
}

impl PatternSource {
    fn is_refutable(self) -> bool {
        match self {
            PatternSource::Match | PatternSource::IfLet | PatternSource::WhileLet => true,
            PatternSource::Let | PatternSource::For | PatternSource::FnParam  => false,
        }
    }
    fn descr(self) -> &'static str {
        match self {
            PatternSource::Match => "match binding",
            PatternSource::IfLet => "if let binding",
            PatternSource::WhileLet => "while let binding",
            PatternSource::Let => "let binding",
            PatternSource::For => "for binding",
            PatternSource::FnParam => "function parameter",
        }
    }
523 524
}

N
Niko Matsakis 已提交
525
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
526
pub enum Namespace {
527
    TypeNS,
C
corentih 已提交
528
    ValueNS,
529
    MacroNS,
530 531
}

J
Jeffrey Seyfried 已提交
532 533 534 535
#[derive(Clone, Default, Debug)]
pub struct PerNS<T> {
    value_ns: T,
    type_ns: T,
536
    macro_ns: Option<T>,
J
Jeffrey Seyfried 已提交
537 538 539 540 541 542 543 544
}

impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
    type Output = T;
    fn index(&self, ns: Namespace) -> &T {
        match ns {
            ValueNS => &self.value_ns,
            TypeNS => &self.type_ns,
545
            MacroNS => self.macro_ns.as_ref().unwrap(),
J
Jeffrey Seyfried 已提交
546 547 548 549 550 551 552 553 554
        }
    }
}

impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
    fn index_mut(&mut self, ns: Namespace) -> &mut T {
        match ns {
            ValueNS => &mut self.value_ns,
            TypeNS => &mut self.type_ns,
555
            MacroNS => self.macro_ns.as_mut().unwrap(),
J
Jeffrey Seyfried 已提交
556 557 558 559
        }
    }
}

560 561
impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
    fn visit_item(&mut self, item: &'tcx Item) {
A
Alex Crichton 已提交
562
        self.resolve_item(item);
563
    }
564
    fn visit_arm(&mut self, arm: &'tcx Arm) {
A
Alex Crichton 已提交
565
        self.resolve_arm(arm);
566
    }
567
    fn visit_block(&mut self, block: &'tcx Block) {
A
Alex Crichton 已提交
568
        self.resolve_block(block);
569
    }
570
    fn visit_expr(&mut self, expr: &'tcx Expr) {
571
        self.resolve_expr(expr, None);
572
    }
573
    fn visit_local(&mut self, local: &'tcx Local) {
A
Alex Crichton 已提交
574
        self.resolve_local(local);
575
    }
576
    fn visit_ty(&mut self, ty: &'tcx Ty) {
A
Alex Crichton 已提交
577
        self.resolve_type(ty);
578
    }
579 580 581
    fn visit_poly_trait_ref(&mut self,
                            tref: &'tcx ast::PolyTraitRef,
                            m: &'tcx ast::TraitBoundModifier) {
J
Jeffrey Seyfried 已提交
582 583 584
        let ast::Path { ref segments, span, global } = tref.trait_ref.path;
        let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
        let def = self.resolve_trait_reference(&path, global, None, span);
585
        self.record_def(tref.trait_ref.ref_id, def);
586
        visit::walk_poly_trait_ref(self, tref, m);
587
    }
C
corentih 已提交
588
    fn visit_variant(&mut self,
589 590
                     variant: &'tcx ast::Variant,
                     generics: &'tcx Generics,
C
corentih 已提交
591
                     item_id: ast::NodeId) {
592 593 594
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
595
                this.visit_expr(dis_expr);
596 597 598
            });
        }

599
        // `visit::walk_variant` without the discriminant expression.
C
corentih 已提交
600 601 602 603 604
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
605
    }
606
    fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
607
        let type_parameters = match foreign_item.node {
608
            ForeignItemKind::Fn(_, ref generics) => {
609
                HasTypeParameters(generics, ItemRibKind)
610
            }
611
            ForeignItemKind::Static(..) => NoTypeParameters,
612 613
        };
        self.with_type_parameter_rib(type_parameters, |this| {
614
            visit::walk_foreign_item(this, foreign_item);
615 616 617
        });
    }
    fn visit_fn(&mut self,
618 619
                function_kind: FnKind<'tcx>,
                declaration: &'tcx FnDecl,
620 621 622
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
V
Vadim Petrochenkov 已提交
623
            FnKind::ItemFn(_, generics, ..) => {
624 625 626
                self.visit_generics(generics);
                ItemRibKind
            }
627
            FnKind::Method(_, sig, _, _) => {
628
                self.visit_generics(&sig.generics);
V
Vadim Petrochenkov 已提交
629
                MethodRibKind(!sig.decl.has_self())
630
            }
631
            FnKind::Closure(_) => ClosureRibKind(node_id),
632
        };
633 634

        // Create a value rib for the function.
J
Jeffrey Seyfried 已提交
635
        self.ribs[ValueNS].push(Rib::new(rib_kind));
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664

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

        // Add each argument to the rib.
        let mut bindings_list = FxHashMap();
        for argument in &declaration.inputs {
            self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);

            self.visit_ty(&argument.ty);

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

        // Resolve the function body.
        match function_kind {
            FnKind::ItemFn(.., body) |
            FnKind::Method(.., body) => {
                self.visit_block(body);
            }
            FnKind::Closure(body) => {
                self.visit_expr(body);
            }
        };

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

        self.label_ribs.pop();
J
Jeffrey Seyfried 已提交
665
        self.ribs[ValueNS].pop();
666
    }
667
}
668

669
pub type ErrorMessage = Option<(Span, String)>;
670

671 672 673
enum FallbackSuggestion {
    NoSuggestion,
    Field,
674
    TraitItem,
675
    TraitMethod(String),
676 677
}

N
Niko Matsakis 已提交
678
#[derive(Copy, Clone)]
679
enum TypeParameters<'a, 'b> {
680
    NoTypeParameters,
C
corentih 已提交
681
    HasTypeParameters(// Type parameters.
682
                      &'b Generics,
683

C
corentih 已提交
684
                      // The kind of the rib used for type parameters.
685
                      RibKind<'a>),
686 687
}

688
// The rib kind controls the translation of local
689
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
690
#[derive(Copy, Clone, Debug)]
691
enum RibKind<'a> {
692 693
    // No translation needs to be applied.
    NormalRibKind,
694

695 696
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
697
    ClosureRibKind(NodeId /* func id */),
698

699
    // We passed through an impl or trait and are now in one of its
700
    // methods. Allow references to ty params that impl or trait
701 702
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
703 704 705
    //
    // The boolean value represents the fact that this method is static or not.
    MethodRibKind(bool),
706

707 708
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
709 710

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

713 714
    // We passed through a module.
    ModuleRibKind(Module<'a>),
715 716

    // We passed through a `macro_rules!` statement with the given expansion
717
    MacroDefinition(Mark),
718 719
}

720
/// One local scope.
J
Jorge Aparicio 已提交
721
#[derive(Debug)]
722
struct Rib<'a> {
723
    bindings: FxHashMap<Ident, Def>,
724
    kind: RibKind<'a>,
B
Brian Anderson 已提交
725
}
726

727 728
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
729
        Rib {
730
            bindings: FxHashMap(),
C
corentih 已提交
731
            kind: kind,
732
        }
733 734 735
    }
}

736
/// A definition along with the index of the rib it was found on
J
Jeffrey Seyfried 已提交
737
#[derive(Copy, Clone)]
738 739
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
740
    def: Def,
741 742
}

743 744
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
J
Jeffrey Seyfried 已提交
745
    Def(Def),
746 747
}

748
impl<'a> LexicalScopeBinding<'a> {
749
    fn item(self) -> Option<&'a NameBinding<'a>> {
750
        match self {
751
            LexicalScopeBinding::Item(binding) => Some(binding),
752 753 754 755 756
            _ => None,
        }
    }
}

J
Jeffrey Seyfried 已提交
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
#[derive(Copy, Clone)]
enum PathScope {
    Global,
    Lexical,
    Import,
}

#[derive(Clone)]
enum PathResult<'a> {
    Module(Module<'a>),
    NonModule(PathResolution),
    Indeterminate,
    Failed(String, bool /* is the error from the last segment? */),
}

J
Jeffrey Seyfried 已提交
772 773 774
enum ModuleKind {
    Block(NodeId),
    Def(Def, Name),
775 776
}

777
/// One node in the tree of modules.
778
pub struct ModuleS<'a> {
J
Jeffrey Seyfried 已提交
779 780
    parent: Option<Module<'a>>,
    kind: ModuleKind,
781

782
    // The node id of the closest normal module (`mod`) ancestor (including this module).
J
Jeffrey Seyfried 已提交
783
    normal_ancestor_id: Option<NodeId>,
784

785
    resolutions: RefCell<FxHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
786
    legacy_macro_resolutions: RefCell<Vec<(Mark, Name, Span)>>,
787
    macro_resolutions: RefCell<Vec<(Box<[Ident]>, PathScope, Span)>>,
788

789 790 791
    // Macro invocations that can expand into items in this module.
    unresolved_invocations: RefCell<FxHashSet<Mark>>,

792
    no_implicit_prelude: bool,
793

794
    glob_importers: RefCell<Vec<&'a ImportDirective<'a>>>,
795
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
796

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

800 801 802
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
803
    populated: Cell<bool>,
804 805
}

806 807 808
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
809
    fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
810
        ModuleS {
J
Jeffrey Seyfried 已提交
811 812
            parent: parent,
            kind: kind,
813
            normal_ancestor_id: None,
814
            resolutions: RefCell::new(FxHashMap()),
815
            legacy_macro_resolutions: RefCell::new(Vec::new()),
816
            macro_resolutions: RefCell::new(Vec::new()),
817
            unresolved_invocations: RefCell::new(FxHashSet()),
818
            no_implicit_prelude: false,
819
            glob_importers: RefCell::new(Vec::new()),
820
            globs: RefCell::new((Vec::new())),
J
Jeffrey Seyfried 已提交
821
            traits: RefCell::new(None),
822
            populated: Cell::new(true),
823
        }
B
Brian Anderson 已提交
824 825
    }

826
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
827
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
828
            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
829 830 831
        }
    }

J
Jeffrey Seyfried 已提交
832 833 834 835 836 837 838
    fn def(&self) -> Option<Def> {
        match self.kind {
            ModuleKind::Def(def, _) => Some(def),
            _ => None,
        }
    }

839
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
840
        self.def().as_ref().map(Def::def_id)
841 842
    }

843
    // `self` resolves to the first module ancestor that `is_normal`.
844
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
845 846
        match self.kind {
            ModuleKind::Def(Def::Mod(_), _) => true,
847 848 849 850 851
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
852 853
        match self.kind {
            ModuleKind::Def(Def::Trait(_), _) => true,
854
            _ => false,
855
        }
B
Brian Anderson 已提交
856
    }
857 858 859 860

    fn is_local(&self) -> bool {
        self.normal_ancestor_id.is_some()
    }
V
Victor Berger 已提交
861 862
}

863
impl<'a> fmt::Debug for ModuleS<'a> {
864
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
J
Jeffrey Seyfried 已提交
865
        write!(f, "{:?}", self.def())
866 867 868
    }
}

869
// Records a possibly-private value, type, or module definition.
870
#[derive(Clone, Debug)]
871
pub struct NameBinding<'a> {
872
    kind: NameBindingKind<'a>,
873
    expansion: Mark,
874
    span: Span,
875
    vis: ty::Visibility,
876 877
}

878 879 880 881 882 883 884 885 886 887
pub trait ToNameBinding<'a> {
    fn to_name_binding(self) -> NameBinding<'a>;
}

impl<'a> ToNameBinding<'a> for NameBinding<'a> {
    fn to_name_binding(self) -> NameBinding<'a> {
        self
    }
}

888
#[derive(Clone, Debug)]
889
enum NameBindingKind<'a> {
890
    Def(Def),
891
    Module(Module<'a>),
892 893
    Import {
        binding: &'a NameBinding<'a>,
894
        directive: &'a ImportDirective<'a>,
895
        used: Cell<bool>,
896
    },
897 898 899 900
    Ambiguity {
        b1: &'a NameBinding<'a>,
        b2: &'a NameBinding<'a>,
    }
901 902
}

903 904
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

J
Jeffrey Seyfried 已提交
905 906 907
struct AmbiguityError<'a> {
    span: Span,
    name: Name,
908
    lexical: bool,
J
Jeffrey Seyfried 已提交
909 910 911 912
    b1: &'a NameBinding<'a>,
    b2: &'a NameBinding<'a>,
}

913
impl<'a> NameBinding<'a> {
J
Jeffrey Seyfried 已提交
914
    fn module(&self) -> Option<Module<'a>> {
915
        match self.kind {
J
Jeffrey Seyfried 已提交
916
            NameBindingKind::Module(module) => Some(module),
917
            NameBindingKind::Import { binding, .. } => binding.module(),
J
Jeffrey Seyfried 已提交
918
            _ => None,
919 920 921
        }
    }

922
    fn def(&self) -> Def {
923
        match self.kind {
924
            NameBindingKind::Def(def) => def,
J
Jeffrey Seyfried 已提交
925
            NameBindingKind::Module(module) => module.def().unwrap(),
926
            NameBindingKind::Import { binding, .. } => binding.def(),
927
            NameBindingKind::Ambiguity { .. } => Def::Err,
928
        }
929
    }
930

J
Jeffrey Seyfried 已提交
931 932 933 934 935 936 937 938
    fn get_macro(&self, resolver: &mut Resolver<'a>) -> Rc<SyntaxExtension> {
        match self.kind {
            NameBindingKind::Import { binding, .. } => binding.get_macro(resolver),
            NameBindingKind::Ambiguity { b1, .. } => b1.get_macro(resolver),
            _ => resolver.get_macro(self.def()),
        }
    }

939 940 941 942 943 944 945
    // 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 {
946 947
            NameBindingKind::Def(Def::Variant(..)) |
            NameBindingKind::Def(Def::VariantCtor(..)) => true,
948 949
            _ => false,
        }
950 951
    }

952
    fn is_extern_crate(&self) -> bool {
953 954 955 956 957 958 959 960
        match self.kind {
            NameBindingKind::Import {
                directive: &ImportDirective {
                    subclass: ImportDirectiveSubclass::ExternCrate, ..
                }, ..
            } => true,
            _ => false,
        }
961
    }
962 963 964 965 966 967 968

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
969 970 971 972

    fn is_glob_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { directive, .. } => directive.is_glob(),
973
            NameBindingKind::Ambiguity { b1, .. } => b1.is_glob_import(),
974 975 976 977 978
            _ => false,
        }
    }

    fn is_importable(&self) -> bool {
979
        match self.def() {
980 981 982 983
            Def::AssociatedConst(..) | Def::Method(..) | Def::AssociatedTy(..) => false,
            _ => true,
        }
    }
984 985
}

986
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
987
struct PrimitiveTypeTable {
988
    primitive_types: FxHashMap<Name, PrimTy>,
989
}
990

991
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
992
    fn new() -> PrimitiveTypeTable {
993
        let mut table = PrimitiveTypeTable { primitive_types: FxHashMap() };
C
corentih 已提交
994 995 996

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
997 998
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
999 1000 1001 1002 1003
        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 已提交
1004
        table.intern("str", TyStr);
1005 1006 1007 1008 1009
        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 已提交
1010 1011 1012 1013

        table
    }

1014
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1015
        self.primitive_types.insert(Symbol::intern(string), primitive_type);
1016 1017 1018
    }
}

1019
/// The main resolver class.
1020
pub struct Resolver<'a> {
E
Eduard Burtescu 已提交
1021
    session: &'a Session,
1022

1023
    pub definitions: Definitions,
1024

1025 1026
    // Maps the node id of a statement to the expansions of the `macro_rules!`s
    // immediately above the statement (if appropriate).
1027
    macros_at_scope: FxHashMap<NodeId, Vec<Mark>>,
1028

1029
    graph_root: Module<'a>,
1030

1031 1032
    prelude: Option<Module<'a>>,

1033
    trait_item_map: FxHashMap<(Name, DefId), bool /* is static method? */>,
1034

V
Vadim Petrochenkov 已提交
1035 1036
    // Names of fields of an item `DefId` accessible with dot syntax.
    // Used for hints during error reporting.
1037
    field_names: FxHashMap<DefId, Vec<Name>>,
1038

1039 1040 1041 1042
    // All imports known to succeed or fail.
    determined_imports: Vec<&'a ImportDirective<'a>>,

    // All non-determined imports.
1043
    indeterminate_imports: Vec<&'a ImportDirective<'a>>,
1044 1045

    // The module that represents the current item scope.
1046
    current_module: Module<'a>,
1047

J
Jeffrey Seyfried 已提交
1048
    // The current set of local scopes for types and values.
1049
    // FIXME #4948: Reuse ribs to avoid allocation.
J
Jeffrey Seyfried 已提交
1050
    ribs: PerNS<Vec<Rib<'a>>>,
1051

1052
    // The current set of local scopes, for labels.
1053
    label_ribs: Vec<Rib<'a>>,
1054

1055
    // The trait that the current context can refer to.
1056 1057 1058 1059
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1061
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1062
    primitive_type_table: PrimitiveTypeTable,
1063

1064
    def_map: DefMap,
1065
    pub freevars: FreevarMap,
1066
    freevars_seen: NodeMap<NodeMap<usize>>,
1067 1068
    pub export_map: ExportMap,
    pub trait_map: TraitMap,
1069

1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
    // 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`.
1084
    module_map: NodeMap<Module<'a>>,
1085
    extern_crate_roots: FxHashMap<(CrateNum, bool /* MacrosOnly? */), Module<'a>>,
1086

1087
    pub make_glob_map: bool,
1088 1089
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
1090
    pub glob_map: GlobMap,
1091

1092 1093
    used_imports: FxHashSet<(NodeId, Namespace)>,
    used_crates: FxHashSet<CrateNum>,
1094
    pub maybe_unused_trait_imports: NodeSet,
G
Garming Sam 已提交
1095

1096
    privacy_errors: Vec<PrivacyError<'a>>,
J
Jeffrey Seyfried 已提交
1097
    ambiguity_errors: Vec<AmbiguityError<'a>>,
1098
    disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
1099 1100

    arenas: &'a ResolverArenas<'a>,
1101
    dummy_binding: &'a NameBinding<'a>,
1102
    use_extern_macros: bool, // true if `#![feature(use_extern_macros)]`
1103

1104
    pub exported_macros: Vec<ast::MacroDef>,
1105
    crate_loader: &'a mut CrateLoader,
1106
    macro_names: FxHashSet<Name>,
1107
    builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
1108
    lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
J
Jeffrey Seyfried 已提交
1109 1110
    macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
    macro_exports: Vec<Export>,
1111 1112

    // Maps the `Mark` of an expansion to its containing module or block.
1113
    invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
1114 1115 1116

    // Avoid duplicated errors for "name already defined".
    name_already_seen: FxHashMap<Name, Span>,
1117 1118
}

1119
pub struct ResolverArenas<'a> {
1120
    modules: arena::TypedArena<ModuleS<'a>>,
1121
    local_modules: RefCell<Vec<Module<'a>>>,
1122
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1123
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1124
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1125
    invocation_data: arena::TypedArena<InvocationData<'a>>,
J
Jeffrey Seyfried 已提交
1126
    legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
1127 1128 1129
}

impl<'a> ResolverArenas<'a> {
1130
    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
1131 1132 1133 1134 1135 1136 1137 1138
        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()
1139 1140 1141 1142
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1143 1144
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1145 1146
        self.import_directives.alloc(import_directive)
    }
1147 1148 1149
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1150 1151 1152
    fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
                             -> &'a InvocationData<'a> {
        self.invocation_data.alloc(expansion_data)
J
Jeffrey Seyfried 已提交
1153
    }
J
Jeffrey Seyfried 已提交
1154 1155 1156
    fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
        self.legacy_bindings.alloc(binding)
    }
1157 1158
}

1159
impl<'a> ty::NodeIdTree for Resolver<'a> {
1160 1161
    fn is_descendant_of(&self, mut node: NodeId, ancestor: NodeId) -> bool {
        while node != ancestor {
J
Jeffrey Seyfried 已提交
1162
            node = match self.module_map[&node].parent {
J
Jeffrey Seyfried 已提交
1163
                Some(parent) => parent.normal_ancestor_id.unwrap(),
1164
                None => return false,
1165
            }
1166
        }
J
Jeffrey Seyfried 已提交
1167
        true
1168 1169 1170
    }
}

1171
impl<'a> hir::lowering::Resolver for Resolver<'a> {
J
Jeffrey Seyfried 已提交
1172
    fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
1173
        let namespace = if is_value { ValueNS } else { TypeNS };
J
Jeffrey Seyfried 已提交
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
        let hir::Path { ref segments, span, global, ref mut def } = *path;
        let path: Vec<_> = segments.iter().map(|seg| Ident::with_empty_ctxt(seg.name)).collect();
        let scope = if global { PathScope::Global } else { PathScope::Lexical };
        match self.resolve_path(&path, scope, Some(namespace), Some(span)) {
            PathResult::Module(module) => *def = module.def().unwrap(),
            PathResult::NonModule(path_res) if path_res.depth == 0 => *def = path_res.base_def,
            PathResult::NonModule(..) => match self.resolve_path(&path, scope, None, Some(span)) {
                PathResult::Failed(msg, _) => {
                    resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                }
                _ => {}
            },
            PathResult::Indeterminate => unreachable!(),
            PathResult::Failed(msg, _) => {
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
1189 1190 1191 1192
            }
        }
    }

1193 1194 1195 1196
    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
        self.def_map.get(&id).cloned()
    }

1197 1198
    fn definitions(&mut self) -> &mut Definitions {
        &mut self.definitions
1199 1200 1201
    }
}

1202
impl<'a> Resolver<'a> {
1203
    pub fn new(session: &'a Session,
1204
               krate: &Crate,
1205
               make_glob_map: MakeGlobMap,
1206
               crate_loader: &'a mut CrateLoader,
1207
               arenas: &'a ResolverArenas<'a>)
1208
               -> Resolver<'a> {
1209 1210 1211 1212 1213 1214
        let root_def = Def::Mod(DefId::local(CRATE_DEF_INDEX));
        let graph_root = arenas.alloc_module(ModuleS {
            normal_ancestor_id: Some(CRATE_NODE_ID),
            no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
            ..ModuleS::new(None, ModuleKind::Def(root_def, keywords::Invalid.name()))
        });
1215 1216
        let mut module_map = NodeMap();
        module_map.insert(CRATE_NODE_ID, graph_root);
K
Kevin Butler 已提交
1217

1218 1219 1220
        let mut definitions = Definitions::new();
        DefCollector::new(&mut definitions).collect_root();

1221
        let mut invocations = FxHashMap();
1222 1223
        invocations.insert(Mark::root(),
                           arenas.alloc_invocation_data(InvocationData::root(graph_root)));
1224

K
Kevin Butler 已提交
1225 1226 1227
        Resolver {
            session: session,

1228
            definitions: definitions,
1229
            macros_at_scope: FxHashMap(),
1230

K
Kevin Butler 已提交
1231 1232
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1233
            graph_root: graph_root,
1234
            prelude: None,
K
Kevin Butler 已提交
1235

1236 1237
            trait_item_map: FxHashMap(),
            field_names: FxHashMap(),
K
Kevin Butler 已提交
1238

1239
            determined_imports: Vec::new(),
1240
            indeterminate_imports: Vec::new(),
K
Kevin Butler 已提交
1241

1242
            current_module: graph_root,
J
Jeffrey Seyfried 已提交
1243 1244 1245
            ribs: PerNS {
                value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
                type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
1246
                macro_ns: None,
J
Jeffrey Seyfried 已提交
1247
            },
1248
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1249 1250 1251 1252 1253 1254

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1255
            def_map: NodeMap(),
1256 1257
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1258 1259
            export_map: NodeMap(),
            trait_map: NodeMap(),
1260
            module_map: module_map,
1261
            extern_crate_roots: FxHashMap(),
K
Kevin Butler 已提交
1262

1263
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1264
            glob_map: NodeMap(),
G
Garming Sam 已提交
1265

1266 1267
            used_imports: FxHashSet(),
            used_crates: FxHashSet(),
S
Seo Sanghyeon 已提交
1268 1269
            maybe_unused_trait_imports: NodeSet(),

1270
            privacy_errors: Vec::new(),
1271
            ambiguity_errors: Vec::new(),
1272
            disallowed_shadowing: Vec::new(),
1273 1274

            arenas: arenas,
1275 1276
            dummy_binding: arenas.alloc_name_binding(NameBinding {
                kind: NameBindingKind::Def(Def::Err),
1277
                expansion: Mark::root(),
1278 1279 1280
                span: DUMMY_SP,
                vis: ty::Visibility::Public,
            }),
1281
            use_extern_macros: session.features.borrow().use_extern_macros,
1282

1283
            exported_macros: Vec::new(),
1284
            crate_loader: crate_loader,
1285 1286
            macro_names: FxHashSet(),
            builtin_macros: FxHashMap(),
J
Jeffrey Seyfried 已提交
1287
            lexical_macro_resolutions: Vec::new(),
J
Jeffrey Seyfried 已提交
1288 1289
            macro_map: FxHashMap(),
            macro_exports: Vec::new(),
1290
            invocations: invocations,
1291
            name_already_seen: FxHashMap(),
1292 1293 1294
        }
    }

1295
    pub fn arenas() -> ResolverArenas<'a> {
1296 1297
        ResolverArenas {
            modules: arena::TypedArena::new(),
1298
            local_modules: RefCell::new(Vec::new()),
1299
            name_bindings: arena::TypedArena::new(),
1300
            import_directives: arena::TypedArena::new(),
1301
            name_resolutions: arena::TypedArena::new(),
1302
            invocation_data: arena::TypedArena::new(),
J
Jeffrey Seyfried 已提交
1303
            legacy_bindings: arena::TypedArena::new(),
K
Kevin Butler 已提交
1304 1305
        }
    }
1306

J
Jeffrey Seyfried 已提交
1307 1308 1309 1310
    fn per_ns<T, F: FnMut(&mut Self, Namespace) -> T>(&mut self, mut f: F) -> PerNS<T> {
        PerNS {
            type_ns: f(self, TypeNS),
            value_ns: f(self, ValueNS),
1311 1312 1313 1314
            macro_ns: match self.use_extern_macros {
                true => Some(f(self, MacroNS)),
                false => None,
            },
J
Jeffrey Seyfried 已提交
1315 1316 1317
        }
    }

1318 1319
    /// Entry point to crate resolution.
    pub fn resolve_crate(&mut self, krate: &Crate) {
1320
        ImportResolver { resolver: self }.finalize_imports();
1321
        self.current_module = self.graph_root;
1322
        self.finalize_current_module_macro_resolutions();
1323 1324 1325
        visit::walk_crate(self, krate);

        check_unused::check_crate(self, krate);
1326
        self.report_errors();
1327
        self.crate_loader.postprocess(krate);
1328 1329
    }

1330 1331 1332 1333 1334 1335
    fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Module<'a> {
        self.arenas.alloc_module(ModuleS {
            normal_ancestor_id: if local { self.current_module.normal_ancestor_id } else { None },
            populated: Cell::new(local),
            ..ModuleS::new(Some(parent), kind)
        })
1336 1337
    }

1338 1339
    fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
                  -> bool /* true if an error was reported */ {
1340
        // track extern crates for unused_extern_crate lint
J
Jeffrey Seyfried 已提交
1341
        if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
1342 1343 1344
            self.used_crates.insert(krate);
        }

1345 1346 1347 1348 1349 1350 1351 1352 1353
        match binding.kind {
            NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
                used.set(true);
                self.used_imports.insert((directive.id, ns));
                self.add_to_glob_map(directive.id, name);
                self.record_use(name, ns, binding, span)
            }
            NameBindingKind::Import { .. } => false,
            NameBindingKind::Ambiguity { b1, b2 } => {
1354 1355 1356
                self.ambiguity_errors.push(AmbiguityError {
                    span: span, name: name, lexical: false, b1: b1, b2: b2,
                });
1357 1358 1359
                true
            }
            _ => false
1360
        }
1361
    }
1362

1363 1364
    fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
        if self.make_glob_map {
1365
            self.glob_map.entry(id).or_insert_with(FxHashSet).insert(name);
1366
        }
1367 1368
    }

1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
    /// 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.
    /// }
    /// ```
1383
    ///
1384 1385
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
1386
    fn resolve_ident_in_lexical_scope(&mut self,
1387
                                      mut ident: Ident,
1388
                                      ns: Namespace,
1389
                                      record_used: Option<Span>)
1390
                                      -> Option<LexicalScopeBinding<'a>> {
1391
        if ns == TypeNS {
1392
            ident = Ident::with_empty_ctxt(ident.name);
1393
        }
1394

1395
        // Walk backwards up the ribs in scope.
J
Jeffrey Seyfried 已提交
1396 1397
        for i in (0 .. self.ribs[ns].len()).rev() {
            if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
1398
                // The ident resolves to a type parameter or local variable.
J
Jeffrey Seyfried 已提交
1399 1400 1401 1402
                return Some(LexicalScopeBinding::Def(if let Some(span) = record_used {
                    self.adjust_local_def(LocalDef { ribs: Some((ns, i)), def: def }, span)
                } else {
                    def
1403
                }));
1404 1405
            }

J
Jeffrey Seyfried 已提交
1406
            if let ModuleRibKind(module) = self.ribs[ns][i].kind {
1407
                let name = ident.name;
J
Jeffrey Seyfried 已提交
1408
                let item = self.resolve_name_in_module(module, name, ns, false, record_used);
J
Jeffrey Seyfried 已提交
1409
                if let Ok(binding) = item {
1410 1411
                    // The ident resolves to an item.
                    return Some(LexicalScopeBinding::Item(binding));
1412
                }
1413

J
Jeffrey Seyfried 已提交
1414
                if let ModuleKind::Block(..) = module.kind { // We can see through blocks
1415
                } else if !module.no_implicit_prelude {
J
Jeffrey Seyfried 已提交
1416
                    return self.prelude.and_then(|prelude| {
J
Jeffrey Seyfried 已提交
1417
                        self.resolve_name_in_module(prelude, name, ns, false, None).ok()
J
Jeffrey Seyfried 已提交
1418 1419 1420
                    }).map(LexicalScopeBinding::Item)
                } else {
                    return None;
1421
                }
1422
            }
1423

J
Jeffrey Seyfried 已提交
1424
            if let MacroDefinition(mac) = self.ribs[ns][i].kind {
1425 1426
                // If an invocation of this macro created `ident`, give up on `ident`
                // and switch to `ident`'s source from the macro definition.
1427 1428 1429
                let (source_ctxt, source_macro) = ident.ctxt.source();
                if source_macro == mac {
                    ident.ctxt = source_ctxt;
1430 1431
                }
            }
1432
        }
1433

1434 1435 1436
        None
    }

1437 1438 1439 1440 1441 1442 1443 1444
    fn resolve_crate_var(&mut self, mut crate_var_ctxt: SyntaxContext) -> Module<'a> {
        while crate_var_ctxt.source().0 != SyntaxContext::empty() {
            crate_var_ctxt = crate_var_ctxt.source().0;
        }
        let module = self.invocations[&crate_var_ctxt.source().1].module.get();
        if module.is_local() { self.graph_root } else { module }
    }

1445 1446
    // AST resolution
    //
1447
    // We maintain a list of value ribs and type ribs.
1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
    //
    // 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.

1463
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1464
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1465
    {
1466 1467
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
1468
            // Move down in the graph.
1469
            let orig_module = replace(&mut self.current_module, module);
J
Jeffrey Seyfried 已提交
1470 1471
            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
1472

1473
            self.finalize_current_module_macro_resolutions();
1474
            f(self);
1475

1476
            self.current_module = orig_module;
J
Jeffrey Seyfried 已提交
1477 1478
            self.ribs[ValueNS].pop();
            self.ribs[TypeNS].pop();
1479 1480 1481
        } else {
            f(self);
        }
1482 1483
    }

S
Seo Sanghyeon 已提交
1484 1485
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1486
    fn search_label(&self, mut ident: Ident) -> Option<Def> {
1487 1488 1489 1490 1491
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
1492 1493 1494
                MacroDefinition(mac) => {
                    // If an invocation of this macro created `ident`, give up on `ident`
                    // and switch to `ident`'s source from the macro definition.
1495 1496 1497
                    let (source_ctxt, source_macro) = ident.ctxt.source();
                    if source_macro == mac {
                        ident.ctxt = source_ctxt;
1498 1499
                    }
                }
1500 1501
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1502
                    return None;
1503 1504
                }
            }
1505
            let result = rib.bindings.get(&ident).cloned();
S
Seo Sanghyeon 已提交
1506
            if result.is_some() {
C
corentih 已提交
1507
                return result;
1508 1509 1510 1511 1512
            }
        }
        None
    }

1513
    fn resolve_item(&mut self, item: &Item) {
1514
        let name = item.ident.name;
1515

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

1518
        match item.node {
1519 1520
            ItemKind::Enum(_, ref generics) |
            ItemKind::Ty(_, ref generics) |
1521
            ItemKind::Struct(_, ref generics) |
1522
            ItemKind::Union(_, ref generics) |
V
Vadim Petrochenkov 已提交
1523
            ItemKind::Fn(.., ref generics, _) => {
1524
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
1525
                                             |this| visit::walk_item(this, item));
1526 1527
            }

1528
            ItemKind::DefaultImpl(_, ref trait_ref) => {
1529
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {}, None);
1530
            }
V
Vadim Petrochenkov 已提交
1531
            ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
1532
                self.resolve_implementation(generics,
1533
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1534
                                            &self_type,
1535
                                            item.id,
1536
                                            impl_items),
1537

1538
            ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
1539
                // Create a new rib for the trait-wide type parameters.
1540
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
1541
                    let local_def_id = this.definitions.local_def_id(item.id);
1542
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1543
                        this.visit_generics(generics);
1544
                        walk_list!(this, visit_ty_param_bound, bounds);
1545 1546

                        for trait_item in trait_items {
1547
                            match trait_item.node {
1548
                                TraitItemKind::Const(_, ref default) => {
1549 1550 1551 1552 1553
                                    // 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| {
1554
                                            visit::walk_trait_item(this, trait_item)
1555 1556
                                        });
                                    } else {
1557
                                        visit::walk_trait_item(this, trait_item)
1558 1559
                                    }
                                }
1560
                                TraitItemKind::Method(ref sig, _) => {
1561 1562
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
V
Vadim Petrochenkov 已提交
1563
                                                          MethodRibKind(!sig.decl.has_self()));
1564
                                    this.with_type_parameter_rib(type_parameters, |this| {
1565
                                        visit::walk_trait_item(this, trait_item)
1566
                                    });
1567
                                }
1568
                                TraitItemKind::Type(..) => {
1569
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1570
                                        visit::walk_trait_item(this, trait_item)
1571
                                    });
1572
                                }
1573
                                TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
1574 1575 1576
                            };
                        }
                    });
1577
                });
1578 1579
            }

1580
            ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
1581
                self.with_scope(item.id, |this| {
1582
                    visit::walk_item(this, item);
1583
                });
1584 1585
            }

1586
            ItemKind::Const(..) | ItemKind::Static(..) => {
A
Alex Crichton 已提交
1587
                self.with_constant_rib(|this| {
1588
                    visit::walk_item(this, item);
1589
                });
1590
            }
1591

1592
            ItemKind::Use(ref view_path) => {
1593
                match view_path.node {
1594
                    ast::ViewPathList(ref prefix, ref items) => {
J
Jeffrey Seyfried 已提交
1595 1596
                        let path: Vec<_> =
                            prefix.segments.iter().map(|seg| seg.identifier).collect();
1597 1598
                        // Resolve prefix of an import with empty braces (issue #28388)
                        if items.is_empty() && !prefix.segments.is_empty() {
J
Jeffrey Seyfried 已提交
1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
                            let (scope, span) = (PathScope::Import, prefix.span);
                            // FIXME(#38012) This should be a module path, not anything in TypeNS.
                            let result =
                                self.resolve_path(&path, scope, Some(TypeNS), Some(span));
                            let (def, msg) = match result {
                                PathResult::Module(module) => (module.def().unwrap(), None),
                                PathResult::NonModule(res) if res.depth == 0 =>
                                    (res.base_def, None),
                                PathResult::NonModule(_) => {
                                    // Resolve a module path for better errors
                                    match self.resolve_path(&path, scope, None, Some(span)) {
                                        PathResult::Failed(msg, _) => (Def::Err, Some(msg)),
                                        _ => unreachable!(),
                                    }
1613
                                }
J
Jeffrey Seyfried 已提交
1614 1615 1616 1617 1618
                                PathResult::Indeterminate => unreachable!(),
                                PathResult::Failed(msg, _) => (Def::Err, Some(msg)),
                            };
                            if let Some(msg) = msg {
                                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
1619
                            }
J
Jeffrey Seyfried 已提交
1620
                            self.record_def(item.id, PathResolution::new(def));
1621 1622 1623
                        }
                    }
                    _ => {}
W
we 已提交
1624 1625 1626
                }
            }

1627
            ItemKind::ExternCrate(_) => {
1628
                // do nothing, these are just around to be encoded
1629
            }
1630 1631

            ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
1632 1633 1634
        }
    }

1635
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1636
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1637
    {
1638
        match type_parameters {
1639
            HasTypeParameters(generics, rib_kind) => {
1640
                let mut function_type_rib = Rib::new(rib_kind);
1641
                let mut seen_bindings = FxHashMap();
1642
                for type_parameter in &generics.ty_params {
1643
                    let name = type_parameter.ident.name;
1644
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1645

C
Chris Stankus 已提交
1646 1647
                    if seen_bindings.contains_key(&name) {
                        let span = seen_bindings.get(&name).unwrap();
1648 1649
                        resolve_error(self,
                                      type_parameter.span,
C
Chris Stankus 已提交
1650 1651
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name,
                                                                                          span));
1652
                    }
C
Chris Stankus 已提交
1653
                    seen_bindings.entry(name).or_insert(type_parameter.span);
1654

1655
                    // plain insert (no renaming)
1656
                    let def_id = self.definitions.local_def_id(type_parameter.id);
1657
                    let def = Def::TyParam(def_id);
1658
                    function_type_rib.bindings.insert(Ident::with_empty_ctxt(name), def);
1659
                    self.record_def(type_parameter.id, PathResolution::new(def));
1660
                }
J
Jeffrey Seyfried 已提交
1661
                self.ribs[TypeNS].push(function_type_rib);
1662 1663
            }

B
Brian Anderson 已提交
1664
            NoTypeParameters => {
1665 1666 1667 1668
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1669
        f(self);
1670

J
Jeffrey Seyfried 已提交
1671
        if let HasTypeParameters(..) = type_parameters {
J
Jeffrey Seyfried 已提交
1672
            self.ribs[TypeNS].pop();
1673 1674 1675
        }
    }

C
corentih 已提交
1676 1677
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1678
    {
1679
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1680
        f(self);
J
Jeffrey Seyfried 已提交
1681
        self.label_ribs.pop();
1682
    }
1683

C
corentih 已提交
1684 1685
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1686
    {
J
Jeffrey Seyfried 已提交
1687 1688
        self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
        self.ribs[TypeNS].push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1689
        f(self);
J
Jeffrey Seyfried 已提交
1690 1691
        self.ribs[TypeNS].pop();
        self.ribs[ValueNS].pop();
1692 1693
    }

F
Felix S. Klock II 已提交
1694
    fn resolve_trait_reference(&mut self,
J
Jeffrey Seyfried 已提交
1695 1696 1697 1698
                               path: &[Ident],
                               global: bool,
                               generics: Option<&Generics>,
                               span: Span)
1699
                               -> PathResolution {
J
Jeffrey Seyfried 已提交
1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716
        let scope = if global { PathScope::Global } else { PathScope::Lexical };
        let def = match self.resolve_path(path, scope, None, Some(span)) {
            PathResult::Module(module) => Some(module.def().unwrap()),
            PathResult::NonModule(..) => return err_path_resolution(),
            PathResult::Failed(msg, false) => {
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                return err_path_resolution();
            }
            _ => match self.resolve_path(path, scope, Some(TypeNS), None) {
                PathResult::NonModule(path_resolution) => Some(path_resolution.base_def),
                _ => None,
            },
        };

        if let Some(def) = def {
            if let Def::Trait(_) = def {
                return PathResolution::new(def);
1717
            }
1718

J
Jeffrey Seyfried 已提交
1719 1720
            let mut err = resolve_struct_error(self, span, {
                ResolutionError::IsNotATrait(&names_to_string(path), def.kind_name())
1721
            });
1722
            if let Some(generics) = generics {
J
Jeffrey Seyfried 已提交
1723
                if let Some(span) = generics.span_for_name(&names_to_string(path)) {
1724 1725 1726
                    err.span_label(span, &"type parameter defined here");
                }
            }
1727 1728

            // If it's a typedef, give a note
J
Jeffrey Seyfried 已提交
1729
            if let Def::TyAlias(..) = def {
1730
                err.note(&format!("type aliases cannot be used for traits"));
1731
            }
1732
            err.emit();
1733
        } else {
1734
            // find possible candidates
J
Jeffrey Seyfried 已提交
1735 1736
            let is_trait = |def| match def { Def::Trait(_) => true, _ => false };
            let candidates = self.lookup_candidates(path.last().unwrap().name, TypeNS, is_trait);
1737

J
Jeffrey Seyfried 已提交
1738 1739
            let path = names_to_string(path);
            resolve_error(self, span, ResolutionError::UndeclaredTraitName(&path, candidates));
1740 1741
        }
        err_path_resolution()
1742 1743
    }

1744 1745
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
1746
    {
1747 1748 1749 1750 1751 1752 1753
        // 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
    }

1754 1755 1756 1757 1758
    fn with_optional_trait_ref<T, F>(&mut self,
                                     opt_trait_ref: Option<&TraitRef>,
                                     f: F,
                                     generics: Option<&Generics>)
        -> T
1759
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
1760
    {
1761
        let mut new_val = None;
1762
        let mut new_id = None;
E
Eduard Burtescu 已提交
1763
        if let Some(trait_ref) = opt_trait_ref {
J
Jeffrey Seyfried 已提交
1764 1765 1766
            let ast::Path { ref segments, span, global } = trait_ref.path;
            let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
            let path_res = self.resolve_trait_reference(&path, global, generics, span);
1767 1768 1769
            assert!(path_res.depth == 0);
            self.record_def(trait_ref.ref_id, path_res);
            if path_res.base_def != Def::Err {
1770 1771
                new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                new_id = Some(path_res.base_def.def_id());
1772
            }
1773
            visit::walk_trait_ref(self, trait_ref);
1774
        }
1775
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
1776
        let result = f(self, new_id);
1777 1778 1779 1780
        self.current_trait_ref = original_trait_ref;
        result
    }

1781 1782 1783 1784 1785 1786
    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....)
1787
        self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
J
Jeffrey Seyfried 已提交
1788
        self.ribs[TypeNS].push(self_type_rib);
1789
        f(self);
J
Jeffrey Seyfried 已提交
1790
        self.ribs[TypeNS].pop();
1791 1792
    }

F
Felix S. Klock II 已提交
1793
    fn resolve_implementation(&mut self,
1794 1795 1796
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
1797
                              item_id: NodeId,
1798
                              impl_items: &[ImplItem]) {
1799
        // If applicable, create a rib for the type parameters.
1800
        self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
1801
            // Resolve the type parameters.
1802
            this.visit_generics(generics);
1803

1804
            // Resolve the trait reference, if necessary.
1805
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
1806
                // Resolve the self type.
1807
                this.visit_ty(self_type);
1808

1809 1810
                let item_def_id = this.definitions.local_def_id(item_id);
                this.with_self_rib(Def::SelfTy(trait_id, Some(item_def_id)), |this| {
1811 1812
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
1813
                            this.resolve_visibility(&impl_item.vis);
1814
                            match impl_item.node {
1815
                                ImplItemKind::Const(..) => {
1816
                                    // If this is a trait impl, ensure the const
1817
                                    // exists in trait
1818
                                    this.check_trait_item(impl_item.ident.name,
1819 1820
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
1821
                                    visit::walk_impl_item(this, impl_item);
1822
                                }
1823
                                ImplItemKind::Method(ref sig, _) => {
1824 1825
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
1826
                                    this.check_trait_item(impl_item.ident.name,
1827 1828
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
1829 1830 1831 1832 1833

                                    // We also need a new scope for the method-
                                    // specific type parameters.
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
V
Vadim Petrochenkov 已提交
1834
                                                          MethodRibKind(!sig.decl.has_self()));
1835
                                    this.with_type_parameter_rib(type_parameters, |this| {
1836
                                        visit::walk_impl_item(this, impl_item);
1837 1838
                                    });
                                }
1839
                                ImplItemKind::Type(ref ty) => {
1840
                                    // If this is a trait impl, ensure the type
1841
                                    // exists in trait
1842
                                    this.check_trait_item(impl_item.ident.name,
1843 1844
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
1845

1846 1847
                                    this.visit_ty(ty);
                                }
1848
                                ImplItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
1849
                            }
1850
                        }
1851
                    });
1852
                });
1853
            }, Some(&generics));
1854
        });
1855 1856
    }

1857
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
C
corentih 已提交
1858 1859 1860 1861
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
1862
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
1863
            if !self.trait_item_map.contains_key(&(name, did)) {
1864
                let path_str = path_names_to_string(&trait_ref.path, 0);
J
Jonas Schievink 已提交
1865
                resolve_error(self, span, err(name, &path_str));
1866 1867 1868 1869
            }
        }
    }

E
Eduard Burtescu 已提交
1870
    fn resolve_local(&mut self, local: &Local) {
1871
        // Resolve the type.
1872
        walk_list!(self, visit_ty, &local.ty);
1873

1874
        // Resolve the initializer.
1875
        walk_list!(self, visit_expr, &local.init);
1876 1877

        // Resolve the pattern.
1878
        self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap());
1879 1880
    }

J
John Clements 已提交
1881 1882 1883 1884
    // 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 已提交
1885
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
1886
        let mut binding_map = FxHashMap();
1887 1888 1889 1890 1891 1892 1893 1894

        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 };
1895
                    binding_map.insert(ident.node, binding_info);
1896 1897 1898
                }
            }
            true
1899
        });
1900 1901

        binding_map
1902 1903
    }

J
John Clements 已提交
1904 1905
    // 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 已提交
1906
    fn check_consistent_bindings(&mut self, arm: &Arm) {
1907
        if arm.pats.is_empty() {
C
corentih 已提交
1908
            return;
1909
        }
J
Jonas Schievink 已提交
1910
        let map_0 = self.binding_mode_map(&arm.pats[0]);
D
Daniel Micay 已提交
1911
        for (i, p) in arm.pats.iter().enumerate() {
J
Jonas Schievink 已提交
1912
            let map_i = self.binding_mode_map(&p);
1913

1914
            for (&key, &binding_0) in &map_0 {
1915
                match map_i.get(&key) {
C
corentih 已提交
1916
                    None => {
1917 1918
                        let error = ResolutionError::VariableNotBoundInPattern(key.name, 1, i + 1);
                        resolve_error(self, p.span, error);
C
corentih 已提交
1919 1920 1921 1922 1923
                    }
                    Some(binding_i) => {
                        if binding_0.binding_mode != binding_i.binding_mode {
                            resolve_error(self,
                                          binding_i.span,
M
Mikhail Modin 已提交
1924 1925 1926 1927
                                          ResolutionError::VariableBoundWithDifferentMode(
                                              key.name,
                                              i + 1,
                                              binding_0.span));
C
corentih 已提交
1928
                        }
1929
                    }
1930 1931 1932
                }
            }

1933
            for (&key, &binding) in &map_i {
1934
                if !map_0.contains_key(&key) {
1935 1936
                    resolve_error(self,
                                  binding.span,
1937
                                  ResolutionError::VariableNotBoundInPattern(key.name, i + 1, 1));
1938 1939 1940
                }
            }
        }
1941 1942
    }

F
Felix S. Klock II 已提交
1943
    fn resolve_arm(&mut self, arm: &Arm) {
J
Jeffrey Seyfried 已提交
1944
        self.ribs[ValueNS].push(Rib::new(NormalRibKind));
1945

1946
        let mut bindings_list = FxHashMap();
1947
        for pattern in &arm.pats {
1948
            self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
1949 1950
        }

1951 1952 1953 1954
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

1955
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
1956
        self.visit_expr(&arm.body);
1957

J
Jeffrey Seyfried 已提交
1958
        self.ribs[ValueNS].pop();
1959 1960
    }

E
Eduard Burtescu 已提交
1961
    fn resolve_block(&mut self, block: &Block) {
1962
        debug!("(resolving block) entering block");
1963
        // Move down in the graph, if there's an anonymous module rooted here.
1964
        let orig_module = self.current_module;
1965
        let anonymous_module = self.module_map.get(&block.id).cloned(); // clones a reference
1966

1967
        let mut num_macro_definition_ribs = 0;
1968 1969
        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
J
Jeffrey Seyfried 已提交
1970 1971
            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
1972
            self.current_module = anonymous_module;
1973
            self.finalize_current_module_macro_resolutions();
1974
        } else {
J
Jeffrey Seyfried 已提交
1975
            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
1976 1977 1978
        }

        // Descend into the block.
1979 1980
        for stmt in &block.stmts {
            if let Some(marks) = self.macros_at_scope.remove(&stmt.id) {
1981
                num_macro_definition_ribs += marks.len() as u32;
1982
                for mark in marks {
J
Jeffrey Seyfried 已提交
1983
                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(mark)));
1984
                    self.label_ribs.push(Rib::new(MacroDefinition(mark)));
1985 1986 1987 1988 1989
                }
            }

            self.visit_stmt(stmt);
        }
1990 1991

        // Move back up.
J
Jeffrey Seyfried 已提交
1992
        self.current_module = orig_module;
1993
        for _ in 0 .. num_macro_definition_ribs {
J
Jeffrey Seyfried 已提交
1994
            self.ribs[ValueNS].pop();
1995
            self.label_ribs.pop();
1996
        }
J
Jeffrey Seyfried 已提交
1997
        self.ribs[ValueNS].pop();
J
Jeffrey Seyfried 已提交
1998
        if let Some(_) = anonymous_module {
J
Jeffrey Seyfried 已提交
1999
            self.ribs[TypeNS].pop();
G
Garming Sam 已提交
2000
        }
2001
        debug!("(resolving block) leaving block");
2002 2003
    }

F
Felix S. Klock II 已提交
2004
    fn resolve_type(&mut self, ty: &Ty) {
J
Jeffrey Seyfried 已提交
2005 2006 2007 2008 2009 2010 2011 2012
        if let TyKind::Path(ref maybe_qself, ref path) = ty.node {
            // This is a path in the type namespace. Walk through scopes looking for it.
            if let Some(def) =
                    self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(), path, TypeNS) {
                match def.base_def {
                    Def::Mod(..) if def.depth == 0 => {
                        self.session.span_err(path.span, "expected type, found module");
                        self.record_def(ty.id, err_path_resolution());
2013
                    }
J
Jeffrey Seyfried 已提交
2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032
                    _ => {
                        // 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());
                // Keep reporting some errors even if they're ignored above.
                let kind = if maybe_qself.is_some() { "associated type" } else { "type name" };
                let is_invalid_self_type_name = {
                    path.segments.len() > 0 &&
                    maybe_qself.is_none() &&
                    path.segments[0].identifier.name == keywords::SelfType.name()
                };

                if is_invalid_self_type_name {
                    resolve_error(self, ty.span, ResolutionError::SelfUsedOutsideImplOrTrait);
2033
                } else {
J
Jeffrey Seyfried 已提交
2034 2035 2036 2037 2038 2039 2040 2041 2042
                    let type_name = path.segments.last().unwrap().identifier.name;
                    let candidates = self.lookup_candidates(type_name, TypeNS, |def| {
                        match def {
                            Def::Trait(_) |
                            Def::Enum(_) |
                            Def::Struct(_) |
                            Def::Union(_) |
                            Def::TyAlias(_) => true,
                            _ => false,
G
Guillaume Gomez 已提交
2043
                        }
J
Jeffrey Seyfried 已提交
2044 2045 2046 2047 2048
                    });

                    let name = &path_names_to_string(path, 0);
                    let error = ResolutionError::UseOfUndeclared(kind, name, candidates);
                    resolve_error(self, ty.span, error);
2049
                }
2050
            }
2051
        }
2052
        // Resolve embedded types.
2053
        visit::walk_ty(self, ty);
2054 2055
    }

2056
    fn fresh_binding(&mut self,
J
Jeffrey Seyfried 已提交
2057
                     ident: &SpannedIdent,
2058 2059 2060
                     pat_id: NodeId,
                     outer_pat_id: NodeId,
                     pat_src: PatternSource,
2061
                     bindings: &mut FxHashMap<Ident, NodeId>)
2062 2063
                     -> PathResolution {
        // Add the binding to the local ribs, if it
2064 2065
        // doesn't already exist in the bindings map. (We
        // must not add it if it's in the bindings map
2066 2067
        // because that breaks the assumptions later
        // passes make about or-patterns.)
2068
        let mut def = Def::Local(self.definitions.local_def_id(pat_id));
2069
        match bindings.get(&ident.node).cloned() {
2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088
            Some(id) if id == outer_pat_id => {
                // `Variant(a, a)`, error
                resolve_error(
                    self,
                    ident.span,
                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
                        &ident.node.name.as_str())
                );
            }
            Some(..) if pat_src == PatternSource::FnParam => {
                // `fn f(a: u8, a: u8)`, error
                resolve_error(
                    self,
                    ident.span,
                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
                        &ident.node.name.as_str())
                );
            }
            Some(..) if pat_src == PatternSource::Match => {
2089 2090
                // `Variant1(a) | Variant2(a)`, ok
                // Reuse definition from the first `a`.
J
Jeffrey Seyfried 已提交
2091
                def = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident.node];
2092 2093 2094 2095 2096 2097
            }
            Some(..) => {
                span_bug!(ident.span, "two bindings with the same name from \
                                       unexpected pattern source {:?}", pat_src);
            }
            None => {
2098
                // A completely fresh binding, add to the lists if it's valid.
2099
                if ident.node.name != keywords::Invalid.name() {
2100
                    bindings.insert(ident.node, outer_pat_id);
J
Jeffrey Seyfried 已提交
2101
                    self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident.node, def);
2102
                }
2103
            }
2104
        }
2105

2106
        PathResolution::new(def)
2107
    }
2108

2109
    fn resolve_pattern_path<ExpectedFn>(&mut self,
2110 2111 2112 2113 2114 2115
                                        pat_id: NodeId,
                                        qself: Option<&QSelf>,
                                        path: &Path,
                                        namespace: Namespace,
                                        expected_fn: ExpectedFn,
                                        expected_what: &str)
2116 2117
        where ExpectedFn: FnOnce(Def) -> bool
    {
2118 2119 2120
        let resolution = if let Some(resolution) = self.resolve_possibly_assoc_item(pat_id,
                                                                        qself, path, namespace) {
            if resolution.depth == 0 {
2121
                if expected_fn(resolution.base_def) || resolution.base_def == Def::Err {
2122
                    resolution
2123
                } else {
2124 2125 2126 2127 2128 2129
                    resolve_error(
                        self,
                        path.span,
                        ResolutionError::PatPathUnexpected(expected_what,
                                                           resolution.kind_name(), path)
                    );
2130 2131
                    err_path_resolution()
                }
2132 2133 2134 2135
            } else {
                // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
                // or `<T>::A::B`. If `B` should be resolved in value namespace then
                // it needs to be added to the trait map.
2136 2137 2138 2139
                if namespace == ValueNS {
                    let item_name = path.segments.last().unwrap().identifier.name;
                    let traits = self.get_traits_containing_item(item_name);
                    self.trait_map.insert(pat_id, traits);
2140
                }
2141
                resolution
2142
            }
2143
        } else {
J
Jeffrey Seyfried 已提交
2144 2145
            let error = ResolutionError::PatPathUnresolved(expected_what, path);
            resolve_error(self, path.span, error);
2146
            err_path_resolution()
2147
        };
2148

2149 2150 2151
        self.record_def(pat_id, resolution);
    }

V
Vadim Petrochenkov 已提交
2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163
    fn resolve_struct_path(&mut self, node_id: NodeId, path: &Path) {
        // Resolution logic is equivalent for expressions and patterns,
        // reuse `resolve_pattern_path` for both.
        self.resolve_pattern_path(node_id, None, path, TypeNS, |def| {
            match def {
                Def::Struct(..) | Def::Union(..) | Def::Variant(..) |
                Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true,
                _ => false,
            }
        }, "struct, variant or union type");
    }

2164 2165 2166 2167 2168
    fn resolve_pattern(&mut self,
                       pat: &Pat,
                       pat_src: PatternSource,
                       // Maps idents to the node ID for the
                       // outermost pattern that binds them.
2169
                       bindings: &mut FxHashMap<Ident, NodeId>) {
2170
        // Visit all direct subpatterns of this pattern.
2171 2172 2173 2174 2175 2176
        let outer_pat_id = pat.id;
        pat.walk(&mut |pat| {
            match pat.node {
                PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                    // First try to resolve the identifier as some existing
                    // entity, then fall back to a fresh binding.
2177
                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, None)
2178
                                      .and_then(LexicalScopeBinding::item);
2179
                    let resolution = binding.map(NameBinding::def).and_then(|def| {
2180 2181
                        let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                             bmode != BindingMode::ByValue(Mutability::Immutable);
2182
                        match def {
2183 2184 2185 2186
                            Def::StructCtor(_, CtorKind::Const) |
                            Def::VariantCtor(_, CtorKind::Const) |
                            Def::Const(..) if !always_binding => {
                                // A unit struct/variant or constant pattern.
2187 2188
                                let name = ident.node.name;
                                self.record_use(name, ValueNS, binding.unwrap(), ident.span);
2189
                                Some(PathResolution::new(def))
2190
                            }
2191
                            Def::StructCtor(..) | Def::VariantCtor(..) |
2192
                            Def::Const(..) | Def::Static(..) => {
2193
                                // A fresh binding that shadows something unacceptable.
2194
                                resolve_error(
2195
                                    self,
2196 2197
                                    ident.span,
                                    ResolutionError::BindingShadowsSomethingUnacceptable(
2198
                                        pat_src.descr(), ident.node.name, binding.unwrap())
2199
                                );
2200
                                None
2201
                            }
2202
                            Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Err => {
2203 2204
                                // These entities are explicitly allowed
                                // to be shadowed by fresh bindings.
2205
                                None
2206 2207 2208
                            }
                            def => {
                                span_bug!(ident.span, "unexpected definition for an \
2209
                                                       identifier in pattern: {:?}", def);
2210
                            }
2211
                        }
2212
                    }).unwrap_or_else(|| {
2213
                        self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
2214
                    });
2215 2216

                    self.record_def(pat.id, resolution);
2217 2218
                }

2219
                PatKind::TupleStruct(ref path, ..) => {
2220 2221
                    self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| {
                        match def {
2222 2223
                            Def::StructCtor(_, CtorKind::Fn) |
                            Def::VariantCtor(_, CtorKind::Fn) => true,
2224
                            _ => false,
2225
                        }
2226
                    }, "tuple struct/variant");
2227 2228
                }

2229 2230
                PatKind::Path(ref qself, ref path) => {
                    self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| {
2231
                        match def {
2232 2233
                            Def::StructCtor(_, CtorKind::Const) |
                            Def::VariantCtor(_, CtorKind::Const) |
2234
                            Def::Const(..) | Def::AssociatedConst(..) => true,
2235
                            _ => false,
2236
                        }
2237
                    }, "unit struct/variant or constant");
2238 2239
                }

V
Vadim Petrochenkov 已提交
2240
                PatKind::Struct(ref path, ..) => {
V
Vadim Petrochenkov 已提交
2241
                    self.resolve_struct_path(pat.id, path);
2242
                }
2243 2244

                _ => {}
2245
            }
2246
            true
2247
        });
2248

2249
        visit::walk_pat(self, pat);
2250 2251
    }

2252 2253 2254
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2255
                                   maybe_qself: Option<&QSelf>,
2256
                                   path: &Path,
J
Jeffrey Seyfried 已提交
2257
                                   ns: Namespace)
2258
                                   -> Option<PathResolution> {
J
Jeffrey Seyfried 已提交
2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269
        let ast::Path { ref segments, global, span } = *path;
        let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
        let scope = if global { PathScope::Global } else { PathScope::Lexical };

        if let Some(qself) = maybe_qself {
            if qself.position == 0 {
                // FIXME: Create some fake resolution that can't possibly be a type.
                return Some(PathResolution {
                    base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)),
                    depth: path.len(),
                });
2270
            }
J
Jeffrey Seyfried 已提交
2271 2272
            // Make sure the trait is valid.
            self.resolve_trait_reference(&path[..qself.position], global, None, span);
2273 2274
        }

J
Jeffrey Seyfried 已提交
2275 2276 2277 2278 2279 2280 2281
        let result = match self.resolve_path(&path, scope, Some(ns), Some(span)) {
            PathResult::NonModule(path_res) => match path_res.base_def {
                Def::Trait(..) if maybe_qself.is_some() => return None,
                _ => path_res,
            },
            PathResult::Module(module) if !module.is_normal() => {
                PathResolution::new(module.def().unwrap())
V
Cleanup  
Vadim Petrochenkov 已提交
2282
            }
2283 2284 2285 2286 2287 2288
            // 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 已提交
2289 2290
            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
            //                     // not to non-existent std::u8::max_value
2291 2292 2293 2294
            // }
            //
            // Such behavior is required for backward compatibility.
            // The same fallback is used when `a` resolves to nothing.
J
Jeffrey Seyfried 已提交
2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310
            _ if self.primitive_type_table.primitive_types.contains_key(&path[0].name) => {
                PathResolution {
                    base_def: Def::PrimTy(self.primitive_type_table.primitive_types[&path[0].name]),
                    depth: segments.len() - 1,
                }
            }
            PathResult::Module(module) => PathResolution::new(module.def().unwrap()),
            PathResult::Failed(msg, false) => {
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                err_path_resolution()
            }
            _ => return None,
        };

        if path.len() == 1 || result.base_def == Def::Err {
            return Some(result);
N
Nick Cameron 已提交
2311
        }
2312

J
Jeffrey Seyfried 已提交
2313 2314 2315 2316 2317
        let unqualified_result = {
            match self.resolve_path(&[*path.last().unwrap()], PathScope::Lexical, Some(ns), None) {
                PathResult::NonModule(path_res) => path_res.base_def,
                PathResult::Module(module) => module.def().unwrap(),
                _ => return Some(result),
N
Nick Cameron 已提交
2318
            }
J
Jeffrey Seyfried 已提交
2319 2320 2321 2322
        };
        if result.base_def == unqualified_result && path[0].name != "$crate" {
            let lint = lint::builtin::UNUSED_QUALIFICATIONS;
            self.session.add_lint(lint, id, span, "unnecessary qualification".to_string());
2323
        }
N
Nick Cameron 已提交
2324

J
Jeffrey Seyfried 已提交
2325
        Some(result)
2326 2327
    }

J
Jeffrey Seyfried 已提交
2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364
    fn resolve_path(&mut self,
                    path: &[Ident],
                    scope: PathScope,
                    opt_ns: Option<Namespace>, // `None` indicates a module path
                    record_used: Option<Span>)
                    -> PathResult<'a> {
        let (mut module, allow_self) = match scope {
            PathScope::Lexical => (None, true),
            PathScope::Import => (Some(self.graph_root), true),
            PathScope::Global => (Some(self.graph_root), false),
        };
        let mut allow_super = allow_self;

        for (i, &ident) in path.iter().enumerate() {
            let is_last = i == path.len() - 1;
            let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };

            if i == 0 && allow_self && ns == TypeNS && ident.name == keywords::SelfValue.name() {
                module = Some(self.module_map[&self.current_module.normal_ancestor_id.unwrap()]);
                continue
            } else if i == 0 && allow_self && ns == TypeNS && ident.name == "$crate" {
                module = Some(self.resolve_crate_var(ident.ctxt));
                continue
            } else if allow_super && ns == TypeNS && ident.name == keywords::Super.name() {
                let current_module = if i == 0 { self.current_module } else { module.unwrap() };
                let self_module = self.module_map[&current_module.normal_ancestor_id.unwrap()];
                if let Some(parent) = self_module.parent {
                    module = Some(self.module_map[&parent.normal_ancestor_id.unwrap()]);
                    continue
                } else {
                    let msg = "There are too many initial `super`s.".to_string();
                    return PathResult::Failed(msg, false);
                }
            }
            allow_super = false;

            let binding = if let Some(module) = module {
J
Jeffrey Seyfried 已提交
2365
                self.resolve_name_in_module(module, ident.name, ns, false, record_used)
2366 2367
            } else if opt_ns == Some(MacroNS) {
                self.resolve_lexical_macro_path_segment(ident.name, ns, record_used)
J
Jeffrey Seyfried 已提交
2368 2369 2370
            } else {
                match self.resolve_ident_in_lexical_scope(ident, ns, record_used) {
                    Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
2371 2372
                    Some(LexicalScopeBinding::Def(def))
                            if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
J
Jeffrey Seyfried 已提交
2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383
                        return PathResult::NonModule(PathResolution {
                            base_def: def,
                            depth: path.len() - 1,
                        });
                    }
                    _ => Err(if record_used.is_some() { Determined } else { Undetermined }),
                }
            };

            match binding {
                Ok(binding) => {
J
Jeffrey Seyfried 已提交
2384
                    if let Some(next_module) = binding.module() {
J
Jeffrey Seyfried 已提交
2385 2386 2387
                        module = Some(next_module);
                    } else if binding.def() == Def::Err {
                        return PathResult::NonModule(err_path_resolution());
2388
                    } else if opt_ns.is_some() && !(opt_ns == Some(MacroNS) && !is_last) {
J
Jeffrey Seyfried 已提交
2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424
                        return PathResult::NonModule(PathResolution {
                            base_def: binding.def(),
                            depth: path.len() - i - 1,
                        });
                    } else {
                        return PathResult::Failed(format!("Not a module `{}`", ident), is_last);
                    }
                }
                Err(Undetermined) => return PathResult::Indeterminate,
                Err(Determined) => {
                    if let Some(module) = module {
                        if opt_ns.is_some() && !module.is_normal() {
                            return PathResult::NonModule(PathResolution {
                                base_def: module.def().unwrap(),
                                depth: path.len() - i,
                            });
                        }
                    }
                    let msg = if module.and_then(ModuleS::def) == self.graph_root.def() {
                        let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
                        let mut candidates =
                            self.lookup_candidates(ident.name, TypeNS, is_mod).candidates;
                        candidates.sort_by_key(|path| (path.segments.len(), path.to_string()));
                        if let Some(candidate) = candidates.get(0) {
                            format!("Did you mean `{}`?", candidate)
                        } else {
                            format!("Maybe a missing `extern crate {};`?", ident)
                        }
                    } else if i == 0 {
                        format!("Use of undeclared type or module `{}`", ident)
                    } else {
                        format!("Could not find `{}` in `{}`", ident, path[i - 1])
                    };
                    return PathResult::Failed(msg, is_last);
                }
            }
2425 2426
        }

J
Jeffrey Seyfried 已提交
2427
        PathResult::Module(module.unwrap())
2428 2429 2430
    }

    // Resolve a local definition, potentially adjusting for closures.
2431
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Def {
2432
        let ribs = match local_def.ribs {
J
Jeffrey Seyfried 已提交
2433 2434
            Some((ns, i)) => &self.ribs[ns][i + 1..],
            None => &[] as &[_],
2435 2436 2437
        };
        let mut def = local_def.def;
        match def {
2438
            Def::Upvar(..) => {
2439
                span_bug!(span, "unexpected {:?} in bindings", def)
2440
            }
2441
            Def::Local(def_id) => {
2442 2443
                for rib in ribs {
                    match rib.kind {
2444
                        NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) => {
2445 2446 2447 2448
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;
2449
                            let node_id = self.definitions.as_local_node_id(def_id).unwrap();
2450

C
corentih 已提交
2451 2452 2453
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2454
                            if let Some(&index) = seen.get(&node_id) {
2455
                                def = Def::Upvar(def_id, index, function_id);
2456 2457
                                continue;
                            }
C
corentih 已提交
2458 2459 2460
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2461
                            let depth = vec.len();
C
corentih 已提交
2462 2463 2464 2465
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2466

2467
                            def = Def::Upvar(def_id, depth, function_id);
2468 2469
                            seen.insert(node_id, depth);
                        }
2470
                        ItemRibKind | MethodRibKind(_) => {
2471 2472 2473
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
C
corentih 已提交
2474 2475 2476
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2477
                            return Def::Err;
2478 2479 2480
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2481 2482 2483
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2484
                            return Def::Err;
2485 2486 2487 2488
                        }
                    }
                }
            }
2489
            Def::TyParam(..) | Def::SelfTy(..) => {
2490 2491
                for rib in ribs {
                    match rib.kind {
2492
                        NormalRibKind | MethodRibKind(_) | ClosureRibKind(..) |
2493
                        ModuleRibKind(..) | MacroDefinition(..) => {
2494 2495 2496 2497 2498 2499 2500 2501 2502
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.

                            resolve_error(self,
                                          span,
                                          ResolutionError::TypeParametersFromOuterFunction);
2503
                            return Def::Err;
2504 2505 2506 2507
                        }
                        ConstantItemRibKind => {
                            // see #9186
                            resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
2508
                            return Def::Err;
2509 2510 2511 2512 2513 2514
                        }
                    }
                }
            }
            _ => {}
        }
2515
        return def;
2516 2517
    }

2518 2519
    // Calls `f` with a `Resolver` whose current lexical scope is `module`'s lexical scope,
    // i.e. the module's items and the prelude (unless the module is `#[no_implicit_prelude]`).
J
Jeffrey Seyfried 已提交
2520
    // FIXME #34673: This needs testing.
2521 2522 2523 2524
    pub fn with_module_lexical_scope<T, F>(&mut self, module: Module<'a>, f: F) -> T
        where F: FnOnce(&mut Resolver<'a>) -> T,
    {
        self.with_empty_ribs(|this| {
J
Jeffrey Seyfried 已提交
2525 2526
            this.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
            this.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
2527 2528 2529 2530 2531 2532 2533
            f(this)
        })
    }

    fn with_empty_ribs<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver<'a>) -> T,
    {
J
Jeffrey Seyfried 已提交
2534
        let ribs = replace(&mut self.ribs, PerNS::<Vec<Rib>>::default());
2535 2536 2537
        let label_ribs = replace(&mut self.label_ribs, Vec::new());

        let result = f(self);
J
Jeffrey Seyfried 已提交
2538
        self.ribs = ribs;
2539 2540 2541 2542
        self.label_ribs = label_ribs;
        result
    }

2543
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
2544
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
2545
            match t.node {
2546 2547
                TyKind::Path(None, _) => Some(t.id),
                TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
2548 2549 2550 2551 2552 2553 2554
                // 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,
            }
        }

2555
        if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
2556
            // Look for a field with the same name in the current self_type.
2557 2558
            if let Some(resolution) = self.def_map.get(&node_id) {
                match resolution.base_def {
2559
                    Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => {
V
Vadim Petrochenkov 已提交
2560 2561
                        if let Some(field_names) = self.field_names.get(&did) {
                            if field_names.iter().any(|&field_name| name == field_name) {
2562 2563
                                return Field;
                            }
2564
                        }
2565
                    }
2566 2567
                    _ => {}
                }
2568
            }
2569 2570 2571
        }

        // Look for a method in the current trait.
2572
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
2573 2574
            if let Some(&is_static_method) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method {
2575
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
2576 2577
                } else {
                    return TraitItem;
2578 2579 2580 2581 2582 2583 2584
                }
            }
        }

        NoSuggestion
    }

2585
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
J
Jeffrey Seyfried 已提交
2586
        if let Some(macro_name) = self.macro_names.iter().find(|&n| n == &name) {
2587 2588 2589
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

J
Jeffrey Seyfried 已提交
2590
        let names = self.ribs[ValueNS]
2591 2592
                    .iter()
                    .rev()
2593
                    .flat_map(|rib| rib.bindings.keys().map(|ident| &ident.name));
2594

2595
        if let Some(found) = find_best_match_for_name(names, name, None) {
2596
            if found != name {
2597
                return SuggestionType::Function(found);
2598
            }
2599
        } SuggestionType::NotFound
2600 2601
    }

J
Jeffrey Seyfried 已提交
2602
    fn resolve_labeled_block(&mut self, label: Option<SpannedIdent>, id: NodeId, block: &Block) {
2603
        if let Some(label) = label {
2604
            let def = Def::Label(id);
2605
            self.with_label_rib(|this| {
J
Jeffrey Seyfried 已提交
2606
                this.label_ribs.last_mut().unwrap().bindings.insert(label.node, def);
2607 2608 2609 2610 2611 2612 2613
                this.visit_block(block);
            });
        } else {
            self.visit_block(block);
        }
    }

2614
    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
P
Patrick Walton 已提交
2615 2616
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
2617 2618 2619

        self.record_candidate_traits_for_expr_if_necessary(expr);

2620
        // Next, resolve the node.
2621
        match expr.node {
2622
            ExprKind::Path(ref maybe_qself, ref path) => {
2623 2624
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
2625 2626
                if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id,
                                                            maybe_qself.as_ref(), path, ValueNS) {
2627
                    // Check if struct variant
2628 2629 2630
                    let is_struct_variant = match path_res.base_def {
                        Def::VariantCtor(_, CtorKind::Fictive) => true,
                        _ => false,
2631 2632
                    };
                    if is_struct_variant {
2633
                        let path_name = path_names_to_string(path, 0);
2634

N
Nick Cameron 已提交
2635 2636
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
2637
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
2638

C
corentih 已提交
2639
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
2640
                                          path_name);
J
Jeffrey Seyfried 已提交
2641
                        err.help(&msg);
N
Nick Cameron 已提交
2642
                        err.emit();
2643
                        self.record_def(expr.id, err_path_resolution());
2644
                    } else {
2645
                        // Write the result into the def map.
2646
                        debug!("(resolving expr) resolved `{}`",
2647
                               path_names_to_string(path, 0));
2648

2649 2650
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
2651
                        if path_res.depth != 0 {
2652
                            let method_name = path.segments.last().unwrap().identifier.name;
2653
                            let traits = self.get_traits_containing_item(method_name);
2654 2655 2656
                            self.trait_map.insert(expr.id, traits);
                        }

2657
                        self.record_def(expr.id, path_res);
2658
                    }
2659 2660
                } else {
                    // Be helpful if the name refers to a struct
2661
                    let path_name = path_names_to_string(path, 0);
J
Jeffrey Seyfried 已提交
2662 2663 2664 2665 2666 2667 2668
                    let ast::Path { ref segments, global, .. } = *path;
                    let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
                    let scope = if global { PathScope::Global } else { PathScope::Lexical };
                    let type_res = match self.resolve_path(&path, scope, Some(TypeNS), None) {
                        PathResult::NonModule(type_res) => Some(type_res),
                        _ => None,
                    };
2669 2670

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

2672
                    if let Some(Def::Struct(..)) = type_res.map(|r| r.base_def) {
J
Jeffrey Seyfried 已提交
2673 2674
                        let error_variant =
                            ResolutionError::StructVariantUsedAsFunction(&path_name);
2675 2676 2677 2678 2679
                        let mut err = resolve_struct_error(self, expr.span, error_variant);

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

J
Jeffrey Seyfried 已提交
2680
                        err.help(&msg);
2681 2682 2683
                        err.emit();
                    } else {
                        // Keep reporting some errors even if they're ignored above.
J
Jeffrey Seyfried 已提交
2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696
                        let mut method_scope = false;
                        let mut is_static = false;
                        self.ribs[ValueNS].iter().rev().all(|rib| {
                            method_scope = match rib.kind {
                                MethodRibKind(is_static_) => {
                                    is_static = is_static_;
                                    true
                                }
                                ItemRibKind | ConstantItemRibKind => false,
                                _ => return true, // Keep advancing
                            };
                            false // Stop advancing
                        });
2697

J
Jeffrey Seyfried 已提交
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714
                        if method_scope && keywords::SelfValue.name() == &*path_name {
                            let error = ResolutionError::SelfNotAvailableInStaticMethod;
                            resolve_error(self, expr.span, error);
                        } else {
                            let fallback =
                                self.find_fallback_in_self_type(path.last().unwrap().name);
                            let (mut msg, is_field) = match fallback {
                                NoSuggestion => {
                                    // limit search to 5 to reduce the number
                                    // of stupid suggestions
                                    (match self.find_best_match(&path_name) {
                                        SuggestionType::Macro(s) => {
                                            format!("the macro `{}`", s)
                                        }
                                        SuggestionType::Function(s) => format!("`{}`", s),
                                        SuggestionType::NotFound => "".to_string(),
                                    }, false)
2715
                                }
J
Jeffrey Seyfried 已提交
2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726
                                Field => {
                                    (if is_static && method_scope {
                                        "".to_string()
                                    } else {
                                        format!("`self.{}`", path_name)
                                    }, true)
                                }
                                TraitItem => (format!("to call `self.{}`", path_name), false),
                                TraitMethod(path_str) =>
                                    (format!("to call `{}::{}`", path_str, path_name), false),
                            };
2727

J
Jeffrey Seyfried 已提交
2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738
                            let mut context = UnresolvedNameContext::Other;
                            let mut def = Def::Err;
                            if !msg.is_empty() {
                                msg = format!("did you mean {}?", msg);
                            } else {
                                // we display a help message if this is a module
                                if let PathResult::Module(module) =
                                        self.resolve_path(&path, scope, None, None) {
                                    def = module.def().unwrap();
                                    context = UnresolvedNameContext::PathIsMod(parent);
                                }
2739
                            }
J
Jeffrey Seyfried 已提交
2740 2741 2742 2743 2744 2745 2746 2747 2748 2749

                            let error = ResolutionError::UnresolvedName {
                                path: &path_name,
                                message: &msg,
                                context: context,
                                is_static_method: method_scope && is_static,
                                is_field: is_field,
                                def: def,
                            };
                            resolve_error(self, expr.span, error);
V
Vincent Belliard 已提交
2750
                        }
2751 2752 2753
                    }
                }

2754
                visit::walk_expr(self, expr);
2755 2756
            }

V
Vadim Petrochenkov 已提交
2757
            ExprKind::Struct(ref path, ..) => {
V
Vadim Petrochenkov 已提交
2758
                self.resolve_struct_path(expr.id, path);
2759

2760
                visit::walk_expr(self, expr);
2761 2762
            }

2763
            ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
2764
                match self.search_label(label.node) {
2765
                    None => {
2766
                        self.record_def(expr.id, err_path_resolution());
2767
                        resolve_error(self,
2768
                                      label.span,
2769
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()));
2770
                    }
2771
                    Some(def @ Def::Label(_)) => {
2772
                        // Since this def is a label, it is never read.
2773
                        self.record_def(expr.id, PathResolution::new(def));
2774 2775
                    }
                    Some(_) => {
2776
                        span_bug!(expr.span, "label wasn't mapped to a label def!");
2777 2778
                    }
                }
2779 2780 2781

                // visit `break` argument if any
                visit::walk_expr(self, expr);
2782
            }
2783 2784 2785 2786

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

J
Jeffrey Seyfried 已提交
2787
                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
2788
                self.resolve_pattern(pattern, PatternSource::IfLet, &mut FxHashMap());
2789
                self.visit_block(if_block);
J
Jeffrey Seyfried 已提交
2790
                self.ribs[ValueNS].pop();
2791 2792 2793 2794

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

J
Jeffrey Seyfried 已提交
2795 2796 2797 2798 2799 2800 2801
            ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block),

            ExprKind::While(ref subexpression, ref block, label) => {
                self.visit_expr(subexpression);
                self.resolve_labeled_block(label, expr.id, &block);
            }

2802 2803
            ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => {
                self.visit_expr(subexpression);
J
Jeffrey Seyfried 已提交
2804
                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
2805
                self.resolve_pattern(pattern, PatternSource::WhileLet, &mut FxHashMap());
2806

J
Jeffrey Seyfried 已提交
2807
                self.resolve_labeled_block(label, expr.id, block);
2808

J
Jeffrey Seyfried 已提交
2809
                self.ribs[ValueNS].pop();
2810 2811 2812 2813
            }

            ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => {
                self.visit_expr(subexpression);
J
Jeffrey Seyfried 已提交
2814
                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
2815
                self.resolve_pattern(pattern, PatternSource::For, &mut FxHashMap());
2816

J
Jeffrey Seyfried 已提交
2817
                self.resolve_labeled_block(label, expr.id, block);
2818

J
Jeffrey Seyfried 已提交
2819
                self.ribs[ValueNS].pop();
2820 2821 2822
            }

            ExprKind::Field(ref subexpression, _) => {
2823 2824
                self.resolve_expr(subexpression, Some(expr));
            }
2825
            ExprKind::MethodCall(_, ref types, ref arguments) => {
2826 2827 2828 2829 2830 2831 2832 2833 2834
                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);
                }
            }
2835

B
Brian Anderson 已提交
2836
            _ => {
2837
                visit::walk_expr(self, expr);
2838 2839 2840 2841
            }
        }
    }

E
Eduard Burtescu 已提交
2842
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
2843
        match expr.node {
2844
            ExprKind::Field(_, name) => {
2845 2846 2847 2848
                // 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.
2849
                let traits = self.get_traits_containing_item(name.node.name);
2850
                self.trait_map.insert(expr.id, traits);
2851
            }
V
Vadim Petrochenkov 已提交
2852
            ExprKind::MethodCall(name, ..) => {
C
corentih 已提交
2853
                debug!("(recording candidate traits for expr) recording traits for {}",
2854
                       expr.id);
2855
                let traits = self.get_traits_containing_item(name.node.name);
2856
                self.trait_map.insert(expr.id, traits);
2857
            }
2858
            _ => {
2859 2860 2861 2862 2863
                // Nothing to do.
            }
        }
    }

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

S
Seo Sanghyeon 已提交
2867 2868 2869 2870
        fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
                          trait_def_id: DefId,
                          import_id: Option<NodeId>,
                          name: Name) {
2871
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
2872 2873
                   trait_def_id,
                   name);
S
Seo Sanghyeon 已提交
2874 2875 2876 2877
            found_traits.push(TraitCandidate {
                def_id: trait_def_id,
                import_id: import_id,
            });
E
Eduard Burtescu 已提交
2878
        }
2879

2880
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
2881 2882 2883
        // 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 已提交
2884
                add_trait_info(&mut found_traits, trait_def_id, None, name);
E
Eduard Burtescu 已提交
2885
            }
J
Jeffrey Seyfried 已提交
2886
        }
2887

J
Jeffrey Seyfried 已提交
2888 2889
        let mut search_module = self.current_module;
        loop {
E
Eduard Burtescu 已提交
2890
            // Look for trait children.
2891
            let mut search_in_module = |this: &mut Self, module: Module<'a>| {
J
Jeffrey Seyfried 已提交
2892 2893 2894
                let mut traits = module.traits.borrow_mut();
                if traits.is_none() {
                    let mut collected_traits = Vec::new();
2895
                    module.for_each_child(|name, ns, binding| {
J
Jeffrey Seyfried 已提交
2896
                        if ns != TypeNS { return }
2897
                        if let Def::Trait(_) = binding.def() {
2898
                            collected_traits.push((name, binding));
J
Jeffrey Seyfried 已提交
2899 2900 2901
                        }
                    });
                    *traits = Some(collected_traits.into_boxed_slice());
2902
                }
J
Jeffrey Seyfried 已提交
2903

2904
                for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
2905
                    let trait_def_id = binding.def().def_id();
2906
                    if this.trait_item_map.contains_key(&(name, trait_def_id)) {
S
Seo Sanghyeon 已提交
2907 2908 2909
                        let mut import_id = None;
                        if let NameBindingKind::Import { directive, .. } = binding.kind {
                            let id = directive.id;
2910
                            this.maybe_unused_trait_imports.insert(id);
2911
                            this.add_to_glob_map(id, trait_name);
S
Seo Sanghyeon 已提交
2912 2913 2914
                            import_id = Some(id);
                        }
                        add_trait_info(&mut found_traits, trait_def_id, import_id, name);
J
Jeffrey Seyfried 已提交
2915 2916 2917
                    }
                }
            };
2918
            search_in_module(self, search_module);
2919

J
Jeffrey Seyfried 已提交
2920 2921 2922
            if let ModuleKind::Block(..) = search_module.kind {
                search_module = search_module.parent.unwrap();
            } else {
2923
                if !search_module.no_implicit_prelude {
J
Jeffrey Seyfried 已提交
2924
                    self.prelude.map(|prelude| search_in_module(self, prelude));
2925
                }
J
Jeffrey Seyfried 已提交
2926
                break;
E
Eduard Burtescu 已提交
2927
            }
2928 2929
        }

E
Eduard Burtescu 已提交
2930
        found_traits
2931 2932
    }

2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952
    /// 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() {
2953
            self.populate_module_if_necessary(in_module);
2954 2955 2956 2957

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

                // avoid imports entirely
2958
                if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
2959 2960

                // collect results based on the filter function
2961 2962
                if name == lookup_name && ns == namespace {
                    if filter_fn(name_binding.def()) {
2963
                        // create the path
2964
                        let ident = Ident::with_empty_ctxt(name);
2965 2966 2967 2968 2969
                        let params = PathParameters::none();
                        let segment = PathSegment {
                            identifier: ident,
                            parameters: params,
                        };
2970
                        let span = name_binding.span;
2971 2972 2973 2974
                        let mut segms = path_segments.clone();
                        segms.push(segment);
                        let path = Path {
                            span: span,
J
Jeffrey Seyfried 已提交
2975
                            global: false,
2976 2977 2978 2979 2980 2981 2982 2983 2984
                            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)
2985
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
2986 2987 2988 2989 2990 2991
                            lookup_results.push(path);
                        }
                    }
                }

                // collect submodules to explore
J
Jeffrey Seyfried 已提交
2992
                if let Some(module) = name_binding.module() {
2993
                    // form the path
2994 2995 2996 2997 2998
                    let mut path_segments = path_segments.clone();
                    path_segments.push(PathSegment {
                        identifier: Ident::with_empty_ctxt(name),
                        parameters: PathParameters::none(),
                    });
2999

3000
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3001
                        // add the module to the lookup
3002
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
J
Jeffrey Seyfried 已提交
3003
                        if !worklist.iter().any(|&(m, ..)| m.def() == module.def()) {
3004 3005
                            worklist.push((module, path_segments, is_extern));
                        }
3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016
                    }
                }
            })
        }

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

3017 3018
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
3019
        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
3020
            panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
3021
        }
3022 3023
    }

3024
    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
J
Jeffrey Seyfried 已提交
3025
        let (segments, span, id) = match *vis {
3026 3027
            ast::Visibility::Public => return ty::Visibility::Public,
            ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
J
Jeffrey Seyfried 已提交
3028
            ast::Visibility::Restricted { ref path, id } => (&path.segments, path.span, id),
3029
            ast::Visibility::Inherited => {
J
Jeffrey Seyfried 已提交
3030
                return ty::Visibility::Restricted(self.current_module.normal_ancestor_id.unwrap());
3031
            }
3032 3033
        };

J
Jeffrey Seyfried 已提交
3034
        let path: Vec<_> = segments.iter().map(|seg| seg.identifier).collect();
3035
        let mut path_resolution = err_path_resolution();
J
Jeffrey Seyfried 已提交
3036 3037
        let vis = match self.resolve_path(&path, PathScope::Import, None, Some(span)) {
            PathResult::Module(module) => {
J
Jeffrey Seyfried 已提交
3038
                path_resolution = PathResolution::new(module.def().unwrap());
J
Jeffrey Seyfried 已提交
3039
                ty::Visibility::Restricted(module.normal_ancestor_id.unwrap())
3040
            }
J
Jeffrey Seyfried 已提交
3041 3042
            PathResult::Failed(msg, _) => {
                self.session.span_err(span, &format!("failed to resolve module path. {}", msg));
3043 3044
                ty::Visibility::Public
            }
J
Jeffrey Seyfried 已提交
3045
            _ => ty::Visibility::Public,
3046
        };
3047
        self.def_map.insert(id, path_resolution);
3048 3049
        if !self.is_accessible(vis) {
            let msg = format!("visibilities can only be restricted to ancestor modules");
J
Jeffrey Seyfried 已提交
3050
            self.session.span_err(span, &msg);
3051 3052 3053 3054
        }
        vis
    }

3055
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
J
Jeffrey Seyfried 已提交
3056
        vis.is_accessible_from(self.current_module.normal_ancestor_id.unwrap(), self)
3057 3058
    }

3059
    fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
J
Jeffrey Seyfried 已提交
3060
        vis.is_accessible_from(module.normal_ancestor_id.unwrap(), self)
3061 3062
    }

3063 3064
    fn report_errors(&mut self) {
        self.report_shadowing_errors();
3065
        let mut reported_spans = FxHashSet();
3066

3067
        for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
3068
            if !reported_spans.insert(span) { continue }
3069 3070 3071 3072 3073
            let participle = |binding: &NameBinding| {
                if binding.is_import() { "imported" } else { "defined" }
            };
            let msg1 = format!("`{}` could resolve to the name {} here", name, participle(b1));
            let msg2 = format!("`{}` could also resolve to the name {} here", name, participle(b2));
3074 3075 3076
            self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
                .span_note(b1.span, &msg1)
                .span_note(b2.span, &msg2)
3077
                .note(&if !lexical && b1.is_glob_import() {
3078
                    format!("consider adding an explicit import of `{}` to disambiguate", name)
3079 3080 3081 3082 3083 3084
                } else if let Def::Macro(..) = b1.def() {
                    format!("macro-expanded {} do not shadow",
                            if b1.is_import() { "macro imports" } else { "macros" })
                } else {
                    format!("macro-expanded {} do not shadow when used in a macro invocation path",
                            if b1.is_import() { "imports" } else { "items" })
3085
                })
3086 3087 3088
                .emit();
        }

3089 3090 3091 3092
        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.
3093 3094 3095 3096
                let node_id = match binding.kind {
                    NameBindingKind::Import { directive, .. } => directive.id,
                    _ => unreachable!(),
                };
3097 3098 3099
                let msg = format!("extern crate `{}` is private", name);
                self.session.add_lint(lint::builtin::INACCESSIBLE_EXTERN_CRATE, node_id, span, msg);
            } else {
3100
                let def = binding.def();
3101 3102 3103 3104
                self.session.span_err(span, &format!("{} `{}` is private", def.kind_name(), name));
            }
        }
    }
3105

3106
    fn report_shadowing_errors(&mut self) {
J
Jeffrey Seyfried 已提交
3107
        for (name, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
3108
            self.resolve_legacy_scope(scope, name, true);
J
Jeffrey Seyfried 已提交
3109 3110
        }

3111
        let mut reported_errors = FxHashSet();
3112
        for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
3113
            if self.resolve_legacy_scope(&binding.parent, binding.name, false).is_some() &&
3114 3115 3116
               reported_errors.insert((binding.name, binding.span)) {
                let msg = format!("`{}` is already in scope", binding.name);
                self.session.struct_span_err(binding.span, &msg)
3117 3118
                    .note("macro-expanded `macro_rules!`s may not shadow \
                           existing macros (see RFC 1560)")
3119 3120 3121 3122 3123
                    .emit();
            }
        }
    }

3124
    fn report_conflict(&mut self,
3125 3126 3127 3128 3129 3130
                       parent: Module,
                       name: Name,
                       ns: Namespace,
                       binding: &NameBinding,
                       old_binding: &NameBinding) {
        // Error on the second of two conflicting names
3131
        if old_binding.span.lo > binding.span.lo {
3132 3133 3134
            return self.report_conflict(parent, name, ns, old_binding, binding);
        }

J
Jeffrey Seyfried 已提交
3135 3136 3137 3138
        let container = match parent.kind {
            ModuleKind::Def(Def::Mod(_), _) => "module",
            ModuleKind::Def(Def::Trait(_), _) => "trait",
            ModuleKind::Block(..) => "block",
3139 3140 3141
            _ => "enum",
        };

3142
        let (participle, noun) = match old_binding.is_import() {
3143 3144 3145 3146
            true => ("imported", "import"),
            false => ("defined", "definition"),
        };

3147
        let span = binding.span;
3148 3149 3150 3151 3152 3153 3154

        if let Some(s) = self.name_already_seen.get(&name) {
            if s == &span {
                return;
            }
        }

3155 3156 3157
        let msg = {
            let kind = match (ns, old_binding.module()) {
                (ValueNS, _) => "a value",
3158
                (MacroNS, _) => "a macro",
3159
                (TypeNS, _) if old_binding.is_extern_crate() => "an extern crate",
J
Jeffrey Seyfried 已提交
3160 3161
                (TypeNS, Some(module)) if module.is_normal() => "a module",
                (TypeNS, Some(module)) if module.is_trait() => "a trait",
3162 3163 3164 3165 3166 3167 3168
                (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()) {
3169 3170 3171 3172 3173
            (true, true) => {
                let mut e = struct_span_err!(self.session, span, E0259, "{}", msg);
                e.span_label(span, &format!("`{}` was already imported", name));
                e
            },
3174
            (true, _) | (_, true) if binding.is_import() && old_binding.is_import() => {
C
crypto-universe 已提交
3175 3176 3177 3178
                let mut e = struct_span_err!(self.session, span, E0254, "{}", msg);
                e.span_label(span, &"already imported");
                e
            },
M
Mohit Agarwal 已提交
3179 3180 3181 3182 3183
            (true, _) | (_, true) => {
                let mut e = struct_span_err!(self.session, span, E0260, "{}", msg);
                e.span_label(span, &format!("`{}` already imported", name));
                e
            },
3184
            _ => match (old_binding.is_import(), binding.is_import()) {
T
trixnz 已提交
3185 3186 3187 3188 3189
                (false, false) => {
                    let mut e = struct_span_err!(self.session, span, E0428, "{}", msg);
                    e.span_label(span, &format!("already defined"));
                    e
                },
A
Adam Medziński 已提交
3190 3191 3192 3193 3194
                (true, true) => {
                    let mut e = struct_span_err!(self.session, span, E0252, "{}", msg);
                    e.span_label(span, &format!("already imported"));
                    e
                },
3195
                _ => {
3196 3197 3198
                    let mut e = struct_span_err!(self.session, span, E0255, "{}", msg);
                    e.span_label(span, &format!("`{}` was already imported", name));
                    e
3199
                }
3200 3201 3202
            },
        };

3203
        if old_binding.span != syntax_pos::DUMMY_SP {
3204
            err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
3205 3206
        }
        err.emit();
3207
        self.name_already_seen.insert(name, span);
3208 3209
    }
}
3210

3211
fn names_to_string(names: &[Ident]) -> String {
3212 3213
    let mut first = true;
    let mut result = String::new();
3214
    for ident in names {
3215 3216 3217 3218 3219
        if first {
            first = false
        } else {
            result.push_str("::")
        }
3220
        result.push_str(&ident.name.as_str());
C
corentih 已提交
3221
    }
3222 3223 3224 3225
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
3226 3227 3228
    let names: Vec<_> =
        path.segments[..path.segments.len() - depth].iter().map(|seg| seg.identifier).collect();
    names_to_string(&names)
3229 3230
}

3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253
/// 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 {
3254
                session.help(
T
tiehuis 已提交
3255
                    &format!("you can import it into scope: `use {};`.",
3256 3257 3258
                        &path_strings[0]),
                );
            } else {
3259
                session.help("you can import several candidates \
3260 3261 3262 3263 3264
                    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 {
3265
                        session.help(
3266 3267 3268 3269
                            &format!("  and {} other candidates", count).to_string(),
                        );
                        break;
                    } else {
3270
                        session.help(
3271 3272 3273 3274 3275 3276 3277 3278
                            &format!("  `{}`", path_string).to_string(),
                        );
                    }
                }
            }
        }
    } else {
        // nothing found:
3279
        session.help(
3280 3281 3282 3283 3284 3285 3286
            &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()),
        );
    };
}

3287
/// A somewhat inefficient routine to obtain the name of a module.
3288
fn module_to_string(module: Module) -> String {
3289 3290
    let mut names = Vec::new();

3291
    fn collect_mod(names: &mut Vec<Ident>, module: Module) {
J
Jeffrey Seyfried 已提交
3292 3293
        if let ModuleKind::Def(_, name) = module.kind {
            if let Some(parent) = module.parent {
3294
                names.push(Ident::with_empty_ctxt(name));
J
Jeffrey Seyfried 已提交
3295
                collect_mod(names, parent);
3296
            }
J
Jeffrey Seyfried 已提交
3297 3298
        } else {
            // danger, shouldn't be ident?
3299
            names.push(Ident::from_str("<opaque>"));
J
Jeffrey Seyfried 已提交
3300
            collect_mod(names, module.parent.unwrap());
3301 3302 3303 3304
        }
    }
    collect_mod(&mut names, module);

3305
    if names.is_empty() {
3306 3307
        return "???".to_string();
    }
3308
    names_to_string(&names.into_iter().rev().collect::<Vec<_>>())
3309 3310
}

3311
fn err_path_resolution() -> PathResolution {
3312
    PathResolution::new(Def::Err)
3313 3314
}

N
Niko Matsakis 已提交
3315
#[derive(PartialEq,Copy, Clone)]
3316 3317
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3318
    No,
3319 3320
}

3321
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }