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

11
#![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
extern crate rustc;
27
extern crate rustc_data_structures;
28

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

360
#[derive(Copy, Clone, Debug)]
361
struct BindingInfo {
362
    span: Span,
363
    binding_mode: BindingMode,
364 365 366
}

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

369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum PatternSource {
    Match,
    IfLet,
    WhileLet,
    Let,
    For,
    FnParam,
}

impl PatternSource {
    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",
        }
    }
390 391
}

392 393 394 395 396 397 398
#[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.
399
    Expr(Option<&'a Expr>),
400 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
    // 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"),
            },
456
            PathSource::Expr(parent) => match parent.map(|p| &p.node) {
457 458 459 460 461 462 463 464 465 466 467 468 469
                // "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 已提交
470 471
                Def::PrimTy(..) | Def::TyParam(..) | Def::SelfTy(..) |
                Def::TyForeign(..) => true,
472 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
                _ => 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",
        }
    }
}

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

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

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

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

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

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
612
                    if item.span.ctxt().outer().expn_info().is_none() {
613
                        self.span = Some(item.span.with_hi(item.span.lo()));
614
                        self.found_use = true;
615 616 617 618 619 620 621
                        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 ) {
622 623 624 625 626 627 628 629 630 631 632 633 634
                    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()));
                                }
                            }
                        }
                    }
635 636 637 638 639 640
                },
            }
        }
    }
}

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

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

        // Create a value rib for the function.
J
Jeffrey Seyfried 已提交
732
        self.ribs[ValueNS].push(Rib::new(rib_kind));
733 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

        // 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 已提交
762
        self.ribs[ValueNS].pop();
763
    }
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
    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); }
    }
790
}
791

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

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

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

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

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

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

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

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

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

    // 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,
837 838
}

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

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

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

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

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

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

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

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

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

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

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

904
    no_implicit_prelude: bool,
905

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

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

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

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

    expansion: Mark,
921 922
}

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

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

949 950 951
    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));
952 953 954
        }
    }

955 956 957 958 959 960 961 962 963 964 965 966 967
    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 已提交
968 969 970 971 972 973 974
    fn def(&self) -> Option<Def> {
        match self.kind {
            ModuleKind::Def(def, _) => Some(def),
            _ => None,
        }
    }

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

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

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

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

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

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

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

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

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

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

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

1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
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 已提交
1057 1058 1059
struct AmbiguityError<'a> {
    span: Span,
    name: Name,
1060
    lexical: bool,
J
Jeffrey Seyfried 已提交
1061 1062
    b1: &'a NameBinding<'a>,
    b2: &'a NameBinding<'a>,
1063
    legacy: bool,
J
Jeffrey Seyfried 已提交
1064 1065
}

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

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

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

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

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

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

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

1129 1130 1131 1132 1133 1134 1135 1136 1137
    fn is_renamed_extern_crate(&self) -> bool {
        if let NameBindingKind::Import { directive, ..} = self.kind {
            if let ImportDirectiveSubclass::ExternCrate(Some(_)) = directive.subclass {
                return true;
            }
        }
        false
    }

1138 1139 1140
    fn is_glob_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { directive, .. } => directive.is_glob(),
1141
            NameBindingKind::Ambiguity { b1, .. } => b1.is_glob_import(),
1142 1143 1144 1145 1146
            _ => false,
        }
    }

    fn is_importable(&self) -> bool {
1147
        match self.def() {
1148 1149 1150 1151
            Def::AssociatedConst(..) | Def::Method(..) | Def::AssociatedTy(..) => false,
            _ => true,
        }
    }
1152 1153 1154 1155 1156 1157 1158

    fn is_macro_def(&self) -> bool {
        match self.kind {
            NameBindingKind::Def(Def::Macro(..)) => true,
            _ => false,
        }
    }
1159 1160 1161 1162

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

1165
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1166
struct PrimitiveTypeTable {
1167
    primitive_types: FxHashMap<Name, PrimTy>,
1168
}
1169

1170
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1171
    fn new() -> PrimitiveTypeTable {
1172
        let mut table = PrimitiveTypeTable { primitive_types: FxHashMap() };
C
corentih 已提交
1173 1174 1175

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
1176 1177
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
1178 1179 1180 1181 1182
        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));
1183
        table.intern("i128", TyInt(IntTy::I128));
C
corentih 已提交
1184
        table.intern("str", TyStr);
1185 1186 1187 1188 1189
        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));
1190
        table.intern("u128", TyUint(UintTy::U128));
K
Kevin Butler 已提交
1191 1192 1193
        table
    }

1194
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1195
        self.primitive_types.insert(Symbol::intern(string), primitive_type);
1196 1197 1198
    }
}

1199
/// The main resolver class.
1200
pub struct Resolver<'a> {
E
Eduard Burtescu 已提交
1201
    session: &'a Session,
1202
    cstore: &'a CrateStore,
1203

1204
    pub definitions: Definitions,
1205

1206
    graph_root: Module<'a>,
1207

1208 1209
    prelude: Option<Module<'a>>,

1210 1211
    // n.b. This is used only for better diagnostics, not name resolution itself.
    has_self: FxHashSet<DefId>,
1212

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

1217 1218 1219 1220
    // All imports known to succeed or fail.
    determined_imports: Vec<&'a ImportDirective<'a>>,

    // All non-determined imports.
1221
    indeterminate_imports: Vec<&'a ImportDirective<'a>>,
1222 1223

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

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

1230
    // The current set of local scopes, for labels.
1231
    label_ribs: Vec<Rib<'a>>,
1232

1233
    // The trait that the current context can refer to.
1234
    current_trait_ref: Option<(Module<'a>, TraitRef)>,
1235 1236 1237

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

1239
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1240
    primitive_type_table: PrimitiveTypeTable,
1241

1242
    def_map: DefMap,
1243
    pub freevars: FreevarMap,
1244
    freevars_seen: NodeMap<NodeMap<usize>>,
1245 1246
    pub export_map: ExportMap,
    pub trait_map: TraitMap,
1247

1248
    // A map from nodes to anonymous modules.
1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    // 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`.
1262 1263
    block_map: NodeMap<Module<'a>>,
    module_map: FxHashMap<DefId, Module<'a>>,
J
Jeffrey Seyfried 已提交
1264
    extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
1265

1266
    pub make_glob_map: bool,
1267 1268
    /// Maps imports to the names of items actually imported (this actually maps
    /// all imports, but only glob imports are actually interesting).
1269
    pub glob_map: GlobMap,
1270

1271
    used_imports: FxHashSet<(NodeId, Namespace)>,
1272
    pub maybe_unused_trait_imports: NodeSet,
1273
    pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
G
Garming Sam 已提交
1274

1275
    /// privacy errors are delayed until the end in order to deduplicate them
1276
    privacy_errors: Vec<PrivacyError<'a>>,
1277
    /// ambiguity errors are delayed for deduplication
J
Jeffrey Seyfried 已提交
1278
    ambiguity_errors: Vec<AmbiguityError<'a>>,
1279 1280 1281
    /// `use` injections are delayed for better placement and deduplication
    use_injections: Vec<UseError<'a>>,

J
Jeffrey Seyfried 已提交
1282
    gated_errors: FxHashSet<Span>,
1283
    disallowed_shadowing: Vec<&'a LegacyBinding<'a>>,
1284 1285

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

1289
    crate_loader: &'a mut CrateLoader,
J
Jeffrey Seyfried 已提交
1290
    macro_names: FxHashSet<Ident>,
J
Jeffrey Seyfried 已提交
1291
    global_macros: FxHashMap<Name, &'a NameBinding<'a>>,
J
Jeffrey Seyfried 已提交
1292
    lexical_macro_resolutions: Vec<(Ident, &'a Cell<LegacyScope<'a>>)>,
J
Jeffrey Seyfried 已提交
1293
    macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
1294 1295
    macro_defs: FxHashMap<Mark, DefId>,
    local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
J
Jeffrey Seyfried 已提交
1296
    macro_exports: Vec<Export>,
1297
    pub whitelisted_legacy_custom_derives: Vec<Name>,
1298
    pub found_unresolved_macro: bool,
1299

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

1304
    // Maps the `Mark` of an expansion to its containing module or block.
1305
    invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
1306 1307 1308

    // Avoid duplicated errors for "name already defined".
    name_already_seen: FxHashMap<Name, Span>,
1309 1310 1311 1312 1313 1314

    // 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>,
1315 1316

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

1318 1319 1320
    // 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)>,
1321 1322 1323

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

1326
pub struct ResolverArenas<'a> {
1327
    modules: arena::TypedArena<ModuleData<'a>>,
1328
    local_modules: RefCell<Vec<Module<'a>>>,
1329
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1330
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1331
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1332
    invocation_data: arena::TypedArena<InvocationData<'a>>,
J
Jeffrey Seyfried 已提交
1333
    legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
1334 1335 1336
}

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

1366 1367 1368 1369
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,
1370
            _ => self.cstore.def_key(id).parent,
1371
        }.map(|index| DefId { index: index, ..id })
1372 1373 1374
    }
}

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

1399 1400 1401 1402
    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
        self.def_map.get(&id).cloned()
    }

1403 1404
    fn definitions(&mut self) -> &mut Definitions {
        &mut self.definitions
1405 1406 1407
    }
}

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

1426
        let mut definitions = Definitions::new();
J
Jeffrey Seyfried 已提交
1427
        DefCollector::new(&mut definitions, Mark::root())
1428
            .collect_root(crate_name, session.local_crate_disambiguator());
1429

1430
        let mut invocations = FxHashMap();
1431 1432
        invocations.insert(Mark::root(),
                           arenas.alloc_invocation_data(InvocationData::root(graph_root)));
1433

1434 1435
        let features = session.features.borrow();

1436 1437 1438
        let mut macro_defs = FxHashMap();
        macro_defs.insert(Mark::root(), root_def_id);

K
Kevin Butler 已提交
1439
        Resolver {
1440
            session,
K
Kevin Butler 已提交
1441

1442 1443
            cstore,

1444
            definitions,
1445

K
Kevin Butler 已提交
1446 1447
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1448
            graph_root,
1449
            prelude: None,
K
Kevin Butler 已提交
1450

1451
            has_self: FxHashSet(),
1452
            field_names: FxHashMap(),
K
Kevin Butler 已提交
1453

1454
            determined_imports: Vec::new(),
1455
            indeterminate_imports: Vec::new(),
K
Kevin Butler 已提交
1456

1457
            current_module: graph_root,
J
Jeffrey Seyfried 已提交
1458 1459 1460
            ribs: PerNS {
                value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
                type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
1461
                macro_ns: Some(vec![Rib::new(ModuleRibKind(graph_root))]),
J
Jeffrey Seyfried 已提交
1462
            },
1463
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1464 1465 1466 1467 1468 1469

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1470
            def_map: NodeMap(),
1471 1472
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
A
Alex Crichton 已提交
1473
            export_map: FxHashMap(),
1474
            trait_map: NodeMap(),
1475
            module_map,
1476
            block_map: NodeMap(),
J
Jeffrey Seyfried 已提交
1477
            extern_module_map: FxHashMap(),
K
Kevin Butler 已提交
1478

1479
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1480
            glob_map: NodeMap(),
G
Garming Sam 已提交
1481

1482
            used_imports: FxHashSet(),
S
Seo Sanghyeon 已提交
1483
            maybe_unused_trait_imports: NodeSet(),
1484
            maybe_unused_extern_crates: Vec::new(),
S
Seo Sanghyeon 已提交
1485

1486
            privacy_errors: Vec::new(),
1487
            ambiguity_errors: Vec::new(),
1488
            use_injections: Vec::new(),
J
Jeffrey Seyfried 已提交
1489
            gated_errors: FxHashSet(),
1490
            disallowed_shadowing: Vec::new(),
1491

1492
            arenas,
1493 1494
            dummy_binding: arenas.alloc_name_binding(NameBinding {
                kind: NameBindingKind::Def(Def::Err),
1495
                expansion: Mark::root(),
1496 1497 1498
                span: DUMMY_SP,
                vis: ty::Visibility::Public,
            }),
1499

1500 1501 1502
            // The `proc_macro` and `decl_macro` features imply `use_extern_macros`
            use_extern_macros:
                features.use_extern_macros || features.proc_macro || features.decl_macro,
1503

1504
            crate_loader,
1505
            macro_names: FxHashSet(),
J
Jeffrey Seyfried 已提交
1506
            global_macros: FxHashMap(),
J
Jeffrey Seyfried 已提交
1507
            lexical_macro_resolutions: Vec::new(),
J
Jeffrey Seyfried 已提交
1508 1509
            macro_map: FxHashMap(),
            macro_exports: Vec::new(),
1510 1511
            invocations,
            macro_defs,
1512
            local_macro_def_scopes: FxHashMap(),
1513
            name_already_seen: FxHashMap(),
1514
            whitelisted_legacy_custom_derives: Vec::new(),
1515 1516
            proc_macro_enabled: features.proc_macro,
            warned_proc_macros: FxHashSet(),
1517
            potentially_unused_imports: Vec::new(),
1518
            struct_constructors: DefIdMap(),
1519
            found_unresolved_macro: false,
E
est31 已提交
1520
            unused_macros: FxHashSet(),
1521
            current_type_ascription: Vec::new(),
1522 1523 1524
        }
    }

1525
    pub fn arenas() -> ResolverArenas<'a> {
1526 1527
        ResolverArenas {
            modules: arena::TypedArena::new(),
1528
            local_modules: RefCell::new(Vec::new()),
1529
            name_bindings: arena::TypedArena::new(),
1530
            import_directives: arena::TypedArena::new(),
1531
            name_resolutions: arena::TypedArena::new(),
1532
            invocation_data: arena::TypedArena::new(),
J
Jeffrey Seyfried 已提交
1533
            legacy_bindings: arena::TypedArena::new(),
K
Kevin Butler 已提交
1534 1535
        }
    }
1536

J
Jeffrey Seyfried 已提交
1537 1538 1539 1540
    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),
1541 1542 1543 1544
            macro_ns: match self.use_extern_macros {
                true => Some(f(self, MacroNS)),
                false => None,
            },
J
Jeffrey Seyfried 已提交
1545 1546 1547
        }
    }

1548 1549
    /// Entry point to crate resolution.
    pub fn resolve_crate(&mut self, krate: &Crate) {
1550
        ImportResolver { resolver: self }.finalize_imports();
1551
        self.current_module = self.graph_root;
1552
        self.finalize_current_module_macro_resolutions();
1553

1554 1555 1556
        visit::walk_crate(self, krate);

        check_unused::check_crate(self, krate);
1557
        self.report_errors(krate);
1558
        self.crate_loader.postprocess(krate);
1559 1560
    }

O
Oliver Schneider 已提交
1561 1562 1563 1564 1565
    fn new_module(
        &self,
        parent: Module<'a>,
        kind: ModuleKind,
        normal_ancestor_id: DefId,
J
Jeffrey Seyfried 已提交
1566
        expansion: Mark,
O
Oliver Schneider 已提交
1567 1568
        span: Span,
    ) -> Module<'a> {
J
Jeffrey Seyfried 已提交
1569 1570
        let module = ModuleData::new(Some(parent), kind, normal_ancestor_id, expansion, span);
        self.arenas.alloc_module(module)
1571 1572
    }

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

1602
    fn add_to_glob_map(&mut self, id: NodeId, ident: Ident) {
1603
        if self.make_glob_map {
1604
            self.glob_map.entry(id).or_insert_with(FxHashSet).insert(ident.name);
1605
        }
1606 1607
    }

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

1639
        // Walk backwards up the ribs in scope.
J
Jeffrey Seyfried 已提交
1640
        let mut module = self.graph_root;
J
Jeffrey Seyfried 已提交
1641 1642
        for i in (0 .. self.ribs[ns].len()).rev() {
            if let Some(def) = self.ribs[ns][i].bindings.get(&ident).cloned() {
1643
                // The ident resolves to a type parameter or local variable.
1644
                return Some(LexicalScopeBinding::Def(
1645
                    self.adjust_local_def(ns, i, def, record_used, path_span)
1646
                ));
1647 1648
            }

J
Jeffrey Seyfried 已提交
1649 1650 1651 1652 1653 1654 1655
            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
1656
                }
J
Jeffrey Seyfried 已提交
1657 1658
                _ => continue,
            };
1659

J
Jeffrey Seyfried 已提交
1660 1661 1662 1663 1664 1665
            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));
1666
            }
1667

J
Jeffrey Seyfried 已提交
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 1702 1703 1704 1705 1706 1707 1708 1709
            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 已提交
1710
        let mut module_expansion = module.expansion.modern(); // for backward compatibility
J
Jeffrey Seyfried 已提交
1711 1712 1713 1714 1715 1716 1717 1718 1719
        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
                };
1720
            }
J
Jeffrey Seyfried 已提交
1721 1722
            module = parent;
            module_expansion = parent_expansion;
1723
        }
1724

1725 1726 1727
        None
    }

J
Jeffrey Seyfried 已提交
1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757
    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);
1758
        while module.span.ctxt().modern() != *ctxt {
J
Jeffrey Seyfried 已提交
1759 1760
            let parent = module.parent.unwrap_or_else(|| self.macro_def_scope(ctxt.remove_mark()));
            module = self.get_module(parent.normal_ancestor_id);
1761
        }
J
Jeffrey Seyfried 已提交
1762
        module
1763 1764
    }

1765 1766
    // AST resolution
    //
1767
    // We maintain a list of value ribs and type ribs.
1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
    //
    // 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.

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

1794
            self.finalize_current_module_macro_resolutions();
1795
            f(self);
1796

1797
            self.current_module = orig_module;
J
Jeffrey Seyfried 已提交
1798 1799
            self.ribs[ValueNS].pop();
            self.ribs[TypeNS].pop();
1800 1801 1802
        } else {
            f(self);
        }
1803 1804
    }

1805 1806 1807
    /// 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 已提交
1808
    /// Stops after meeting a closure.
1809 1810 1811
    fn search_label<P, R>(&self, mut ident: Ident, pred: P) -> Option<R>
        where P: Fn(&Rib, Ident) -> Option<R>
    {
1812 1813
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
J
Jeffrey Seyfried 已提交
1814 1815 1816
                NormalRibKind => {}
                // If an invocation of this macro created `ident`, give up on `ident`
                // and switch to `ident`'s source from the macro definition.
1817
                MacroDefinition(def) => {
J
Jeffrey Seyfried 已提交
1818 1819
                    if def == self.macro_defs[&ident.ctxt.outer()] {
                        ident.ctxt.remove_mark();
1820 1821
                    }
                }
1822 1823
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1824
                    return None;
1825 1826
                }
            }
1827 1828 1829
            let r = pred(rib, ident);
            if r.is_some() {
                return r;
1830 1831 1832 1833 1834
            }
        }
        None
    }

1835
    fn resolve_item(&mut self, item: &Item) {
1836
        let name = item.ident.name;
1837

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

1840 1841
        self.check_proc_macro_attrs(&item.attrs);

1842
        match item.node {
1843 1844
            ItemKind::Enum(_, ref generics) |
            ItemKind::Ty(_, ref generics) |
1845
            ItemKind::Struct(_, ref generics) |
1846
            ItemKind::Union(_, ref generics) |
V
Vadim Petrochenkov 已提交
1847
            ItemKind::Fn(.., ref generics, _) => {
1848
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind),
1849
                                             |this| visit::walk_item(this, item));
1850 1851
            }

1852
            ItemKind::AutoImpl(_, ref trait_ref) => {
1853 1854 1855 1856
                self.with_optional_trait_ref(Some(trait_ref), |this, _| {
                    // Resolve type arguments in trait path
                    visit::walk_trait_ref(this, trait_ref);
                });
1857
            }
V
Vadim Petrochenkov 已提交
1858
            ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
1859
                self.resolve_implementation(generics,
1860
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1861
                                            &self_type,
1862
                                            item.id,
1863
                                            impl_items),
1864

1865
            ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
1866
                // Create a new rib for the trait-wide type parameters.
1867
                self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
1868
                    let local_def_id = this.definitions.local_def_id(item.id);
1869
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1870
                        this.visit_generics(generics);
1871
                        walk_list!(this, visit_ty_param_bound, bounds);
1872 1873

                        for trait_item in trait_items {
1874 1875
                            this.check_proc_macro_attrs(&trait_item.attrs);

1876
                            match trait_item.node {
1877 1878 1879
                                TraitItemKind::Const(ref ty, ref default) => {
                                    this.visit_ty(ty);

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

1909
            ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
1910
                self.with_scope(item.id, |this| {
1911
                    visit::walk_item(this, item);
1912
                });
1913 1914
            }

1915 1916 1917 1918 1919 1920 1921
            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);
                    });
1922
                });
1923
            }
1924

1925
            ItemKind::Use(ref view_path) => {
1926
                match view_path.node {
1927 1928 1929
                    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);
1930 1931
                    }
                    _ => {}
W
we 已提交
1932 1933 1934
                }
            }

1935
            ItemKind::ExternCrate(_) | ItemKind::MacroDef(..) | ItemKind::GlobalAsm(_)=> {
1936
                // do nothing, these are just around to be encoded
1937
            }
1938 1939

            ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
1940 1941 1942
        }
    }

1943
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1944
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1945
    {
1946
        match type_parameters {
1947
            HasTypeParameters(generics, rib_kind) => {
1948
                let mut function_type_rib = Rib::new(rib_kind);
1949
                let mut seen_bindings = FxHashMap();
1950
                for type_parameter in &generics.ty_params {
J
Jeffrey Seyfried 已提交
1951
                    let ident = type_parameter.ident.modern();
1952
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1953

1954 1955 1956 1957 1958
                    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);
1959
                    }
1960
                    seen_bindings.entry(ident).or_insert(type_parameter.span);
1961

1962
                    // plain insert (no renaming)
1963
                    let def_id = self.definitions.local_def_id(type_parameter.id);
1964
                    let def = Def::TyParam(def_id);
1965
                    function_type_rib.bindings.insert(ident, def);
1966
                    self.record_def(type_parameter.id, PathResolution::new(def));
1967
                }
J
Jeffrey Seyfried 已提交
1968
                self.ribs[TypeNS].push(function_type_rib);
1969 1970
            }

B
Brian Anderson 已提交
1971
            NoTypeParameters => {
1972 1973 1974 1975
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1976
        f(self);
1977

J
Jeffrey Seyfried 已提交
1978
        if let HasTypeParameters(..) = type_parameters {
J
Jeffrey Seyfried 已提交
1979
            self.ribs[TypeNS].pop();
1980 1981 1982
        }
    }

C
corentih 已提交
1983 1984
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1985
    {
1986
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1987
        f(self);
J
Jeffrey Seyfried 已提交
1988
        self.label_ribs.pop();
1989
    }
1990

1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
    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 已提交
2001 2002
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
2003
    {
J
Jeffrey Seyfried 已提交
2004
        self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2005
        f(self);
J
Jeffrey Seyfried 已提交
2006
        self.ribs[ValueNS].pop();
2007 2008
    }

2009 2010
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2011
    {
2012 2013 2014 2015 2016 2017 2018
        // 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
    }

2019
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
2020
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2021
    {
2022
        let mut new_val = None;
2023
        let mut new_id = None;
E
Eduard Burtescu 已提交
2024
        if let Some(trait_ref) = opt_trait_ref {
2025 2026 2027
            let path: Vec<_> = trait_ref.path.segments.iter()
                .map(|seg| respan(seg.span, seg.identifier))
                .collect();
2028 2029 2030 2031 2032 2033 2034
            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();
2035 2036
            if def != Def::Err {
                new_id = Some(def.def_id());
2037 2038 2039 2040
                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()));
                }
2041
            }
2042
        }
2043
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2044
        let result = f(self, new_id);
2045 2046 2047 2048
        self.current_trait_ref = original_trait_ref;
        result
    }

2049 2050 2051 2052 2053 2054
    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....)
2055
        self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def);
J
Jeffrey Seyfried 已提交
2056
        self.ribs[TypeNS].push(self_type_rib);
2057
        f(self);
J
Jeffrey Seyfried 已提交
2058
        self.ribs[TypeNS].pop();
2059 2060
    }

F
Felix S. Klock II 已提交
2061
    fn resolve_implementation(&mut self,
2062 2063 2064
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2065
                              item_id: NodeId,
2066
                              impl_items: &[ImplItem]) {
2067
        // If applicable, create a rib for the type parameters.
2068
        self.with_type_parameter_rib(HasTypeParameters(generics, ItemRibKind), |this| {
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090
            // 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
2091
                                        this.check_trait_item(impl_item.ident,
2092 2093 2094
                                                            ValueNS,
                                                            impl_item.span,
                                            |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2095 2096 2097
                                        this.with_constant_rib(|this|
                                            visit::walk_impl_item(this, impl_item)
                                        );
2098 2099 2100 2101
                                    }
                                    ImplItemKind::Method(ref sig, _) => {
                                        // If this is a trait impl, ensure the method
                                        // exists in trait
2102
                                        this.check_trait_item(impl_item.ident,
2103 2104 2105 2106 2107 2108 2109
                                                            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 =
2110
                                            HasTypeParameters(&impl_item.generics,
2111 2112 2113 2114 2115 2116 2117 2118
                                                            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
2119
                                        this.check_trait_item(impl_item.ident,
2120 2121 2122 2123 2124 2125 2126 2127
                                                            TypeNS,
                                                            impl_item.span,
                                            |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));

                                        this.visit_ty(ty);
                                    }
                                    ImplItemKind::Macro(_) =>
                                        panic!("unexpanded macro in resolve!"),
2128
                                }
2129
                            }
2130
                        });
2131
                    });
2132
                });
2133
            });
2134
        });
2135 2136
    }

2137
    fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
C
corentih 已提交
2138 2139 2140 2141
        where F: FnOnce(Name, &str) -> ResolutionError
    {
        // If there is a TraitRef in scope for an impl, then the method must be in the
        // trait.
2142 2143 2144 2145
        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)));
2146 2147 2148 2149
            }
        }
    }

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

2154
        // Resolve the initializer.
2155
        walk_list!(self, visit_expr, &local.init);
2156 2157

        // Resolve the pattern.
2158
        self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap());
2159 2160
    }

J
John Clements 已提交
2161 2162 2163 2164
    // 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 已提交
2165
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2166
        let mut binding_map = FxHashMap();
2167 2168 2169

        pat.walk(&mut |pat| {
            if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
2170 2171
                if sub_pat.is_some() || match self.def_map.get(&pat.id).map(|res| res.base_def()) {
                    Some(Def::Local(..)) => true,
2172 2173 2174
                    _ => false,
                } {
                    let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
2175
                    binding_map.insert(ident.node, binding_info);
2176 2177 2178
                }
            }
            true
2179
        });
2180 2181

        binding_map
2182 2183
    }

J
John Clements 已提交
2184 2185
    // 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 已提交
2186
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2187
        if arm.pats.is_empty() {
C
corentih 已提交
2188
            return;
2189
        }
2190 2191 2192

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

2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207
            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,
2208 2209
                                origin: BTreeSet::new(),
                                target: BTreeSet::new(),
2210 2211 2212
                            });
                        binding_error.origin.insert(binding_i.span);
                        binding_error.target.insert(q.span);
C
corentih 已提交
2213
                    }
2214 2215 2216 2217 2218 2219 2220
                    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,
2221 2222
                                        origin: BTreeSet::new(),
                                        target: BTreeSet::new(),
2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
                                    });
                                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 已提交
2234
                        }
2235
                    }
2236 2237
                }
            }
2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249
        }
        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));
2250
        }
2251 2252
    }

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

2256
        let mut bindings_list = FxHashMap();
2257
        for pattern in &arm.pats {
2258
            self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
2259 2260
        }

2261 2262 2263 2264
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2265
        walk_list!(self, visit_expr, &arm.guard);
J
Jonas Schievink 已提交
2266
        self.visit_expr(&arm.body);
2267

J
Jeffrey Seyfried 已提交
2268
        self.ribs[ValueNS].pop();
2269 2270
    }

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

2277
        let mut num_macro_definition_ribs = 0;
2278 2279
        if let Some(anonymous_module) = anonymous_module {
            debug!("(resolving block) found anonymous module, moving down");
J
Jeffrey Seyfried 已提交
2280 2281
            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
2282
            self.current_module = anonymous_module;
2283
            self.finalize_current_module_macro_resolutions();
2284
        } else {
J
Jeffrey Seyfried 已提交
2285
            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
2286 2287 2288
        }

        // Descend into the block.
2289
        for stmt in &block.stmts {
2290
            if let ast::StmtKind::Item(ref item) = stmt.node {
2291
                if let ast::ItemKind::MacroDef(..) = item.node {
2292
                    num_macro_definition_ribs += 1;
2293 2294 2295
                    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)));
2296 2297 2298 2299 2300
                }
            }

            self.visit_stmt(stmt);
        }
2301 2302

        // Move back up.
J
Jeffrey Seyfried 已提交
2303
        self.current_module = orig_module;
2304
        for _ in 0 .. num_macro_definition_ribs {
J
Jeffrey Seyfried 已提交
2305
            self.ribs[ValueNS].pop();
2306
            self.label_ribs.pop();
2307
        }
J
Jeffrey Seyfried 已提交
2308
        self.ribs[ValueNS].pop();
J
Jeffrey Seyfried 已提交
2309
        if let Some(_) = anonymous_module {
J
Jeffrey Seyfried 已提交
2310
            self.ribs[TypeNS].pop();
G
Garming Sam 已提交
2311
        }
2312
        debug!("(resolving block) leaving block");
2313 2314
    }

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

2365
        PathResolution::new(def)
2366
    }
2367

2368 2369 2370 2371 2372
    fn resolve_pattern(&mut self,
                       pat: &Pat,
                       pat_src: PatternSource,
                       // Maps idents to the node ID for the
                       // outermost pattern that binds them.
2373
                       bindings: &mut FxHashMap<Ident, NodeId>) {
2374
        // Visit all direct subpatterns of this pattern.
2375 2376 2377 2378 2379 2380
        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.
2381 2382
                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS,
                                                                      false, pat.span)
2383
                                      .and_then(LexicalScopeBinding::item);
2384
                    let resolution = binding.map(NameBinding::def).and_then(|def| {
2385 2386
                        let is_syntactic_ambiguity = opt_pat.is_none() &&
                            bmode == BindingMode::ByValue(Mutability::Immutable);
2387
                        match def {
2388 2389
                            Def::StructCtor(_, CtorKind::Const) |
                            Def::VariantCtor(_, CtorKind::Const) |
2390 2391 2392
                            Def::Const(..) if is_syntactic_ambiguity => {
                                // Disambiguate in favor of a unit struct/variant
                                // or constant pattern.
2393
                                self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span);
2394
                                Some(PathResolution::new(def))
2395
                            }
2396
                            Def::StructCtor(..) | Def::VariantCtor(..) |
2397
                            Def::Const(..) | Def::Static(..) => {
2398 2399 2400 2401 2402
                                // This is unambiguously a fresh binding, either syntactically
                                // (e.g. `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
                                // to something unusable as a pattern (e.g. constructor function),
                                // but we still conservatively report an error, see
                                // issues/33118#issuecomment-233962221 for one reason why.
2403
                                resolve_error(
2404
                                    self,
2405 2406
                                    ident.span,
                                    ResolutionError::BindingShadowsSomethingUnacceptable(
2407
                                        pat_src.descr(), ident.node.name, binding.unwrap())
2408
                                );
2409
                                None
2410
                            }
2411
                            Def::Fn(..) | Def::Err => {
2412 2413
                                // These entities are explicitly allowed
                                // to be shadowed by fresh bindings.
2414
                                None
2415 2416 2417
                            }
                            def => {
                                span_bug!(ident.span, "unexpected definition for an \
2418
                                                       identifier in pattern: {:?}", def);
2419
                            }
2420
                        }
2421
                    }).unwrap_or_else(|| {
2422
                        self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
2423
                    });
2424 2425

                    self.record_def(pat.id, resolution);
2426 2427
                }

2428
                PatKind::TupleStruct(ref path, ..) => {
2429
                    self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct);
2430 2431
                }

2432
                PatKind::Path(ref qself, ref path) => {
2433
                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
2434 2435
                }

V
Vadim Petrochenkov 已提交
2436
                PatKind::Struct(ref path, ..) => {
2437
                    self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
2438
                }
2439 2440

                _ => {}
2441
            }
2442
            true
2443
        });
2444

2445
        visit::walk_pat(self, pat);
2446 2447
    }

2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458
    // 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 {
2459 2460 2461
        let segments = &path.segments.iter()
            .map(|seg| respan(seg.span, seg.identifier))
            .collect::<Vec<_>>();
2462 2463
        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)
2464 2465 2466
    }

    fn smart_resolve_path_fragment(&mut self,
2467
                                   id: NodeId,
2468
                                   qself: Option<&QSelf>,
2469
                                   path: &[SpannedIdent],
2470
                                   span: Span,
2471
                                   ident_span: Span,
2472 2473 2474 2475
                                   source: PathSource)
                                   -> PathResolution {
        let ns = source.namespace();
        let is_expected = &|def| source.is_expected(def);
2476
        let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
2477 2478 2479 2480 2481 2482 2483

        // 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());
2484
            let (base_msg, fallback_label, base_span) = if let Some(def) = def {
2485
                (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
2486
                 format!("not a {}", expected), span)
2487
            } else {
2488 2489
                let item_str = path[path.len() - 1].node;
                let item_span = path[path.len() - 1].span;
2490 2491
                let (mod_prefix, mod_str) = if path.len() == 1 {
                    (format!(""), format!("this scope"))
2492
                } else if path.len() == 2 && path[0].node.name == keywords::CrateRoot.name() {
2493 2494 2495
                    (format!(""), format!("the crate root"))
                } else {
                    let mod_path = &path[..path.len() - 1];
2496
                    let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS), false, span) {
2497 2498 2499 2500 2501 2502
                        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),
2503
                 format!("not found in {}", mod_str), item_span)
2504
            };
2505
            let code = DiagnosticId::Error(code.into());
2506
            let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
2507 2508 2509 2510

            // Emit special messages for unresolved `Self` and `self`.
            if is_self_type(path, ns) {
                __diagnostic_used!(E0411);
2511
                err.code(DiagnosticId::Error("E0411".into()));
2512
                err.span_label(span, "`Self` is only available in traits and impls");
2513
                return (err, Vec::new());
2514 2515 2516
            }
            if is_self_value(path, ns) {
                __diagnostic_used!(E0424);
2517
                err.code(DiagnosticId::Error("E0424".into()));
2518
                err.span_label(span, format!("`self` value is only available in \
2519
                                               methods with `self` parameter"));
2520
                return (err, Vec::new());
2521 2522 2523
            }

            // Try to lookup the name in more relaxed fashion for better error reporting.
2524
            let ident = *path.last().unwrap();
2525
            let candidates = this.lookup_import_candidates(ident.node.name, ns, is_expected);
2526
            if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
2527
                let enum_candidates =
2528
                    this.lookup_import_candidates(ident.node.name, ns, is_enum_variant);
E
Esteban Küber 已提交
2529 2530 2531 2532 2533
                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 {
2534 2535 2536 2537
                        let msg = format!("there is an enum variant `{}`, \
                                        try using `{}`?",
                                        variant_path,
                                        enum_path);
2538 2539
                        err.help(&msg);
                    } else {
2540 2541
                        err.span_suggestion(span, "you can try using the variant's enum",
                                            enum_path);
2542 2543
                    }
                }
2544
            }
2545
            if path.len() == 1 && this.self_type_is_available(span) {
2546 2547
                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);
2548 2549
                    match candidate {
                        AssocSuggestion::Field => {
2550 2551
                            err.span_suggestion(span, "try",
                                                format!("self.{}", path_str));
2552
                            if !self_is_available {
2553
                                err.span_label(span, format!("`self` value is only available in \
2554 2555 2556 2557
                                                               methods with `self` parameter"));
                            }
                        }
                        AssocSuggestion::MethodWithSelf if self_is_available => {
2558 2559
                            err.span_suggestion(span, "try",
                                                format!("self.{}", path_str));
2560 2561
                        }
                        AssocSuggestion::MethodWithSelf | AssocSuggestion::AssocItem => {
2562 2563
                            err.span_suggestion(span, "try",
                                                format!("Self::{}", path_str));
2564 2565
                        }
                    }
2566
                    return (err, candidates);
2567 2568 2569
                }
            }

2570 2571 2572
            let mut levenshtein_worked = false;

            // Try Levenshtein.
2573
            if let Some(candidate) = this.lookup_typo_candidate(path, ns, is_expected, span) {
2574
                err.span_label(ident_span, format!("did you mean `{}`?", candidate));
2575 2576 2577
                levenshtein_worked = true;
            }

2578 2579 2580 2581
            // Try context dependent help if relaxed lookup didn't work.
            if let Some(def) = def {
                match (def, source) {
                    (Def::Macro(..), _) => {
2582
                        err.span_label(span, format!("did you mean `{}!(...)`?", path_str));
2583
                        return (err, candidates);
2584 2585
                    }
                    (Def::TyAlias(..), PathSource::Trait) => {
2586
                        err.span_label(span, "type aliases cannot be used for traits");
2587
                        return (err, candidates);
2588
                    }
2589
                    (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node {
2590
                        ExprKind::Field(_, ident) => {
2591
                            err.span_label(parent.span, format!("did you mean `{}::{}`?",
2592
                                                                 path_str, ident.node));
2593
                            return (err, candidates);
2594
                        }
2595
                        ExprKind::MethodCall(ref segment, ..) => {
2596
                            err.span_label(parent.span, format!("did you mean `{}::{}(...)`?",
2597
                                                                 path_str, segment.identifier));
2598
                            return (err, candidates);
2599 2600 2601 2602
                        }
                        _ => {}
                    },
                    _ if ns == ValueNS && is_struct_like(def) => {
2603 2604 2605 2606
                        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) {
2607
                                    err.span_label(span, format!("constructor is not visible \
2608 2609 2610 2611
                                                                   here due to private fields"));
                                }
                            }
                        }
2612
                        err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
2613
                                                     path_str));
2614
                        return (err, candidates);
2615 2616 2617 2618 2619
                    }
                    _ => {}
                }
            }

2620
            // Fallback label.
2621
            if !levenshtein_worked {
2622
                err.span_label(base_span, fallback_label);
2623
                this.type_ascription_suggestion(&mut err, base_span);
2624
            }
2625
            (err, candidates)
2626 2627
        };
        let report_errors = |this: &mut Self, def: Option<Def>| {
2628 2629 2630 2631 2632
            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 });
2633 2634 2635 2636 2637 2638
            err_path_resolution()
        };

        let resolution = match self.resolve_qpath_anywhere(id, qself, path, ns, span,
                                                           source.defer_to_typeck(),
                                                           source.global_by_default()) {
2639 2640
            Some(resolution) if resolution.unresolved_segments() == 0 => {
                if is_expected(resolution.base_def()) || resolution.base_def() == Def::Err {
2641 2642
                    resolution
                } else {
2643 2644 2645
                    // Add a temporary hack to smooth the transition to new struct ctor
                    // visibility rules. See #38932 for more details.
                    let mut res = None;
2646
                    if let Def::Struct(def_id) = resolution.base_def() {
2647
                        if let Some((ctor_def, ctor_vis))
2648
                                = self.struct_constructors.get(&def_id).cloned() {
2649 2650
                            if is_expected(ctor_def) && self.is_accessible(ctor_vis) {
                                let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
2651
                                self.session.buffer_lint(lint, id, span,
2652
                                    "private struct constructors are not usable through \
2653 2654
                                     reexports in outer modules",
                                );
2655 2656 2657 2658 2659
                                res = Some(PathResolution::new(ctor_def));
                            }
                        }
                    }

2660
                    res.unwrap_or_else(|| report_errors(self, Some(resolution.base_def())))
2661 2662 2663 2664 2665 2666 2667
                }
            }
            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 {
2668
                    let item_name = path.last().unwrap().node;
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683
                    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
    }

2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695
    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);
2696 2697
                    let line_sp = cm.lookup_char_pos(sp.hi()).line;
                    let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718
                    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;
                }
            }
        }
    }

2719 2720 2721
    fn self_type_is_available(&mut self, span: Span) -> bool {
        let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(),
                                                          TypeNS, false, span);
2722 2723 2724
        if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false }
    }

2725
    fn self_value_is_available(&mut self, ctxt: SyntaxContext, span: Span) -> bool {
2726
        let ident = Ident { name: keywords::SelfValue.name(), ctxt: ctxt };
2727
        let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, false, span);
2728 2729 2730 2731 2732 2733 2734
        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>,
2735
                              path: &[SpannedIdent],
2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748
                              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.
2749 2750
                    Some(res) if res.unresolved_segments() == 0 || defer_to_typeck =>
                        return Some(res),
2751 2752 2753 2754
                    res => if fin_res.is_none() { fin_res = res },
                };
            }
        }
2755
        let is_global = self.global_macros.get(&path[0].node.name).cloned()
2756
            .map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
2757 2758
        if primary_ns != MacroNS && (is_global ||
                                     self.macro_names.contains(&path[0].node.modern())) {
2759
            // Return some dummy definition, it's enough for error reporting.
J
Josh Driver 已提交
2760 2761 2762
            return Some(
                PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
            );
2763 2764 2765 2766 2767 2768 2769 2770
        }
        fin_res
    }

    /// Handles paths that may refer to associated items.
    fn resolve_qpath(&mut self,
                     id: NodeId,
                     qself: Option<&QSelf>,
2771
                     path: &[SpannedIdent],
2772 2773 2774 2775 2776
                     ns: Namespace,
                     span: Span,
                     global_by_default: bool)
                     -> Option<PathResolution> {
        if let Some(qself) = qself {
J
Jeffrey Seyfried 已提交
2777 2778
            if qself.position == 0 {
                // FIXME: Create some fake resolution that can't possibly be a type.
2779 2780 2781
                return Some(PathResolution::with_unresolved_segments(
                    Def::Mod(DefId::local(CRATE_DEF_INDEX)), path.len()
                ));
2782
            }
2783 2784
            // 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 };
2785
            let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1],
2786
                                                       span, span, PathSource::TraitItem(ns));
2787 2788 2789
            return Some(PathResolution::with_unresolved_segments(
                res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1
            ));
2790 2791
        }

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

                        }
                    }
                    _ => {}
                }
2825
                PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
J
Jeffrey Seyfried 已提交
2826 2827
            }
            PathResult::Module(module) => PathResolution::new(module.def().unwrap()),
2828
            PathResult::Failed(span, msg, false) => {
J
Jeffrey Seyfried 已提交
2829 2830 2831
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
                err_path_resolution()
            }
2832 2833
            PathResult::Failed(..) => return None,
            PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
J
Jeffrey Seyfried 已提交
2834 2835
        };

2836
        if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
2837 2838
           path[0].node.name != keywords::CrateRoot.name() &&
           path[0].node.name != keywords::DollarCrate.name() {
2839
            let unqualified_result = {
2840
                match self.resolve_path(&[*path.last().unwrap()], Some(ns), false, span) {
2841
                    PathResult::NonModule(path_res) => path_res.base_def(),
2842 2843 2844 2845
                    PathResult::Module(module) => module.def().unwrap(),
                    _ => return Some(result),
                }
            };
2846
            if result.base_def() == unqualified_result {
2847
                let lint = lint::builtin::UNUSED_QUALIFICATIONS;
2848
                self.session.buffer_lint(lint, id, span, "unnecessary qualification")
N
Nick Cameron 已提交
2849
            }
2850
        }
N
Nick Cameron 已提交
2851

J
Jeffrey Seyfried 已提交
2852
        Some(result)
2853 2854
    }

J
Jeffrey Seyfried 已提交
2855
    fn resolve_path(&mut self,
2856
                    path: &[SpannedIdent],
J
Jeffrey Seyfried 已提交
2857
                    opt_ns: Option<Namespace>, // `None` indicates a module path
2858 2859
                    record_used: bool,
                    path_span: Span)
J
Jeffrey Seyfried 已提交
2860
                    -> PathResult<'a> {
2861 2862
        let mut module = None;
        let mut allow_super = true;
J
Jeffrey Seyfried 已提交
2863 2864

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

2869 2870
            if i == 0 && ns == TypeNS && ident.node.name == keywords::SelfValue.name() {
                let mut ctxt = ident.node.ctxt.modern();
J
Jeffrey Seyfried 已提交
2871
                module = Some(self.resolve_self(&mut ctxt, self.current_module));
J
Jeffrey Seyfried 已提交
2872
                continue
2873 2874
            } else if allow_super && ns == TypeNS && ident.node.name == keywords::Super.name() {
                let mut ctxt = ident.node.ctxt.modern();
J
Jeffrey Seyfried 已提交
2875 2876 2877 2878
                let self_module = match i {
                    0 => self.resolve_self(&mut ctxt, self.current_module),
                    _ => module.unwrap(),
                };
J
Jeffrey Seyfried 已提交
2879
                if let Some(parent) = self_module.parent {
J
Jeffrey Seyfried 已提交
2880
                    module = Some(self.resolve_self(&mut ctxt, parent));
J
Jeffrey Seyfried 已提交
2881 2882 2883
                    continue
                } else {
                    let msg = "There are too many initial `super`s.".to_string();
2884
                    return PathResult::Failed(ident.span, msg, false);
J
Jeffrey Seyfried 已提交
2885 2886 2887 2888
                }
            }
            allow_super = false;

2889 2890
            if i == 0 && ns == TypeNS && ident.node.name == keywords::CrateRoot.name() {
                module = Some(self.resolve_crate_root(ident.node.ctxt.modern()));
2891
                continue
2892 2893
            } else if i == 0 && ns == TypeNS && ident.node.name == keywords::DollarCrate.name() {
                module = Some(self.resolve_crate_root(ident.node.ctxt));
2894 2895 2896
                continue
            }

J
Jeffrey Seyfried 已提交
2897
            let binding = if let Some(module) = module {
2898
                self.resolve_ident_in_module(module, ident.node, ns, false, record_used, path_span)
2899
            } else if opt_ns == Some(MacroNS) {
2900
                self.resolve_lexical_macro_path_segment(ident.node, ns, record_used, path_span)
2901
                    .map(MacroBinding::binding)
J
Jeffrey Seyfried 已提交
2902
            } else {
2903
                match self.resolve_ident_in_lexical_scope(ident.node, ns, record_used, path_span) {
J
Jeffrey Seyfried 已提交
2904
                    Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
2905 2906
                    Some(LexicalScopeBinding::Def(def))
                            if opt_ns == Some(TypeNS) || opt_ns == Some(ValueNS) => {
2907 2908 2909
                        return PathResult::NonModule(PathResolution::with_unresolved_segments(
                            def, path.len() - 1
                        ));
J
Jeffrey Seyfried 已提交
2910
                    }
2911
                    _ => Err(if record_used { Determined } else { Undetermined }),
J
Jeffrey Seyfried 已提交
2912 2913 2914 2915 2916
                }
            };

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

2962
        PathResult::Module(module.unwrap_or(self.graph_root))
2963 2964 2965
    }

    // Resolve a local definition, potentially adjusting for closures.
2966 2967 2968 2969
    fn adjust_local_def(&mut self,
                        ns: Namespace,
                        rib_index: usize,
                        mut def: Def,
2970 2971
                        record_used: bool,
                        span: Span) -> Def {
2972 2973 2974 2975
        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 {
2976
            if record_used {
2977
                resolve_error(self, span, ResolutionError::ForwardDeclaredTyParam);
2978 2979 2980 2981 2982
            }
            assert_eq!(def, Def::Err);
            return Def::Err;
        }

2983
        match def {
2984
            Def::Upvar(..) => {
2985
                span_bug!(span, "unexpected {:?} in bindings", def)
2986
            }
2987
            Def::Local(node_id) => {
2988 2989
                for rib in ribs {
                    match rib.kind {
2990 2991
                        NormalRibKind | ModuleRibKind(..) | MacroDefinition(..) |
                        ForwardTyParamBanRibKind => {
2992 2993 2994 2995 2996
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;

C
corentih 已提交
2997 2998 2999
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
3000
                            if let Some(&index) = seen.get(&node_id) {
3001
                                def = Def::Upvar(node_id, index, function_id);
3002 3003
                                continue;
                            }
C
corentih 已提交
3004 3005 3006
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
3007
                            let depth = vec.len();
3008
                            def = Def::Upvar(node_id, depth, function_id);
3009

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

3064
    fn lookup_assoc_candidate<FilterFn>(&mut self,
3065
                                        ident: Ident,
3066 3067 3068 3069 3070
                                        ns: Namespace,
                                        filter_fn: FilterFn)
                                        -> Option<AssocSuggestion>
        where FilterFn: Fn(Def) -> bool
    {
3071
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
3072
            match t.node {
3073 3074
                TyKind::Path(None, _) => Some(t.id),
                TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
3075 3076 3077 3078 3079 3080 3081
                // 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,
            }
        }

3082
        // Fields are generally expected in the same contexts as locals.
3083
        if filter_fn(Def::Local(ast::DUMMY_NODE_ID)) {
3084 3085 3086
            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) {
3087 3088 3089
                    match resolution.base_def() {
                        Def::Struct(did) | Def::Union(did)
                                if resolution.unresolved_segments() == 0 => {
3090
                            if let Some(field_names) = self.field_names.get(&did) {
3091
                                if field_names.iter().any(|&field_name| ident.name == field_name) {
3092 3093
                                    return Some(AssocSuggestion::Field);
                                }
3094
                            }
3095
                        }
3096
                        _ => {}
3097
                    }
3098
                }
3099
            }
3100 3101
        }

3102
        // Look for associated items in the current trait.
3103 3104 3105 3106
        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();
3107
                if filter_fn(def) {
3108
                    return Some(if self.has_self.contains(&def.def_id()) {
3109 3110 3111 3112
                        AssocSuggestion::MethodWithSelf
                    } else {
                        AssocSuggestion::AssocItem
                    });
3113 3114 3115 3116
                }
            }
        }

3117
        None
3118 3119
    }

3120
    fn lookup_typo_candidate<FilterFn>(&mut self,
3121
                                       path: &[SpannedIdent],
3122
                                       ns: Namespace,
3123 3124
                                       filter_fn: FilterFn,
                                       span: Span)
3125
                                       -> Option<Symbol>
3126 3127
        where FilterFn: Fn(Def) -> bool
    {
3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138
        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();
3139
        if path.len() == 1 {
3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175
            // 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];
3176 3177
            if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS),
                                                                  false, span) {
3178 3179
                add_module_candidates(module, &mut names);
            }
3180
        }
3181

3182
        let name = path[path.len() - 1].node.name;
3183 3184 3185
        // 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) {
3186
            Some(found) if found != name => Some(found),
3187
            _ => None,
3188
        }
3189 3190
    }

3191 3192 3193
    fn with_resolved_label<F>(&mut self, label: Option<SpannedIdent>, id: NodeId, f: F)
        where F: FnOnce(&mut Resolver)
    {
3194
        if let Some(label) = label {
3195
            let def = Def::Label(id);
3196
            self.with_label_rib(|this| {
J
Jeffrey Seyfried 已提交
3197
                this.label_ribs.last_mut().unwrap().bindings.insert(label.node, def);
3198
                f(this);
3199 3200
            });
        } else {
3201
            f(self);
3202 3203 3204
        }
    }

3205 3206 3207 3208
    fn resolve_labeled_block(&mut self, label: Option<SpannedIdent>, id: NodeId, block: &Block) {
        self.with_resolved_label(label, id, |this| this.visit_block(block));
    }

3209
    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
P
Patrick Walton 已提交
3210 3211
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3212 3213 3214

        self.record_candidate_traits_for_expr_if_necessary(expr);

3215
        // Next, resolve the node.
3216
        match expr.node {
3217 3218
            ExprKind::Path(ref qself, ref path) => {
                self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent));
3219
                visit::walk_expr(self, expr);
3220 3221
            }

V
Vadim Petrochenkov 已提交
3222
            ExprKind::Struct(ref path, ..) => {
3223
                self.smart_resolve_path(expr.id, None, path, PathSource::Struct);
3224
                visit::walk_expr(self, expr);
3225 3226
            }

3227
            ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
3228
                match self.search_label(label.node, |rib, id| rib.bindings.get(&id).cloned()) {
3229
                    None => {
3230 3231 3232 3233 3234 3235 3236
                        // 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)
                        });
3237
                        self.record_def(expr.id, err_path_resolution());
3238
                        resolve_error(self,
3239
                                      label.span,
3240 3241
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str(),
                                                                       close_match));
3242
                    }
3243
                    Some(def @ Def::Label(_)) => {
3244
                        // Since this def is a label, it is never read.
3245
                        self.record_def(expr.id, PathResolution::new(def));
3246 3247
                    }
                    Some(_) => {
3248
                        span_bug!(expr.span, "label wasn't mapped to a label def!");
3249 3250
                    }
                }
3251 3252 3253

                // visit `break` argument if any
                visit::walk_expr(self, expr);
3254
            }
3255 3256 3257 3258

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

J
Jeffrey Seyfried 已提交
3259
                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
3260
                self.resolve_pattern(pattern, PatternSource::IfLet, &mut FxHashMap());
3261
                self.visit_block(if_block);
J
Jeffrey Seyfried 已提交
3262
                self.ribs[ValueNS].pop();
3263 3264 3265 3266

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

J
Jeffrey Seyfried 已提交
3267 3268 3269
            ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block),

            ExprKind::While(ref subexpression, ref block, label) => {
3270 3271 3272 3273
                self.with_resolved_label(label, expr.id, |this| {
                    this.visit_expr(subexpression);
                    this.visit_block(block);
                });
J
Jeffrey Seyfried 已提交
3274 3275
            }

3276
            ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => {
3277 3278
                self.with_resolved_label(label, expr.id, |this| {
                    this.visit_expr(subexpression);
3279
                    this.ribs[ValueNS].push(Rib::new(NormalRibKind));
3280 3281
                    this.resolve_pattern(pattern, PatternSource::WhileLet, &mut FxHashMap());
                    this.visit_block(block);
3282
                    this.ribs[ValueNS].pop();
3283
                });
3284 3285 3286 3287
            }

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

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

J
Jeffrey Seyfried 已提交
3293
                self.ribs[ValueNS].pop();
3294 3295
            }

3296
            // Equivalent to `visit::walk_expr` + passing some context to children.
3297
            ExprKind::Field(ref subexpression, _) => {
3298
                self.resolve_expr(subexpression, Some(expr));
3299
            }
3300
            ExprKind::MethodCall(ref segment, ref arguments) => {
3301
                let mut arguments = arguments.iter();
3302
                self.resolve_expr(arguments.next().unwrap(), Some(expr));
3303 3304 3305
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
3306
                self.visit_path_segment(expr.span, segment);
3307
            }
3308 3309 3310 3311 3312 3313 3314

            ExprKind::Repeat(ref element, ref count) => {
                self.visit_expr(element);
                self.with_constant_rib(|this| {
                    this.visit_expr(count);
                });
            }
3315
            ExprKind::Call(ref callee, ref arguments) => {
3316
                self.resolve_expr(callee, Some(expr));
3317 3318 3319 3320
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
            }
3321 3322 3323 3324 3325
            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 已提交
3326
            _ => {
3327
                visit::walk_expr(self, expr);
3328 3329 3330 3331
            }
        }
    }

E
Eduard Burtescu 已提交
3332
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3333
        match expr.node {
3334
            ExprKind::Field(_, name) => {
3335 3336 3337 3338
                // 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.
3339
                let traits = self.get_traits_containing_item(name.node, ValueNS);
3340
                self.trait_map.insert(expr.id, traits);
3341
            }
3342
            ExprKind::MethodCall(ref segment, ..) => {
C
corentih 已提交
3343
                debug!("(recording candidate traits for expr) recording traits for {}",
3344
                       expr.id);
3345
                let traits = self.get_traits_containing_item(segment.identifier, ValueNS);
3346
                self.trait_map.insert(expr.id, traits);
3347
            }
3348
            _ => {
3349 3350 3351 3352 3353
                // Nothing to do.
            }
        }
    }

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

3358
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3359
        // Look for the current trait.
3360 3361 3362 3363
        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 已提交
3364
            }
J
Jeffrey Seyfried 已提交
3365
        }
3366

J
Jeffrey Seyfried 已提交
3367
        ident.ctxt = ident.ctxt.modern();
J
Jeffrey Seyfried 已提交
3368 3369
        let mut search_module = self.current_module;
        loop {
3370
            self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
J
Jeffrey Seyfried 已提交
3371 3372
            search_module =
                unwrap_or!(self.hygienic_lexical_parent(search_module, &mut ident.ctxt), break);
3373
        }
3374

3375 3376
        if let Some(prelude) = self.prelude {
            if !search_module.no_implicit_prelude {
3377
                self.get_traits_in_module_containing_item(ident, ns, prelude, &mut found_traits);
E
Eduard Burtescu 已提交
3378
            }
3379 3380
        }

E
Eduard Burtescu 已提交
3381
        found_traits
3382 3383
    }

3384
    fn get_traits_in_module_containing_item(&mut self,
3385
                                            ident: Ident,
3386
                                            ns: Namespace,
3387
                                            module: Module<'a>,
3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401
                                            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() {
3402
            let module = binding.module().unwrap();
J
Jeffrey Seyfried 已提交
3403
            let mut ident = ident;
3404
            if ident.ctxt.glob_adjust(module.expansion, binding.span.ctxt().modern()).is_none() {
J
Jeffrey Seyfried 已提交
3405 3406 3407 3408
                continue
            }
            if self.resolve_ident_in_module_unadjusted(module, ident, ns, false, false, module.span)
                   .is_ok() {
3409 3410 3411 3412 3413 3414 3415 3416
                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,
                };
3417
                let trait_def_id = module.def_id().unwrap();
3418 3419 3420 3421 3422
                found_traits.push(TraitCandidate { def_id: trait_def_id, import_id: import_id });
            }
        }
    }

3423 3424 3425 3426 3427 3428 3429
    /// 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).
3430 3431 3432 3433 3434 3435 3436 3437
    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();
3438
        let mut worklist = Vec::new();
3439
        let mut seen_modules = FxHashSet();
3440 3441 3442 3443 3444
        worklist.push((self.graph_root, Vec::new(), false));

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

3447 3448 3449
            // 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| {
3450
                // avoid imports entirely
3451
                if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
3452 3453
                // avoid non-importable candidates as well
                if !name_binding.is_importable() { return; }
3454 3455

                // collect results based on the filter function
3456
                if ident.name == lookup_name && ns == namespace {
3457
                    if filter_fn(name_binding.def()) {
3458 3459
                        // create the path
                        let mut segms = path_segments.clone();
3460
                        segms.push(ast::PathSegment::from_ident(ident, name_binding.span));
3461
                        let path = Path {
3462
                            span: name_binding.span,
3463 3464 3465 3466 3467 3468 3469 3470 3471
                            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)
3472
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3473
                            candidates.push(ImportSuggestion { path: path });
3474 3475 3476 3477 3478
                        }
                    }
                }

                // collect submodules to explore
J
Jeffrey Seyfried 已提交
3479
                if let Some(module) = name_binding.module() {
3480
                    // form the path
3481
                    let mut path_segments = path_segments.clone();
3482
                    path_segments.push(ast::PathSegment::from_ident(ident, name_binding.span));
3483

3484
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3485
                        // add the module to the lookup
3486
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3487
                        if seen_modules.insert(module.def_id().unwrap()) {
3488 3489
                            worklist.push((module, path_segments, is_extern));
                        }
3490 3491 3492 3493 3494
                    }
                }
            })
        }

3495
        candidates
3496 3497
    }

3498 3499
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
3500
        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
3501
            panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
3502
        }
3503 3504
    }

3505
    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
3506 3507 3508
        match *vis {
            ast::Visibility::Public => ty::Visibility::Public,
            ast::Visibility::Crate(..) => ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
3509
            ast::Visibility::Inherited => {
3510
                ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
3511
            }
3512
            ast::Visibility::Restricted { ref path, id } => {
3513 3514
                let def = self.smart_resolve_path(id, None, path,
                                                  PathSource::Visibility).base_def();
3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526
                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
                    }
                }
3527 3528 3529 3530
            }
        }
    }

3531
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
3532
        vis.is_accessible_from(self.current_module.normal_ancestor_id, self)
3533 3534
    }

3535
    fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
3536
        vis.is_accessible_from(module.normal_ancestor_id, self)
3537 3538
    }

3539
    fn report_errors(&mut self, krate: &Crate) {
3540
        self.report_shadowing_errors();
3541
        self.report_with_use_injections(krate);
3542
        let mut reported_spans = FxHashSet();
3543

3544
        for &AmbiguityError { span, name, b1, b2, lexical, legacy } in &self.ambiguity_errors {
3545
            if !reported_spans.insert(span) { continue }
3546 3547 3548
            let participle = |binding: &NameBinding| {
                if binding.is_import() { "imported" } else { "defined" }
            };
3549 3550
            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));
3551
            let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568
                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);
3569
                self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg);
3570
            } else {
3571 3572 3573 3574 3575 3576 3577 3578 3579
                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();
3580
            }
3581 3582
        }

3583 3584
        for &PrivacyError(span, name, binding) in &self.privacy_errors {
            if !reported_spans.insert(span) { continue }
G
Guillaume Gomez 已提交
3585
            span_err!(self.session, span, E0603, "{} `{}` is private", binding.descr(), name);
3586 3587
        }
    }
3588

3589 3590 3591 3592 3593
    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,
3594
                found_use: false,
3595 3596 3597
            };
            visit::walk_crate(&mut finder, krate);
            if !candidates.is_empty() {
3598
                show_candidates(&mut err, finder.span, &candidates, better, finder.found_use);
3599 3600 3601 3602 3603
            }
            err.emit();
        }
    }

3604
    fn report_shadowing_errors(&mut self) {
J
Jeffrey Seyfried 已提交
3605 3606
        for (ident, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
            self.resolve_legacy_scope(scope, ident, true);
J
Jeffrey Seyfried 已提交
3607 3608
        }

3609
        let mut reported_errors = FxHashSet();
3610
        for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
J
Jeffrey Seyfried 已提交
3611 3612 3613
            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);
3614
                self.session.struct_span_err(binding.span, &msg)
3615 3616
                    .note("macro-expanded `macro_rules!`s may not shadow \
                           existing macros (see RFC 1560)")
3617 3618 3619 3620 3621
                    .emit();
            }
        }
    }

C
Cldfire 已提交
3622
    fn report_conflict<'b>(&mut self,
3623
                       parent: Module,
3624
                       ident: Ident,
3625
                       ns: Namespace,
C
Cldfire 已提交
3626 3627
                       new_binding: &NameBinding<'b>,
                       old_binding: &NameBinding<'b>) {
3628
        // Error on the second of two conflicting names
3629
        if old_binding.span.lo() > new_binding.span.lo() {
3630
            return self.report_conflict(parent, ident, ns, old_binding, new_binding);
3631 3632
        }

J
Jeffrey Seyfried 已提交
3633 3634 3635 3636
        let container = match parent.kind {
            ModuleKind::Def(Def::Mod(_), _) => "module",
            ModuleKind::Def(Def::Trait(_), _) => "trait",
            ModuleKind::Block(..) => "block",
3637 3638 3639
            _ => "enum",
        };

3640 3641 3642
        let old_noun = match old_binding.is_import() {
            true => "import",
            false => "definition",
3643 3644
        };

3645 3646 3647 3648 3649 3650
        let new_participle = match new_binding.is_import() {
            true => "imported",
            false => "defined",
        };

        let (name, span) = (ident.name, new_binding.span);
3651 3652 3653 3654 3655 3656 3657

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

3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670
        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",
3671 3672
        };

3673 3674 3675
        let msg = format!("the name `{}` is defined multiple times", name);

        let mut err = match (old_binding.is_extern_crate(), new_binding.is_extern_crate()) {
3676
            (true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
3677
            (true, _) | (_, true) => match new_binding.is_import() && old_binding.is_import() {
3678 3679
                true => struct_span_err!(self.session, span, E0254, "{}", msg),
                false => struct_span_err!(self.session, span, E0260, "{}", msg),
M
Mohit Agarwal 已提交
3680
            },
3681
            _ => match (old_binding.is_import(), new_binding.is_import()) {
3682 3683 3684
                (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),
3685 3686 3687
            },
        };

3688 3689 3690 3691 3692 3693
        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));
3694
        if old_binding.span != syntax_pos::DUMMY_SP {
3695 3696
            err.span_label(old_binding.span, format!("previous {} of the {} `{}` here",
                                                      old_noun, old_kind, name));
3697
        }
3698

C
Cldfire 已提交
3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709
        // 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";

3710 3711
            if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span),
                                           binding.is_renamed_extern_crate()) {
C
Cldfire 已提交
3712 3713 3714 3715 3716 3717 3718 3719
                err.span_suggestion(binding.span,
                                    rename_msg,
                                    format!("{} as Other{}", snippet, name));
            } else {
                err.span_label(binding.span, rename_msg);
            }
        }

3720
        err.emit();
3721
        self.name_already_seen.insert(name, span);
3722
    }
J
Jeffrey Seyfried 已提交
3723 3724 3725

    fn warn_legacy_self_import(&self, directive: &'a ImportDirective<'a>) {
        let (id, span) = (directive.id, directive.span);
3726 3727
        let msg = "`self` no longer imports values";
        self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, msg);
J
Jeffrey Seyfried 已提交
3728
    }
3729 3730 3731 3732 3733

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

        for attr in attrs {
3734 3735 3736 3737
            if attr.path.segments.len() > 1 {
                continue
            }
            let ident = attr.path.segments[0].identifier;
3738 3739 3740 3741
            let result = self.resolve_lexical_macro_path_segment(ident,
                                                                 MacroNS,
                                                                 false,
                                                                 attr.path.span);
3742 3743
            if let Ok(binding) = result {
                if let SyntaxExtension::AttrProcMacro(..) = *binding.binding().get_macro(self) {
3744 3745 3746 3747 3748 3749 3750
                    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)
3751
                        .span_note(binding.span(), "procedural macro imported here")
3752 3753 3754 3755 3756
                        .emit();
                }
            }
        }
    }
3757
}
3758

3759 3760 3761 3762 3763 3764 3765
fn is_struct_like(def: Def) -> bool {
    match def {
        Def::VariantCtor(_, CtorKind::Fictive) => true,
        _ => PathSource::Struct.is_expected(def),
    }
}

3766 3767
fn is_self_type(path: &[SpannedIdent], namespace: Namespace) -> bool {
    namespace == TypeNS && path.len() == 1 && path[0].node.name == keywords::SelfType.name()
3768 3769
}

3770 3771
fn is_self_value(path: &[SpannedIdent], namespace: Namespace) -> bool {
    namespace == ValueNS && path.len() == 1 && path[0].node.name == keywords::SelfValue.name()
3772 3773
}

3774
fn names_to_string(idents: &[SpannedIdent]) -> String {
3775
    let mut result = String::new();
3776 3777 3778
    for (i, ident) in idents.iter()
                            .filter(|i| i.node.name != keywords::CrateRoot.name())
                            .enumerate() {
3779 3780 3781
        if i > 0 {
            result.push_str("::");
        }
3782
        result.push_str(&ident.node.name.as_str());
C
corentih 已提交
3783
    }
3784 3785 3786
    result
}

3787
fn path_names_to_string(path: &Path) -> String {
3788 3789 3790
    names_to_string(&path.segments.iter()
                        .map(|seg| respan(seg.span, seg.identifier))
                        .collect::<Vec<_>>())
3791 3792
}

3793
/// Get the path for an enum and the variant from an `ImportSuggestion` for an enum variant.
E
Esteban Küber 已提交
3794
fn import_candidate_to_paths(suggestion: &ImportSuggestion) -> (Span, String, String) {
3795 3796 3797 3798 3799 3800 3801 3802 3803 3804
    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 已提交
3805
    (suggestion.path.span, variant_path_string, enum_path_string)
3806 3807 3808
}


3809 3810 3811
/// 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
3812
fn show_candidates(err: &mut DiagnosticBuilder,
3813 3814
                   // This is `None` if all placement locations are inside expansions
                   span: Option<Span>,
3815
                   candidates: &[ImportSuggestion],
3816 3817
                   better: bool,
                   found_use: bool) {
3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828

    // 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",
3829
    };
3830 3831
    let msg = format!("possible {}candidate{} into scope", better, msg_diff);

3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842
    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);
        }
3843

3844 3845 3846 3847 3848 3849 3850 3851 3852
        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);
        }
    }
3853 3854
}

3855
/// A somewhat inefficient routine to obtain the name of a module.
3856
fn module_to_string(module: Module) -> String {
3857 3858
    let mut names = Vec::new();

3859
    fn collect_mod(names: &mut Vec<Ident>, module: Module) {
J
Jeffrey Seyfried 已提交
3860 3861
        if let ModuleKind::Def(_, name) = module.kind {
            if let Some(parent) = module.parent {
3862
                names.push(Ident::with_empty_ctxt(name));
J
Jeffrey Seyfried 已提交
3863
                collect_mod(names, parent);
3864
            }
J
Jeffrey Seyfried 已提交
3865 3866
        } else {
            // danger, shouldn't be ident?
3867
            names.push(Ident::from_str("<opaque>"));
J
Jeffrey Seyfried 已提交
3868
            collect_mod(names, module.parent.unwrap());
3869 3870 3871 3872
        }
    }
    collect_mod(&mut names, module);

3873
    if names.is_empty() {
3874 3875
        return "???".to_string();
    }
3876 3877 3878 3879
    names_to_string(&names.into_iter()
                        .rev()
                        .map(|n| dummy_spanned(n))
                        .collect::<Vec<_>>())
3880 3881
}

3882
fn err_path_resolution() -> PathResolution {
3883
    PathResolution::new(Def::Err)
3884 3885
}

N
Niko Matsakis 已提交
3886
#[derive(PartialEq,Copy, Clone)]
3887 3888
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3889
    No,
3890 3891
}

3892
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }