lib.rs 158.0 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
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
12
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
13
      html_root_url = "https://doc.rust-lang.org/nightly/")]
14
#![deny(warnings)]
15

A
Alex Crichton 已提交
16
#![feature(rustc_diagnostic_macros)]
17

C
corentih 已提交
18 19 20 21
#[macro_use]
extern crate log;
#[macro_use]
extern crate syntax;
22 23
extern crate syntax_pos;
extern crate rustc_errors as errors;
24
extern crate arena;
C
corentih 已提交
25
#[macro_use]
26 27
extern crate rustc;

S
Steven Fackler 已提交
28 29 30 31
use self::Namespace::*;
use self::TypeParameters::*;
use self::RibKind::*;

32
use rustc::hir::map::{Definitions, DefCollector};
33
use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
34
use rustc::middle::cstore::{CrateStore, CrateLoader};
35 36
use rustc::session::Session;
use rustc::lint;
37
use rustc::hir::def::*;
38
use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
39
use rustc::ty;
S
Seo Sanghyeon 已提交
40
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
41
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
42

43
use syntax::codemap::{dummy_spanned, respan};
J
Jeffrey Seyfried 已提交
44
use syntax::ext::hygiene::{Mark, SyntaxContext};
45
use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy};
J
Jeffrey Seyfried 已提交
46
use syntax::ext::base::SyntaxExtension;
J
Jeffrey Seyfried 已提交
47
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
48
use syntax::ext::base::MacroKind;
49
use syntax::symbol::{Symbol, keywords};
50
use syntax::util::lev_distance::find_best_match_for_name;
51

52
use syntax::visit::{self, FnKind, Visitor};
53
use syntax::attr;
54 55 56
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
57
use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
J
Jeffrey Seyfried 已提交
58
use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind};
59
use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue};
60

61
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
62 63
use errors::DiagnosticBuilder;

64
use std::cell::{Cell, RefCell};
65
use std::cmp;
66
use std::collections::BTreeSet;
67
use std::fmt;
68
use std::mem::replace;
69
use std::rc::Rc;
70

71
use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
72
use macros::{InvocationData, LegacyBinding, LegacyScope, MacroBinding};
73

74 75
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
J
Jeffrey Seyfried 已提交
76
mod diagnostics;
77

78
mod macros;
A
Alex Crichton 已提交
79
mod check_unused;
80
mod build_reduced_graph;
81
mod resolve_imports;
82

83 84 85
/// A free importable items suggested in case of resolution failure.
struct ImportSuggestion {
    path: Path,
86 87
}

88 89 90 91 92
/// A field or associated item from self type suggested in case of resolution failure.
enum AssocSuggestion {
    Field,
    MethodWithSelf,
    AssocItem,
93 94
}

95 96 97
#[derive(Eq)]
struct BindingError {
    name: Name,
98 99
    origin: BTreeSet<Span>,
    target: BTreeSet<Span>,
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
}

impl PartialOrd for BindingError {
    fn partial_cmp(&self, other: &BindingError) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for BindingError {
    fn eq(&self, other: &BindingError) -> bool {
        self.name == other.name
    }
}

impl Ord for BindingError {
    fn cmp(&self, other: &BindingError) -> cmp::Ordering {
        self.name.cmp(&other.name)
    }
}

J
Jeffrey Seyfried 已提交
120
enum ResolutionError<'a> {
121
    /// error E0401: can't use type parameters from outer function
122
    TypeParametersFromOuterFunction,
123
    /// error E0403: the name is already used for a type parameter in this type parameter list
C
Chris Stankus 已提交
124
    NameAlreadyUsedInTypeParameterList(Name, &'a Span),
125
    /// error E0407: method is not a member of trait
126
    MethodNotMemberOfTrait(Name, &'a str),
127 128 129 130
    /// 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),
131 132 133 134
    /// error E0408: variable `{}` is not bound in all patterns
    VariableNotBoundInPattern(&'a BindingError),
    /// error E0409: variable `{}` is bound in inconsistent ways within the same match arm
    VariableBoundWithDifferentMode(Name, Span),
135
    /// error E0415: identifier is bound more than once in this parameter list
136
    IdentifierBoundMoreThanOnceInParameterList(&'a str),
137
    /// error E0416: identifier is bound more than once in the same pattern
138
    IdentifierBoundMoreThanOnceInSamePattern(&'a str),
139
    /// error E0426: use of undeclared label
140
    UndeclaredLabel(&'a str, Option<Name>),
141
    /// error E0429: `self` imports are only allowed within a { } list
142
    SelfImportsOnlyAllowedWithin,
143
    /// error E0430: `self` import can only appear once in the list
144
    SelfImportCanOnlyAppearOnceInTheList,
145
    /// error E0431: `self` import can only appear in an import list with a non-empty prefix
146
    SelfImportOnlyInImportListWithNonEmptyPrefix,
147
    /// error E0432: unresolved import
148
    UnresolvedImport(Option<(Span, &'a str, &'a str)>),
149
    /// error E0433: failed to resolve
150
    FailedToResolve(&'a str),
151
    /// error E0434: can't capture dynamic environment in a fn item
152
    CannotCaptureDynamicEnvironmentInFnItem,
153
    /// error E0435: attempt to use a non-constant value in a constant
154
    AttemptToUseNonConstantValueInConstant,
155
    /// error E0530: X bindings cannot shadow Ys
156
    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
157 158
    /// error E0128: type parameters with a default cannot use forward declared identifiers
    ForwardDeclaredTyParam,
159 160
}

161 162 163
fn resolve_error<'sess, 'a>(resolver: &'sess Resolver,
                            span: Span,
                            resolution_error: ResolutionError<'a>) {
N
Nick Cameron 已提交
164
    resolve_struct_error(resolver, span, resolution_error).emit();
N
Nick Cameron 已提交
165 166
}

167 168 169 170
fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
                                   span: Span,
                                   resolution_error: ResolutionError<'a>)
                                   -> DiagnosticBuilder<'sess> {
N
Nick Cameron 已提交
171
    match resolution_error {
172
        ResolutionError::TypeParametersFromOuterFunction => {
173 174 175 176 177
            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");
178
            err.span_label(span, "use of type variable from outer function");
179
            err
C
corentih 已提交
180
        }
C
Chris Stankus 已提交
181 182 183 184 185 186 187
        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);
188 189
             err.span_label(span, "already used");
             err.span_label(first_use_span.clone(), format!("first use of `{}`", name));
C
Chris Stankus 已提交
190
             err
C
corentih 已提交
191
        }
192
        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
C
crypto-universe 已提交
193 194 195 196 197 198
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0407,
                                           "method `{}` is not a member of trait `{}`",
                                           method,
                                           trait_);
199
            err.span_label(span, format!("not a member of trait `{}`", trait_));
C
crypto-universe 已提交
200
            err
C
corentih 已提交
201
        }
202
        ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
S
Shyam Sundar B 已提交
203
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
204 205 206 207
                             span,
                             E0437,
                             "type `{}` is not a member of trait `{}`",
                             type_,
S
Shyam Sundar B 已提交
208
                             trait_);
209
            err.span_label(span, format!("not a member of trait `{}`", trait_));
S
Shyam Sundar B 已提交
210
            err
C
corentih 已提交
211
        }
212
        ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
S
Shyam Sundar B 已提交
213
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
214 215 216 217
                             span,
                             E0438,
                             "const `{}` is not a member of trait `{}`",
                             const_,
S
Shyam Sundar B 已提交
218
                             trait_);
219
            err.span_label(span, format!("not a member of trait `{}`", trait_));
S
Shyam Sundar B 已提交
220
            err
C
corentih 已提交
221
        }
222
        ResolutionError::VariableNotBoundInPattern(binding_error) => {
223
            let target_sp = binding_error.target.iter().map(|x| *x).collect::<Vec<_>>();
224 225 226 227
            let msp = MultiSpan::from_spans(target_sp.clone());
            let msg = format!("variable `{}` is not bound in all patterns", binding_error.name);
            let mut err = resolver.session.struct_span_err_with_code(msp, &msg, "E0408");
            for sp in target_sp {
228
                err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name));
229
            }
230
            let origin_sp = binding_error.origin.iter().map(|x| *x).collect::<Vec<_>>();
231
            for sp in origin_sp {
232
                err.span_label(sp, "variable not in all patterns");
233
            }
234
            err
C
corentih 已提交
235
        }
M
Mikhail Modin 已提交
236 237 238
        ResolutionError::VariableBoundWithDifferentMode(variable_name,
                                                        first_binding_span) => {
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
239 240
                             span,
                             E0409,
241 242 243
                             "variable `{}` is bound in inconsistent \
                             ways within the same match arm",
                             variable_name);
244 245
            err.span_label(span, "bound in different ways");
            err.span_label(first_binding_span, "first binding");
M
Mikhail Modin 已提交
246
            err
C
corentih 已提交
247
        }
248
        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
249
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
250 251 252
                             span,
                             E0415,
                             "identifier `{}` is bound more than once in this parameter list",
253
                             identifier);
254
            err.span_label(span, "used as parameter more than once");
255
            err
C
corentih 已提交
256
        }
257
        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
258
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
259 260 261
                             span,
                             E0416,
                             "identifier `{}` is bound more than once in the same pattern",
262
                             identifier);
263
            err.span_label(span, "used in a pattern more than once");
264
            err
C
corentih 已提交
265
        }
266
        ResolutionError::UndeclaredLabel(name, lev_candidate) => {
C
crypto-universe 已提交
267 268 269 270 271
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0426,
                                           "use of undeclared label `{}`",
                                           name);
272 273 274 275 276
            if let Some(lev_candidate) = lev_candidate {
                err.span_label(span, format!("did you mean `{}`?", lev_candidate));
            } else {
                err.span_label(span, format!("undeclared label `{}`", name));
            }
C
crypto-universe 已提交
277
            err
C
corentih 已提交
278
        }
279
        ResolutionError::SelfImportsOnlyAllowedWithin => {
N
Nick Cameron 已提交
280 281 282 283 284
            struct_span_err!(resolver.session,
                             span,
                             E0429,
                             "{}",
                             "`self` imports are only allowed within a { } list")
C
corentih 已提交
285
        }
286
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
N
Nick Cameron 已提交
287 288 289 290
            struct_span_err!(resolver.session,
                             span,
                             E0430,
                             "`self` import can only appear once in the list")
C
corentih 已提交
291
        }
292
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
N
Nick Cameron 已提交
293 294 295 296 297
            struct_span_err!(resolver.session,
                             span,
                             E0431,
                             "`self` import can only appear in an import list with a \
                              non-empty prefix")
298
        }
299
        ResolutionError::UnresolvedImport(name) => {
300 301 302
            let (span, msg) = match name {
                Some((sp, n, _)) => (sp, format!("unresolved import `{}`", n)),
                None => (span, "unresolved import".to_owned()),
303
            };
K
Knight 已提交
304
            let mut err = struct_span_err!(resolver.session, span, E0432, "{}", msg);
305
            if let Some((_, _, p)) = name {
306
                err.span_label(span, p);
K
Knight 已提交
307 308
            }
            err
C
corentih 已提交
309
        }
310
        ResolutionError::FailedToResolve(msg) => {
J
Jonathan Turner 已提交
311 312
            let mut err = struct_span_err!(resolver.session, span, E0433,
                                           "failed to resolve. {}", msg);
313
            err.span_label(span, msg);
314
            err
C
corentih 已提交
315
        }
316
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
N
Nick Cameron 已提交
317 318 319 320 321 322
            struct_span_err!(resolver.session,
                             span,
                             E0434,
                             "{}",
                             "can't capture dynamic environment in a fn item; use the || { ... } \
                              closure form instead")
C
corentih 已提交
323 324
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
S
Shyam Sundar B 已提交
325
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
326 327
                             span,
                             E0435,
S
Shyam Sundar B 已提交
328
                             "attempt to use a non-constant value in a constant");
329
            err.span_label(span, "non-constant value");
S
Shyam Sundar B 已提交
330
            err
C
corentih 已提交
331
        }
332
        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
333
            let shadows_what = PathResolution::new(binding.def()).kind_name();
334 335
            let mut err = struct_span_err!(resolver.session,
                                           span,
336
                                           E0530,
337
                                           "{}s cannot shadow {}s", what_binding, shadows_what);
338
            err.span_label(span, format!("cannot be named the same as a {}", shadows_what));
339
            let participle = if binding.is_import() { "imported" } else { "defined" };
340
            let msg = format!("a {} `{}` is {} here", shadows_what, name, participle);
341
            err.span_label(binding.span, msg);
342 343
            err
        }
344 345 346 347
        ResolutionError::ForwardDeclaredTyParam => {
            let mut err = struct_span_err!(resolver.session, span, E0128,
                                           "type parameters with a default cannot use \
                                            forward declared identifiers");
348
            err.span_label(span, format!("defaulted type parameters \
349 350 351
                                           cannot be forward declared"));
            err
        }
N
Nick Cameron 已提交
352
    }
353 354
}

355
#[derive(Copy, Clone, Debug)]
356
struct BindingInfo {
357
    span: Span,
358
    binding_mode: BindingMode,
359 360 361
}

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

364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
#[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",
        }
    }
391 392
}

393 394 395 396 397 398 399
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum PathSource<'a> {
    // Type paths `Path`.
    Type,
    // Trait paths in bounds or impls.
    Trait,
    // Expression paths `path`, with optional parent context.
400
    Expr(Option<&'a Expr>),
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
    // Paths in path patterns `Path`.
    Pat,
    // Paths in struct expressions and patterns `Path { .. }`.
    Struct,
    // Paths in tuple struct patterns `Path(..)`.
    TupleStruct,
    // `m::A::B` in `<T as m::A>::B::C`.
    TraitItem(Namespace),
    // Path in `pub(path)`
    Visibility,
    // Path in `use a::b::{...};`
    ImportPrefix,
}

impl<'a> PathSource<'a> {
    fn namespace(self) -> Namespace {
        match self {
            PathSource::Type | PathSource::Trait | PathSource::Struct |
            PathSource::Visibility | PathSource::ImportPrefix => TypeNS,
            PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS,
            PathSource::TraitItem(ns) => ns,
        }
    }

    fn global_by_default(self) -> bool {
        match self {
            PathSource::Visibility | PathSource::ImportPrefix => true,
            PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
            PathSource::Struct | PathSource::TupleStruct |
            PathSource::Trait | PathSource::TraitItem(..) => false,
        }
    }

    fn defer_to_typeck(self) -> bool {
        match self {
            PathSource::Type | PathSource::Expr(..) | PathSource::Pat |
            PathSource::Struct | PathSource::TupleStruct => true,
            PathSource::Trait | PathSource::TraitItem(..) |
            PathSource::Visibility | PathSource::ImportPrefix => false,
        }
    }

    fn descr_expected(self) -> &'static str {
        match self {
            PathSource::Type => "type",
            PathSource::Trait => "trait",
            PathSource::Pat => "unit struct/variant or constant",
            PathSource::Struct => "struct, variant or union type",
            PathSource::TupleStruct => "tuple struct/variant",
            PathSource::Visibility => "module",
            PathSource::ImportPrefix => "module or enum",
            PathSource::TraitItem(ns) => match ns {
                TypeNS => "associated type",
                ValueNS => "method or associated constant",
                MacroNS => bug!("associated macro"),
            },
457
            PathSource::Expr(parent) => match parent.map(|p| &p.node) {
458 459 460 461 462 463 464 465 466 467 468 469 470
                // "function" here means "anything callable" rather than `Def::Fn`,
                // this is not precise but usually more helpful than just "value".
                Some(&ExprKind::Call(..)) => "function",
                _ => "value",
            },
        }
    }

    fn is_expected(self, def: Def) -> bool {
        match self {
            PathSource::Type => match def {
                Def::Struct(..) | Def::Union(..) | Def::Enum(..) |
                Def::Trait(..) | Def::TyAlias(..) | Def::AssociatedTy(..) |
P
Paul Lietar 已提交
471 472
                Def::PrimTy(..) | Def::TyParam(..) | Def::SelfTy(..) |
                Def::TyForeign(..) => true,
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 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 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
                _ => false,
            },
            PathSource::Trait => match def {
                Def::Trait(..) => true,
                _ => false,
            },
            PathSource::Expr(..) => match def {
                Def::StructCtor(_, CtorKind::Const) | Def::StructCtor(_, CtorKind::Fn) |
                Def::VariantCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Fn) |
                Def::Const(..) | Def::Static(..) | Def::Local(..) | Def::Upvar(..) |
                Def::Fn(..) | Def::Method(..) | Def::AssociatedConst(..) => true,
                _ => false,
            },
            PathSource::Pat => match def {
                Def::StructCtor(_, CtorKind::Const) |
                Def::VariantCtor(_, CtorKind::Const) |
                Def::Const(..) | Def::AssociatedConst(..) => true,
                _ => false,
            },
            PathSource::TupleStruct => match def {
                Def::StructCtor(_, CtorKind::Fn) | Def::VariantCtor(_, CtorKind::Fn) => true,
                _ => false,
            },
            PathSource::Struct => match def {
                Def::Struct(..) | Def::Union(..) | Def::Variant(..) |
                Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true,
                _ => false,
            },
            PathSource::TraitItem(ns) => match def {
                Def::AssociatedConst(..) | Def::Method(..) if ns == ValueNS => true,
                Def::AssociatedTy(..) if ns == TypeNS => true,
                _ => false,
            },
            PathSource::ImportPrefix => match def {
                Def::Mod(..) | Def::Enum(..) => true,
                _ => false,
            },
            PathSource::Visibility => match def {
                Def::Mod(..) => true,
                _ => false,
            },
        }
    }

    fn error_code(self, has_unexpected_resolution: bool) -> &'static str {
        __diagnostic_used!(E0404);
        __diagnostic_used!(E0405);
        __diagnostic_used!(E0412);
        __diagnostic_used!(E0422);
        __diagnostic_used!(E0423);
        __diagnostic_used!(E0425);
        __diagnostic_used!(E0531);
        __diagnostic_used!(E0532);
        __diagnostic_used!(E0573);
        __diagnostic_used!(E0574);
        __diagnostic_used!(E0575);
        __diagnostic_used!(E0576);
        __diagnostic_used!(E0577);
        __diagnostic_used!(E0578);
        match (self, has_unexpected_resolution) {
            (PathSource::Trait, true) => "E0404",
            (PathSource::Trait, false) => "E0405",
            (PathSource::Type, true) => "E0573",
            (PathSource::Type, false) => "E0412",
            (PathSource::Struct, true) => "E0574",
            (PathSource::Struct, false) => "E0422",
            (PathSource::Expr(..), true) => "E0423",
            (PathSource::Expr(..), false) => "E0425",
            (PathSource::Pat, true) | (PathSource::TupleStruct, true) => "E0532",
            (PathSource::Pat, false) | (PathSource::TupleStruct, false) => "E0531",
            (PathSource::TraitItem(..), true) => "E0575",
            (PathSource::TraitItem(..), false) => "E0576",
            (PathSource::Visibility, true) | (PathSource::ImportPrefix, true) => "E0577",
            (PathSource::Visibility, false) | (PathSource::ImportPrefix, false) => "E0578",
        }
    }
}

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

J
Jeffrey Seyfried 已提交
558 559 560 561
#[derive(Clone, Default, Debug)]
pub struct PerNS<T> {
    value_ns: T,
    type_ns: T,
562
    macro_ns: Option<T>,
J
Jeffrey Seyfried 已提交
563 564 565 566 567 568 569 570
}

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,
571
            MacroNS => self.macro_ns.as_ref().unwrap(),
J
Jeffrey Seyfried 已提交
572 573 574 575 576 577 578 579 580
        }
    }
}

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,
581
            MacroNS => self.macro_ns.as_mut().unwrap(),
J
Jeffrey Seyfried 已提交
582 583 584 585
        }
    }
}

586 587 588
struct UsePlacementFinder {
    target_module: NodeId,
    span: Option<Span>,
589
    found_use: bool,
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
}

impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
    fn visit_mod(
        &mut self,
        module: &'tcx ast::Mod,
        _: Span,
        _: &[ast::Attribute],
        node_id: NodeId,
    ) {
        if self.span.is_some() {
            return;
        }
        if node_id != self.target_module {
            visit::walk_mod(self, module);
            return;
        }
        // find a use statement
        for item in &module.items {
            match item.node {
                ItemKind::Use(..) => {
                    // don't suggest placing a use before the prelude
                    // import or other generated ones
613
                    if item.span.ctxt().outer().expn_info().is_none() {
614
                        self.span = Some(item.span.with_hi(item.span.lo()));
615
                        self.found_use = true;
616 617 618 619 620 621 622
                        return;
                    }
                },
                // don't place use before extern crate
                ItemKind::ExternCrate(_) => {}
                // but place them before the first other item
                _ => if self.span.map_or(true, |span| item.span < span ) {
623 624 625 626 627 628 629 630 631 632 633 634 635
                    if item.span.ctxt().outer().expn_info().is_none() {
                        // don't insert between attributes and an item
                        if item.attrs.is_empty() {
                            self.span = Some(item.span.with_hi(item.span.lo()));
                        } else {
                            // find the first attribute on the item
                            for attr in &item.attrs {
                                if self.span.map_or(true, |span| attr.span < span) {
                                    self.span = Some(attr.span.with_hi(attr.span.lo()));
                                }
                            }
                        }
                    }
636 637 638 639 640 641
                },
            }
        }
    }
}

642 643
impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
    fn visit_item(&mut self, item: &'tcx Item) {
A
Alex Crichton 已提交
644
        self.resolve_item(item);
645
    }
646
    fn visit_arm(&mut self, arm: &'tcx Arm) {
A
Alex Crichton 已提交
647
        self.resolve_arm(arm);
648
    }
649
    fn visit_block(&mut self, block: &'tcx Block) {
A
Alex Crichton 已提交
650
        self.resolve_block(block);
651
    }
652
    fn visit_expr(&mut self, expr: &'tcx Expr) {
653
        self.resolve_expr(expr, None);
654
    }
655
    fn visit_local(&mut self, local: &'tcx Local) {
A
Alex Crichton 已提交
656
        self.resolve_local(local);
657
    }
658
    fn visit_ty(&mut self, ty: &'tcx Ty) {
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
        match ty.node {
            TyKind::Path(ref qself, ref path) => {
                self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
            }
            TyKind::ImplicitSelf => {
                let self_ty = keywords::SelfType.ident();
                let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, true, ty.span)
                              .map_or(Def::Err, |d| d.def());
                self.record_def(ty.id, PathResolution::new(def));
            }
            TyKind::Array(ref element, ref length) => {
                self.visit_ty(element);
                self.with_constant_rib(|this| {
                    this.visit_expr(length);
                });
                return;
            }
            _ => (),
677 678
        }
        visit::walk_ty(self, ty);
679
    }
680 681 682
    fn visit_poly_trait_ref(&mut self,
                            tref: &'tcx ast::PolyTraitRef,
                            m: &'tcx ast::TraitBoundModifier) {
683 684
        self.smart_resolve_path(tref.trait_ref.ref_id, None,
                                &tref.trait_ref.path, PathSource::Trait);
685
        visit::walk_poly_trait_ref(self, tref, m);
686
    }
C
corentih 已提交
687
    fn visit_variant(&mut self,
688 689
                     variant: &'tcx ast::Variant,
                     generics: &'tcx Generics,
C
corentih 已提交
690
                     item_id: ast::NodeId) {
691 692 693
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
694
                this.visit_expr(dis_expr);
695 696 697
            });
        }

698
        // `visit::walk_variant` without the discriminant expression.
C
corentih 已提交
699 700 701 702 703
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
704
    }
705
    fn visit_foreign_item(&mut self, foreign_item: &'tcx ForeignItem) {
706
        let type_parameters = match foreign_item.node {
707
            ForeignItemKind::Fn(_, ref generics) => {
708
                HasTypeParameters(generics, ItemRibKind)
709
            }
710
            ForeignItemKind::Static(..) => NoTypeParameters,
P
Paul Lietar 已提交
711
            ForeignItemKind::Ty => NoTypeParameters,
712 713
        };
        self.with_type_parameter_rib(type_parameters, |this| {
714
            visit::walk_foreign_item(this, foreign_item);
715 716 717
        });
    }
    fn visit_fn(&mut self,
718 719
                function_kind: FnKind<'tcx>,
                declaration: &'tcx FnDecl,
720 721 722
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
723
            FnKind::ItemFn(..) => {
724 725
                ItemRibKind
            }
726
            FnKind::Method(_, sig, _, _) => {
V
Vadim Petrochenkov 已提交
727
                MethodRibKind(!sig.decl.has_self())
728
            }
729
            FnKind::Closure(_) => ClosureRibKind(node_id),
730
        };
731 732

        // Create a value rib for the function.
J
Jeffrey Seyfried 已提交
733
        self.ribs[ValueNS].push(Rib::new(rib_kind));
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762

        // 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 已提交
763
        self.ribs[ValueNS].pop();
764
    }
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
    fn visit_generics(&mut self, generics: &'tcx Generics) {
        // For type parameter defaults, we have to ban access
        // to following type parameters, as the Substs can only
        // provide previous type parameters as they're built.
        let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind);
        default_ban_rib.bindings.extend(generics.ty_params.iter()
            .skip_while(|p| p.default.is_none())
            .map(|p| (Ident::with_empty_ctxt(p.ident.name), Def::Err)));

        for param in &generics.ty_params {
            for bound in &param.bounds {
                self.visit_ty_param_bound(bound);
            }

            if let Some(ref ty) = param.default {
                self.ribs[TypeNS].push(default_ban_rib);
                self.visit_ty(ty);
                default_ban_rib = self.ribs[TypeNS].pop().unwrap();
            }

            // Allow all following defaults to refer to this type parameter.
            default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
        }
        for lt in &generics.lifetimes { self.visit_lifetime_def(lt); }
        for p in &generics.where_clause.predicates { self.visit_where_predicate(p); }
    }
791
}
792

N
Niko Matsakis 已提交
793
#[derive(Copy, Clone)]
794
enum TypeParameters<'a, 'b> {
795
    NoTypeParameters,
C
corentih 已提交
796
    HasTypeParameters(// Type parameters.
797
                      &'b Generics,
798

C
corentih 已提交
799
                      // The kind of the rib used for type parameters.
800
                      RibKind<'a>),
801 802
}

803
// The rib kind controls the translation of local
804
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
805
#[derive(Copy, Clone, Debug)]
806
enum RibKind<'a> {
807 808
    // No translation needs to be applied.
    NormalRibKind,
809

810 811
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
812
    ClosureRibKind(NodeId /* func id */),
813

814
    // We passed through an impl or trait and are now in one of its
815
    // methods. Allow references to ty params that impl or trait
816 817
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
818 819 820
    //
    // The boolean value represents the fact that this method is static or not.
    MethodRibKind(bool),
821

822 823
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
824 825

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

828 829
    // We passed through a module.
    ModuleRibKind(Module<'a>),
830

831 832
    // We passed through a `macro_rules!` statement
    MacroDefinition(DefId),
833 834 835 836 837

    // All bindings in this rib are type parameters that can't be used
    // from the default of a type parameter because they're not declared
    // before said type parameter. Also see the `visit_generics` override.
    ForwardTyParamBanRibKind,
838 839
}

840
/// One local scope.
J
Jorge Aparicio 已提交
841
#[derive(Debug)]
842
struct Rib<'a> {
843
    bindings: FxHashMap<Ident, Def>,
844
    kind: RibKind<'a>,
B
Brian Anderson 已提交
845
}
846

847 848
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
849
        Rib {
850
            bindings: FxHashMap(),
851
            kind,
852
        }
853 854 855
    }
}

856 857
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
J
Jeffrey Seyfried 已提交
858
    Def(Def),
859 860
}

861
impl<'a> LexicalScopeBinding<'a> {
862
    fn item(self) -> Option<&'a NameBinding<'a>> {
863
        match self {
864
            LexicalScopeBinding::Item(binding) => Some(binding),
865 866 867
            _ => None,
        }
    }
868 869 870 871 872 873 874

    fn def(self) -> Def {
        match self {
            LexicalScopeBinding::Item(binding) => binding.def(),
            LexicalScopeBinding::Def(def) => def,
        }
    }
875 876
}

J
Jeffrey Seyfried 已提交
877 878 879 880 881
#[derive(Clone)]
enum PathResult<'a> {
    Module(Module<'a>),
    NonModule(PathResolution),
    Indeterminate,
882
    Failed(Span, String, bool /* is the error from the last segment? */),
J
Jeffrey Seyfried 已提交
883 884
}

J
Jeffrey Seyfried 已提交
885 886 887
enum ModuleKind {
    Block(NodeId),
    Def(Def, Name),
888 889
}

890
/// One node in the tree of modules.
891
pub struct ModuleData<'a> {
J
Jeffrey Seyfried 已提交
892 893
    parent: Option<Module<'a>>,
    kind: ModuleKind,
894

895 896
    // The def id of the closest normal module (`mod`) ancestor (including this module).
    normal_ancestor_id: DefId,
897

898
    resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
899
    legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span, MacroKind)>>,
900
    macro_resolutions: RefCell<Vec<(Box<[Ident]>, Span)>>,
901

902 903 904
    // Macro invocations that can expand into items in this module.
    unresolved_invocations: RefCell<FxHashSet<Mark>>,

905
    no_implicit_prelude: bool,
906

907
    glob_importers: RefCell<Vec<&'a ImportDirective<'a>>>,
908
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
909

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

913 914 915
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
916
    populated: Cell<bool>,
917 918 919

    /// Span of the module itself. Used for error reporting.
    span: Span,
J
Jeffrey Seyfried 已提交
920 921

    expansion: Mark,
922 923
}

924
type Module<'a> = &'a ModuleData<'a>;
925

926
impl<'a> ModuleData<'a> {
O
Oliver Schneider 已提交
927 928 929
    fn new(parent: Option<Module<'a>>,
           kind: ModuleKind,
           normal_ancestor_id: DefId,
J
Jeffrey Seyfried 已提交
930
           expansion: Mark,
O
Oliver Schneider 已提交
931
           span: Span) -> Self {
932
        ModuleData {
933 934 935
            parent,
            kind,
            normal_ancestor_id,
936
            resolutions: RefCell::new(FxHashMap()),
937
            legacy_macro_resolutions: RefCell::new(Vec::new()),
938
            macro_resolutions: RefCell::new(Vec::new()),
939
            unresolved_invocations: RefCell::new(FxHashSet()),
940
            no_implicit_prelude: false,
941
            glob_importers: RefCell::new(Vec::new()),
942
            globs: RefCell::new((Vec::new())),
J
Jeffrey Seyfried 已提交
943
            traits: RefCell::new(None),
944
            populated: Cell::new(normal_ancestor_id.is_local()),
945 946
            span,
            expansion,
947
        }
B
Brian Anderson 已提交
948 949
    }

950 951 952
    fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
        for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
            name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
953 954 955
        }
    }

956 957 958 959 960 961 962 963 964 965 966 967 968
    fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
        let resolutions = self.resolutions.borrow();
        let mut resolutions = resolutions.iter().map(|(&(ident, ns), &resolution)| {
                                                    // Pre-compute keys for sorting
                                                    (ident.name.as_str(), ns, ident, resolution)
                                                })
                                                .collect::<Vec<_>>();
        resolutions.sort_unstable_by_key(|&(str, ns, ..)| (str, ns));
        for &(_, ns, ident, resolution) in resolutions.iter() {
            resolution.borrow().binding.map(|binding| f(ident, ns, binding));
        }
    }

J
Jeffrey Seyfried 已提交
969 970 971 972 973 974 975
    fn def(&self) -> Option<Def> {
        match self.kind {
            ModuleKind::Def(def, _) => Some(def),
            _ => None,
        }
    }

976
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
977
        self.def().as_ref().map(Def::def_id)
978 979
    }

980
    // `self` resolves to the first module ancestor that `is_normal`.
981
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
982 983
        match self.kind {
            ModuleKind::Def(Def::Mod(_), _) => true,
984 985 986 987 988
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
989 990
        match self.kind {
            ModuleKind::Def(Def::Trait(_), _) => true,
991
            _ => false,
992
        }
B
Brian Anderson 已提交
993
    }
994 995

    fn is_local(&self) -> bool {
996
        self.normal_ancestor_id.is_local()
997
    }
998 999 1000 1001

    fn nearest_item_scope(&'a self) -> Module<'a> {
        if self.is_trait() { self.parent.unwrap() } else { self }
    }
V
Victor Berger 已提交
1002 1003
}

1004
impl<'a> fmt::Debug for ModuleData<'a> {
1005
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
J
Jeffrey Seyfried 已提交
1006
        write!(f, "{:?}", self.def())
1007 1008 1009
    }
}

1010
// Records a possibly-private value, type, or module definition.
1011
#[derive(Clone, Debug)]
1012
pub struct NameBinding<'a> {
1013
    kind: NameBindingKind<'a>,
1014
    expansion: Mark,
1015
    span: Span,
1016
    vis: ty::Visibility,
1017 1018
}

1019
pub trait ToNameBinding<'a> {
J
Jeffrey Seyfried 已提交
1020
    fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>;
1021 1022
}

J
Jeffrey Seyfried 已提交
1023 1024
impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
    fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
1025 1026 1027 1028
        self
    }
}

1029
#[derive(Clone, Debug)]
1030
enum NameBindingKind<'a> {
1031
    Def(Def),
1032
    Module(Module<'a>),
1033 1034
    Import {
        binding: &'a NameBinding<'a>,
1035
        directive: &'a ImportDirective<'a>,
1036
        used: Cell<bool>,
J
Jeffrey Seyfried 已提交
1037
        legacy_self_import: bool,
1038
    },
1039 1040 1041
    Ambiguity {
        b1: &'a NameBinding<'a>,
        b2: &'a NameBinding<'a>,
1042
        legacy: bool,
1043
    }
1044 1045
}

1046 1047
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
struct UseError<'a> {
    err: DiagnosticBuilder<'a>,
    /// Attach `use` statements for these candidates
    candidates: Vec<ImportSuggestion>,
    /// The node id of the module to place the use statements in
    node_id: NodeId,
    /// Whether the diagnostic should state that it's "better"
    better: bool,
}

J
Jeffrey Seyfried 已提交
1058 1059 1060
struct AmbiguityError<'a> {
    span: Span,
    name: Name,
1061
    lexical: bool,
J
Jeffrey Seyfried 已提交
1062 1063
    b1: &'a NameBinding<'a>,
    b2: &'a NameBinding<'a>,
1064
    legacy: bool,
J
Jeffrey Seyfried 已提交
1065 1066
}

1067
impl<'a> NameBinding<'a> {
J
Jeffrey Seyfried 已提交
1068
    fn module(&self) -> Option<Module<'a>> {
1069
        match self.kind {
J
Jeffrey Seyfried 已提交
1070
            NameBindingKind::Module(module) => Some(module),
1071
            NameBindingKind::Import { binding, .. } => binding.module(),
1072
            NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.module(),
J
Jeffrey Seyfried 已提交
1073
            _ => None,
1074 1075 1076
        }
    }

1077
    fn def(&self) -> Def {
1078
        match self.kind {
1079
            NameBindingKind::Def(def) => def,
J
Jeffrey Seyfried 已提交
1080
            NameBindingKind::Module(module) => module.def().unwrap(),
1081
            NameBindingKind::Import { binding, .. } => binding.def(),
1082
            NameBindingKind::Ambiguity { legacy: true, b1, .. } => b1.def(),
1083
            NameBindingKind::Ambiguity { .. } => Def::Err,
1084
        }
1085
    }
1086

1087
    fn def_ignoring_ambiguity(&self) -> Def {
J
Jeffrey Seyfried 已提交
1088
        match self.kind {
1089 1090 1091
            NameBindingKind::Import { binding, .. } => binding.def_ignoring_ambiguity(),
            NameBindingKind::Ambiguity { b1, .. } => b1.def_ignoring_ambiguity(),
            _ => self.def(),
J
Jeffrey Seyfried 已提交
1092 1093 1094
        }
    }

1095 1096 1097 1098
    fn get_macro(&self, resolver: &mut Resolver<'a>) -> Rc<SyntaxExtension> {
        resolver.get_macro(self.def_ignoring_ambiguity())
    }

1099 1100 1101 1102 1103 1104 1105
    // 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 {
1106 1107
            NameBindingKind::Def(Def::Variant(..)) |
            NameBindingKind::Def(Def::VariantCtor(..)) => true,
1108 1109
            _ => false,
        }
1110 1111
    }

1112
    fn is_extern_crate(&self) -> bool {
1113 1114 1115
        match self.kind {
            NameBindingKind::Import {
                directive: &ImportDirective {
1116
                    subclass: ImportDirectiveSubclass::ExternCrate, ..
1117 1118 1119 1120
                }, ..
            } => true,
            _ => false,
        }
1121
    }
1122 1123 1124 1125 1126 1127 1128

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
1129 1130 1131 1132

    fn is_glob_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { directive, .. } => directive.is_glob(),
1133
            NameBindingKind::Ambiguity { b1, .. } => b1.is_glob_import(),
1134 1135 1136 1137 1138
            _ => false,
        }
    }

    fn is_importable(&self) -> bool {
1139
        match self.def() {
1140 1141 1142 1143
            Def::AssociatedConst(..) | Def::Method(..) | Def::AssociatedTy(..) => false,
            _ => true,
        }
    }
1144 1145 1146 1147 1148 1149 1150

    fn is_macro_def(&self) -> bool {
        match self.kind {
            NameBindingKind::Def(Def::Macro(..)) => true,
            _ => false,
        }
    }
1151 1152 1153 1154

    fn descr(&self) -> &'static str {
        if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
    }
1155 1156
}

1157
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1158
struct PrimitiveTypeTable {
1159
    primitive_types: FxHashMap<Name, PrimTy>,
1160
}
1161

1162
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1163
    fn new() -> PrimitiveTypeTable {
1164
        let mut table = PrimitiveTypeTable { primitive_types: FxHashMap() };
C
corentih 已提交
1165 1166 1167

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
1168 1169
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
1170 1171 1172 1173 1174
        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));
1175
        table.intern("i128", TyInt(IntTy::I128));
C
corentih 已提交
1176
        table.intern("str", TyStr);
1177 1178 1179 1180 1181
        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));
1182
        table.intern("u128", TyUint(UintTy::U128));
K
Kevin Butler 已提交
1183 1184 1185
        table
    }

1186
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1187
        self.primitive_types.insert(Symbol::intern(string), primitive_type);
1188 1189 1190
    }
}

1191
/// The main resolver class.
1192
pub struct Resolver<'a> {
E
Eduard Burtescu 已提交
1193
    session: &'a Session,
1194
    cstore: &'a CrateStore,
1195

1196
    pub definitions: Definitions,
1197

1198
    graph_root: Module<'a>,
1199

1200 1201
    prelude: Option<Module<'a>>,

1202 1203
    // n.b. This is used only for better diagnostics, not name resolution itself.
    has_self: FxHashSet<DefId>,
1204

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

1209 1210 1211 1212
    // All imports known to succeed or fail.
    determined_imports: Vec<&'a ImportDirective<'a>>,

    // All non-determined imports.
1213
    indeterminate_imports: Vec<&'a ImportDirective<'a>>,
1214 1215

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

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

1222
    // The current set of local scopes, for labels.
1223
    label_ribs: Vec<Rib<'a>>,
1224

1225
    // The trait that the current context can refer to.
1226
    current_trait_ref: Option<(Module<'a>, TraitRef)>,
1227 1228 1229

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

1231
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1232
    primitive_type_table: PrimitiveTypeTable,
1233

1234
    def_map: DefMap,
1235
    pub freevars: FreevarMap,
1236
    freevars_seen: NodeMap<NodeMap<usize>>,
1237 1238
    pub export_map: ExportMap,
    pub trait_map: TraitMap,
1239

1240
    // A map from nodes to anonymous modules.
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
    // 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`.
1254 1255
    block_map: NodeMap<Module<'a>>,
    module_map: FxHashMap<DefId, Module<'a>>,
J
Jeffrey Seyfried 已提交
1256
    extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
1257

1258
    pub make_glob_map: bool,
1259 1260
    /// Maps imports to the names of items actually imported (this actually maps
    /// all imports, but only glob imports are actually interesting).
1261
    pub glob_map: GlobMap,
1262

1263
    used_imports: FxHashSet<(NodeId, Namespace)>,
1264
    pub maybe_unused_trait_imports: NodeSet,
1265
    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
G
Garming Sam 已提交
1266

1267
    /// privacy errors are delayed until the end in order to deduplicate them
1268
    privacy_errors: Vec<PrivacyError<'a>>,
1269
    /// ambiguity errors are delayed for deduplication
J
Jeffrey Seyfried 已提交
1270
    ambiguity_errors: Vec<AmbiguityError<'a>>,
1271 1272 1273
    /// `use` injections are delayed for better placement and deduplication
    use_injections: Vec<UseError<'a>>,

J
Jeffrey Seyfried 已提交
1274
    gated_errors: FxHashSet<Span>,
1275
    disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
1276 1277

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

1281
    crate_loader: &'a mut CrateLoader,
J
Jeffrey Seyfried 已提交
1282
    macro_names: FxHashSet<Ident>,
J
Jeffrey Seyfried 已提交
1283
    global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
J
Jeffrey Seyfried 已提交
1284
    lexical_macro_resolutions: Vec<(Ident, &'a Cell<LegacyScope<'a>>)>,
J
Jeffrey Seyfried 已提交
1285
    macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
1286 1287
    macro_defs: FxHashMap<Mark, DefId>,
    local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
J
Jeffrey Seyfried 已提交
1288
    macro_exports: Vec<Export>,
1289
    pub whitelisted_legacy_custom_derives: Vec<Name>,
1290
    pub found_unresolved_macro: bool,
1291

E
est31 已提交
1292
    // List of crate local macros that we need to warn about as being unused.
E
est31 已提交
1293
    // Right now this only includes macro_rules! macros, and macros 2.0.
E
est31 已提交
1294
    unused_macros: FxHashSet<DefId>,
E
est31 已提交
1295

1296
    // Maps the `Mark` of an expansion to its containing module or block.
1297
    invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
1298 1299 1300

    // Avoid duplicated errors for "name already defined".
    name_already_seen: FxHashMap<Name, Span>,
1301 1302 1303 1304 1305 1306

    // If `#![feature(proc_macro)]` is set
    proc_macro_enabled: bool,

    // A set of procedural macros imported by `#[macro_use]` that have already been warned about
    warned_proc_macros: FxHashSet<Name>,
1307 1308

    potentially_unused_imports: Vec<&'a ImportDirective<'a>>,
1309

1310 1311 1312
    // This table maps struct IDs into struct constructor IDs,
    // it's not used during normal resolution, only for better error reporting.
    struct_constructors: DefIdMap<(Def, ty::Visibility)>,
1313 1314 1315

    // Only used for better errors on `fn(): fn()`
    current_type_ascription: Vec<Span>,
1316 1317
}

1318
pub struct ResolverArenas<'a> {
1319
    modules: arena::TypedArena<ModuleData<'a>>,
1320
    local_modules: RefCell<Vec<Module<'a>>>,
1321
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1322
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1323
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1324
    invocation_data: arena::TypedArena<InvocationData<'a>>,
J
Jeffrey Seyfried 已提交
1325
    legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
1326 1327 1328
}

impl<'a> ResolverArenas<'a> {
1329
    fn alloc_module(&'a self, module: ModuleData<'a>) -> Module<'a> {
1330 1331 1332 1333 1334 1335 1336 1337
        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()
1338 1339 1340 1341
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1342 1343
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1344 1345
        self.import_directives.alloc(import_directive)
    }
1346 1347 1348
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1349 1350 1351
    fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
                             -> &'a InvocationData<'a> {
        self.invocation_data.alloc(expansion_data)
J
Jeffrey Seyfried 已提交
1352
    }
J
Jeffrey Seyfried 已提交
1353 1354 1355
    fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
        self.legacy_bindings.alloc(binding)
    }
1356 1357
}

1358 1359 1360 1361
impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> {
    fn parent(self, id: DefId) -> Option<DefId> {
        match id.krate {
            LOCAL_CRATE => self.definitions.def_key(id.index).parent,
1362
            _ => self.cstore.def_key(id).parent,
1363
        }.map(|index| DefId { index: index, ..id })
1364 1365 1366
    }
}

1367
impl<'a> hir::lowering::Resolver for Resolver<'a> {
J
Jeffrey Seyfried 已提交
1368
    fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
1369
        let namespace = if is_value { ValueNS } else { TypeNS };
1370
        let hir::Path { ref segments, span, ref mut def } = *path;
1371 1372 1373
        let path: Vec<SpannedIdent> = segments.iter()
            .map(|seg| respan(span, Ident::with_empty_ctxt(seg.name)))
            .collect();
1374
        match self.resolve_path(&path, Some(namespace), true, span) {
J
Jeffrey Seyfried 已提交
1375
            PathResult::Module(module) => *def = module.def().unwrap(),
1376 1377
            PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
                *def = path_res.base_def(),
1378
            PathResult::NonModule(..) => match self.resolve_path(&path, None, true, span) {
1379
                PathResult::Failed(span, msg, _) => {
J
Jeffrey Seyfried 已提交
1380 1381 1382 1383 1384
                    resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                }
                _ => {}
            },
            PathResult::Indeterminate => unreachable!(),
1385
            PathResult::Failed(span, msg, _) => {
J
Jeffrey Seyfried 已提交
1386
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
1387 1388 1389 1390
            }
        }
    }

1391 1392 1393 1394
    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
        self.def_map.get(&id).cloned()
    }

1395 1396
    fn definitions(&mut self) -> &mut Definitions {
        &mut self.definitions
1397 1398 1399
    }
}

1400
impl<'a> Resolver<'a> {
1401
    pub fn new(session: &'a Session,
1402
               cstore: &'a CrateStore,
1403
               krate: &Crate,
1404
               crate_name: &str,
1405
               make_glob_map: MakeGlobMap,
1406
               crate_loader: &'a mut CrateLoader,
1407
               arenas: &'a ResolverArenas<'a>)
1408
               -> Resolver<'a> {
1409 1410
        let root_def_id = DefId::local(CRATE_DEF_INDEX);
        let root_module_kind = ModuleKind::Def(Def::Mod(root_def_id), keywords::Invalid.name());
1411
        let graph_root = arenas.alloc_module(ModuleData {
1412
            no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
J
Jeffrey Seyfried 已提交
1413
            ..ModuleData::new(None, root_module_kind, root_def_id, Mark::root(), krate.span)
1414
        });
1415 1416
        let mut module_map = FxHashMap();
        module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
K
Kevin Butler 已提交
1417

1418
        let mut definitions = Definitions::new();
J
Jeffrey Seyfried 已提交
1419
        DefCollector::new(&mut definitions, Mark::root())
1420
            .collect_root(crate_name, session.local_crate_disambiguator());
1421

1422
        let mut invocations = FxHashMap();
1423 1424
        invocations.insert(Mark::root(),
                           arenas.alloc_invocation_data(InvocationData::root(graph_root)));
1425

1426 1427
        let features = session.features.borrow();

1428 1429 1430
        let mut macro_defs = FxHashMap();
        macro_defs.insert(Mark::root(), root_def_id);

K
Kevin Butler 已提交
1431
        Resolver {
1432
            session,
K
Kevin Butler 已提交
1433

1434 1435
            cstore,

1436
            definitions,
1437

K
Kevin Butler 已提交
1438 1439
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1440
            graph_root,
1441
            prelude: None,
K
Kevin Butler 已提交
1442

1443
            has_self: FxHashSet(),
1444
            field_names: FxHashMap(),
K
Kevin Butler 已提交
1445

1446
            determined_imports: Vec::new(),
1447
            indeterminate_imports: Vec::new(),
K
Kevin Butler 已提交
1448

1449
            current_module: graph_root,
J
Jeffrey Seyfried 已提交
1450 1451 1452
            ribs: PerNS {
                value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
                type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
1453
                macro_ns: Some(vec![Rib::new(ModuleRibKind(graph_root))]),
J
Jeffrey Seyfried 已提交
1454
            },
1455
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1456 1457 1458 1459 1460 1461

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1462
            def_map: NodeMap(),
1463 1464
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
A
Alex Crichton 已提交
1465
            export_map: FxHashMap(),
1466
            trait_map: NodeMap(),
1467
            module_map,
1468
            block_map: NodeMap(),
J
Jeffrey Seyfried 已提交
1469
            extern_module_map: FxHashMap(),
K
Kevin Butler 已提交
1470

1471
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1472
            glob_map: NodeMap(),
G
Garming Sam 已提交
1473

1474
            used_imports: FxHashSet(),
S
Seo Sanghyeon 已提交
1475
            maybe_unused_trait_imports: NodeSet(),
1476
            maybe_unused_extern_crates: Vec::new(),
S
Seo Sanghyeon 已提交
1477

1478
            privacy_errors: Vec::new(),
1479
            ambiguity_errors: Vec::new(),
1480
            use_injections: Vec::new(),
J
Jeffrey Seyfried 已提交
1481
            gated_errors: FxHashSet(),
1482
            disallowed_shadowing: Vec::new(),
1483

1484
            arenas,
1485 1486
            dummy_binding: arenas.alloc_name_binding(NameBinding {
                kind: NameBindingKind::Def(Def::Err),
1487
                expansion: Mark::root(),
1488 1489 1490
                span: DUMMY_SP,
                vis: ty::Visibility::Public,
            }),
1491

1492 1493 1494
            // The `proc_macro` and `decl_macro` features imply `use_extern_macros`
            use_extern_macros:
                features.use_extern_macros || features.proc_macro || features.decl_macro,
1495

1496
            crate_loader,
1497
            macro_names: FxHashSet(),
J
Jeffrey Seyfried 已提交
1498
            global_macros: FxHashMap(),
J
Jeffrey Seyfried 已提交
1499
            lexical_macro_resolutions: Vec::new(),
J
Jeffrey Seyfried 已提交
1500 1501
            macro_map: FxHashMap(),
            macro_exports: Vec::new(),
1502 1503
            invocations,
            macro_defs,
1504
            local_macro_def_scopes: FxHashMap(),
1505
            name_already_seen: FxHashMap(),
1506
            whitelisted_legacy_custom_derives: Vec::new(),
1507 1508
            proc_macro_enabled: features.proc_macro,
            warned_proc_macros: FxHashSet(),
1509
            potentially_unused_imports: Vec::new(),
1510
            struct_constructors: DefIdMap(),
1511
            found_unresolved_macro: false,
E
est31 已提交
1512
            unused_macros: FxHashSet(),
1513
            current_type_ascription: Vec::new(),
1514 1515 1516
        }
    }

1517
    pub fn arenas() -> ResolverArenas<'a> {
1518 1519
        ResolverArenas {
            modules: arena::TypedArena::new(),
1520
            local_modules: RefCell::new(Vec::new()),
1521
            name_bindings: arena::TypedArena::new(),
1522
            import_directives: arena::TypedArena::new(),
1523
            name_resolutions: arena::TypedArena::new(),
1524
            invocation_data: arena::TypedArena::new(),
J
Jeffrey Seyfried 已提交
1525
            legacy_bindings: arena::TypedArena::new(),
K
Kevin Butler 已提交
1526 1527
        }
    }
1528

J
Jeffrey Seyfried 已提交
1529 1530 1531 1532
    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),
1533 1534 1535 1536
            macro_ns: match self.use_extern_macros {
                true => Some(f(self, MacroNS)),
                false => None,
            },
J
Jeffrey Seyfried 已提交
1537 1538 1539
        }
    }

1540 1541
    /// Entry point to crate resolution.
    pub fn resolve_crate(&mut self, krate: &Crate) {
1542
        ImportResolver { resolver: self }.finalize_imports();
1543
        self.current_module = self.graph_root;
1544
        self.finalize_current_module_macro_resolutions();
1545

1546 1547 1548
        visit::walk_crate(self, krate);

        check_unused::check_crate(self, krate);
1549
        self.report_errors(krate);
1550
        self.crate_loader.postprocess(krate);
1551 1552
    }

O
Oliver Schneider 已提交
1553 1554 1555 1556 1557
    fn new_module(
        &self,
        parent: Module<'a>,
        kind: ModuleKind,
        normal_ancestor_id: DefId,
J
Jeffrey Seyfried 已提交
1558
        expansion: Mark,
O
Oliver Schneider 已提交
1559 1560
        span: Span,
    ) -> Module<'a> {
J
Jeffrey Seyfried 已提交
1561 1562
        let module = ModuleData::new(Some(parent), kind, normal_ancestor_id, expansion, span);
        self.arenas.alloc_module(module)
1563 1564
    }

1565
    fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
1566
                  -> bool /* true if an error was reported */ {
1567
        match binding.kind {
J
Jeffrey Seyfried 已提交
1568 1569
            NameBindingKind::Import { directive, binding, ref used, legacy_self_import }
                    if !used.get() => {
1570
                used.set(true);
1571
                directive.used.set(true);
J
Jeffrey Seyfried 已提交
1572 1573 1574 1575
                if legacy_self_import {
                    self.warn_legacy_self_import(directive);
                    return false;
                }
1576
                self.used_imports.insert((directive.id, ns));
1577 1578
                self.add_to_glob_map(directive.id, ident);
                self.record_use(ident, ns, binding, span)
1579 1580
            }
            NameBindingKind::Import { .. } => false,
1581
            NameBindingKind::Ambiguity { b1, b2, legacy } => {
1582
                self.ambiguity_errors.push(AmbiguityError {
1583
                    span: span, name: ident.name, lexical: false, b1: b1, b2: b2, legacy,
1584
                });
1585
                if legacy {
A
Alex Crichton 已提交
1586
                    self.record_use(ident, ns, b1, span);
1587 1588
                }
                !legacy
1589 1590
            }
            _ => false
1591
        }
1592
    }
1593

1594
    fn add_to_glob_map(&mut self, id: NodeId, ident: Ident) {
1595
        if self.make_glob_map {
1596
            self.glob_map.entry(id).or_insert_with(FxHashSet).insert(ident.name);
1597
        }
1598 1599
    }

1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
    /// 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.
    /// }
    /// ```
1614
    ///
1615 1616
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
1617
    fn resolve_ident_in_lexical_scope(&mut self,
1618
                                      mut ident: Ident,
1619
                                      ns: Namespace,
1620 1621
                                      record_used: bool,
                                      path_span: Span)
1622
                                      -> Option<LexicalScopeBinding<'a>> {
1623
        if ns == TypeNS {
J
Jeffrey Seyfried 已提交
1624 1625 1626 1627 1628
            ident.ctxt = if ident.name == keywords::SelfType.name() {
                SyntaxContext::empty() // FIXME(jseyfried) improve `Self` hygiene
            } else {
                ident.ctxt.modern()
            }
1629
        }
1630

1631
        // Walk backwards up the ribs in scope.
J
Jeffrey Seyfried 已提交
1632
        let mut module = self.graph_root;
J
Jeffrey Seyfried 已提交
1633 1634
        for i in (0 .. self.ribs[ns].len()).rev() {
            if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
1635
                // The ident resolves to a type parameter or local variable.
1636
                return Some(LexicalScopeBinding::Def(
1637
                    self.adjust_local_def(ns, i, def, record_used, path_span)
1638
                ));
1639 1640
            }

J
Jeffrey Seyfried 已提交
1641 1642 1643 1644 1645 1646 1647
            module = match self.ribs[ns][i].kind {
                ModuleRibKind(module) => module,
                MacroDefinition(def) if def == self.macro_defs[&ident.ctxt.outer()] => {
                    // If an invocation of this macro created `ident`, give up on `ident`
                    // and switch to `ident`'s source from the macro definition.
                    ident.ctxt.remove_mark();
                    continue
1648
                }
J
Jeffrey Seyfried 已提交
1649 1650
                _ => continue,
            };
1651

J
Jeffrey Seyfried 已提交
1652 1653 1654 1655 1656 1657
            let item = self.resolve_ident_in_module_unadjusted(
                module, ident, ns, false, record_used, path_span,
            );
            if let Ok(binding) = item {
                // The ident resolves to an item.
                return Some(LexicalScopeBinding::Item(binding));
1658
            }
1659

J
Jeffrey Seyfried 已提交
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
            match module.kind {
                ModuleKind::Block(..) => {}, // We can see through blocks
                _ => break,
            }
        }

        ident.ctxt = ident.ctxt.modern();
        loop {
            module = unwrap_or!(self.hygienic_lexical_parent(module, &mut ident.ctxt), break);
            let orig_current_module = self.current_module;
            self.current_module = module; // Lexical resolutions can never be a privacy error.
            let result = self.resolve_ident_in_module_unadjusted(
                module, ident, ns, false, record_used, path_span,
            );
            self.current_module = orig_current_module;

            match result {
                Ok(binding) => return Some(LexicalScopeBinding::Item(binding)),
                Err(Undetermined) => return None,
                Err(Determined) => {}
            }
        }

        match self.prelude {
            Some(prelude) if !module.no_implicit_prelude => {
                self.resolve_ident_in_module_unadjusted(prelude, ident, ns, false, false, path_span)
                    .ok().map(LexicalScopeBinding::Item)
            }
            _ => None,
        }
    }

    fn hygienic_lexical_parent(&mut self, mut module: Module<'a>, ctxt: &mut SyntaxContext)
                               -> Option<Module<'a>> {
        if !module.expansion.is_descendant_of(ctxt.outer()) {
            return Some(self.macro_def_scope(ctxt.remove_mark()));
        }

        if let ModuleKind::Block(..) = module.kind {
            return Some(module.parent.unwrap());
        }

B
Bastien Orivel 已提交
1702
        let mut module_expansion = module.expansion.modern(); // for backward compatibility
J
Jeffrey Seyfried 已提交
1703 1704 1705 1706 1707 1708 1709 1710 1711
        while let Some(parent) = module.parent {
            let parent_expansion = parent.expansion.modern();
            if module_expansion.is_descendant_of(parent_expansion) &&
               parent_expansion != module_expansion {
                return if parent_expansion.is_descendant_of(ctxt.outer()) {
                    Some(parent)
                } else {
                    None
                };
1712
            }
J
Jeffrey Seyfried 已提交
1713 1714
            module = parent;
            module_expansion = parent_expansion;
1715
        }
1716

1717 1718 1719
        None
    }

J
Jeffrey Seyfried 已提交
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
    fn resolve_ident_in_module(&mut self,
                               module: Module<'a>,
                               mut ident: Ident,
                               ns: Namespace,
                               ignore_unresolved_invocations: bool,
                               record_used: bool,
                               span: Span)
                               -> Result<&'a NameBinding<'a>, Determinacy> {
        ident.ctxt = ident.ctxt.modern();
        let orig_current_module = self.current_module;
        if let Some(def) = ident.ctxt.adjust(module.expansion) {
            self.current_module = self.macro_def_scope(def);
        }
        let result = self.resolve_ident_in_module_unadjusted(
            module, ident, ns, ignore_unresolved_invocations, record_used, span,
        );
        self.current_module = orig_current_module;
        result
    }

    fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext) -> Module<'a> {
        let module = match ctxt.adjust(Mark::root()) {
            Some(def) => self.macro_def_scope(def),
            None => return self.graph_root,
        };
        self.get_module(DefId { index: CRATE_DEF_INDEX, ..module.normal_ancestor_id })
    }

    fn resolve_self(&mut self, ctxt: &mut SyntaxContext, module: Module<'a>) -> Module<'a> {
        let mut module = self.get_module(module.normal_ancestor_id);
1750
        while module.span.ctxt().modern() != *ctxt {
J
Jeffrey Seyfried 已提交
1751 1752
            let parent = module.parent.unwrap_or_else(|| self.macro_def_scope(ctxt.remove_mark()));
            module = self.get_module(parent.normal_ancestor_id);
1753
        }
J
Jeffrey Seyfried 已提交
1754
        module
1755 1756
    }

1757 1758
    // AST resolution
    //
1759
    // We maintain a list of value ribs and type ribs.
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
    //
    // 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.

1775
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1776
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1777
    {
1778
        let id = self.definitions.local_def_id(id);
1779 1780
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
1781
            // Move down in the graph.
1782
            let orig_module = replace(&mut self.current_module, module);
J
Jeffrey Seyfried 已提交
1783 1784
            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
1785

1786
            self.finalize_current_module_macro_resolutions();
1787
            f(self);
1788

1789
            self.current_module = orig_module;
J
Jeffrey Seyfried 已提交
1790 1791
            self.ribs[ValueNS].pop();
            self.ribs[TypeNS].pop();
1792 1793 1794
        } else {
            f(self);
        }
1795 1796
    }

1797 1798 1799
    /// Searches the current set of local scopes for labels. Returns the first non-None label that
    /// is returned by the given predicate function
    ///
S
Seo Sanghyeon 已提交
1800
    /// Stops after meeting a closure.
1801 1802 1803
    fn search_label<P, R>(&self, mut ident: Ident, pred: P) -> Option<R>
        where P: Fn(&Rib, Ident) -> Option<R>
    {
1804 1805
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
J
Jeffrey Seyfried 已提交
1806 1807 1808
                NormalRibKind => {}
                // If an invocation of this macro created `ident`, give up on `ident`
                // and switch to `ident`'s source from the macro definition.
1809
                MacroDefinition(def) => {
J
Jeffrey Seyfried 已提交
1810 1811
                    if def == self.macro_defs[&ident.ctxt.outer()] {
                        ident.ctxt.remove_mark();
1812 1813
                    }
                }
1814 1815
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1816
                    return None;
1817 1818
                }
            }
1819 1820 1821
            let r = pred(rib, ident);
            if r.is_some() {
                return r;
1822 1823 1824 1825 1826
            }
        }
        None
    }

1827
    fn resolve_item(&mut self, item: &Item) {
1828
        let name = item.ident.name;
1829

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

1832 1833
        self.check_proc_macro_attrs(&item.attrs);

1834
        match item.node {
1835 1836
            ItemKind::Enum(_, ref generics) |
            ItemKind::Ty(_, ref generics) |
1837
            ItemKind::Struct(_, ref generics) |
1838
            ItemKind::Union(_, ref generics) |
V
Vadim Petrochenkov 已提交
1839
            ItemKind::Fn(.., ref generics, _) => {
1840
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
1841
                                             |this| visit::walk_item(this, item));
1842 1843
            }

1844
            ItemKind::DefaultImpl(_, ref trait_ref) => {
1845 1846 1847 1848
                self.with_optional_trait_ref(Some(trait_ref), |this, _| {
                    // Resolve type arguments in trait path
                    visit::walk_trait_ref(this, trait_ref);
                });
1849
            }
V
Vadim Petrochenkov 已提交
1850
            ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
1851
                self.resolve_implementation(generics,
1852
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1853
                                            &self_type,
1854
                                            item.id,
1855
                                            impl_items),
1856

1857
            ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
1858
                // Create a new rib for the trait-wide type parameters.
1859
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
1860
                    let local_def_id = this.definitions.local_def_id(item.id);
1861
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1862
                        this.visit_generics(generics);
1863
                        walk_list!(this, visit_ty_param_bound, bounds);
1864 1865

                        for trait_item in trait_items {
1866 1867
                            this.check_proc_macro_attrs(&trait_item.attrs);

1868
                            match trait_item.node {
1869 1870 1871
                                TraitItemKind::Const(ref ty, ref default) => {
                                    this.visit_ty(ty);

1872
                                    // Only impose the restrictions of
1873
                                    // ConstRibKind for an actual constant
1874
                                    // expression in a provided default.
1875
                                    if let Some(ref expr) = *default{
1876
                                        this.with_constant_rib(|this| {
1877
                                            this.visit_expr(expr);
1878 1879 1880
                                        });
                                    }
                                }
1881
                                TraitItemKind::Method(ref sig, _) => {
1882
                                    let type_parameters =
1883
                                        HasTypeParameters(&trait_item.generics,
V
Vadim Petrochenkov 已提交
1884
                                                          MethodRibKind(!sig.decl.has_self()));
1885
                                    this.with_type_parameter_rib(type_parameters, |this| {
1886
                                        visit::walk_trait_item(this, trait_item)
1887
                                    });
1888
                                }
1889
                                TraitItemKind::Type(..) => {
1890
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1891
                                        visit::walk_trait_item(this, trait_item)
1892
                                    });
1893
                                }
1894
                                TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
1895 1896 1897
                            };
                        }
                    });
1898
                });
1899 1900
            }

1901
            ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
1902
                self.with_scope(item.id, |this| {
1903
                    visit::walk_item(this, item);
1904
                });
1905 1906
            }

1907 1908 1909 1910 1911 1912 1913
            ItemKind::Static(ref ty, _, ref expr) |
            ItemKind::Const(ref ty, ref expr) => {
                self.with_item_rib(|this| {
                    this.visit_ty(ty);
                    this.with_constant_rib(|this| {
                        this.visit_expr(expr);
                    });
1914
                });
1915
            }
1916

1917
            ItemKind::Use(ref view_path) => {
1918
                match view_path.node {
1919 1920 1921
                    ast::ViewPathList(ref prefix, ref items) if items.is_empty() => {
                        // Resolve prefix of an import with empty braces (issue #28388).
                        self.smart_resolve_path(item.id, None, prefix, PathSource::ImportPrefix);
1922 1923
                    }
                    _ => {}
W
we 已提交
1924 1925 1926
                }
            }

1927
            ItemKind::ExternCrate(_) | ItemKind::MacroDef(..) | ItemKind::GlobalAsm(_)=> {
1928
                // do nothing, these are just around to be encoded
1929
            }
1930 1931

            ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
1932 1933 1934
        }
    }

1935
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1936
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1937
    {
1938
        match type_parameters {
1939
            HasTypeParameters(generics, rib_kind) => {
1940
                let mut function_type_rib = Rib::new(rib_kind);
1941
                let mut seen_bindings = FxHashMap();
1942
                for type_parameter in &generics.ty_params {
J
Jeffrey Seyfried 已提交
1943
                    let ident = type_parameter.ident.modern();
1944
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1945

1946 1947 1948 1949 1950
                    if seen_bindings.contains_key(&ident) {
                        let span = seen_bindings.get(&ident).unwrap();
                        let err =
                            ResolutionError::NameAlreadyUsedInTypeParameterList(ident.name, span);
                        resolve_error(self, type_parameter.span, err);
1951
                    }
1952
                    seen_bindings.entry(ident).or_insert(type_parameter.span);
1953

1954
                    // plain insert (no renaming)
1955
                    let def_id = self.definitions.local_def_id(type_parameter.id);
1956
                    let def = Def::TyParam(def_id);
1957
                    function_type_rib.bindings.insert(ident, def);
1958
                    self.record_def(type_parameter.id, PathResolution::new(def));
1959
                }
J
Jeffrey Seyfried 已提交
1960
                self.ribs[TypeNS].push(function_type_rib);
1961 1962
            }

B
Brian Anderson 已提交
1963
            NoTypeParameters => {
1964 1965 1966 1967
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1968
        f(self);
1969

J
Jeffrey Seyfried 已提交
1970
        if let HasTypeParameters(..) = type_parameters {
J
Jeffrey Seyfried 已提交
1971
            self.ribs[TypeNS].pop();
1972 1973 1974
        }
    }

C
corentih 已提交
1975 1976
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1977
    {
1978
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1979
        f(self);
J
Jeffrey Seyfried 已提交
1980
        self.label_ribs.pop();
1981
    }
1982

1983 1984 1985 1986 1987 1988 1989 1990 1991 1992
    fn with_item_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
    {
        self.ribs[ValueNS].push(Rib::new(ItemRibKind));
        self.ribs[TypeNS].push(Rib::new(ItemRibKind));
        f(self);
        self.ribs[TypeNS].pop();
        self.ribs[ValueNS].pop();
    }

C
corentih 已提交
1993 1994
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1995
    {
J
Jeffrey Seyfried 已提交
1996
        self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1997
        f(self);
J
Jeffrey Seyfried 已提交
1998
        self.ribs[ValueNS].pop();
1999 2000
    }

2001 2002
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2003
    {
2004 2005 2006 2007 2008 2009 2010
        // 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
    }

2011
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2012
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2013
    {
2014
        let mut new_val = None;
2015
        let mut new_id = None;
E
Eduard Burtescu 已提交
2016
        if let Some(trait_ref) = opt_trait_ref {
2017 2018 2019
            let path: Vec<_> = trait_ref.path.segments.iter()
                .map(|seg| respan(seg.span, seg.identifier))
                .collect();
2020 2021 2022 2023 2024 2025 2026
            let def = self.smart_resolve_path_fragment(trait_ref.ref_id,
                                                       None,
                                                       &path,
                                                       trait_ref.path.span,
                                                       trait_ref.path.segments.last().unwrap().span,
                                                       PathSource::Trait)
                .base_def();
2027 2028
            if def != Def::Err {
                new_id = Some(def.def_id());
2029 2030 2031 2032
                let span = trait_ref.path.span;
                if let PathResult::Module(module) = self.resolve_path(&path, None, false, span) {
                    new_val = Some((module, trait_ref.clone()));
                }
2033
            }
2034
        }
2035
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2036
        let result = f(self, new_id);
2037 2038 2039 2040
        self.current_trait_ref = original_trait_ref;
        result
    }

2041 2042 2043 2044 2045 2046
    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....)
2047
        self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
J
Jeffrey Seyfried 已提交
2048
        self.ribs[TypeNS].push(self_type_rib);
2049
        f(self);
J
Jeffrey Seyfried 已提交
2050
        self.ribs[TypeNS].pop();
2051 2052
    }

F
Felix S. Klock II 已提交
2053
    fn resolve_implementation(&mut self,
2054 2055 2056
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2057
                              item_id: NodeId,
2058
                              impl_items: &[ImplItem]) {
2059
        // If applicable, create a rib for the type parameters.
2060
        self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082
            // Dummy self type for better errors if `Self` is used in the trait path.
            this.with_self_rib(Def::SelfTy(None, None), |this| {
                // Resolve the trait reference, if necessary.
                this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
                    let item_def_id = this.definitions.local_def_id(item_id);
                    this.with_self_rib(Def::SelfTy(trait_id, Some(item_def_id)), |this| {
                        if let Some(trait_ref) = opt_trait_reference.as_ref() {
                            // Resolve type arguments in trait path
                            visit::walk_trait_ref(this, trait_ref);
                        }
                        // Resolve the self type.
                        this.visit_ty(self_type);
                        // Resolve the type parameters.
                        this.visit_generics(generics);
                        this.with_current_self_type(self_type, |this| {
                            for impl_item in impl_items {
                                this.check_proc_macro_attrs(&impl_item.attrs);
                                this.resolve_visibility(&impl_item.vis);
                                match impl_item.node {
                                    ImplItemKind::Const(..) => {
                                        // If this is a trait impl, ensure the const
                                        // exists in trait
2083
                                        this.check_trait_item(impl_item.ident,
2084 2085 2086
                                                            ValueNS,
                                                            impl_item.span,
                                            |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2087 2088 2089
                                        this.with_constant_rib(|this|
                                            visit::walk_impl_item(this, impl_item)
                                        );
2090 2091 2092 2093
                                    }
                                    ImplItemKind::Method(ref sig, _) => {
                                        // If this is a trait impl, ensure the method
                                        // exists in trait
2094
                                        this.check_trait_item(impl_item.ident,
2095 2096 2097 2098 2099 2100 2101
                                                            ValueNS,
                                                            impl_item.span,
                                            |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));

                                        // We also need a new scope for the method-
                                        // specific type parameters.
                                        let type_parameters =
2102
                                            HasTypeParameters(&impl_item.generics,
2103 2104 2105 2106 2107 2108 2109 2110
                                                            MethodRibKind(!sig.decl.has_self()));
                                        this.with_type_parameter_rib(type_parameters, |this| {
                                            visit::walk_impl_item(this, impl_item);
                                        });
                                    }
                                    ImplItemKind::Type(ref ty) => {
                                        // If this is a trait impl, ensure the type
                                        // exists in trait
2111
                                        this.check_trait_item(impl_item.ident,
2112 2113 2114 2115 2116 2117 2118 2119
                                                            TypeNS,
                                                            impl_item.span,
                                            |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));

                                        this.visit_ty(ty);
                                    }
                                    ImplItemKind::Macro(_) =>
                                        panic!("unexpanded macro in resolve!"),
2120
                                }
2121
                            }
2122
                        });
2123
                    });
2124
                });
2125
            });
2126
        });
2127 2128
    }

2129
    fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
C
corentih 已提交
2130 2131 2132 2133
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2134 2135 2136 2137
        if let Some((module, _)) = self.current_trait_ref {
            if self.resolve_ident_in_module(module, ident, ns, false, false, span).is_err() {
                let path = &self.current_trait_ref.as_ref().unwrap().1.path;
                resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
2138 2139 2140 2141
            }
        }
    }

E
Eduard Burtescu 已提交
2142
    fn resolve_local(&mut self, local: &Local) {
2143
        // Resolve the type.
2144
        walk_list!(self, visit_ty, &local.ty);
2145

2146
        // Resolve the initializer.
2147
        walk_list!(self, visit_expr, &local.init);
2148 2149

        // Resolve the pattern.
2150
        self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap());
2151 2152
    }

J
John Clements 已提交
2153 2154 2155 2156
    // 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 已提交
2157
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2158
        let mut binding_map = FxHashMap();
2159 2160 2161

        pat.walk(&mut |pat| {
            if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
2162 2163
                if sub_pat.is_some() || match self.def_map.get(&pat.id).map(|res| res.base_def()) {
                    Some(Def::Local(..)) => true,
2164 2165 2166
                    _ => false,
                } {
                    let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
2167
                    binding_map.insert(ident.node, binding_info);
2168 2169 2170
                }
            }
            true
2171
        });
2172 2173

        binding_map
2174 2175
    }

J
John Clements 已提交
2176 2177
    // 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 已提交
2178
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2179
        if arm.pats.is_empty() {
C
corentih 已提交
2180
            return;
2181
        }
2182 2183 2184

        let mut missing_vars = FxHashMap();
        let mut inconsistent_vars = FxHashMap();
D
Daniel Micay 已提交
2185
        for (i, p) in arm.pats.iter().enumerate() {
J
Jonas Schievink 已提交
2186
            let map_i = self.binding_mode_map(&p);
2187

2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199
            for (j, q) in arm.pats.iter().enumerate() {
                if i == j {
                    continue;
                }

                let map_j = self.binding_mode_map(&q);
                for (&key, &binding_i) in &map_i {
                    if map_j.len() == 0 {                   // Account for missing bindings when
                        let binding_error = missing_vars    // map_j has none.
                            .entry(key.name)
                            .or_insert(BindingError {
                                name: key.name,
2200 2201
                                origin: BTreeSet::new(),
                                target: BTreeSet::new(),
2202 2203 2204
                            });
                        binding_error.origin.insert(binding_i.span);
                        binding_error.target.insert(q.span);
C
corentih 已提交
2205
                    }
2206 2207 2208 2209 2210 2211 2212
                    for (&key_j, &binding_j) in &map_j {
                        match map_i.get(&key_j) {
                            None => {  // missing binding
                                let binding_error = missing_vars
                                    .entry(key_j.name)
                                    .or_insert(BindingError {
                                        name: key_j.name,
2213 2214
                                        origin: BTreeSet::new(),
                                        target: BTreeSet::new(),
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225
                                    });
                                binding_error.origin.insert(binding_j.span);
                                binding_error.target.insert(p.span);
                            }
                            Some(binding_i) => {  // check consistent binding
                                if binding_i.binding_mode != binding_j.binding_mode {
                                    inconsistent_vars
                                        .entry(key.name)
                                        .or_insert((binding_j.span, binding_i.span));
                                }
                            }
C
corentih 已提交
2226
                        }
2227
                    }
2228 2229
                }
            }
2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241
        }
        let mut missing_vars = missing_vars.iter().collect::<Vec<_>>();
        missing_vars.sort();
        for (_, v) in missing_vars {
            resolve_error(self,
                          *v.origin.iter().next().unwrap(),
                          ResolutionError::VariableNotBoundInPattern(v));
        }
        let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
        inconsistent_vars.sort();
        for (name, v) in inconsistent_vars {
            resolve_error(self, v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
2242
        }
2243 2244
    }

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

2248
        let mut bindings_list = FxHashMap();
2249
        for pattern in &arm.pats {
2250
            self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
2251 2252
        }

2253 2254 2255 2256
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2257
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2258
        self.visit_expr(&arm.body);
2259

J
Jeffrey Seyfried 已提交
2260
        self.ribs[ValueNS].pop();
2261 2262
    }

E
Eduard Burtescu 已提交
2263
    fn resolve_block(&mut self, block: &Block) {
2264
        debug!("(resolving block) entering block");
2265
        // Move down in the graph, if there's an anonymous module rooted here.
2266
        let orig_module = self.current_module;
2267
        let anonymous_module = self.block_map.get(&block.id).cloned(); // clones a reference
2268

2269
        let mut num_macro_definition_ribs = 0;
2270 2271
        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
J
Jeffrey Seyfried 已提交
2272 2273
            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
2274
            self.current_module = anonymous_module;
2275
            self.finalize_current_module_macro_resolutions();
2276
        } else {
J
Jeffrey Seyfried 已提交
2277
            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
2278 2279 2280
        }

        // Descend into the block.
2281
        for stmt in &block.stmts {
2282
            if let ast::StmtKind::Item(ref item) = stmt.node {
2283
                if let ast::ItemKind::MacroDef(..) = item.node {
2284
                    num_macro_definition_ribs += 1;
2285 2286 2287
                    let def = self.definitions.local_def_id(item.id);
                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(def)));
                    self.label_ribs.push(Rib::new(MacroDefinition(def)));
2288 2289 2290 2291 2292
                }
            }

            self.visit_stmt(stmt);
        }
2293 2294

        // Move back up.
J
Jeffrey Seyfried 已提交
2295
        self.current_module = orig_module;
2296
        for _ in 0 .. num_macro_definition_ribs {
J
Jeffrey Seyfried 已提交
2297
            self.ribs[ValueNS].pop();
2298
            self.label_ribs.pop();
2299
        }
J
Jeffrey Seyfried 已提交
2300
        self.ribs[ValueNS].pop();
J
Jeffrey Seyfried 已提交
2301
        if let Some(_) = anonymous_module {
J
Jeffrey Seyfried 已提交
2302
            self.ribs[TypeNS].pop();
G
Garming Sam 已提交
2303
        }
2304
        debug!("(resolving block) leaving block");
2305 2306
    }

2307
    fn fresh_binding(&mut self,
J
Jeffrey Seyfried 已提交
2308
                     ident: &SpannedIdent,
2309 2310 2311
                     pat_id: NodeId,
                     outer_pat_id: NodeId,
                     pat_src: PatternSource,
2312
                     bindings: &mut FxHashMap<Ident, NodeId>)
2313 2314
                     -> PathResolution {
        // Add the binding to the local ribs, if it
2315 2316
        // doesn't already exist in the bindings map. (We
        // must not add it if it's in the bindings map
2317 2318
        // because that breaks the assumptions later
        // passes make about or-patterns.)
2319
        let mut def = Def::Local(pat_id);
2320
        match bindings.get(&ident.node).cloned() {
2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339
            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 => {
2340 2341
                // `Variant1(a) | Variant2(a)`, ok
                // Reuse definition from the first `a`.
J
Jeffrey Seyfried 已提交
2342
                def = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident.node];
2343 2344 2345 2346 2347 2348
            }
            Some(..) => {
                span_bug!(ident.span, "two bindings with the same name from \
                                       unexpected pattern source {:?}", pat_src);
            }
            None => {
2349
                // A completely fresh binding, add to the lists if it's valid.
2350
                if ident.node.name != keywords::Invalid.name() {
2351
                    bindings.insert(ident.node, outer_pat_id);
J
Jeffrey Seyfried 已提交
2352
                    self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident.node, def);
2353
                }
2354
            }
2355
        }
2356

2357
        PathResolution::new(def)
2358
    }
2359

2360 2361 2362 2363 2364
    fn resolve_pattern(&mut self,
                       pat: &Pat,
                       pat_src: PatternSource,
                       // Maps idents to the node ID for the
                       // outermost pattern that binds them.
2365
                       bindings: &mut FxHashMap<Ident, NodeId>) {
2366
        // Visit all direct subpatterns of this pattern.
2367 2368 2369 2370 2371 2372
        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.
2373 2374
                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS,
                                                                      false, pat.span)
2375
                                      .and_then(LexicalScopeBinding::item);
2376
                    let resolution = binding.map(NameBinding::def).and_then(|def| {
2377
                        let ivmode = BindingMode::ByValue(Mutability::Immutable);
2378
                        let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
2379
                                             bmode != ivmode;
2380
                        match def {
2381 2382 2383 2384
                            Def::StructCtor(_, CtorKind::Const) |
                            Def::VariantCtor(_, CtorKind::Const) |
                            Def::Const(..) if !always_binding => {
                                // A unit struct/variant or constant pattern.
2385
                                self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span);
2386
                                Some(PathResolution::new(def))
2387
                            }
2388
                            Def::StructCtor(..) | Def::VariantCtor(..) |
2389
                            Def::Const(..) | Def::Static(..) => {
2390
                                // A fresh binding that shadows something unacceptable.
2391
                                resolve_error(
2392
                                    self,
2393 2394
                                    ident.span,
                                    ResolutionError::BindingShadowsSomethingUnacceptable(
2395
                                        pat_src.descr(), ident.node.name, binding.unwrap())
2396
                                );
2397
                                None
2398
                            }
2399
                            Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Err => {
2400 2401
                                // These entities are explicitly allowed
                                // to be shadowed by fresh bindings.
2402
                                None
2403 2404 2405
                            }
                            def => {
                                span_bug!(ident.span, "unexpected definition for an \
2406
                                                       identifier in pattern: {:?}", def);
2407
                            }
2408
                        }
2409
                    }).unwrap_or_else(|| {
2410
                        self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
2411
                    });
2412 2413

                    self.record_def(pat.id, resolution);
2414 2415
                }

2416
                PatKind::TupleStruct(ref path, ..) => {
2417
                    self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct);
2418 2419
                }

2420
                PatKind::Path(ref qself, ref path) => {
2421
                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
2422 2423
                }

V
Vadim Petrochenkov 已提交
2424
                PatKind::Struct(ref path, ..) => {
2425
                    self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
2426
                }
2427 2428

                _ => {}
2429
            }
2430
            true
2431
        });
2432

2433
        visit::walk_pat(self, pat);
2434 2435
    }

2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446
    // High-level and context dependent path resolution routine.
    // Resolves the path and records the resolution into definition map.
    // If resolution fails tries several techniques to find likely
    // resolution candidates, suggest imports or other help, and report
    // errors in user friendly way.
    fn smart_resolve_path(&mut self,
                          id: NodeId,
                          qself: Option<&QSelf>,
                          path: &Path,
                          source: PathSource)
                          -> PathResolution {
2447 2448 2449
        let segments = &path.segments.iter()
            .map(|seg| respan(seg.span, seg.identifier))
            .collect::<Vec<_>>();
2450 2451
        let ident_span = path.segments.last().map_or(path.span, |seg| seg.span);
        self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source)
2452 2453 2454
    }

    fn smart_resolve_path_fragment(&mut self,
2455
                                   id: NodeId,
2456
                                   qself: Option<&QSelf>,
2457
                                   path: &[SpannedIdent],
2458
                                   span: Span,
2459
                                   ident_span: Span,
2460 2461 2462 2463
                                   source: PathSource)
                                   -> PathResolution {
        let ns = source.namespace();
        let is_expected = &|def| source.is_expected(def);
2464
        let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
2465 2466 2467 2468 2469 2470 2471

        // Base error is amended with one short label and possibly some longer helps/notes.
        let report_errors = |this: &mut Self, def: Option<Def>| {
            // Make the base error.
            let expected = source.descr_expected();
            let path_str = names_to_string(path);
            let code = source.error_code(def.is_some());
2472
            let (base_msg, fallback_label, base_span) = if let Some(def) = def {
2473
                (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
2474
                 format!("not a {}", expected), span)
2475
            } else {
2476 2477
                let item_str = path[path.len() - 1].node;
                let item_span = path[path.len() - 1].span;
2478 2479
                let (mod_prefix, mod_str) = if path.len() == 1 {
                    (format!(""), format!("this scope"))
2480
                } else if path.len() == 2 && path[0].node.name == keywords::CrateRoot.name() {
2481 2482 2483
                    (format!(""), format!("the crate root"))
                } else {
                    let mod_path = &path[..path.len() - 1];
2484
                    let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), false, span) {
2485 2486 2487 2488 2489 2490
                        PathResult::Module(module) => module.def(),
                        _ => None,
                    }.map_or(format!(""), |def| format!("{} ", def.kind_name()));
                    (mod_prefix, format!("`{}`", names_to_string(mod_path)))
                };
                (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
2491
                 format!("not found in {}", mod_str), item_span)
2492
            };
2493
            let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
2494 2495 2496 2497 2498

            // Emit special messages for unresolved `Self` and `self`.
            if is_self_type(path, ns) {
                __diagnostic_used!(E0411);
                err.code("E0411".into());
2499
                err.span_label(span, "`Self` is only available in traits and impls");
2500
                return (err, Vec::new());
2501 2502 2503 2504
            }
            if is_self_value(path, ns) {
                __diagnostic_used!(E0424);
                err.code("E0424".into());
2505
                err.span_label(span, format!("`self` value is only available in \
2506
                                               methods with `self` parameter"));
2507
                return (err, Vec::new());
2508 2509 2510
            }

            // Try to lookup the name in more relaxed fashion for better error reporting.
2511
            let ident = *path.last().unwrap();
2512
            let candidates = this.lookup_import_candidates(ident.node.name, ns, is_expected);
2513
            if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
2514
                let enum_candidates =
2515
                    this.lookup_import_candidates(ident.node.name, ns, is_enum_variant);
E
Esteban Küber 已提交
2516 2517 2518 2519 2520
                let mut enum_candidates = enum_candidates.iter()
                    .map(|suggestion| import_candidate_to_paths(&suggestion)).collect::<Vec<_>>();
                enum_candidates.sort();
                for (sp, variant_path, enum_path) in enum_candidates {
                    if sp == DUMMY_SP {
2521 2522 2523 2524
                        let msg = format!("there is an enum variant `{}`, \
                                        try using `{}`?",
                                        variant_path,
                                        enum_path);
2525 2526
                        err.help(&msg);
                    } else {
2527 2528
                        err.span_suggestion(span, "you can try using the variant's enum",
                                            enum_path);
2529 2530
                    }
                }
2531
            }
2532
            if path.len() == 1 && this.self_type_is_available(span) {
2533 2534
                if let Some(candidate) = this.lookup_assoc_candidate(ident.node, ns, is_expected) {
                    let self_is_available = this.self_value_is_available(path[0].node.ctxt, span);
2535 2536
                    match candidate {
                        AssocSuggestion::Field => {
2537 2538
                            err.span_suggestion(span, "try",
                                                format!("self.{}", path_str));
2539
                            if !self_is_available {
2540
                                err.span_label(span, format!("`self` value is only available in \
2541 2542 2543 2544
                                                               methods with `self` parameter"));
                            }
                        }
                        AssocSuggestion::MethodWithSelf if self_is_available => {
2545 2546
                            err.span_suggestion(span, "try",
                                                format!("self.{}", path_str));
2547 2548
                        }
                        AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
2549 2550
                            err.span_suggestion(span, "try",
                                                format!("Self::{}", path_str));
2551 2552
                        }
                    }
2553
                    return (err, candidates);
2554 2555 2556
                }
            }

2557 2558 2559
            let mut levenshtein_worked = false;

            // Try Levenshtein.
2560
            if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected, span) {
2561
                err.span_label(ident_span, format!("did you mean `{}`?", candidate));
2562 2563 2564
                levenshtein_worked = true;
            }

2565 2566 2567 2568
            // Try context dependent help if relaxed lookup didn't work.
            if let Some(def) = def {
                match (def, source) {
                    (Def::Macro(..), _) => {
2569
                        err.span_label(span, format!("did you mean `{}!(...)`?", path_str));
2570
                        return (err, candidates);
2571 2572
                    }
                    (Def::TyAlias(..), PathSource::Trait) => {
2573
                        err.span_label(span, "type aliases cannot be used for traits");
2574
                        return (err, candidates);
2575
                    }
2576
                    (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
2577
                        ExprKind::Field(_, ident) => {
2578
                            err.span_label(parent.span, format!("did you mean `{}::{}`?",
2579
                                                                 path_str, ident.node));
2580
                            return (err, candidates);
2581
                        }
2582
                        ExprKind::MethodCall(ref segment, ..) => {
2583
                            err.span_label(parent.span, format!("did you mean `{}::{}(...)`?",
2584
                                                                 path_str, segment.identifier));
2585
                            return (err, candidates);
2586 2587 2588 2589
                        }
                        _ => {}
                    },
                    _ if ns == ValueNS && is_struct_like(def) => {
2590 2591 2592 2593
                        if let Def::Struct(def_id) = def {
                            if let Some((ctor_def, ctor_vis))
                                    = this.struct_constructors.get(&def_id).cloned() {
                                if is_expected(ctor_def) && !this.is_accessible(ctor_vis) {
2594
                                    err.span_label(span, format!("constructor is not visible \
2595 2596 2597 2598
                                                                   here due to private fields"));
                                }
                            }
                        }
2599
                        err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
2600
                                                       path_str));
2601
                        return (err, candidates);
2602 2603 2604 2605 2606
                    }
                    _ => {}
                }
            }

2607
            // Fallback label.
2608
            if !levenshtein_worked {
2609
                err.span_label(base_span, fallback_label);
2610
                this.type_ascription_suggestion(&mut err, base_span);
2611
            }
2612
            (err, candidates)
2613 2614
        };
        let report_errors = |this: &mut Self, def: Option<Def>| {
2615 2616 2617 2618 2619
            let (err, candidates) = report_errors(this, def);
            let def_id = this.current_module.normal_ancestor_id;
            let node_id = this.definitions.as_local_node_id(def_id).unwrap();
            let better = def.is_some();
            this.use_injections.push(UseError { err, candidates, node_id, better });
2620 2621 2622 2623 2624 2625
            err_path_resolution()
        };

        let resolution = match self.resolve_qpath_anywhere(id, qself, path, ns, span,
                                                           source.defer_to_typeck(),
                                                           source.global_by_default()) {
2626 2627
            Some(resolution) if resolution.unresolved_segments() == 0 => {
                if is_expected(resolution.base_def()) || resolution.base_def() == Def::Err {
2628 2629
                    resolution
                } else {
2630 2631 2632
                    // Add a temporary hack to smooth the transition to new struct ctor
                    // visibility rules. See #38932 for more details.
                    let mut res = None;
2633
                    if let Def::Struct(def_id) = resolution.base_def() {
2634
                        if let Some((ctor_def, ctor_vis))
2635
                                = self.struct_constructors.get(&def_id).cloned() {
2636 2637
                            if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
                                let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
2638
                                self.session.buffer_lint(lint, id, span,
2639
                                    "private struct constructors are not usable through \
2640 2641
                                     reexports in outer modules",
                                );
2642 2643 2644 2645 2646
                                res = Some(PathResolution::new(ctor_def));
                            }
                        }
                    }

2647
                    res.unwrap_or_else(|| report_errors(self, Some(resolution.base_def())))
2648 2649 2650 2651 2652 2653 2654
                }
            }
            Some(resolution) if source.defer_to_typeck() => {
                // 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.
                if ns == ValueNS {
2655
                    let item_name = path.last().unwrap().node;
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670
                    let traits = self.get_traits_containing_item(item_name, ns);
                    self.trait_map.insert(id, traits);
                }
                resolution
            }
            _ => report_errors(self, None)
        };

        if let PathSource::TraitItem(..) = source {} else {
            // Avoid recording definition of `A::B` in `<T as A>::B::C`.
            self.record_def(id, resolution);
        }
        resolution
    }

2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682
    fn type_ascription_suggestion(&self,
                                  err: &mut DiagnosticBuilder,
                                  base_span: Span) {
        debug!("type_ascription_suggetion {:?}", base_span);
        let cm = self.session.codemap();
        debug!("self.current_type_ascription {:?}", self.current_type_ascription);
        if let Some(sp) = self.current_type_ascription.last() {
            let mut sp = *sp;
            loop {  // try to find the `:`, bail on first non-':'/non-whitespace
                sp = sp.next_point();
                if let Ok(snippet) = cm.span_to_snippet(sp.to(sp.next_point())) {
                    debug!("snippet {:?}", snippet);
2683 2684
                    let line_sp = cm.lookup_char_pos(sp.hi()).line;
                    let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705
                    debug!("{:?} {:?}", line_sp, line_base_sp);
                    if snippet == ":" {
                        err.span_label(base_span,
                                       "expecting a type here because of type ascription");
                        if line_sp != line_base_sp {
                            err.span_suggestion_short(sp,
                                                      "did you mean to use `;` here instead?",
                                                      ";".to_string());
                        }
                        break;
                    } else if snippet.trim().len() != 0  {
                        debug!("tried to find type ascription `:` token, couldn't find it");
                        break;
                    }
                } else {
                    break;
                }
            }
        }
    }

2706 2707 2708
    fn self_type_is_available(&mut self, span: Span) -> bool {
        let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
                                                          TypeNS, false, span);
2709 2710 2711
        if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
    }

2712
    fn self_value_is_available(&mut self, ctxt: SyntaxContext, span: Span) -> bool {
2713
        let ident = Ident { name: keywords::SelfValue.name(), ctxt: ctxt };
2714
        let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, false, span);
2715 2716 2717 2718 2719 2720 2721
        if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
    }

    // Resolve in alternative namespaces if resolution in the primary namespace fails.
    fn resolve_qpath_anywhere(&mut self,
                              id: NodeId,
                              qself: Option<&QSelf>,
2722
                              path: &[SpannedIdent],
2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735
                              primary_ns: Namespace,
                              span: Span,
                              defer_to_typeck: bool,
                              global_by_default: bool)
                              -> Option<PathResolution> {
        let mut fin_res = None;
        // FIXME: can't resolve paths in macro namespace yet, macros are
        // processed by the little special hack below.
        for (i, ns) in [primary_ns, TypeNS, ValueNS, /*MacroNS*/].iter().cloned().enumerate() {
            if i == 0 || ns != primary_ns {
                match self.resolve_qpath(id, qself, path, ns, span, global_by_default) {
                    // If defer_to_typeck, then resolution > no resolution,
                    // otherwise full resolution > partial resolution > no resolution.
2736 2737
                    Some(res) if res.unresolved_segments() == 0 || defer_to_typeck =>
                        return Some(res),
2738 2739 2740 2741
                    res => if fin_res.is_none() { fin_res = res },
                };
            }
        }
2742
        let is_global = self.global_macros.get(&path[0].node.name).cloned()
2743
            .map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
2744 2745
        if primary_ns != MacroNS && (is_global ||
                                     self.macro_names.contains(&path[0].node.modern())) {
2746
            // Return some dummy definition, it's enough for error reporting.
J
Josh Driver 已提交
2747 2748 2749
            return Some(
                PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
            );
2750 2751 2752 2753 2754 2755 2756 2757
        }
        fin_res
    }

    /// Handles paths that may refer to associated items.
    fn resolve_qpath(&mut self,
                     id: NodeId,
                     qself: Option<&QSelf>,
2758
                     path: &[SpannedIdent],
2759 2760 2761 2762 2763
                     ns: Namespace,
                     span: Span,
                     global_by_default: bool)
                     -> Option<PathResolution> {
        if let Some(qself) = qself {
J
Jeffrey Seyfried 已提交
2764 2765
            if qself.position == 0 {
                // FIXME: Create some fake resolution that can't possibly be a type.
2766 2767 2768
                return Some(PathResolution::with_unresolved_segments(
                    Def::Mod(DefId::local(CRATE_DEF_INDEX)), path.len()
                ));
2769
            }
2770 2771
            // Make sure `A::B` in `<T as A>::B::C` is a trait item.
            let ns = if qself.position + 1 == path.len() { ns } else { TypeNS };
2772
            let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
2773
                                                       span, span, PathSource::TraitItem(ns));
2774 2775 2776
            return Some(PathResolution::with_unresolved_segments(
                res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
            ));
2777 2778
        }

2779
        let result = match self.resolve_path(&path, Some(ns), true, span) {
2780
            PathResult::NonModule(path_res) => path_res,
J
Jeffrey Seyfried 已提交
2781 2782
            PathResult::Module(module) if !module.is_normal() => {
                PathResolution::new(module.def().unwrap())
V
Cleanup  
Vadim Petrochenkov 已提交
2783
            }
2784 2785 2786 2787 2788 2789
            // 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 已提交
2790 2791
            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
            //                     // not to non-existent std::u8::max_value
2792 2793 2794 2795
            // }
            //
            // Such behavior is required for backward compatibility.
            // The same fallback is used when `a` resolves to nothing.
2796
            PathResult::Module(..) | PathResult::Failed(..)
2797
                    if (ns == TypeNS || path.len() > 1) &&
2798 2799 2800
                       self.primitive_type_table.primitive_types
                           .contains_key(&path[0].node.name) => {
                let prim = self.primitive_type_table.primitive_types[&path[0].node.name];
2801 2802
                match prim {
                    TyUint(UintTy::U128) | TyInt(IntTy::I128) => {
S
Simonas Kazlauskas 已提交
2803 2804
                        if !self.session.features.borrow().i128_type {
                            emit_feature_err(&self.session.parse_sess,
2805 2806 2807 2808 2809 2810 2811
                                                "i128_type", span, GateIssue::Language,
                                                "128-bit type is unstable");

                        }
                    }
                    _ => {}
                }
2812
                PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
J
Jeffrey Seyfried 已提交
2813 2814
            }
            PathResult::Module(module) => PathResolution::new(module.def().unwrap()),
2815
            PathResult::Failed(span, msg, false) => {
J
Jeffrey Seyfried 已提交
2816 2817 2818
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                err_path_resolution()
            }
2819 2820
            PathResult::Failed(..) => return None,
            PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
J
Jeffrey Seyfried 已提交
2821 2822
        };

2823
        if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
2824 2825
           path[0].node.name != keywords::CrateRoot.name() &&
           path[0].node.name != keywords::DollarCrate.name() {
2826
            let unqualified_result = {
2827
                match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
2828
                    PathResult::NonModule(path_res) => path_res.base_def(),
2829 2830 2831 2832
                    PathResult::Module(module) => module.def().unwrap(),
                    _ => return Some(result),
                }
            };
2833
            if result.base_def() == unqualified_result {
2834
                let lint = lint::builtin::UNUSED_QUALIFICATIONS;
2835
                self.session.buffer_lint(lint, id, span, "unnecessary qualification")
N
Nick Cameron 已提交
2836
            }
2837
        }
N
Nick Cameron 已提交
2838

J
Jeffrey Seyfried 已提交
2839
        Some(result)
2840 2841
    }

J
Jeffrey Seyfried 已提交
2842
    fn resolve_path(&mut self,
2843
                    path: &[SpannedIdent],
J
Jeffrey Seyfried 已提交
2844
                    opt_ns: Option<Namespace>, // `None` indicates a module path
2845 2846
                    record_used: bool,
                    path_span: Span)
J
Jeffrey Seyfried 已提交
2847
                    -> PathResult<'a> {
2848 2849
        let mut module = None;
        let mut allow_super = true;
J
Jeffrey Seyfried 已提交
2850 2851

        for (i, &ident) in path.iter().enumerate() {
2852
            debug!("resolve_path ident {} {:?}", i, ident);
J
Jeffrey Seyfried 已提交
2853 2854 2855
            let is_last = i == path.len() - 1;
            let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };

2856 2857
            if i == 0 && ns == TypeNS && ident.node.name == keywords::SelfValue.name() {
                let mut ctxt = ident.node.ctxt.modern();
J
Jeffrey Seyfried 已提交
2858
                module = Some(self.resolve_self(&mut ctxt, self.current_module));
J
Jeffrey Seyfried 已提交
2859
                continue
2860 2861
            } else if allow_super && ns == TypeNS && ident.node.name == keywords::Super.name() {
                let mut ctxt = ident.node.ctxt.modern();
J
Jeffrey Seyfried 已提交
2862 2863 2864 2865
                let self_module = match i {
                    0 => self.resolve_self(&mut ctxt, self.current_module),
                    _ => module.unwrap(),
                };
J
Jeffrey Seyfried 已提交
2866
                if let Some(parent) = self_module.parent {
J
Jeffrey Seyfried 已提交
2867
                    module = Some(self.resolve_self(&mut ctxt, parent));
J
Jeffrey Seyfried 已提交
2868 2869 2870
                    continue
                } else {
                    let msg = "There are too many initial `super`s.".to_string();
2871
                    return PathResult::Failed(ident.span, msg, false);
J
Jeffrey Seyfried 已提交
2872 2873 2874 2875
                }
            }
            allow_super = false;

2876 2877
            if i == 0 && ns == TypeNS && ident.node.name == keywords::CrateRoot.name() {
                module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
2878
                continue
2879 2880
            } else if i == 0 && ns == TypeNS && ident.node.name == keywords::DollarCrate.name() {
                module = Some(self.resolve_crate_root(ident.node.ctxt));
2881 2882 2883
                continue
            }

J
Jeffrey Seyfried 已提交
2884
            let binding = if let Some(module) = module {
2885
                self.resolve_ident_in_module(module, ident.node, ns, false, record_used, path_span)
2886
            } else if opt_ns == Some(MacroNS) {
2887
                self.resolve_lexical_macro_path_segment(ident.node, ns, record_used, path_span)
2888
                    .map(MacroBinding::binding)
J
Jeffrey Seyfried 已提交
2889
            } else {
2890
                match self.resolve_ident_in_lexical_scope(ident.node, ns, record_used, path_span) {
J
Jeffrey Seyfried 已提交
2891
                    Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
2892 2893
                    Some(LexicalScopeBinding::Def(def))
                            if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
2894 2895 2896
                        return PathResult::NonModule(PathResolution::with_unresolved_segments(
                            def, path.len() - 1
                        ));
J
Jeffrey Seyfried 已提交
2897
                    }
2898
                    _ => Err(if record_used { Determined } else { Undetermined }),
J
Jeffrey Seyfried 已提交
2899 2900 2901 2902 2903
                }
            };

            match binding {
                Ok(binding) => {
2904 2905
                    let def = binding.def();
                    let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
J
Jeffrey Seyfried 已提交
2906
                    if let Some(next_module) = binding.module() {
J
Jeffrey Seyfried 已提交
2907
                        module = Some(next_module);
2908
                    } else if def == Def::Err {
J
Jeffrey Seyfried 已提交
2909
                        return PathResult::NonModule(err_path_resolution());
2910
                    } else if opt_ns.is_some() && (is_last || maybe_assoc) {
2911 2912 2913
                        return PathResult::NonModule(PathResolution::with_unresolved_segments(
                            def, path.len() - i - 1
                        ));
J
Jeffrey Seyfried 已提交
2914
                    } else {
2915 2916 2917
                        return PathResult::Failed(ident.span,
                                                  format!("Not a module `{}`", ident.node),
                                                  is_last);
J
Jeffrey Seyfried 已提交
2918 2919 2920 2921 2922 2923
                    }
                }
                Err(Undetermined) => return PathResult::Indeterminate,
                Err(Determined) => {
                    if let Some(module) = module {
                        if opt_ns.is_some() && !module.is_normal() {
2924 2925 2926
                            return PathResult::NonModule(PathResolution::with_unresolved_segments(
                                module.def().unwrap(), path.len() - i
                            ));
J
Jeffrey Seyfried 已提交
2927 2928
                        }
                    }
2929
                    let msg = if module.and_then(ModuleData::def) == self.graph_root.def() {
J
Jeffrey Seyfried 已提交
2930 2931
                        let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
                        let mut candidates =
2932
                            self.lookup_import_candidates(ident.node.name, TypeNS, is_mod);
2933
                        candidates.sort_by_key(|c| (c.path.segments.len(), c.path.to_string()));
J
Jeffrey Seyfried 已提交
2934
                        if let Some(candidate) = candidates.get(0) {
2935
                            format!("Did you mean `{}`?", candidate.path)
J
Jeffrey Seyfried 已提交
2936
                        } else {
2937
                            format!("Maybe a missing `extern crate {};`?", ident.node)
J
Jeffrey Seyfried 已提交
2938 2939
                        }
                    } else if i == 0 {
2940
                        format!("Use of undeclared type or module `{}`", ident.node)
J
Jeffrey Seyfried 已提交
2941
                    } else {
2942
                        format!("Could not find `{}` in `{}`", ident.node, path[i - 1].node)
J
Jeffrey Seyfried 已提交
2943
                    };
2944
                    return PathResult::Failed(ident.span, msg, is_last);
J
Jeffrey Seyfried 已提交
2945 2946
                }
            }
2947 2948
        }

2949
        PathResult::Module(module.unwrap_or(self.graph_root))
2950 2951 2952
    }

    // Resolve a local definition, potentially adjusting for closures.
2953 2954 2955 2956
    fn adjust_local_def(&mut self,
                        ns: Namespace,
                        rib_index: usize,
                        mut def: Def,
2957 2958
                        record_used: bool,
                        span: Span) -> Def {
2959 2960 2961 2962
        let ribs = &self.ribs[ns][rib_index + 1..];

        // An invalid forward use of a type parameter from a previous default.
        if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind {
2963
            if record_used {
2964
                resolve_error(self, span, ResolutionError::ForwardDeclaredTyParam);
2965 2966 2967 2968 2969
            }
            assert_eq!(def, Def::Err);
            return Def::Err;
        }

2970
        match def {
2971
            Def::Upvar(..) => {
2972
                span_bug!(span, "unexpected {:?} in bindings", def)
2973
            }
2974
            Def::Local(node_id) => {
2975 2976
                for rib in ribs {
                    match rib.kind {
2977 2978
                        NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
                        ForwardTyParamBanRibKind => {
2979 2980 2981 2982 2983
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;

C
corentih 已提交
2984 2985 2986
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2987
                            if let Some(&index) = seen.get(&node_id) {
2988
                                def = Def::Upvar(node_id, index, function_id);
2989 2990
                                continue;
                            }
C
corentih 已提交
2991 2992 2993
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2994
                            let depth = vec.len();
2995
                            def = Def::Upvar(node_id, depth, function_id);
2996

2997
                            if record_used {
2998 2999
                                vec.push(Freevar {
                                    def: prev_def,
3000
                                    span,
3001 3002 3003
                                });
                                seen.insert(node_id, depth);
                            }
3004
                        }
3005
                        ItemRibKind | MethodRibKind(_) => {
3006 3007 3008
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
3009
                            if record_used {
3010 3011 3012
                                resolve_error(self, span,
                                        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
                            }
3013
                            return Def::Err;
3014 3015 3016
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
3017
                            if record_used {
3018 3019 3020
                                resolve_error(self, span,
                                        ResolutionError::AttemptToUseNonConstantValueInConstant);
                            }
3021
                            return Def::Err;
3022 3023 3024 3025
                        }
                    }
                }
            }
3026
            Def::TyParam(..) | Def::SelfTy(..) => {
3027 3028
                for rib in ribs {
                    match rib.kind {
3029
                        NormalRibKind | MethodRibKind(_) | ClosureRibKind(..) |
3030 3031
                        ModuleRibKind(..) | MacroDefinition(..) | ForwardTyParamBanRibKind |
                        ConstantItemRibKind => {
3032 3033 3034 3035 3036
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
3037
                            if record_used {
3038 3039 3040
                                resolve_error(self, span,
                                              ResolutionError::TypeParametersFromOuterFunction);
                            }
3041
                            return Def::Err;
3042 3043 3044 3045 3046 3047
                        }
                    }
                }
            }
            _ => {}
        }
3048
        return def;
3049 3050
    }

3051
    fn lookup_assoc_candidate<FilterFn>(&mut self,
3052
                                        ident: Ident,
3053 3054 3055 3056 3057
                                        ns: Namespace,
                                        filter_fn: FilterFn)
                                        -> Option<AssocSuggestion>
        where FilterFn: Fn(Def) -> bool
    {
3058
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
3059
            match t.node {
3060 3061
                TyKind::Path(None, _) => Some(t.id),
                TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
3062 3063 3064 3065 3066 3067 3068
                // 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,
            }
        }

3069
        // Fields are generally expected in the same contexts as locals.
3070
        if filter_fn(Def::Local(ast::DUMMY_NODE_ID)) {
3071 3072 3073
            if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
                // Look for a field with the same name in the current self_type.
                if let Some(resolution) = self.def_map.get(&node_id) {
3074 3075 3076
                    match resolution.base_def() {
                        Def::Struct(did) | Def::Union(did)
                                if resolution.unresolved_segments() == 0 => {
3077
                            if let Some(field_names) = self.field_names.get(&did) {
3078
                                if field_names.iter().any(|&field_name| ident.name == field_name) {
3079 3080
                                    return Some(AssocSuggestion::Field);
                                }
3081
                            }
3082
                        }
3083
                        _ => {}
3084
                    }
3085
                }
3086
            }
3087 3088
        }

3089
        // Look for associated items in the current trait.
3090 3091 3092 3093
        if let Some((module, _)) = self.current_trait_ref {
            if let Ok(binding) =
                    self.resolve_ident_in_module(module, ident, ns, false, false, module.span) {
                let def = binding.def();
3094
                if filter_fn(def) {
3095
                    return Some(if self.has_self.contains(&def.def_id()) {
3096 3097 3098 3099
                        AssocSuggestion::MethodWithSelf
                    } else {
                        AssocSuggestion::AssocItem
                    });
3100 3101 3102 3103
                }
            }
        }

3104
        None
3105 3106
    }

3107
    fn lookup_typo_candidate<FilterFn>(&mut self,
3108
                                       path: &[SpannedIdent],
3109
                                       ns: Namespace,
3110 3111
                                       filter_fn: FilterFn,
                                       span: Span)
3112
                                       -> Option<Symbol>
3113 3114
        where FilterFn: Fn(Def) -> bool
    {
3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125
        let add_module_candidates = |module: Module, names: &mut Vec<Name>| {
            for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
                if let Some(binding) = resolution.borrow().binding {
                    if filter_fn(binding.def()) {
                        names.push(ident.name);
                    }
                }
            }
        };

        let mut names = Vec::new();
3126
        if path.len() == 1 {
3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
            // Search in lexical scope.
            // Walk backwards up the ribs in scope and collect candidates.
            for rib in self.ribs[ns].iter().rev() {
                // Locals and type parameters
                for (ident, def) in &rib.bindings {
                    if filter_fn(*def) {
                        names.push(ident.name);
                    }
                }
                // Items in scope
                if let ModuleRibKind(module) = rib.kind {
                    // Items from this module
                    add_module_candidates(module, &mut names);

                    if let ModuleKind::Block(..) = module.kind {
                        // We can see through blocks
                    } else {
                        // Items from the prelude
                        if let Some(prelude) = self.prelude {
                            if !module.no_implicit_prelude {
                                add_module_candidates(prelude, &mut names);
                            }
                        }
                        break;
                    }
                }
            }
            // Add primitive types to the mix
            if filter_fn(Def::PrimTy(TyBool)) {
                for (name, _) in &self.primitive_type_table.primitive_types {
                    names.push(*name);
                }
            }
        } else {
            // Search in module.
            let mod_path = &path[..path.len() - 1];
3163 3164
            if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS),
                                                                  false, span) {
3165 3166
                add_module_candidates(module, &mut names);
            }
3167
        }
3168

3169
        let name = path[path.len() - 1].node.name;
3170 3171 3172
        // Make sure error reporting is deterministic.
        names.sort_by_key(|name| name.as_str());
        match find_best_match_for_name(names.iter(), &name.as_str(), None) {
3173
            Some(found) if found != name => Some(found),
3174
            _ => None,
3175
        }
3176 3177
    }

3178 3179 3180
    fn with_resolved_label<F>(&mut self, label: Option<SpannedIdent>, id: NodeId, f: F)
        where F: FnOnce(&mut Resolver)
    {
3181
        if let Some(label) = label {
3182
            let def = Def::Label(id);
3183
            self.with_label_rib(|this| {
J
Jeffrey Seyfried 已提交
3184
                this.label_ribs.last_mut().unwrap().bindings.insert(label.node, def);
3185
                f(this);
3186 3187
            });
        } else {
3188
            f(self);
3189 3190 3191
        }
    }

3192 3193 3194 3195
    fn resolve_labeled_block(&mut self, label: Option<SpannedIdent>, id: NodeId, block: &Block) {
        self.with_resolved_label(label, id, |this| this.visit_block(block));
    }

3196
    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
P
Patrick Walton 已提交
3197 3198
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3199 3200 3201

        self.record_candidate_traits_for_expr_if_necessary(expr);

3202
        // Next, resolve the node.
3203
        match expr.node {
3204 3205
            ExprKind::Path(ref qself, ref path) => {
                self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent));
3206
                visit::walk_expr(self, expr);
3207 3208
            }

V
Vadim Petrochenkov 已提交
3209
            ExprKind::Struct(ref path, ..) => {
3210
                self.smart_resolve_path(expr.id, None, path, PathSource::Struct);
3211
                visit::walk_expr(self, expr);
3212 3213
            }

3214
            ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
3215
                match self.search_label(label.node, |rib, id| rib.bindings.get(&id).cloned()) {
3216
                    None => {
3217 3218 3219 3220 3221 3222 3223
                        // Search again for close matches...
                        // Picks the first label that is "close enough", which is not necessarily
                        // the closest match
                        let close_match = self.search_label(label.node, |rib, ident| {
                            let names = rib.bindings.iter().map(|(id, _)| &id.name);
                            find_best_match_for_name(names, &*ident.name.as_str(), None)
                        });
3224
                        self.record_def(expr.id, err_path_resolution());
3225
                        resolve_error(self,
3226
                                      label.span,
3227 3228
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str(),
                                                                       close_match));
3229
                    }
3230
                    Some(def @ Def::Label(_)) => {
3231
                        // Since this def is a label, it is never read.
3232
                        self.record_def(expr.id, PathResolution::new(def));
3233 3234
                    }
                    Some(_) => {
3235
                        span_bug!(expr.span, "label wasn't mapped to a label def!");
3236 3237
                    }
                }
3238 3239 3240

                // visit `break` argument if any
                visit::walk_expr(self, expr);
3241
            }
3242 3243 3244 3245

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

J
Jeffrey Seyfried 已提交
3246
                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
3247
                self.resolve_pattern(pattern, PatternSource::IfLet, &mut FxHashMap());
3248
                self.visit_block(if_block);
J
Jeffrey Seyfried 已提交
3249
                self.ribs[ValueNS].pop();
3250 3251 3252 3253

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

J
Jeffrey Seyfried 已提交
3254 3255 3256
            ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block),

            ExprKind::While(ref subexpression, ref block, label) => {
3257 3258 3259 3260
                self.with_resolved_label(label, expr.id, |this| {
                    this.visit_expr(subexpression);
                    this.visit_block(block);
                });
J
Jeffrey Seyfried 已提交
3261 3262
            }

3263
            ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => {
3264 3265
                self.with_resolved_label(label, expr.id, |this| {
                    this.visit_expr(subexpression);
3266
                    this.ribs[ValueNS].push(Rib::new(NormalRibKind));
3267 3268
                    this.resolve_pattern(pattern, PatternSource::WhileLet, &mut FxHashMap());
                    this.visit_block(block);
3269
                    this.ribs[ValueNS].pop();
3270
                });
3271 3272 3273 3274
            }

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

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

J
Jeffrey Seyfried 已提交
3280
                self.ribs[ValueNS].pop();
3281 3282
            }

3283
            // Equivalent to `visit::walk_expr` + passing some context to children.
3284
            ExprKind::Field(ref subexpression, _) => {
3285
                self.resolve_expr(subexpression, Some(expr));
3286
            }
3287
            ExprKind::MethodCall(ref segment, ref arguments) => {
3288
                let mut arguments = arguments.iter();
3289
                self.resolve_expr(arguments.next().unwrap(), Some(expr));
3290 3291 3292
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
3293
                self.visit_path_segment(expr.span, segment);
3294
            }
3295 3296 3297 3298 3299 3300 3301

            ExprKind::Repeat(ref element, ref count) => {
                self.visit_expr(element);
                self.with_constant_rib(|this| {
                    this.visit_expr(count);
                });
            }
3302
            ExprKind::Call(ref callee, ref arguments) => {
3303
                self.resolve_expr(callee, Some(expr));
3304 3305 3306 3307
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
            }
3308 3309 3310 3311 3312
            ExprKind::Type(ref type_expr, _) => {
                self.current_type_ascription.push(type_expr.span);
                visit::walk_expr(self, expr);
                self.current_type_ascription.pop();
            }
B
Brian Anderson 已提交
3313
            _ => {
3314
                visit::walk_expr(self, expr);
3315 3316 3317 3318
            }
        }
    }

E
Eduard Burtescu 已提交
3319
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3320
        match expr.node {
3321
            ExprKind::Field(_, name) => {
3322 3323 3324 3325
                // 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.
3326
                let traits = self.get_traits_containing_item(name.node, ValueNS);
3327
                self.trait_map.insert(expr.id, traits);
3328
            }
3329
            ExprKind::MethodCall(ref segment, ..) => {
C
corentih 已提交
3330
                debug!("(recording candidate traits for expr) recording traits for {}",
3331
                       expr.id);
3332
                let traits = self.get_traits_containing_item(segment.identifier, ValueNS);
3333
                self.trait_map.insert(expr.id, traits);
3334
            }
3335
            _ => {
3336 3337 3338 3339 3340
                // Nothing to do.
            }
        }
    }

J
Jeffrey Seyfried 已提交
3341 3342
    fn get_traits_containing_item(&mut self, mut ident: Ident, ns: Namespace)
                                  -> Vec<TraitCandidate> {
3343
        debug!("(getting traits containing item) looking for '{}'", ident.name);
E
Eduard Burtescu 已提交
3344

3345
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3346
        // Look for the current trait.
3347 3348 3349 3350
        if let Some((module, _)) = self.current_trait_ref {
            if self.resolve_ident_in_module(module, ident, ns, false, false, module.span).is_ok() {
                let def_id = module.def_id().unwrap();
                found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
E
Eduard Burtescu 已提交
3351
            }
J
Jeffrey Seyfried 已提交
3352
        }
3353

J
Jeffrey Seyfried 已提交
3354
        ident.ctxt = ident.ctxt.modern();
J
Jeffrey Seyfried 已提交
3355 3356
        let mut search_module = self.current_module;
        loop {
3357
            self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
J
Jeffrey Seyfried 已提交
3358 3359
            search_module =
                unwrap_or!(self.hygienic_lexical_parent(search_module, &mut ident.ctxt), break);
3360
        }
3361

3362 3363
        if let Some(prelude) = self.prelude {
            if !search_module.no_implicit_prelude {
3364
                self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
E
Eduard Burtescu 已提交
3365
            }
3366 3367
        }

E
Eduard Burtescu 已提交
3368
        found_traits
3369 3370
    }

3371
    fn get_traits_in_module_containing_item(&mut self,
3372
                                            ident: Ident,
3373
                                            ns: Namespace,
3374
                                            module: Module<'a>,
3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388
                                            found_traits: &mut Vec<TraitCandidate>) {
        let mut traits = module.traits.borrow_mut();
        if traits.is_none() {
            let mut collected_traits = Vec::new();
            module.for_each_child(|name, ns, binding| {
                if ns != TypeNS { return }
                if let Def::Trait(_) = binding.def() {
                    collected_traits.push((name, binding));
                }
            });
            *traits = Some(collected_traits.into_boxed_slice());
        }

        for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
3389
            let module = binding.module().unwrap();
J
Jeffrey Seyfried 已提交
3390
            let mut ident = ident;
3391
            if ident.ctxt.glob_adjust(module.expansion, binding.span.ctxt().modern()).is_none() {
J
Jeffrey Seyfried 已提交
3392 3393 3394 3395
                continue
            }
            if self.resolve_ident_in_module_unadjusted(module, ident, ns, false, false, module.span)
                   .is_ok() {
3396 3397 3398 3399 3400 3401 3402 3403
                let import_id = match binding.kind {
                    NameBindingKind::Import { directive, .. } => {
                        self.maybe_unused_trait_imports.insert(directive.id);
                        self.add_to_glob_map(directive.id, trait_name);
                        Some(directive.id)
                    }
                    _ => None,
                };
3404
                let trait_def_id = module.def_id().unwrap();
3405 3406 3407 3408 3409
                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
            }
        }
    }

3410 3411 3412 3413 3414 3415 3416
    /// 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).
3417 3418 3419 3420 3421 3422 3423 3424
    fn lookup_import_candidates<FilterFn>(&mut self,
                                          lookup_name: Name,
                                          namespace: Namespace,
                                          filter_fn: FilterFn)
                                          -> Vec<ImportSuggestion>
        where FilterFn: Fn(Def) -> bool
    {
        let mut candidates = Vec::new();
3425
        let mut worklist = Vec::new();
3426
        let mut seen_modules = FxHashSet();
3427 3428 3429 3430 3431
        worklist.push((self.graph_root, Vec::new(), false));

        while let Some((in_module,
                        path_segments,
                        in_module_is_extern)) = worklist.pop() {
3432
            self.populate_module_if_necessary(in_module);
3433

3434 3435 3436
            // We have to visit module children in deterministic order to avoid
            // instabilities in reported imports (#43552).
            in_module.for_each_child_stable(|ident, ns, name_binding| {
3437
                // avoid imports entirely
3438
                if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
3439 3440
                // avoid non-importable candidates as well
                if !name_binding.is_importable() { return; }
3441 3442

                // collect results based on the filter function
3443
                if ident.name == lookup_name && ns == namespace {
3444
                    if filter_fn(name_binding.def()) {
3445 3446
                        // create the path
                        let mut segms = path_segments.clone();
3447
                        segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
3448
                        let path = Path {
3449
                            span: name_binding.span,
3450 3451 3452 3453 3454 3455 3456 3457 3458
                            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)
3459
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3460
                            candidates.push(ImportSuggestion { path: path });
3461 3462 3463 3464 3465
                        }
                    }
                }

                // collect submodules to explore
J
Jeffrey Seyfried 已提交
3466
                if let Some(module) = name_binding.module() {
3467
                    // form the path
3468
                    let mut path_segments = path_segments.clone();
3469
                    path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
3470

3471
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3472
                        // add the module to the lookup
3473
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3474
                        if seen_modules.insert(module.def_id().unwrap()) {
3475 3476
                            worklist.push((module, path_segments, is_extern));
                        }
3477 3478 3479 3480 3481
                    }
                }
            })
        }

3482
        candidates
3483 3484
    }

3485 3486
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
3487
        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
3488
            panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
3489
        }
3490 3491
    }

3492
    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
3493 3494 3495
        match *vis {
            ast::Visibility::Public => ty::Visibility::Public,
            ast::Visibility::Crate(..) => ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
3496
            ast::Visibility::Inherited => {
3497
                ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
3498
            }
3499
            ast::Visibility::Restricted { ref path, id } => {
3500 3501
                let def = self.smart_resolve_path(id, None, path,
                                                  PathSource::Visibility).base_def();
3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513
                if def == Def::Err {
                    ty::Visibility::Public
                } else {
                    let vis = ty::Visibility::Restricted(def.def_id());
                    if self.is_accessible(vis) {
                        vis
                    } else {
                        self.session.span_err(path.span, "visibilities can only be restricted \
                                                          to ancestor modules");
                        ty::Visibility::Public
                    }
                }
3514 3515 3516 3517
            }
        }
    }

3518
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
3519
        vis.is_accessible_from(self.current_module.normal_ancestor_id, self)
3520 3521
    }

3522
    fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
3523
        vis.is_accessible_from(module.normal_ancestor_id, self)
3524 3525
    }

3526
    fn report_errors(&mut self, krate: &Crate) {
3527
        self.report_shadowing_errors();
3528
        self.report_with_use_injections(krate);
3529
        let mut reported_spans = FxHashSet();
3530

3531
        for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {
3532
            if !reported_spans.insert(span) { continue }
3533 3534 3535
            let participle = |binding: &NameBinding| {
                if binding.is_import() { "imported" } else { "defined" }
            };
3536 3537
            let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
            let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
3538
            let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555
                format!("consider adding an explicit import of `{}` to disambiguate", name)
            } 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" })
            };
            if legacy {
                let id = match b2.kind {
                    NameBindingKind::Import { directive, .. } => directive.id,
                    _ => unreachable!(),
                };
                let mut span = MultiSpan::from_span(span);
                span.push_span_label(b1.span, msg1);
                span.push_span_label(b2.span, msg2);
                let msg = format!("`{}` is ambiguous", name);
3556
                self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg);
3557
            } else {
3558 3559 3560 3561 3562 3563 3564 3565 3566
                let mut err =
                    self.session.struct_span_err(span, &format!("`{}` is ambiguous", name));
                err.span_note(b1.span, &msg1);
                match b2.def() {
                    Def::Macro(..) if b2.span == DUMMY_SP =>
                        err.note(&format!("`{}` is also a builtin macro", name)),
                    _ => err.span_note(b2.span, &msg2),
                };
                err.note(&note).emit();
3567
            }
3568 3569
        }

3570 3571
        for &PrivacyError(span, name, binding) in &self.privacy_errors {
            if !reported_spans.insert(span) { continue }
G
Guillaume Gomez 已提交
3572
            span_err!(self.session, span, E0603, "{} `{}` is private", binding.descr(), name);
3573 3574
        }
    }
3575

3576 3577 3578 3579 3580
    fn report_with_use_injections(&mut self, krate: &Crate) {
        for UseError { mut err, candidates, node_id, better } in self.use_injections.drain(..) {
            let mut finder = UsePlacementFinder {
                target_module: node_id,
                span: None,
3581
                found_use: false,
3582 3583 3584
            };
            visit::walk_crate(&mut finder, krate);
            if !candidates.is_empty() {
3585
                show_candidates(&mut err, finder.span, &candidates, better, finder.found_use);
3586 3587 3588 3589 3590
            }
            err.emit();
        }
    }

3591
    fn report_shadowing_errors(&mut self) {
J
Jeffrey Seyfried 已提交
3592 3593
        for (ident, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
            self.resolve_legacy_scope(scope, ident, true);
J
Jeffrey Seyfried 已提交
3594 3595
        }

3596
        let mut reported_errors = FxHashSet();
3597
        for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
J
Jeffrey Seyfried 已提交
3598 3599 3600
            if self.resolve_legacy_scope(&binding.parent, binding.ident, false).is_some() &&
               reported_errors.insert((binding.ident, binding.span)) {
                let msg = format!("`{}` is already in scope", binding.ident);
3601
                self.session.struct_span_err(binding.span, &msg)
3602 3603
                    .note("macro-expanded `macro_rules!`s may not shadow \
                           existing macros (see RFC 1560)")
3604 3605 3606 3607 3608
                    .emit();
            }
        }
    }

C
Cldfire 已提交
3609
    fn report_conflict<'b>(&mut self,
3610
                       parent: Module,
3611
                       ident: Ident,
3612
                       ns: Namespace,
C
Cldfire 已提交
3613 3614
                       new_binding: &NameBinding<'b>,
                       old_binding: &NameBinding<'b>) {
3615
        // Error on the second of two conflicting names
3616
        if old_binding.span.lo() > new_binding.span.lo() {
3617
            return self.report_conflict(parent, ident, ns, old_binding, new_binding);
3618 3619
        }

J
Jeffrey Seyfried 已提交
3620 3621 3622 3623
        let container = match parent.kind {
            ModuleKind::Def(Def::Mod(_), _) => "module",
            ModuleKind::Def(Def::Trait(_), _) => "trait",
            ModuleKind::Block(..) => "block",
3624 3625 3626
            _ => "enum",
        };

3627 3628 3629
        let old_noun = match old_binding.is_import() {
            true => "import",
            false => "definition",
3630 3631
        };

3632 3633 3634 3635 3636 3637
        let new_participle = match new_binding.is_import() {
            true => "imported",
            false => "defined",
        };

        let (name, span) = (ident.name, new_binding.span);
3638 3639 3640 3641 3642 3643 3644

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

3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657
        let old_kind = match (ns, old_binding.module()) {
            (ValueNS, _) => "value",
            (MacroNS, _) => "macro",
            (TypeNS, _) if old_binding.is_extern_crate() => "extern crate",
            (TypeNS, Some(module)) if module.is_normal() => "module",
            (TypeNS, Some(module)) if module.is_trait() => "trait",
            (TypeNS, _) => "type",
        };

        let namespace = match ns {
            ValueNS => "value",
            MacroNS => "macro",
            TypeNS => "type",
3658 3659
        };

3660 3661 3662
        let msg = format!("the name `{}` is defined multiple times", name);

        let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
3663
            (true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
3664
            (true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() {
3665 3666
                true => struct_span_err!(self.session, span, E0254, "{}", msg),
                false => struct_span_err!(self.session, span, E0260, "{}", msg),
M
Mohit Agarwal 已提交
3667
            },
3668
            _ => match (old_binding.is_import(), new_binding.is_import()) {
3669 3670 3671
                (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
                (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
                _ => struct_span_err!(self.session, span, E0255, "{}", msg),
3672 3673 3674
            },
        };

3675 3676 3677 3678 3679 3680
        err.note(&format!("`{}` must be defined only once in the {} namespace of this {}",
                          name,
                          namespace,
                          container));

        err.span_label(span, format!("`{}` re{} here", name, new_participle));
3681
        if old_binding.span != syntax_pos::DUMMY_SP {
3682 3683
            err.span_label(old_binding.span, format!("previous {} of the {} `{}` here",
                                                      old_noun, old_kind, name));
3684
        }
3685

C
Cldfire 已提交
3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705
        // See https://github.com/rust-lang/rust/issues/32354
        if old_binding.is_import() || new_binding.is_import() {
            let binding = if new_binding.is_import() {
                new_binding
            } else {
                old_binding
            };

            let cm = self.session.codemap();
            let rename_msg = "You can use `as` to change the binding name of the import";

            if let Ok(snippet) = cm.span_to_snippet(binding.span) {
                err.span_suggestion(binding.span,
                                    rename_msg,
                                    format!("{} as Other{}", snippet, name));
            } else {
                err.span_label(binding.span, rename_msg);
            }
        }

3706
        err.emit();
3707
        self.name_already_seen.insert(name, span);
3708
    }
J
Jeffrey Seyfried 已提交
3709 3710 3711

    fn warn_legacy_self_import(&self, directive: &'a ImportDirective<'a>) {
        let (id, span) = (directive.id, directive.span);
3712 3713
        let msg = "`self` no longer imports values";
        self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
J
Jeffrey Seyfried 已提交
3714
    }
3715 3716 3717 3718 3719

    fn check_proc_macro_attrs(&mut self, attrs: &[ast::Attribute]) {
        if self.proc_macro_enabled { return; }

        for attr in attrs {
3720 3721 3722 3723
            if attr.path.segments.len() > 1 {
                continue
            }
            let ident = attr.path.segments[0].identifier;
3724 3725 3726 3727
            let result = self.resolve_lexical_macro_path_segment(ident,
                                                                 MacroNS,
                                                                 false,
                                                                 attr.path.span);
3728 3729
            if let Ok(binding) = result {
                if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
3730 3731 3732 3733 3734 3735 3736
                    attr::mark_known(attr);

                    let msg = "attribute procedural macros are experimental";
                    let feature = "proc_macro";

                    feature_err(&self.session.parse_sess, feature,
                                attr.span, GateIssue::Language, msg)
3737
                        .span_note(binding.span(), "procedural macro imported here")
3738 3739 3740 3741 3742
                        .emit();
                }
            }
        }
    }
3743
}
3744

3745 3746 3747 3748 3749 3750 3751
fn is_struct_like(def: Def) -> bool {
    match def {
        Def::VariantCtor(_, CtorKind::Fictive) => true,
        _ => PathSource::Struct.is_expected(def),
    }
}

3752 3753
fn is_self_type(path: &[SpannedIdent], namespace: Namespace) -> bool {
    namespace == TypeNS && path.len() == 1 && path[0].node.name == keywords::SelfType.name()
3754 3755
}

3756 3757
fn is_self_value(path: &[SpannedIdent], namespace: Namespace) -> bool {
    namespace == ValueNS && path.len() == 1 && path[0].node.name == keywords::SelfValue.name()
3758 3759
}

3760
fn names_to_string(idents: &[SpannedIdent]) -> String {
3761
    let mut result = String::new();
3762 3763 3764
    for (i, ident) in idents.iter()
                            .filter(|i| i.node.name != keywords::CrateRoot.name())
                            .enumerate() {
3765 3766 3767
        if i > 0 {
            result.push_str("::");
        }
3768
        result.push_str(&ident.node.name.as_str());
C
corentih 已提交
3769
    }
3770 3771 3772
    result
}

3773
fn path_names_to_string(path: &Path) -> String {
3774 3775 3776
    names_to_string(&path.segments.iter()
                        .map(|seg| respan(seg.span, seg.identifier))
                        .collect::<Vec<_>>())
3777 3778
}

3779
/// Get the path for an enum and the variant from an `ImportSuggestion` for an enum variant.
E
Esteban Küber 已提交
3780
fn import_candidate_to_paths(suggestion: &ImportSuggestion) -> (Span, String, String) {
3781 3782 3783 3784 3785 3786 3787 3788 3789 3790
    let variant_path = &suggestion.path;
    let variant_path_string = path_names_to_string(variant_path);

    let path_len = suggestion.path.segments.len();
    let enum_path = ast::Path {
        span: suggestion.path.span,
        segments: suggestion.path.segments[0..path_len - 1].to_vec(),
    };
    let enum_path_string = path_names_to_string(&enum_path);

E
Esteban Küber 已提交
3791
    (suggestion.path.span, variant_path_string, enum_path_string)
3792 3793 3794
}


3795 3796 3797
/// 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
3798
fn show_candidates(err: &mut DiagnosticBuilder,
3799 3800
                   // This is `None` if all placement locations are inside expansions
                   span: Option<Span>,
3801
                   candidates: &[ImportSuggestion],
3802 3803
                   better: bool,
                   found_use: bool) {
3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814

    // 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<_> =
        candidates.into_iter().map(|c| path_names_to_string(&c.path)).collect();
    path_strings.sort();

    let better = if better { "better " } else { "" };
    let msg_diff = match path_strings.len() {
        1 => " is found in another module, you can import it",
        _ => "s are found in other modules, you can import them",
3815
    };
3816 3817
    let msg = format!("possible {}candidate{} into scope", better, msg_diff);

3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828
    if let Some(span) = span {
        for candidate in &mut path_strings {
            // produce an additional newline to separate the new use statement
            // from the directly following item.
            let additional_newline = if found_use {
                ""
            } else {
                "\n"
            };
            *candidate = format!("use {};\n{}", candidate, additional_newline);
        }
3829

3830 3831 3832 3833 3834 3835 3836 3837 3838
        err.span_suggestions(span, &msg, path_strings);
    } else {
        let mut msg = msg;
        msg.push(':');
        for candidate in path_strings {
            msg.push('\n');
            msg.push_str(&candidate);
        }
    }
3839 3840
}

3841
/// A somewhat inefficient routine to obtain the name of a module.
3842
fn module_to_string(module: Module) -> String {
3843 3844
    let mut names = Vec::new();

3845
    fn collect_mod(names: &mut Vec<Ident>, module: Module) {
J
Jeffrey Seyfried 已提交
3846 3847
        if let ModuleKind::Def(_, name) = module.kind {
            if let Some(parent) = module.parent {
3848
                names.push(Ident::with_empty_ctxt(name));
J
Jeffrey Seyfried 已提交
3849
                collect_mod(names, parent);
3850
            }
J
Jeffrey Seyfried 已提交
3851 3852
        } else {
            // danger, shouldn't be ident?
3853
            names.push(Ident::from_str("<opaque>"));
J
Jeffrey Seyfried 已提交
3854
            collect_mod(names, module.parent.unwrap());
3855 3856 3857 3858
        }
    }
    collect_mod(&mut names, module);

3859
    if names.is_empty() {
3860 3861
        return "???".to_string();
    }
3862 3863 3864 3865
    names_to_string(&names.into_iter()
                        .rev()
                        .map(|n| dummy_spanned(n))
                        .collect::<Vec<_>>())
3866 3867
}

3868
fn err_path_resolution() -> PathResolution {
3869
    PathResolution::new(Def::Err)
3870 3871
}

N
Niko Matsakis 已提交
3872
#[derive(PartialEq,Copy, Clone)]
3873 3874
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3875
    No,
3876 3877
}

3878
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }