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

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

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

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

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

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

56
use syntax::ext::mtwt;
57
use syntax::ast::{self, FloatTy};
58
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
59
use syntax::parse::token::{self, keywords};
60
use syntax::util::lev_distance::find_best_match_for_name;
61

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

69 70 71
use syntax_pos::Span;
use errors::DiagnosticBuilder;

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

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

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

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

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

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

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

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

    /// `Other` means we have no extra information about the context
    /// of the unresolved name error. (Maybe we could eliminate all
    /// such cases; but for now, this is an information-free default.)
179 180 181
    Other,
}

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

188
fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
189
                                        span: syntax_pos::Span,
190 191
                                        resolution_error: ResolutionError<'c>)
                                        -> DiagnosticBuilder<'a> {
192
    if !resolver.emit_errors {
N
Nick Cameron 已提交
193
        return resolver.session.diagnostic().struct_dummy();
194
    }
N
Nick Cameron 已提交
195

N
Nick Cameron 已提交
196
    match resolution_error {
197
        ResolutionError::TypeParametersFromOuterFunction => {
198 199 200 201 202
            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");
203
            err.span_label(span, &format!("use of type variable from outer function"));
204
            err
C
corentih 已提交
205
        }
206
        ResolutionError::OuterTypeParameterContext => {
N
Nick Cameron 已提交
207 208 209 210
            struct_span_err!(resolver.session,
                             span,
                             E0402,
                             "cannot use an outer type parameter in this context")
C
corentih 已提交
211
        }
212
        ResolutionError::NameAlreadyUsedInTypeParameterList(name) => {
N
Nick Cameron 已提交
213 214 215 216 217 218
            struct_span_err!(resolver.session,
                             span,
                             E0403,
                             "the name `{}` is already used for a type parameter in this type \
                              parameter list",
                             name)
C
corentih 已提交
219
        }
220
        ResolutionError::IsNotATrait(name) => {
N
Nick Cameron 已提交
221
            struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
C
corentih 已提交
222
        }
223 224 225 226 227 228
        ResolutionError::UndeclaredTraitName(name, candidates) => {
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0405,
                                           "trait `{}` is not in scope",
                                           name);
229
            show_candidates(&mut err, &candidates);
230
            err.span_label(span, &format!("`{}` is not in scope", name));
231
            err
C
corentih 已提交
232
        }
233
        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
N
Nick Cameron 已提交
234 235 236 237 238 239
            struct_span_err!(resolver.session,
                             span,
                             E0407,
                             "method `{}` is not a member of trait `{}`",
                             method,
                             trait_)
C
corentih 已提交
240
        }
241
        ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
N
Nick Cameron 已提交
242 243 244 245 246 247
            struct_span_err!(resolver.session,
                             span,
                             E0437,
                             "type `{}` is not a member of trait `{}`",
                             type_,
                             trait_)
C
corentih 已提交
248
        }
249
        ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
N
Nick Cameron 已提交
250 251 252 253 254 255
            struct_span_err!(resolver.session,
                             span,
                             E0438,
                             "const `{}` is not a member of trait `{}`",
                             const_,
                             trait_)
C
corentih 已提交
256
        }
M
Manish Goregaokar 已提交
257
        ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => {
N
Nick Cameron 已提交
258 259 260
            struct_span_err!(resolver.session,
                             span,
                             E0408,
M
Manish Goregaokar 已提交
261
                             "variable `{}` from pattern #{} is not bound in pattern #{}",
N
Nick Cameron 已提交
262
                             variable_name,
M
Manish Goregaokar 已提交
263 264
                             from,
                             to)
C
corentih 已提交
265
        }
266
        ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
N
Nick Cameron 已提交
267 268 269 270 271 272 273
            struct_span_err!(resolver.session,
                             span,
                             E0409,
                             "variable `{}` is bound with different mode in pattern #{} than in \
                              pattern #1",
                             variable_name,
                             pattern_number)
C
corentih 已提交
274
        }
275
        ResolutionError::SelfUsedOutsideImplOrTrait => {
276 277 278 279
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0411,
                                           "use of `Self` outside of an impl or trait");
J
Jonathan Turner 已提交
280
            err.span_label(span, &format!("used outside of impl or trait"));
281
            err
C
corentih 已提交
282
        }
283 284 285 286 287 288 289
        ResolutionError::UseOfUndeclared(kind, name, candidates) => {
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0412,
                                           "{} `{}` is undefined or not in scope",
                                           kind,
                                           name);
290
            show_candidates(&mut err, &candidates);
291
            err.span_label(span, &format!("undefined or not in scope"));
292
            err
C
corentih 已提交
293
        }
294
        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
295
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
296 297 298
                             span,
                             E0415,
                             "identifier `{}` is bound more than once in this parameter list",
299
                             identifier);
300
            err.span_label(span, &format!("used as parameter more than once"));
301
            err
C
corentih 已提交
302
        }
303
        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
304
            let mut err = struct_span_err!(resolver.session,
N
Nick Cameron 已提交
305 306 307
                             span,
                             E0416,
                             "identifier `{}` is bound more than once in the same pattern",
308
                             identifier);
309
            err.span_label(span, &format!("used in a pattern more than once"));
310
            err
C
corentih 已提交
311
        }
312
        ResolutionError::DoesNotNameAStruct(name) => {
N
Nick Cameron 已提交
313 314 315 316 317
            struct_span_err!(resolver.session,
                             span,
                             E0422,
                             "`{}` does not name a structure",
                             name)
C
corentih 已提交
318
        }
319
        ResolutionError::StructVariantUsedAsFunction(path_name) => {
N
Nick Cameron 已提交
320 321 322 323 324 325
            struct_span_err!(resolver.session,
                             span,
                             E0423,
                             "`{}` is the name of a struct or struct variant, but this expression \
                             uses it like a function name",
                             path_name)
C
corentih 已提交
326
        }
327
        ResolutionError::SelfNotAvailableInStaticMethod => {
N
Nick Cameron 已提交
328 329 330 331 332
            struct_span_err!(resolver.session,
                             span,
                             E0424,
                             "`self` is not available in a static method. Maybe a `self` \
                             argument is missing?")
C
corentih 已提交
333
        }
334
        ResolutionError::UnresolvedName { path, message: msg, context, is_static_method,
G
ggomez 已提交
335
                                          is_field, def } => {
N
Nick Cameron 已提交
336 337 338 339 340 341
            let mut err = struct_span_err!(resolver.session,
                                           span,
                                           E0425,
                                           "unresolved name `{}`{}",
                                           path,
                                           msg);
342
            match context {
343 344 345 346 347 348
                UnresolvedNameContext::Other => {
                    if msg.is_empty() && is_static_method && is_field {
                        err.help("this is an associated function, you don't have access to \
                                  this type's fields or methods");
                    }
                }
349
                UnresolvedNameContext::PathIsMod(parent) => {
350
                    err.help(&match parent.map(|parent| &parent.node) {
351
                        Some(&ExprKind::Field(_, ident)) => {
G
ggomez 已提交
352
                            format!("to reference an item from the `{module}` module, \
353 354 355
                                     use `{module}::{ident}`",
                                    module = path,
                                    ident = ident.node)
356
                        }
357
                        Some(&ExprKind::MethodCall(ident, _, _)) => {
G
ggomez 已提交
358
                            format!("to call a function from the `{module}` module, \
359 360 361 362 363
                                     use `{module}::{ident}(..)`",
                                    module = path,
                                    ident = ident.node)
                        }
                        _ => {
G
ggomez 已提交
364 365
                            format!("{def} `{module}` cannot be used as an expression",
                                    def = def.kind_name(),
366 367 368
                                    module = path)
                        }
                    });
369 370
                }
            }
N
Nick Cameron 已提交
371
            err
C
corentih 已提交
372
        }
373
        ResolutionError::UndeclaredLabel(name) => {
N
Nick Cameron 已提交
374 375 376 377 378
            struct_span_err!(resolver.session,
                             span,
                             E0426,
                             "use of undeclared label `{}`",
                             name)
C
corentih 已提交
379
        }
380
        ResolutionError::SelfImportsOnlyAllowedWithin => {
N
Nick Cameron 已提交
381 382 383 384 385
            struct_span_err!(resolver.session,
                             span,
                             E0429,
                             "{}",
                             "`self` imports are only allowed within a { } list")
C
corentih 已提交
386
        }
387
        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
N
Nick Cameron 已提交
388 389 390 391
            struct_span_err!(resolver.session,
                             span,
                             E0430,
                             "`self` import can only appear once in the list")
C
corentih 已提交
392
        }
393
        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
N
Nick Cameron 已提交
394 395 396 397 398
            struct_span_err!(resolver.session,
                             span,
                             E0431,
                             "`self` import can only appear in an import list with a \
                              non-empty prefix")
399
        }
400
        ResolutionError::UnresolvedImport(name) => {
401
            let msg = match name {
402
                Some((n, p)) => format!("unresolved import `{}`{}", n, p),
C
corentih 已提交
403
                None => "unresolved import".to_owned(),
404
            };
N
Nick Cameron 已提交
405
            struct_span_err!(resolver.session, span, E0432, "{}", msg)
C
corentih 已提交
406
        }
407
        ResolutionError::FailedToResolve(msg) => {
N
Nick Cameron 已提交
408
            struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg)
C
corentih 已提交
409
        }
410
        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
N
Nick Cameron 已提交
411 412 413 414 415 416
            struct_span_err!(resolver.session,
                             span,
                             E0434,
                             "{}",
                             "can't capture dynamic environment in a fn item; use the || { ... } \
                              closure form instead")
C
corentih 已提交
417 418
        }
        ResolutionError::AttemptToUseNonConstantValueInConstant => {
N
Nick Cameron 已提交
419 420 421 422
            struct_span_err!(resolver.session,
                             span,
                             E0435,
                             "attempt to use a non-constant value in a constant")
C
corentih 已提交
423
        }
424 425 426
        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => {
            let mut err = struct_span_err!(resolver.session,
                                           span,
427
                                           E0530,
428 429
                                           "{}s cannot shadow {}s", what_binding, shadows_what);
            err.span_label(span, &format!("cannot be named the same as a {}", shadows_what));
430
            if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
431 432 433 434 435 436 437 438 439
                let participle = if binding.is_import() { "imported" } else { "defined" };
                err.span_label(binding.span, &format!("a {} `{}` is {} here",
                                                      shadows_what, name, participle));
            }
            err
        }
        ResolutionError::PatPathUnresolved(expected_what, path) => {
            struct_span_err!(resolver.session,
                             span,
440
                             E0531,
441 442 443 444 445 446 447
                             "unresolved {} `{}`",
                             expected_what,
                             path.segments.last().unwrap().identifier)
        }
        ResolutionError::PatPathUnexpected(expected_what, found_what, path) => {
            struct_span_err!(resolver.session,
                             span,
448
                             E0532,
449 450 451 452 453
                             "expected {}, found {} `{}`",
                             expected_what,
                             found_what,
                             path.segments.last().unwrap().identifier)
        }
N
Nick Cameron 已提交
454
    }
455 456
}

N
Niko Matsakis 已提交
457
#[derive(Copy, Clone)]
458
struct BindingInfo {
459
    span: Span,
460
    binding_mode: BindingMode,
461 462 463
}

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

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum PatternSource {
    Match,
    IfLet,
    WhileLet,
    Let,
    For,
    FnParam,
}

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

N
Niko Matsakis 已提交
495
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
496
pub enum Namespace {
497
    TypeNS,
C
corentih 已提交
498
    ValueNS,
499 500
}

501
impl<'a> Visitor for Resolver<'a> {
502
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
503
        self.resolve_item(item);
504
    }
505
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
506
        self.resolve_arm(arm);
507
    }
508
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
509
        self.resolve_block(block);
510
    }
511
    fn visit_expr(&mut self, expr: &Expr) {
512
        self.resolve_expr(expr, None);
513
    }
514
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
515
        self.resolve_local(local);
516
    }
517
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
518
        self.resolve_type(ty);
519
    }
520
    fn visit_poly_trait_ref(&mut self, tref: &ast::PolyTraitRef, m: &ast::TraitBoundModifier) {
521 522
        match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) {
            Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
C
corentih 已提交
523 524
            Err(_) => {
                // error already reported
525
                self.record_def(tref.trait_ref.ref_id, err_path_resolution())
C
corentih 已提交
526
            }
527
        }
528
        visit::walk_poly_trait_ref(self, tref, m);
529
    }
C
corentih 已提交
530
    fn visit_variant(&mut self,
531
                     variant: &ast::Variant,
C
corentih 已提交
532 533
                     generics: &Generics,
                     item_id: ast::NodeId) {
534 535 536
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
537
                this.visit_expr(dis_expr);
538 539 540
            });
        }

541
        // `visit::walk_variant` without the discriminant expression.
C
corentih 已提交
542 543 544 545 546
        self.visit_variant_data(&variant.node.data,
                                variant.node.name,
                                generics,
                                item_id,
                                variant.span);
547
    }
548
    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
549
        let type_parameters = match foreign_item.node {
550
            ForeignItemKind::Fn(_, ref generics) => {
551 552
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
553
            ForeignItemKind::Static(..) => NoTypeParameters,
554 555
        };
        self.with_type_parameter_rib(type_parameters, |this| {
556
            visit::walk_foreign_item(this, foreign_item);
557 558 559
        });
    }
    fn visit_fn(&mut self,
560 561 562
                function_kind: FnKind,
                declaration: &FnDecl,
                block: &Block,
563 564 565
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
566
            FnKind::ItemFn(_, generics, _, _, _, _) => {
567 568 569
                self.visit_generics(generics);
                ItemRibKind
            }
570
            FnKind::Method(_, sig, _) => {
571
                self.visit_generics(&sig.generics);
V
Vadim Petrochenkov 已提交
572
                MethodRibKind(!sig.decl.has_self())
573
            }
574
            FnKind::Closure => ClosureRibKind(node_id),
575 576 577
        };
        self.resolve_function(rib_kind, declaration, block);
    }
578
}
579

580
pub type ErrorMessage = Option<(Span, String)>;
581

582
#[derive(Clone, PartialEq, Eq)]
583
pub enum ResolveResult<T> {
C
corentih 已提交
584 585 586
    Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
    Indeterminate, // Couldn't determine due to unresolved globs.
    Success(T), // Successfully resolved the import.
587 588
}

589
impl<T> ResolveResult<T> {
590 591 592 593 594
    fn and_then<U, F: FnOnce(T) -> ResolveResult<U>>(self, f: F) -> ResolveResult<U> {
        match self {
            Failed(msg) => Failed(msg),
            Indeterminate => Indeterminate,
            Success(t) => f(t),
C
corentih 已提交
595
        }
596
    }
597 598 599 600 601 602 603

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

606 607 608
enum FallbackSuggestion {
    NoSuggestion,
    Field,
609
    TraitItem,
610
    TraitMethod(String),
611 612
}

N
Niko Matsakis 已提交
613
#[derive(Copy, Clone)]
614
enum TypeParameters<'a, 'b> {
615
    NoTypeParameters,
C
corentih 已提交
616
    HasTypeParameters(// Type parameters.
617
                      &'b Generics,
618

C
corentih 已提交
619 620 621
                      // Identifies the things that these parameters
                      // were declared on (type, fn, etc)
                      ParamSpace,
622

C
corentih 已提交
623
                      // The kind of the rib used for type parameters.
624
                      RibKind<'a>),
625 626
}

627
// The rib kind controls the translation of local
628
// definitions (`Def::Local`) to upvars (`Def::Upvar`).
N
Niko Matsakis 已提交
629
#[derive(Copy, Clone, Debug)]
630
enum RibKind<'a> {
631 632
    // No translation needs to be applied.
    NormalRibKind,
633

634 635
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
636
    ClosureRibKind(NodeId /* func id */),
637

638
    // We passed through an impl or trait and are now in one of its
639
    // methods. Allow references to ty params that impl or trait
640 641
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
642 643 644
    //
    // The boolean value represents the fact that this method is static or not.
    MethodRibKind(bool),
645

646 647
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
648 649

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

652 653
    // We passed through a module.
    ModuleRibKind(Module<'a>),
654 655
}

N
Niko Matsakis 已提交
656
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
657
enum UseLexicalScopeFlag {
658
    DontUseLexicalScope,
C
corentih 已提交
659
    UseLexicalScope,
660 661
}

662
enum ModulePrefixResult<'a> {
663
    NoPrefixFound,
664
    PrefixFound(Module<'a>, usize),
665 666
}

667
/// One local scope.
J
Jorge Aparicio 已提交
668
#[derive(Debug)]
669
struct Rib<'a> {
670
    bindings: HashMap<Name, Def>,
671
    kind: RibKind<'a>,
B
Brian Anderson 已提交
672
}
673

674 675
impl<'a> Rib<'a> {
    fn new(kind: RibKind<'a>) -> Rib<'a> {
676
        Rib {
677
            bindings: HashMap::new(),
C
corentih 已提交
678
            kind: kind,
679
        }
680 681 682
    }
}

683 684 685
/// A definition along with the index of the rib it was found on
struct LocalDef {
    ribs: Option<(Namespace, usize)>,
C
corentih 已提交
686
    def: Def,
687 688 689 690 691 692
}

impl LocalDef {
    fn from_def(def: Def) -> Self {
        LocalDef {
            ribs: None,
C
corentih 已提交
693
            def: def,
694 695 696 697
        }
    }
}

698 699 700 701 702
enum LexicalScopeBinding<'a> {
    Item(&'a NameBinding<'a>),
    LocalDef(LocalDef),
}

703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
impl<'a> LexicalScopeBinding<'a> {
    fn local_def(self) -> LocalDef {
        match self {
            LexicalScopeBinding::LocalDef(local_def) => local_def,
            LexicalScopeBinding::Item(binding) => LocalDef::from_def(binding.def().unwrap()),
        }
    }

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

719
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
720
#[derive(Clone,Debug)]
721
enum ParentLink<'a> {
722
    NoParentLink,
723 724
    ModuleParentLink(Module<'a>, Name),
    BlockParentLink(Module<'a>, NodeId),
725 726
}

727
/// One node in the tree of modules.
728 729
pub struct ModuleS<'a> {
    parent_link: ParentLink<'a>,
J
Jeffrey Seyfried 已提交
730
    def: Option<Def>,
731

732 733 734
    // If the module is an extern crate, `def` is root of the external crate and `extern_crate_id`
    // is the NodeId of the local `extern crate` item (otherwise, `extern_crate_id` is None).
    extern_crate_id: Option<NodeId>,
735

736
    resolutions: RefCell<HashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
737
    unresolved_imports: RefCell<Vec<&'a ImportDirective<'a>>>,
738

739
    no_implicit_prelude: Cell<bool>,
740

741
    glob_importers: RefCell<Vec<(Module<'a>, &'a ImportDirective<'a>)>>,
742
    globs: RefCell<Vec<&'a ImportDirective<'a>>>,
743

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

747 748 749
    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
750
    populated: Cell<bool>,
751 752

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

755 756 757
pub type Module<'a> = &'a ModuleS<'a>;

impl<'a> ModuleS<'a> {
758 759 760 761
    fn new(parent_link: ParentLink<'a>,
           def: Option<Def>,
           external: bool,
           arenas: &'a ResolverArenas<'a>) -> Self {
762
        ModuleS {
763
            parent_link: parent_link,
J
Jeffrey Seyfried 已提交
764
            def: def,
765
            extern_crate_id: None,
766
            resolutions: RefCell::new(HashMap::new()),
767
            unresolved_imports: RefCell::new(Vec::new()),
768
            no_implicit_prelude: Cell::new(false),
769
            glob_importers: RefCell::new(Vec::new()),
770
            globs: RefCell::new((Vec::new())),
J
Jeffrey Seyfried 已提交
771
            traits: RefCell::new(None),
772
            populated: Cell::new(!external),
773
            arenas: arenas
774
        }
B
Brian Anderson 已提交
775 776
    }

777
    fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
778
        for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
779
            name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
780 781 782
        }
    }

783
    fn def_id(&self) -> Option<DefId> {
J
Jeffrey Seyfried 已提交
784
        self.def.as_ref().map(Def::def_id)
785 786
    }

787
    // `self` resolves to the first module ancestor that `is_normal`.
788
    fn is_normal(&self) -> bool {
J
Jeffrey Seyfried 已提交
789
        match self.def {
790
            Some(Def::Mod(_)) => true,
791 792 793 794 795
            _ => false,
        }
    }

    fn is_trait(&self) -> bool {
J
Jeffrey Seyfried 已提交
796
        match self.def {
797
            Some(Def::Trait(_)) => true,
798
            _ => false,
799
        }
B
Brian Anderson 已提交
800
    }
V
Victor Berger 已提交
801 802
}

803
impl<'a> fmt::Debug for ModuleS<'a> {
804
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
805
        write!(f, "{:?}", self.def)
806 807 808
    }
}

809
// Records a possibly-private value, type, or module definition.
810
#[derive(Clone, Debug)]
811
pub struct NameBinding<'a> {
812
    kind: NameBindingKind<'a>,
813
    span: Span,
814
    vis: ty::Visibility,
815 816
}

817
#[derive(Clone, Debug)]
818
enum NameBindingKind<'a> {
819
    Def(Def),
820
    Module(Module<'a>),
821 822
    Import {
        binding: &'a NameBinding<'a>,
823
        directive: &'a ImportDirective<'a>,
824 825
        // Some(error) if using this imported name causes the import to be a privacy error
        privacy_error: Option<Box<PrivacyError<'a>>>,
826
    },
827 828
}

829 830 831
#[derive(Clone, Debug)]
struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);

832
impl<'a> NameBinding<'a> {
833
    fn module(&self) -> Option<Module<'a>> {
834 835 836 837
        match self.kind {
            NameBindingKind::Module(module) => Some(module),
            NameBindingKind::Def(_) => None,
            NameBindingKind::Import { binding, .. } => binding.module(),
838 839 840
        }
    }

841
    fn def(&self) -> Option<Def> {
842 843 844 845
        match self.kind {
            NameBindingKind::Def(def) => Some(def),
            NameBindingKind::Module(module) => module.def,
            NameBindingKind::Import { binding, .. } => binding.def(),
846
        }
847
    }
848

849 850 851 852 853 854 855 856 857 858 859 860 861 862
    fn is_pseudo_public(&self) -> bool {
        self.pseudo_vis() == ty::Visibility::Public
    }

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

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

865
    fn is_extern_crate(&self) -> bool {
866
        self.module().and_then(|module| module.extern_crate_id).is_some()
867
    }
868 869 870 871 872 873 874

    fn is_import(&self) -> bool {
        match self.kind {
            NameBindingKind::Import { .. } => true,
            _ => false,
        }
    }
875 876 877 878 879 880 881 882 883 884 885 886 887 888

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

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

891
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
892
struct PrimitiveTypeTable {
893
    primitive_types: HashMap<Name, PrimTy>,
894
}
895

896
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
897
    fn new() -> PrimitiveTypeTable {
C
corentih 已提交
898 899 900 901
        let mut table = PrimitiveTypeTable { primitive_types: HashMap::new() };

        table.intern("bool", TyBool);
        table.intern("char", TyChar);
902 903
        table.intern("f32", TyFloat(FloatTy::F32));
        table.intern("f64", TyFloat(FloatTy::F64));
904 905 906 907 908
        table.intern("isize", TyInt(IntTy::Is));
        table.intern("i8", TyInt(IntTy::I8));
        table.intern("i16", TyInt(IntTy::I16));
        table.intern("i32", TyInt(IntTy::I32));
        table.intern("i64", TyInt(IntTy::I64));
C
corentih 已提交
909
        table.intern("str", TyStr);
910 911 912 913 914
        table.intern("usize", TyUint(UintTy::Us));
        table.intern("u8", TyUint(UintTy::U8));
        table.intern("u16", TyUint(UintTy::U16));
        table.intern("u32", TyUint(UintTy::U32));
        table.intern("u64", TyUint(UintTy::U64));
K
Kevin Butler 已提交
915 916 917 918

        table
    }

919
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
920
        self.primitive_types.insert(token::intern(string), primitive_type);
921 922 923
    }
}

924
/// The main resolver class.
925
pub struct Resolver<'a> {
E
Eduard Burtescu 已提交
926
    session: &'a Session,
927

928
    definitions: &'a mut Definitions,
929

930
    graph_root: Module<'a>,
931

932 933
    prelude: Option<Module<'a>>,

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

936
    structs: FnvHashMap<DefId, Vec<Name>>,
937

938
    // The number of imports that are currently unresolved.
939
    unresolved_imports: usize,
940 941

    // The module that represents the current item scope.
942
    current_module: Module<'a>,
943 944

    // The current set of local scopes, for values.
945
    // FIXME #4948: Reuse ribs to avoid allocation.
946
    value_ribs: Vec<Rib<'a>>,
947 948

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

951
    // The current set of local scopes, for labels.
952
    label_ribs: Vec<Rib<'a>>,
953

954
    // The trait that the current context can refer to.
955 956 957 958
    current_trait_ref: Option<(DefId, TraitRef)>,

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

960
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
961
    primitive_type_table: PrimitiveTypeTable,
962

963 964
    pub def_map: DefMap,
    pub freevars: FreevarMap,
965
    freevars_seen: NodeMap<NodeMap<usize>>,
966 967
    pub export_map: ExportMap,
    pub trait_map: TraitMap,
968

969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
    // A map from nodes to modules, both normal (`mod`) modules and anonymous modules.
    // Anonymous modules are pseudo-modules that are implicitly created around items
    // contained within blocks.
    //
    // For example, if we have this:
    //
    //  fn f() {
    //      fn g() {
    //          ...
    //      }
    //  }
    //
    // There will be an anonymous module created around `g` with the ID of the
    // entry block for `f`.
    module_map: NodeMap<Module<'a>>,

985 986 987 988 989
    // Whether or not to print error messages. Can be set to true
    // when getting additional info for error message suggestions,
    // so as to avoid printing duplicate errors
    emit_errors: bool,

990
    pub make_glob_map: bool,
991 992
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
993
    pub glob_map: GlobMap,
994

995
    used_imports: HashSet<(NodeId, Namespace)>,
996
    used_crates: HashSet<CrateNum>,
997
    pub maybe_unused_trait_imports: NodeSet,
G
Garming Sam 已提交
998

999
    privacy_errors: Vec<PrivacyError<'a>>,
1000 1001 1002 1003

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

J
Jeffrey Seyfried 已提交
1004
struct ResolverArenas<'a> {
1005
    modules: arena::TypedArena<ModuleS<'a>>,
1006
    local_modules: RefCell<Vec<Module<'a>>>,
1007
    name_bindings: arena::TypedArena<NameBinding<'a>>,
1008
    import_directives: arena::TypedArena<ImportDirective<'a>>,
1009
    name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
1010 1011 1012
}

impl<'a> ResolverArenas<'a> {
1013
    fn alloc_module(&'a self, module: ModuleS<'a>) -> Module<'a> {
1014 1015 1016 1017 1018 1019 1020 1021
        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()
1022 1023 1024 1025
    }
    fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
        self.name_bindings.alloc(name_binding)
    }
1026 1027
    fn alloc_import_directive(&'a self, import_directive: ImportDirective<'a>)
                              -> &'a ImportDirective {
1028 1029
        self.import_directives.alloc(import_directive)
    }
1030 1031 1032
    fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
        self.name_resolutions.alloc(Default::default())
    }
1033 1034
}

1035
impl<'a> ty::NodeIdTree for Resolver<'a> {
1036
    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
1037
        let ancestor = self.definitions.local_def_id(ancestor);
1038
        let mut module = *self.module_map.get(&node).unwrap();
J
Jeffrey Seyfried 已提交
1039
        while module.def_id() != Some(ancestor) {
1040 1041 1042 1043 1044 1045
            let module_parent = match self.get_nearest_normal_module_parent(module) {
                Some(parent) => parent,
                None => return false,
            };
            module = module_parent;
        }
J
Jeffrey Seyfried 已提交
1046
        true
1047 1048 1049
    }
}

1050 1051 1052 1053 1054 1055 1056 1057 1058
impl<'a> hir::lowering::Resolver for Resolver<'a> {
    fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def {
        let namespace = if is_value { ValueNS } else { TypeNS };
        match self.resolve_crate_relative_path(path.span, &path.segments, namespace) {
            Ok(binding) => binding.def().unwrap(),
            Err(true) => Def::Err,
            Err(false) => {
                let path_name = &format!("{}", path);
                let error =
1059 1060 1061 1062 1063
                    ResolutionError::UnresolvedName {
                        path: path_name,
                        message: "",
                        context: UnresolvedNameContext::Other,
                        is_static_method: false,
G
ggomez 已提交
1064 1065
                        is_field: false,
                        def: Def::Err,
1066
                    };
1067 1068 1069 1070 1071 1072
                resolve_error(self, path.span, error);
                Def::Err
            }
        }
    }

1073 1074 1075 1076
    fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution> {
        self.def_map.get(&id).cloned()
    }

1077
    fn record_resolution(&mut self, id: NodeId, def: Def) {
1078
        self.def_map.insert(id, PathResolution::new(def));
1079
    }
1080 1081 1082

    fn definitions(&mut self) -> Option<&mut Definitions> {
        Some(self.definitions)
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
    }
}

trait Named {
    fn name(&self) -> Name;
}

impl Named for ast::PathSegment {
    fn name(&self) -> Name {
        self.identifier.name
    }
}

impl Named for hir::PathSegment {
    fn name(&self) -> Name {
V
Vadim Petrochenkov 已提交
1098
        self.name
1099 1100 1101
    }
}

1102
impl<'a> Resolver<'a> {
1103
    fn new(session: &'a Session,
1104
           definitions: &'a mut Definitions,
1105 1106
           make_glob_map: MakeGlobMap,
           arenas: &'a ResolverArenas<'a>)
1107 1108
           -> Resolver<'a> {
        let root_def_id = definitions.local_def_id(CRATE_NODE_ID);
1109
        let graph_root =
1110
            ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas);
1111
        let graph_root = arenas.alloc_module(graph_root);
1112 1113
        let mut module_map = NodeMap();
        module_map.insert(CRATE_NODE_ID, graph_root);
K
Kevin Butler 已提交
1114 1115 1116 1117

        Resolver {
            session: session,

1118
            definitions: definitions,
1119

K
Kevin Butler 已提交
1120 1121
            // The outermost module has def ID 0; this is not reflected in the
            // AST.
1122
            graph_root: graph_root,
1123
            prelude: None,
K
Kevin Butler 已提交
1124

1125 1126
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1127 1128 1129

            unresolved_imports: 0,

1130
            current_module: graph_root,
1131 1132
            value_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
            type_ribs: vec![Rib::new(ModuleRibKind(graph_root))],
1133
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1134 1135 1136 1137 1138 1139

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1140
            def_map: NodeMap(),
1141 1142
            freevars: NodeMap(),
            freevars_seen: NodeMap(),
1143 1144
            export_map: NodeMap(),
            trait_map: NodeMap(),
1145
            module_map: module_map,
K
Kevin Butler 已提交
1146 1147

            emit_errors: true,
1148
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
1149
            glob_map: NodeMap(),
G
Garming Sam 已提交
1150

S
Seo Sanghyeon 已提交
1151 1152 1153 1154
            used_imports: HashSet::new(),
            used_crates: HashSet::new(),
            maybe_unused_trait_imports: NodeSet(),

1155
            privacy_errors: Vec::new(),
1156 1157 1158 1159 1160 1161 1162 1163

            arenas: arenas,
        }
    }

    fn arenas() -> ResolverArenas<'a> {
        ResolverArenas {
            modules: arena::TypedArena::new(),
1164
            local_modules: RefCell::new(Vec::new()),
1165
            name_bindings: arena::TypedArena::new(),
1166
            import_directives: arena::TypedArena::new(),
1167
            name_resolutions: arena::TypedArena::new(),
K
Kevin Butler 已提交
1168 1169
        }
    }
1170

1171 1172 1173
    fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, external: bool)
                  -> Module<'a> {
        self.arenas.alloc_module(ModuleS::new(parent_link, def, external, self.arenas))
1174 1175
    }

1176
    fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId)
1177
                               -> Module<'a> {
1178
        let mut module = ModuleS::new(parent_link, Some(def), false, self.arenas);
1179
        module.extern_crate_id = Some(local_node_id);
1180 1181 1182
        self.arenas.modules.alloc(module)
    }

1183 1184 1185 1186
    fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec<Rib<'a>> {
        match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs }
    }

1187
    #[inline]
S
Seo Sanghyeon 已提交
1188
    fn record_use(&mut self, name: Name, binding: &'a NameBinding<'a>) {
1189 1190 1191 1192 1193
        // track extern crates for unused_extern_crate lint
        if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
            self.used_crates.insert(krate);
        }

1194 1195 1196
        let (directive, privacy_error) = match binding.kind {
            NameBindingKind::Import { directive, ref privacy_error, .. } =>
                (directive, privacy_error),
1197 1198 1199
            _ => return,
        };

1200 1201 1202
        if let Some(error) = privacy_error.as_ref() {
            self.privacy_errors.push((**error).clone());
        }
1203

1204 1205 1206
        if !self.make_glob_map {
            return;
        }
1207 1208
        if self.glob_map.contains_key(&directive.id) {
            self.glob_map.get_mut(&directive.id).unwrap().insert(name);
1209 1210 1211
            return;
        }

1212
        let mut new_set = FnvHashSet();
1213
        new_set.insert(name);
1214
        self.glob_map.insert(directive.id, new_set);
1215 1216
    }

1217
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1218
    fn resolve_module_path_from_root(&mut self,
1219
                                     module_: Module<'a>,
1220
                                     module_path: &[Name],
1221
                                     index: usize,
J
Jeffrey Seyfried 已提交
1222 1223
                                     span: Span)
                                     -> ResolveResult<Module<'a>> {
1224
        fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
1225 1226
            match module.resolve_name(needle, TypeNS, false) {
                Success(binding) if binding.is_extern_crate() => Some(module),
1227
                _ => match module.parent_link {
1228
                    ModuleParentLink(ref parent, _) => {
1229
                        search_parent_externals(needle, parent)
1230
                    }
C
corentih 已提交
1231 1232
                    _ => None,
                },
1233
            }
1234 1235
        }

1236
        let mut search_module = module_;
1237
        let mut index = index;
A
Alex Crichton 已提交
1238
        let module_path_len = module_path.len();
1239 1240 1241 1242 1243

        // Resolve the module part of the path. This does not involve looking
        // upward though scope chains; we simply resolve names directly in
        // modules as we go.
        while index < module_path_len {
A
Alex Crichton 已提交
1244
            let name = module_path[index];
1245
            match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
1246
                Failed(None) => {
1247
                    let segment_name = name.as_str();
1248
                    let module_name = module_to_string(search_module);
1249
                    let msg = if "???" == &module_name {
C
corentih 已提交
1250
                        match search_parent_externals(name, &self.current_module) {
1251
                            Some(module) => {
1252
                                let path_str = names_to_string(module_path);
J
Jonas Schievink 已提交
1253 1254
                                let target_mod_str = module_to_string(&module);
                                let current_mod_str = module_to_string(&self.current_module);
1255 1256 1257 1258 1259 1260 1261

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

1262
                                format!("Did you mean `{}{}`?", prefix, path_str)
C
corentih 已提交
1263 1264
                            }
                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
1265
                        }
1266
                    } else {
C
corentih 已提交
1267
                        format!("Could not find `{}` in `{}`", segment_name, module_name)
1268
                    };
1269

1270
                    return Failed(Some((span, msg)));
1271
                }
1272
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1273
                Indeterminate => {
C
corentih 已提交
1274 1275 1276
                    debug!("(resolving module path for import) module resolution is \
                            indeterminate: {}",
                           name);
B
Brian Anderson 已提交
1277
                    return Indeterminate;
1278
                }
1279
                Success(binding) => {
1280 1281
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
J
Jeffrey Seyfried 已提交
1282
                    if let Some(module_def) = binding.module() {
1283
                        self.check_privacy(name, binding, span);
1284 1285 1286 1287
                        search_module = module_def;
                    } else {
                        let msg = format!("Not a module `{}`", name);
                        return Failed(Some((span, msg)));
1288 1289 1290 1291
                    }
                }
            }

T
Tim Chevalier 已提交
1292
            index += 1;
1293 1294
        }

J
Jeffrey Seyfried 已提交
1295
        return Success(search_module);
1296 1297
    }

1298 1299
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
F
Felix S. Klock II 已提交
1300
    fn resolve_module_path(&mut self,
1301
                           module_path: &[Name],
1302
                           use_lexical_scope: UseLexicalScopeFlag,
J
Jeffrey Seyfried 已提交
1303
                           span: Span)
J
Jeffrey Seyfried 已提交
1304
                           -> ResolveResult<Module<'a>> {
1305
        if module_path.len() == 0 {
J
Jeffrey Seyfried 已提交
1306
            return Success(self.graph_root) // Use the crate root
1307
        }
1308

1309
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1310
               names_to_string(module_path),
1311
               module_to_string(self.current_module));
1312

1313
        // Resolve the module prefix, if any.
1314
        let module_prefix_result = self.resolve_module_prefix(module_path, span);
1315

1316 1317
        let search_module;
        let start_index;
1318
        match module_prefix_result {
1319
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1320
            Indeterminate => {
C
corentih 已提交
1321
                debug!("(resolving module path for import) indeterminate; bailing");
B
Brian Anderson 已提交
1322
                return Indeterminate;
1323
            }
1324 1325 1326 1327 1328 1329 1330 1331
            Success(NoPrefixFound) => {
                // There was no prefix, so we're considering the first element
                // of the path. How we handle this depends on whether we were
                // instructed to use lexical scope or not.
                match use_lexical_scope {
                    DontUseLexicalScope => {
                        // This is a crate-relative path. We will start the
                        // resolution process at index zero.
1332
                        search_module = self.graph_root;
1333 1334 1335 1336 1337 1338
                        start_index = 0;
                    }
                    UseLexicalScope => {
                        // This is not a crate-relative path. We resolve the
                        // first component of the path in the current lexical
                        // scope and then proceed to resolve below that.
1339
                        let ident = ast::Ident::with_empty_ctxt(module_path[0]);
1340 1341 1342 1343 1344 1345
                        match self.resolve_ident_in_lexical_scope(ident, TypeNS, true)
                                  .and_then(LexicalScopeBinding::module) {
                            None => return Failed(None),
                            Some(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1346 1347 1348 1349 1350
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1351
            Success(PrefixFound(ref containing_module, index)) => {
1352
                search_module = containing_module;
1353
                start_index = index;
1354 1355 1356
            }
        }

1357 1358 1359
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
J
Jeffrey Seyfried 已提交
1360
                                           span)
1361 1362
    }

1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
    /// 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.
    /// }
    /// ```
1377
    ///
1378 1379
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
1380
    fn resolve_ident_in_lexical_scope(&mut self,
1381
                                      ident: ast::Ident,
1382 1383 1384
                                      ns: Namespace,
                                      record_used: bool)
                                      -> Option<LexicalScopeBinding<'a>> {
1385
        let name = match ns { ValueNS => mtwt::resolve(ident), TypeNS => ident.name };
1386

1387
        // Walk backwards up the ribs in scope.
1388 1389 1390 1391 1392 1393 1394
        for i in (0 .. self.get_ribs(ns).len()).rev() {
            if let Some(def) = self.get_ribs(ns)[i].bindings.get(&name).cloned() {
                // The ident resolves to a type parameter or local variable.
                return Some(LexicalScopeBinding::LocalDef(LocalDef {
                    ribs: Some((ns, i)),
                    def: def,
                }));
1395 1396
            }

1397
            if let ModuleRibKind(module) = self.get_ribs(ns)[i].kind {
1398
                let name = ident.name;
1399 1400 1401 1402
                let item = self.resolve_name_in_module(module, name, ns, true, record_used);
                if let Success(binding) = item {
                    // The ident resolves to an item.
                    return Some(LexicalScopeBinding::Item(binding));
1403
                }
1404

1405
                // We can only see through anonymous modules
1406
                if module.def.is_some() {
1407 1408 1409 1410 1411 1412 1413
                    return match self.prelude {
                        Some(prelude) if !module.no_implicit_prelude.get() => {
                            prelude.resolve_name(name, ns, false).success()
                                   .map(LexicalScopeBinding::Item)
                        }
                        _ => None,
                    };
1414
                }
1415 1416
            }
        }
1417

1418 1419 1420
        None
    }

1421
    /// Returns the nearest normal module parent of the given module.
1422
    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
1423 1424
        let mut module_ = module_;
        loop {
1425
            match module_.parent_link {
1426 1427 1428
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
1429
                    let new_module = new_module;
1430 1431
                    if new_module.is_normal() {
                        return Some(new_module);
1432
                    }
1433
                    module_ = new_module;
1434 1435 1436 1437 1438
                }
            }
        }
    }

1439 1440
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
1441
    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
1442 1443 1444
        if module_.is_normal() {
            return module_;
        }
1445
        match self.get_nearest_normal_module_parent(module_) {
1446 1447
            None => module_,
            Some(new_module) => new_module,
1448 1449 1450
        }
    }

1451
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1452
    /// (b) some chain of `super::`.
1453
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
1454
    fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
1455
                             -> ResolveResult<ModulePrefixResult<'a>> {
1456 1457
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1458 1459 1460 1461 1462
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
1463
        let module_ = self.current_module;
1464
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1465 1466

        // Now loop through all the `super`s we find.
1467
        while i < module_path.len() && "super" == module_path[i].as_str() {
1468
            debug!("(resolving module prefix) resolving `super` at {}",
J
Jonas Schievink 已提交
1469
                   module_to_string(&containing_module));
1470
            match self.get_nearest_normal_module_parent(containing_module) {
1471 1472 1473 1474
                None => {
                    let msg = "There are too many initial `super`s.".into();
                    return Failed(Some((span, msg)));
                }
1475 1476 1477
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1478 1479 1480 1481
                }
            }
        }

1482
        debug!("(resolving module prefix) finished resolving prefix at {}",
J
Jonas Schievink 已提交
1483
               module_to_string(&containing_module));
1484 1485

        return Success(PrefixFound(containing_module, i));
1486 1487
    }

1488
    /// Attempts to resolve the supplied name in the given module for the
J
Jeffrey Seyfried 已提交
1489
    /// given namespace. If successful, returns the binding corresponding to
1490
    /// the name.
F
Felix S. Klock II 已提交
1491
    fn resolve_name_in_module(&mut self,
1492
                              module: Module<'a>,
1493
                              name: Name,
1494
                              namespace: Namespace,
1495
                              use_lexical_scope: bool,
1496
                              record_used: bool)
1497
                              -> ResolveResult<&'a NameBinding<'a>> {
1498
        debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
1499

1500
        self.populate_module_if_necessary(module);
1501
        module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
1502
            if record_used {
S
Seo Sanghyeon 已提交
1503 1504 1505 1506
                if let NameBindingKind::Import { directive, .. } = binding.kind {
                    self.used_imports.insert((directive.id, namespace));
                }
                self.record_use(name, binding);
1507
            }
1508 1509
            Success(binding)
        })
1510 1511 1512 1513
    }

    // AST resolution
    //
1514
    // We maintain a list of value ribs and type ribs.
1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
    //
    // 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.

1530
    fn with_scope<F>(&mut self, id: NodeId, f: F)
C
corentih 已提交
1531
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1532
    {
1533 1534
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
1535 1536 1537 1538
            // Move down in the graph.
            let orig_module = ::std::mem::replace(&mut self.current_module, module);
            self.value_ribs.push(Rib::new(ModuleRibKind(module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(module)));
1539

1540
            f(self);
1541

1542 1543 1544 1545 1546 1547
            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
1548 1549
    }

S
Seo Sanghyeon 已提交
1550 1551
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
1552
    fn search_label(&self, name: Name) -> Option<Def> {
1553 1554 1555 1556 1557 1558 1559
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
C
corentih 已提交
1560
                    return None;
1561 1562 1563
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
1564
            if result.is_some() {
C
corentih 已提交
1565
                return result;
1566 1567 1568 1569 1570
            }
        }
        None
    }

1571
    fn resolve_crate(&mut self, krate: &Crate) {
1572
        debug!("(resolving crate) starting");
1573
        self.current_module = self.graph_root;
1574
        visit::walk_crate(self, krate);
1575 1576
    }

1577
    fn resolve_item(&mut self, item: &Item) {
1578
        let name = item.ident.name;
1579

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

1582
        match item.node {
1583 1584 1585
            ItemKind::Enum(_, ref generics) |
            ItemKind::Ty(_, ref generics) |
            ItemKind::Struct(_, ref generics) => {
C
corentih 已提交
1586
                self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind),
1587
                                             |this| visit::walk_item(this, item));
1588
            }
1589
            ItemKind::Fn(_, _, _, _, ref generics, _) => {
C
corentih 已提交
1590
                self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind),
1591
                                             |this| visit::walk_item(this, item));
1592 1593
            }

1594
            ItemKind::DefaultImpl(_, ref trait_ref) => {
1595
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
1596
            }
1597
            ItemKind::Impl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) =>
1598
                self.resolve_implementation(generics,
1599
                                            opt_trait_ref,
J
Jonas Schievink 已提交
1600
                                            &self_type,
1601
                                            item.id,
1602
                                            impl_items),
1603

1604
            ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
1605 1606 1607 1608 1609
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
1610
                    let local_def_id = this.definitions.local_def_id(item.id);
1611
                    this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
1612
                        this.visit_generics(generics);
1613
                        walk_list!(this, visit_ty_param_bound, bounds);
1614 1615

                        for trait_item in trait_items {
1616
                            match trait_item.node {
1617
                                TraitItemKind::Const(_, ref default) => {
1618 1619 1620 1621 1622
                                    // Only impose the restrictions of
                                    // ConstRibKind if there's an actual constant
                                    // expression in a provided default.
                                    if default.is_some() {
                                        this.with_constant_rib(|this| {
1623
                                            visit::walk_trait_item(this, trait_item)
1624 1625
                                        });
                                    } else {
1626
                                        visit::walk_trait_item(this, trait_item)
1627 1628
                                    }
                                }
1629
                                TraitItemKind::Method(ref sig, _) => {
1630 1631 1632
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
V
Vadim Petrochenkov 已提交
1633
                                                          MethodRibKind(!sig.decl.has_self()));
1634
                                    this.with_type_parameter_rib(type_parameters, |this| {
1635
                                        visit::walk_trait_item(this, trait_item)
1636
                                    });
1637
                                }
1638
                                TraitItemKind::Type(..) => {
1639
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
1640
                                        visit::walk_trait_item(this, trait_item)
1641
                                    });
1642
                                }
1643
                                TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
1644 1645 1646
                            };
                        }
                    });
1647
                });
1648 1649
            }

1650
            ItemKind::Mod(_) | ItemKind::ForeignMod(_) => {
1651
                self.with_scope(item.id, |this| {
1652
                    visit::walk_item(this, item);
1653
                });
1654 1655
            }

1656
            ItemKind::Const(..) | ItemKind::Static(..) => {
A
Alex Crichton 已提交
1657
                self.with_constant_rib(|this| {
1658
                    visit::walk_item(this, item);
1659
                });
1660
            }
1661

1662
            ItemKind::Use(ref view_path) => {
1663
                match view_path.node {
1664
                    ast::ViewPathList(ref prefix, ref items) => {
1665 1666 1667 1668 1669
                        // Resolve prefix of an import with empty braces (issue #28388)
                        if items.is_empty() && !prefix.segments.is_empty() {
                            match self.resolve_crate_relative_path(prefix.span,
                                                                   &prefix.segments,
                                                                   TypeNS) {
1670 1671
                                Ok(binding) => {
                                    let def = binding.def().unwrap();
1672
                                    self.record_def(item.id, PathResolution::new(def));
1673
                                }
1674 1675
                                Err(true) => self.record_def(item.id, err_path_resolution()),
                                Err(false) => {
1676 1677 1678 1679
                                    resolve_error(self,
                                                  prefix.span,
                                                  ResolutionError::FailedToResolve(
                                                      &path_names_to_string(prefix, 0)));
1680
                                    self.record_def(item.id, err_path_resolution());
1681
                                }
1682 1683 1684 1685
                            }
                        }
                    }
                    _ => {}
W
we 已提交
1686 1687 1688
                }
            }

1689
            ItemKind::ExternCrate(_) => {
1690
                // do nothing, these are just around to be encoded
1691
            }
1692 1693

            ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
1694 1695 1696
        }
    }

1697
    fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<'a, 'b>, f: F)
C
corentih 已提交
1698
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1699
    {
1700
        match type_parameters {
1701
            HasTypeParameters(generics, space, rib_kind) => {
1702
                let mut function_type_rib = Rib::new(rib_kind);
1703
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
1704
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
1705
                    let name = type_parameter.ident.name;
1706
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
1707

1708
                    if seen_bindings.contains(&name) {
1709 1710
                        resolve_error(self,
                                      type_parameter.span,
C
corentih 已提交
1711
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(name));
1712
                    }
1713
                    seen_bindings.insert(name);
1714

1715
                    // plain insert (no renaming)
1716
                    let def_id = self.definitions.local_def_id(type_parameter.id);
1717 1718
                    let def = Def::TyParam(space, index as u32, def_id, name);
                    function_type_rib.bindings.insert(name, def);
1719
                }
1720
                self.type_ribs.push(function_type_rib);
1721 1722
            }

B
Brian Anderson 已提交
1723
            NoTypeParameters => {
1724 1725 1726 1727
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
1728
        f(self);
1729

J
Jeffrey Seyfried 已提交
1730 1731
        if let HasTypeParameters(..) = type_parameters {
            self.type_ribs.pop();
1732 1733 1734
        }
    }

C
corentih 已提交
1735 1736
    fn with_label_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1737
    {
1738
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
1739
        f(self);
J
Jeffrey Seyfried 已提交
1740
        self.label_ribs.pop();
1741
    }
1742

C
corentih 已提交
1743 1744
    fn with_constant_rib<F>(&mut self, f: F)
        where F: FnOnce(&mut Resolver)
J
Jorge Aparicio 已提交
1745
    {
1746 1747
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
1748
        f(self);
J
Jeffrey Seyfried 已提交
1749 1750
        self.type_ribs.pop();
        self.value_ribs.pop();
1751 1752
    }

1753 1754 1755 1756
    fn resolve_function(&mut self,
                        rib_kind: RibKind<'a>,
                        declaration: &FnDecl,
                        block: &Block) {
1757
        // Create a value rib for the function.
1758
        self.value_ribs.push(Rib::new(rib_kind));
1759

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

1763 1764 1765
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
1766
            self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
1767

J
Jonas Schievink 已提交
1768
            self.visit_ty(&argument.ty);
1769

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

1774
        // Resolve the function body.
1775
        self.visit_block(block);
1776

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

J
Jeffrey Seyfried 已提交
1779 1780
        self.label_ribs.pop();
        self.value_ribs.pop();
1781 1782
    }

F
Felix S. Klock II 已提交
1783
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
1784
                               id: NodeId,
1785
                               trait_path: &Path,
1786
                               path_depth: usize)
1787
                               -> Result<PathResolution, ()> {
1788
        self.resolve_path(id, trait_path, path_depth, TypeNS).and_then(|path_res| {
1789
            if let Def::Trait(_) = path_res.base_def {
1790 1791 1792
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
N
Nick Cameron 已提交
1793 1794 1795
                let mut err =
                    resolve_struct_error(self,
                                  trait_path.span,
J
Jonas Schievink 已提交
1796
                                  ResolutionError::IsNotATrait(&path_names_to_string(trait_path,
N
Nick Cameron 已提交
1797
                                                                                      path_depth)));
1798 1799

                // If it's a typedef, give a note
1800
                if let Def::TyAlias(..) = path_res.base_def {
1801
                    let trait_name = trait_path.segments.last().unwrap().identifier.name;
1802 1803
                    err.span_label(trait_path.span,
                                   &format!("`{}` is not a trait", trait_name));
1804 1805 1806 1807 1808 1809 1810

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

1814
                    if definition_site != syntax_pos::DUMMY_SP {
1815 1816
                        err.span_label(definition_site,
                                       &format!("type aliases cannot be used for traits"));
V
vegai 已提交
1817
                    }
1818
                }
N
Nick Cameron 已提交
1819
                err.emit();
1820
                Err(true)
1821
            }
1822 1823
        }).map_err(|error_reported| {
            if error_reported { return }
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845

            // find possible candidates
            let trait_name = trait_path.segments.last().unwrap().identifier.name;
            let candidates =
                self.lookup_candidates(
                    trait_name,
                    TypeNS,
                    |def| match def {
                        Def::Trait(_) => true,
                        _             => false,
                    },
                );

            // create error object
            let name = &path_names_to_string(trait_path, path_depth);
            let error =
                ResolutionError::UndeclaredTraitName(
                    name,
                    candidates,
                );

            resolve_error(self, trait_path.span, error);
1846
        })
1847 1848
    }

1849 1850
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
1851
    {
1852 1853 1854 1855 1856 1857 1858
        // Handle nested impls (inside fn bodies)
        let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
        let result = f(self);
        self.current_self_type = previous_value;
        result
    }

C
corentih 已提交
1859
    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
1860
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
1861
    {
1862
        let mut new_val = None;
1863
        let mut new_id = None;
E
Eduard Burtescu 已提交
1864
        if let Some(trait_ref) = opt_trait_ref {
1865
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
C
corentih 已提交
1866 1867
                                                               &trait_ref.path,
                                                               0) {
1868 1869 1870 1871
                assert!(path_res.depth == 0);
                self.record_def(trait_ref.ref_id, path_res);
                new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                new_id = Some(path_res.base_def.def_id());
1872 1873
            } else {
                self.record_def(trait_ref.ref_id, err_path_resolution());
1874
            }
1875
            visit::walk_trait_ref(self, trait_ref);
1876
        }
1877
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
1878
        let result = f(self, new_id);
1879 1880 1881 1882
        self.current_trait_ref = original_trait_ref;
        result
    }

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

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

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

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

                                    // We also need a new scope for the method-
                                    // specific type parameters.
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
V
Vadim Petrochenkov 已提交
1939
                                                          MethodRibKind(!sig.decl.has_self()));
1940
                                    this.with_type_parameter_rib(type_parameters, |this| {
1941
                                        visit::walk_impl_item(this, impl_item);
1942 1943
                                    });
                                }
1944
                                ImplItemKind::Type(ref ty) => {
1945
                                    // If this is a trait impl, ensure the type
1946
                                    // exists in trait
1947
                                    this.check_trait_item(impl_item.ident.name,
1948 1949
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
1950

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

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

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

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

        // Resolve the pattern.
1983
        self.resolve_pattern(&local.pat, PatternSource::Let, &mut HashMap::new());
1984 1985
    }

J
John Clements 已提交
1986 1987 1988 1989
    // build a map from pattern identifiers to binding-info's.
    // this is done hygienically. This could arise for a macro
    // that expands into an or-pattern where one 'x' was from the
    // user and one 'x' came from the macro.
E
Eduard Burtescu 已提交
1990
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003
        let mut binding_map = HashMap::new();

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

        binding_map
2007 2008
    }

J
John Clements 已提交
2009 2010
    // check that all of the arms in an or-pattern have exactly the
    // same set of bindings, with the same binding modes for each.
F
Felix S. Klock II 已提交
2011
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2012
        if arm.pats.is_empty() {
C
corentih 已提交
2013
            return;
2014
        }
J
Jonas Schievink 已提交
2015
        let map_0 = self.binding_mode_map(&arm.pats[0]);
D
Daniel Micay 已提交
2016
        for (i, p) in arm.pats.iter().enumerate() {
J
Jonas Schievink 已提交
2017
            let map_i = self.binding_mode_map(&p);
2018

2019
            for (&key, &binding_0) in &map_0 {
2020
                match map_i.get(&key) {
C
corentih 已提交
2021
                    None => {
2022
                        resolve_error(self,
C
corentih 已提交
2023
                                      p.span,
M
Manish Goregaokar 已提交
2024
                                      ResolutionError::VariableNotBoundInPattern(key, 1, i + 1));
C
corentih 已提交
2025 2026 2027 2028 2029 2030 2031 2032
                    }
                    Some(binding_i) => {
                        if binding_0.binding_mode != binding_i.binding_mode {
                            resolve_error(self,
                                          binding_i.span,
                                          ResolutionError::VariableBoundWithDifferentMode(key,
                                                                                          i + 1));
                        }
2033
                    }
2034 2035 2036
                }
            }

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

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

2050
        let mut bindings_list = HashMap::new();
2051
        for pattern in &arm.pats {
2052
            self.resolve_pattern(&pattern, PatternSource::Match, &mut bindings_list);
2053 2054
        }

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

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

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

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

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

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

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

F
Felix S. Klock II 已提交
2092
    fn resolve_type(&mut self, ty: &Ty) {
2093
        match ty.node {
2094
            TyKind::Path(ref maybe_qself, ref path) => {
2095
                // This is a path in the type namespace. Walk through scopes
2096
                // looking for it.
2097 2098
                if let Some(def) = self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(),
                                                                    path, TypeNS) {
2099
                    match def.base_def {
2100
                        Def::Mod(..) if def.depth == 0 => {
2101 2102 2103 2104 2105 2106 2107 2108 2109 2110
                            self.session.span_err(path.span, "expected type, found module");
                            self.record_def(ty.id, err_path_resolution());
                        }
                        _ => {
                            // Write the result into the def map.
                            debug!("(resolving type) writing resolution for `{}` (id {}) = {:?}",
                                   path_names_to_string(path, 0), ty.id, def);
                            self.record_def(ty.id, def);
                        }
                    }
2111 2112
                } else {
                    self.record_def(ty.id, err_path_resolution());
2113

2114 2115 2116 2117
                    // Keep reporting some errors even if they're ignored above.
                    if let Err(true) = self.resolve_path(ty.id, path, 0, TypeNS) {
                        // `resolve_path` already reported the error
                    } else {
2118 2119 2120 2121
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2122
                        };
2123

C
corentih 已提交
2124 2125 2126
                        let is_invalid_self_type_name = path.segments.len() > 0 &&
                                                        maybe_qself.is_none() &&
                                                        path.segments[0].identifier.name ==
2127
                                                        keywords::SelfType.name();
G
Guillaume Gomez 已提交
2128
                        if is_invalid_self_type_name {
2129 2130
                            resolve_error(self,
                                          ty.span,
2131
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2132
                        } else {
2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159
                            let segment = path.segments.last();
                            let segment = segment.expect("missing name in path");
                            let type_name = segment.identifier.name;

                            let candidates =
                                self.lookup_candidates(
                                    type_name,
                                    TypeNS,
                                    |def| match def {
                                        Def::Trait(_) |
                                        Def::Enum(_) |
                                        Def::Struct(_) |
                                        Def::TyAlias(_) => true,
                                        _               => false,
                                    },
                                );

                            // create error object
                            let name = &path_names_to_string(path, 0);
                            let error =
                                ResolutionError::UseOfUndeclared(
                                    kind,
                                    name,
                                    candidates,
                                );

                            resolve_error(self, ty.span, error);
G
Guillaume Gomez 已提交
2160
                        }
2161 2162
                    }
                }
2163
            }
2164
            _ => {}
2165
        }
2166
        // Resolve embedded types.
2167
        visit::walk_ty(self, ty);
2168 2169
    }

2170 2171 2172 2173 2174
    fn fresh_binding(&mut self,
                     ident: &ast::SpannedIdent,
                     pat_id: NodeId,
                     outer_pat_id: NodeId,
                     pat_src: PatternSource,
2175
                     bindings: &mut HashMap<Name, NodeId>)
2176 2177
                     -> PathResolution {
        // Add the binding to the local ribs, if it
2178 2179
        // doesn't already exist in the bindings map. (We
        // must not add it if it's in the bindings map
2180 2181 2182
        // because that breaks the assumptions later
        // passes make about or-patterns.)
        let renamed = mtwt::resolve(ident.node);
2183
        let def = match bindings.get(&renamed).cloned() {
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204
            Some(id) if id == outer_pat_id => {
                // `Variant(a, a)`, error
                resolve_error(
                    self,
                    ident.span,
                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
                        &ident.node.name.as_str())
                );
                Def::Err
            }
            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())
                );
                Def::Err
            }
            Some(..) if pat_src == PatternSource::Match => {
2205 2206 2207
                // `Variant1(a) | Variant2(a)`, ok
                // Reuse definition from the first `a`.
                self.value_ribs.last_mut().unwrap().bindings[&renamed]
2208 2209 2210 2211 2212 2213
            }
            Some(..) => {
                span_bug!(ident.span, "two bindings with the same name from \
                                       unexpected pattern source {:?}", pat_src);
            }
            None => {
2214 2215 2216
                // A completely fresh binding, add to the lists.
                // FIXME: Later stages are not ready to deal with `Def::Err` here yet, so
                // define `Invalid` bindings as `Def::Local`, just don't add them to the lists.
2217
                let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id);
2218
                if ident.node.name != keywords::Invalid.name() {
2219
                    bindings.insert(renamed, outer_pat_id);
2220 2221
                    self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def);
                }
2222 2223 2224
                def
            }
        };
2225

2226
        PathResolution::new(def)
2227
    }
2228

2229
    fn resolve_pattern_path<ExpectedFn>(&mut self,
2230 2231 2232 2233 2234 2235
                                        pat_id: NodeId,
                                        qself: Option<&QSelf>,
                                        path: &Path,
                                        namespace: Namespace,
                                        expected_fn: ExpectedFn,
                                        expected_what: &str)
2236 2237
        where ExpectedFn: FnOnce(Def) -> bool
    {
2238 2239 2240 2241 2242
        let resolution = if let Some(resolution) = self.resolve_possibly_assoc_item(pat_id,
                                                                        qself, path, namespace) {
            if resolution.depth == 0 {
                if expected_fn(resolution.base_def) {
                    resolution
2243
                } else {
2244 2245 2246 2247 2248 2249
                    resolve_error(
                        self,
                        path.span,
                        ResolutionError::PatPathUnexpected(expected_what,
                                                           resolution.kind_name(), path)
                    );
2250 2251
                    err_path_resolution()
                }
2252 2253 2254 2255
            } else {
                // Not fully resolved associated item `T::A::B` or `<T as Tr>::A::B`
                // or `<T>::A::B`. If `B` should be resolved in value namespace then
                // it needs to be added to the trait map.
2256 2257 2258 2259
                if namespace == ValueNS {
                    let item_name = path.segments.last().unwrap().identifier.name;
                    let traits = self.get_traits_containing_item(item_name);
                    self.trait_map.insert(pat_id, traits);
2260
                }
2261
                resolution
2262
            }
2263 2264 2265 2266 2267 2268 2269 2270 2271
        } else {
            if let Err(false) = self.resolve_path(pat_id, path, 0, namespace) {
                resolve_error(
                    self,
                    path.span,
                    ResolutionError::PatPathUnresolved(expected_what, path)
                );
            }
            err_path_resolution()
2272
        };
2273

2274 2275 2276 2277 2278 2279 2280 2281
        self.record_def(pat_id, resolution);
    }

    fn resolve_pattern(&mut self,
                       pat: &Pat,
                       pat_src: PatternSource,
                       // Maps idents to the node ID for the
                       // outermost pattern that binds them.
2282 2283
                       bindings: &mut HashMap<Name, NodeId>) {
        // Visit all direct subpatterns of this pattern.
2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298
        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.
                    let resolution = if let Ok(resolution) = self.resolve_path(pat.id,
                                &Path::from_ident(ident.span, ident.node), 0, ValueNS) {
                        let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                             bmode != BindingMode::ByValue(Mutability::Immutable);
                        match resolution.base_def {
                            Def::Struct(..) | Def::Variant(..) |
                            Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                // A constant, unit variant, etc pattern.
                                resolution
2299
                            }
2300 2301 2302
                            Def::Struct(..) | Def::Variant(..) |
                            Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
                                // A fresh binding that shadows something unacceptable.
2303
                                resolve_error(
2304
                                    self,
2305 2306 2307
                                    ident.span,
                                    ResolutionError::BindingShadowsSomethingUnacceptable(
                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
2308
                                );
2309 2310 2311 2312 2313 2314
                                err_path_resolution()
                            }
                            Def::Local(..) | Def::Upvar(..) | Def::Fn(..) | Def::Err => {
                                // These entities are explicitly allowed
                                // to be shadowed by fresh bindings.
                                self.fresh_binding(ident, pat.id, outer_pat_id,
2315
                                                   pat_src, bindings)
2316 2317 2318 2319
                            }
                            def => {
                                span_bug!(ident.span, "unexpected definition for an \
                                                       identifier in pattern {:?}", def);
2320
                            }
2321
                        }
2322
                    } else {
2323
                        // Fall back to a fresh binding.
2324
                        self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
2325 2326 2327
                    };

                    self.record_def(pat.id, resolution);
2328 2329
                }

2330 2331 2332 2333 2334
                PatKind::TupleStruct(ref path, _, _) => {
                    self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| {
                        match def {
                            Def::Struct(..) | Def::Variant(..) | Def::Err => true,
                            _ => false,
2335
                        }
2336 2337 2338
                    }, "variant or struct");
                }

2339 2340
                PatKind::Path(ref qself, ref path) => {
                    self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| {
2341 2342 2343 2344
                        match def {
                            Def::Struct(..) | Def::Variant(..) |
                            Def::Const(..) | Def::AssociatedConst(..) | Def::Err => true,
                            _ => false,
2345
                        }
2346
                    }, "variant, struct or constant");
2347 2348
                }

2349 2350 2351 2352 2353 2354 2355 2356
                PatKind::Struct(ref path, _, _) => {
                    self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| {
                        match def {
                            Def::Struct(..) | Def::Variant(..) |
                            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::Err => true,
                            _ => false,
                        }
                    }, "variant, struct or type alias");
2357
                }
2358 2359

                _ => {}
2360
            }
2361
            true
2362
        });
2363

2364
        visit::walk_pat(self, pat);
2365 2366
    }

2367 2368 2369
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
2370
                                   maybe_qself: Option<&QSelf>,
2371
                                   path: &Path,
J
Jeffrey Seyfried 已提交
2372
                                   namespace: Namespace)
2373
                                   -> Option<PathResolution> {
2374 2375
        let max_assoc_types;

2376
        match maybe_qself {
2377 2378
            Some(qself) => {
                if qself.position == 0 {
2379 2380 2381
                    // FIXME: Create some fake resolution that can't possibly be a type.
                    return Some(PathResolution {
                        base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)),
2382
                        depth: path.segments.len(),
2383
                    });
2384 2385 2386 2387 2388 2389 2390 2391
                }
                max_assoc_types = path.segments.len() - qself.position;
                // Make sure the trait is valid.
                let _ = self.resolve_trait_reference(id, path, max_assoc_types);
            }
            None => {
                max_assoc_types = path.segments.len();
            }
2392 2393 2394
        }

        let mut resolution = self.with_no_errors(|this| {
2395
            this.resolve_path(id, path, 0, namespace).ok()
2396 2397 2398 2399 2400 2401
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
2402 2403 2404 2405 2406 2407
                let partial_resolution = this.resolve_path(id, path, depth, TypeNS).ok();
                if let Some(Def::Mod(..)) = partial_resolution.map(|r| r.base_def) {
                    // Modules cannot have associated items
                } else {
                    resolution = partial_resolution;
                }
2408 2409
            });
        }
2410
        resolution
2411 2412
    }

2413
    /// Skips `path_depth` trailing segments, which is also reflected in the
2414
    /// returned value. See `hir::def::PathResolution` for more info.
J
Jeffrey Seyfried 已提交
2415
    fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace)
2416
                    -> Result<PathResolution, bool /* true if an error was reported */ > {
2417 2418
        debug!("resolve_path(id={:?} path={:?}, path_depth={:?})", id, path, path_depth);

2419
        let span = path.span;
C
corentih 已提交
2420
        let segments = &path.segments[..path.segments.len() - path_depth];
2421

2422
        let mk_res = |def| PathResolution { base_def: def, depth: path_depth };
2423

2424
        if path.global {
2425 2426
            let binding = self.resolve_crate_relative_path(span, segments, namespace);
            return binding.map(|binding| mk_res(binding.def().unwrap()));
2427 2428
        }

2429
        // Try to find a path to an item in a module.
2430
        let last_ident = segments.last().unwrap().identifier;
V
Cleanup  
Vadim Petrochenkov 已提交
2431 2432 2433 2434 2435 2436 2437
        // Resolve a single identifier with fallback to primitive types
        let resolve_identifier_with_fallback = |this: &mut Self, record_used| {
            let def = this.resolve_identifier(last_ident, namespace, record_used);
            match def {
                None | Some(LocalDef{def: Def::Mod(..), ..}) if namespace == TypeNS =>
                    this.primitive_type_table
                        .primitive_types
2438
                        .get(&last_ident.name)
V
Cleanup  
Vadim Petrochenkov 已提交
2439 2440 2441 2442
                        .map_or(def, |prim_ty| Some(LocalDef::from_def(Def::PrimTy(*prim_ty)))),
                _ => def
            }
        };
2443

2444 2445 2446 2447 2448 2449 2450
        if segments.len() == 1 {
            // In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
            // don't report an error right away, but try to fallback to a primitive type.
            // So, we are still able to successfully resolve something like
            //
            // use std::u8; // bring module u8 in scope
            // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8
V
Cleanup  
Vadim Petrochenkov 已提交
2451 2452
            //     u8::max_value() // OK, resolves to associated function <u8>::max_value,
            //                     // not to non-existent std::u8::max_value
2453 2454 2455 2456
            // }
            //
            // Such behavior is required for backward compatibility.
            // The same fallback is used when `a` resolves to nothing.
2457 2458
            let def = resolve_identifier_with_fallback(self, true).ok_or(false);
            return def.and_then(|def| self.adjust_local_def(def, span).ok_or(true)).map(mk_res);
N
Nick Cameron 已提交
2459
        }
2460

V
Cleanup  
Vadim Petrochenkov 已提交
2461
        let unqualified_def = resolve_identifier_with_fallback(self, false);
2462 2463 2464
        let qualified_binding = self.resolve_module_relative_path(span, segments, namespace);
        match (qualified_binding, unqualified_def) {
            (Ok(binding), Some(ref ud)) if binding.def().unwrap() == ud.def => {
N
Nick Cameron 已提交
2465 2466
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
C
corentih 已提交
2467 2468
                              id,
                              span,
N
Nick Cameron 已提交
2469 2470 2471
                              "unnecessary qualification".to_string());
            }
            _ => {}
2472
        }
N
Nick Cameron 已提交
2473

2474
        qualified_binding.map(|binding| mk_res(binding.def().unwrap()))
2475 2476
    }

2477
    // Resolve a single identifier
F
Felix S. Klock II 已提交
2478
    fn resolve_identifier(&mut self,
2479
                          identifier: ast::Ident,
2480
                          namespace: Namespace,
2481
                          record_used: bool)
2482
                          -> Option<LocalDef> {
2483
        if identifier.name == keywords::Invalid.name() {
2484
            return Some(LocalDef::from_def(Def::Err));
2485 2486
        }

2487 2488
        self.resolve_ident_in_lexical_scope(identifier, namespace, record_used)
            .map(LexicalScopeBinding::local_def)
2489 2490 2491
    }

    // Resolve a local definition, potentially adjusting for closures.
2492
    fn adjust_local_def(&mut self, local_def: LocalDef, span: Span) -> Option<Def> {
2493
        let ribs = match local_def.ribs {
C
corentih 已提交
2494 2495 2496
            Some((TypeNS, i)) => &self.type_ribs[i + 1..],
            Some((ValueNS, i)) => &self.value_ribs[i + 1..],
            _ => &[] as &[_],
2497 2498 2499
        };
        let mut def = local_def.def;
        match def {
2500
            Def::Upvar(..) => {
2501
                span_bug!(span, "unexpected {:?} in bindings", def)
2502
            }
2503
            Def::Local(_, node_id) => {
2504 2505
                for rib in ribs {
                    match rib.kind {
2506
                        NormalRibKind | ModuleRibKind(..) => {
2507 2508 2509 2510
                            // Nothing to do. Continue.
                        }
                        ClosureRibKind(function_id) => {
                            let prev_def = def;
2511
                            let node_def_id = self.definitions.local_def_id(node_id);
2512

C
corentih 已提交
2513 2514 2515
                            let seen = self.freevars_seen
                                           .entry(function_id)
                                           .or_insert_with(|| NodeMap());
2516
                            if let Some(&index) = seen.get(&node_id) {
2517
                                def = Def::Upvar(node_def_id, node_id, index, function_id);
2518 2519
                                continue;
                            }
C
corentih 已提交
2520 2521 2522
                            let vec = self.freevars
                                          .entry(function_id)
                                          .or_insert_with(|| vec![]);
2523
                            let depth = vec.len();
C
corentih 已提交
2524 2525 2526 2527
                            vec.push(Freevar {
                                def: prev_def,
                                span: span,
                            });
2528

2529
                            def = Def::Upvar(node_def_id, node_id, depth, function_id);
2530 2531
                            seen.insert(node_id, depth);
                        }
2532
                        ItemRibKind | MethodRibKind(_) => {
2533 2534 2535
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
C
corentih 已提交
2536 2537 2538
                            resolve_error(self,
                                          span,
                                          ResolutionError::CannotCaptureDynamicEnvironmentInFnItem);
2539 2540 2541 2542
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
C
corentih 已提交
2543 2544 2545
                            resolve_error(self,
                                          span,
                                          ResolutionError::AttemptToUseNonConstantValueInConstant);
2546 2547 2548 2549 2550
                            return None;
                        }
                    }
                }
            }
2551
            Def::TyParam(..) | Def::SelfTy(..) => {
2552 2553
                for rib in ribs {
                    match rib.kind {
2554
                        NormalRibKind | MethodRibKind(_) | ClosureRibKind(..) |
2555
                        ModuleRibKind(..) => {
2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.

                            resolve_error(self,
                                          span,
                                          ResolutionError::TypeParametersFromOuterFunction);
                            return None;
                        }
                        ConstantItemRibKind => {
                            // see #9186
                            resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
                            return None;
                        }
                    }
                }
            }
            _ => {}
        }
        return Some(def);
2578 2579
    }

2580
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
2581
    fn resolve_module_relative_path(&mut self,
2582
                                    span: Span,
2583
                                    segments: &[ast::PathSegment],
2584
                                    namespace: Namespace)
2585 2586
                                    -> Result<&'a NameBinding<'a>,
                                              bool /* true if an error was reported */> {
C
corentih 已提交
2587 2588 2589 2590 2591 2592
        let module_path = segments.split_last()
                                  .unwrap()
                                  .1
                                  .iter()
                                  .map(|ps| ps.identifier.name)
                                  .collect::<Vec<_>>();
2593

2594
        let containing_module;
2595
        match self.resolve_module_path(&module_path, UseLexicalScope, span) {
2596 2597 2598 2599
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
2600
                        let msg = format!("Use of undeclared type or module `{}`",
2601
                                          names_to_string(&module_path));
2602
                        (span, msg)
2603 2604
                    }
                };
2605

J
Jonas Schievink 已提交
2606
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2607
                return Err(true);
2608
            }
2609
            Indeterminate => return Err(false),
J
Jeffrey Seyfried 已提交
2610
            Success(resulting_module) => {
2611 2612 2613 2614
                containing_module = resulting_module;
            }
        }

2615
        let name = segments.last().unwrap().identifier.name;
2616
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2617
        result.success().map(|binding| {
2618
            self.check_privacy(name, binding, span);
2619
            binding
2620
        }).ok_or(false)
2621 2622
    }

2623 2624
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
2625 2626 2627 2628 2629 2630
    fn resolve_crate_relative_path<T>(&mut self, span: Span, segments: &[T], namespace: Namespace)
                                      -> Result<&'a NameBinding<'a>,
                                                bool /* true if an error was reported */>
        where T: Named,
    {
        let module_path = segments.split_last().unwrap().1.iter().map(T::name).collect::<Vec<_>>();
2631
        let root_module = self.graph_root;
2632

2633
        let containing_module;
2634
        match self.resolve_module_path_from_root(root_module,
2635
                                                 &module_path,
2636
                                                 0,
J
Jeffrey Seyfried 已提交
2637
                                                 span) {
2638 2639 2640 2641 2642
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
2643
                                          names_to_string(&module_path));
2644
                        (span, msg)
2645 2646 2647
                    }
                };

J
Jonas Schievink 已提交
2648
                resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
2649
                return Err(true);
2650 2651
            }

2652
            Indeterminate => return Err(false),
2653

J
Jeffrey Seyfried 已提交
2654
            Success(resulting_module) => {
2655 2656 2657 2658
                containing_module = resulting_module;
            }
        }

2659
        let name = segments.last().unwrap().name();
J
Jeffrey Seyfried 已提交
2660
        let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
2661
        result.success().map(|binding| {
2662
            self.check_privacy(name, binding, span);
2663
            binding
2664
        }).ok_or(false)
2665 2666
    }

C
corentih 已提交
2667 2668
    fn with_no_errors<T, F>(&mut self, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2669
    {
2670
        self.emit_errors = false;
A
Alex Crichton 已提交
2671
        let rs = f(self);
2672 2673 2674 2675
        self.emit_errors = true;
        rs
    }

2676
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
2677
        fn extract_node_id(t: &Ty) -> Option<NodeId> {
2678
            match t.node {
2679 2680
                TyKind::Path(None, _) => Some(t.id),
                TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty),
2681 2682 2683 2684 2685 2686 2687
                // 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,
            }
        }

2688
        if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) {
2689
            // Look for a field with the same name in the current self_type.
2690 2691 2692 2693 2694 2695 2696 2697
            if let Some(resolution) = self.def_map.get(&node_id) {
                match resolution.base_def {
                    Def::Enum(did) | Def::TyAlias(did) |
                    Def::Struct(did) | Def::Variant(_, did) if resolution.depth == 0 => {
                        if let Some(fields) = self.structs.get(&did) {
                            if fields.iter().any(|&field_name| name == field_name) {
                                return Field;
                            }
2698
                        }
2699
                    }
2700 2701
                    _ => {}
                }
2702
            }
2703 2704 2705
        }

        // Look for a method in the current trait.
2706
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
2707 2708
            if let Some(&is_static_method) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method {
2709
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
2710 2711
                } else {
                    return TraitItem;
2712 2713 2714 2715 2716 2717 2718
                }
            }
        }

        NoSuggestion
    }

2719
    fn find_best_match(&mut self, name: &str) -> SuggestionType {
2720
        if let Some(macro_name) = self.session.available_macros
2721
                                  .borrow().iter().find(|n| n.as_str() == name) {
2722 2723 2724
            return SuggestionType::Macro(format!("{}!", macro_name));
        }

2725 2726 2727 2728
        let names = self.value_ribs
                    .iter()
                    .rev()
                    .flat_map(|rib| rib.bindings.keys());
2729

2730
        if let Some(found) = find_best_match_for_name(names, name, None) {
J
Jonas Schievink 已提交
2731
            if name != found {
2732
                return SuggestionType::Function(found);
2733
            }
2734
        } SuggestionType::NotFound
2735 2736
    }

2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748
    fn resolve_labeled_block(&mut self, label: Option<ast::Ident>, id: NodeId, block: &Block) {
        if let Some(label) = label {
            let (label, def) = (mtwt::resolve(label), Def::Label(id));
            self.with_label_rib(|this| {
                this.label_ribs.last_mut().unwrap().bindings.insert(label, def);
                this.visit_block(block);
            });
        } else {
            self.visit_block(block);
        }
    }

2749
    fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
P
Patrick Walton 已提交
2750 2751
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
2752 2753 2754

        self.record_candidate_traits_for_expr_if_necessary(expr);

2755
        // Next, resolve the node.
2756
        match expr.node {
2757
            ExprKind::Path(ref maybe_qself, ref path) => {
2758 2759
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
2760 2761
                if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id,
                                                            maybe_qself.as_ref(), path, ValueNS) {
2762
                    // Check if struct variant
2763
                    let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
2764 2765 2766 2767 2768 2769
                        self.structs.contains_key(&variant_id)
                    } else {
                        false
                    };
                    if is_struct_variant {
                        let _ = self.structs.contains_key(&path_res.base_def.def_id());
2770
                        let path_name = path_names_to_string(path, 0);
2771

N
Nick Cameron 已提交
2772 2773
                        let mut err = resolve_struct_error(self,
                                        expr.span,
J
Jonas Schievink 已提交
2774
                                        ResolutionError::StructVariantUsedAsFunction(&path_name));
2775

C
corentih 已提交
2776
                        let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
2777 2778
                                          path_name);
                        if self.emit_errors {
2779
                            err.help(&msg);
2780
                        } else {
N
Nick Cameron 已提交
2781
                            err.span_help(expr.span, &msg);
2782
                        }
N
Nick Cameron 已提交
2783
                        err.emit();
2784
                        self.record_def(expr.id, err_path_resolution());
2785
                    } else {
2786
                        // Write the result into the def map.
2787
                        debug!("(resolving expr) resolved `{}`",
2788
                               path_names_to_string(path, 0));
2789

2790 2791
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
2792
                        if path_res.depth != 0 {
2793
                            let method_name = path.segments.last().unwrap().identifier.name;
2794
                            let traits = self.get_traits_containing_item(method_name);
2795 2796 2797
                            self.trait_map.insert(expr.id, traits);
                        }

2798
                        self.record_def(expr.id, path_res);
2799
                    }
2800 2801 2802 2803 2804
                } else {
                    // Be helpful if the name refers to a struct
                    // (The pattern matching def_tys where the id is in self.structs
                    // matches on regular structs while excluding tuple- and enum-like
                    // structs, which wouldn't result in this error.)
2805
                    let path_name = path_names_to_string(path, 0);
2806
                    let type_res = self.with_no_errors(|this| {
J
Jeffrey Seyfried 已提交
2807
                        this.resolve_path(expr.id, path, 0, TypeNS)
2808
                    });
2809 2810

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

2812
                    if let Ok(Def::Struct(..)) = type_res.map(|r| r.base_def) {
J
Jeffrey Seyfried 已提交
2813 2814
                        let error_variant =
                            ResolutionError::StructVariantUsedAsFunction(&path_name);
2815 2816 2817 2818 2819 2820
                        let mut err = resolve_struct_error(self, expr.span, error_variant);

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

                        if self.emit_errors {
2821
                            err.help(&msg);
2822 2823 2824 2825 2826 2827 2828 2829 2830
                        } else {
                            err.span_help(expr.span, &msg);
                        }
                        err.emit();
                    } else {
                        // Keep reporting some errors even if they're ignored above.
                        if let Err(true) = self.resolve_path(expr.id, path, 0, ValueNS) {
                            // `resolve_path` already reported the error
                        } else {
2831
                            let mut method_scope = false;
2832
                            let mut is_static = false;
2833 2834
                            self.value_ribs.iter().rev().all(|rib| {
                                method_scope = match rib.kind {
2835 2836 2837 2838
                                    MethodRibKind(is_static_) => {
                                        is_static = is_static_;
                                        true
                                    }
2839 2840 2841 2842 2843
                                    ItemRibKind | ConstantItemRibKind => false,
                                    _ => return true, // Keep advancing
                                };
                                false // Stop advancing
                            });
2844

2845
                            if method_scope &&
2846
                                    &path_name[..] == keywords::SelfValue.name().as_str() {
C
corentih 已提交
2847 2848 2849
                                resolve_error(self,
                                              expr.span,
                                              ResolutionError::SelfNotAvailableInStaticMethod);
2850 2851
                            } else {
                                let last_name = path.segments.last().unwrap().identifier.name;
2852 2853
                                let (mut msg, is_field) =
                                    match self.find_fallback_in_self_type(last_name) {
2854 2855 2856
                                    NoSuggestion => {
                                        // limit search to 5 to reduce the number
                                        // of stupid suggestions
2857
                                        (match self.find_best_match(&path_name) {
2858 2859 2860 2861 2862
                                            SuggestionType::Macro(s) => {
                                                format!("the macro `{}`", s)
                                            }
                                            SuggestionType::Function(s) => format!("`{}`", s),
                                            SuggestionType::NotFound => "".to_string(),
2863 2864 2865 2866 2867 2868 2869 2870
                                        }, false)
                                    }
                                    Field => {
                                        (if is_static && method_scope {
                                            "".to_string()
                                        } else {
                                            format!("`self.{}`", path_name)
                                        }, true)
2871
                                    }
2872
                                    TraitItem => (format!("to call `self.{}`", path_name), false),
2873
                                    TraitMethod(path_str) =>
2874
                                        (format!("to call `{}::{}`", path_str, path_name), false),
2875 2876
                                };

2877
                                let mut context =  UnresolvedNameContext::Other;
G
ggomez 已提交
2878
                                let mut def = Def::Err;
2879
                                if !msg.is_empty() {
2880 2881 2882 2883 2884 2885 2886 2887
                                    msg = format!(". Did you mean {}?", msg);
                                } else {
                                    // we check if this a module and if so, we display a help
                                    // message
                                    let name_path = path.segments.iter()
                                                        .map(|seg| seg.identifier.name)
                                                        .collect::<Vec<_>>();

2888
                                    match self.resolve_module_path(&name_path[..],
J
Jeffrey Seyfried 已提交
2889 2890
                                                                   UseLexicalScope,
                                                                   expr.span) {
G
ggomez 已提交
2891 2892 2893 2894
                                        Success(e) => {
                                            if let Some(def_type) = e.def {
                                                def = def_type;
                                            }
2895
                                            context = UnresolvedNameContext::PathIsMod(parent);
2896 2897 2898
                                        },
                                        _ => {},
                                    };
2899
                                }
2900

2901 2902
                                resolve_error(self,
                                              expr.span,
2903 2904 2905 2906 2907 2908
                                              ResolutionError::UnresolvedName {
                                                  path: &path_name,
                                                  message: &msg,
                                                  context: context,
                                                  is_static_method: method_scope && is_static,
                                                  is_field: is_field,
G
ggomez 已提交
2909
                                                  def: def,
2910
                                              });
2911
                            }
V
Vincent Belliard 已提交
2912
                        }
2913 2914 2915
                    }
                }

2916
                visit::walk_expr(self, expr);
2917 2918
            }

2919
            ExprKind::Struct(ref path, _, _) => {
2920 2921 2922
                // Resolve the path to the structure it goes to. We don't
                // check to ensure that the path is actually a structure; that
                // is checked later during typeck.
J
Jeffrey Seyfried 已提交
2923
                match self.resolve_path(expr.id, path, 0, TypeNS) {
2924 2925 2926
                    Ok(definition) => self.record_def(expr.id, definition),
                    Err(true) => self.record_def(expr.id, err_path_resolution()),
                    Err(false) => {
2927
                        debug!("(resolving expression) didn't find struct def",);
2928

2929 2930
                        resolve_error(self,
                                      path.span,
2931
                                      ResolutionError::DoesNotNameAStruct(
J
Jonas Schievink 已提交
2932
                                                                &path_names_to_string(path, 0))
2933
                                     );
2934
                        self.record_def(expr.id, err_path_resolution());
2935 2936 2937
                    }
                }

2938
                visit::walk_expr(self, expr);
2939 2940
            }

2941
            ExprKind::Loop(_, Some(label)) | ExprKind::While(_, _, Some(label)) => {
2942
                self.with_label_rib(|this| {
2943
                    let def = Def::Label(expr.id);
2944

2945
                    {
2946
                        let rib = this.label_ribs.last_mut().unwrap();
2947
                        rib.bindings.insert(mtwt::resolve(label.node), def);
2948
                    }
2949

2950
                    visit::walk_expr(this, expr);
2951
                })
2952 2953
            }

2954
            ExprKind::Break(Some(label)) | ExprKind::Continue(Some(label)) => {
2955
                match self.search_label(mtwt::resolve(label.node)) {
2956
                    None => {
2957
                        self.record_def(expr.id, err_path_resolution());
2958
                        resolve_error(self,
2959 2960
                                      label.span,
                                      ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
2961
                    }
2962
                    Some(def @ Def::Label(_)) => {
2963
                        // Since this def is a label, it is never read.
2964
                        self.record_def(expr.id, PathResolution::new(def))
2965 2966
                    }
                    Some(_) => {
2967
                        span_bug!(expr.span, "label wasn't mapped to a label def!")
2968 2969 2970
                    }
                }
            }
2971 2972 2973 2974 2975

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

                self.value_ribs.push(Rib::new(NormalRibKind));
2976
                self.resolve_pattern(pattern, PatternSource::IfLet, &mut HashMap::new());
2977 2978 2979 2980 2981 2982 2983 2984 2985
                self.visit_block(if_block);
                self.value_ribs.pop();

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

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

2988
                self.resolve_labeled_block(label.map(|l| l.node), expr.id, block);
2989 2990 2991 2992 2993 2994 2995

                self.value_ribs.pop();
            }

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

2998
                self.resolve_labeled_block(label.map(|l| l.node), expr.id, block);
2999 3000 3001 3002 3003

                self.value_ribs.pop();
            }

            ExprKind::Field(ref subexpression, _) => {
3004 3005
                self.resolve_expr(subexpression, Some(expr));
            }
3006
            ExprKind::MethodCall(_, ref types, ref arguments) => {
3007 3008 3009 3010 3011 3012 3013 3014 3015
                let mut arguments = arguments.iter();
                self.resolve_expr(arguments.next().unwrap(), Some(expr));
                for argument in arguments {
                    self.resolve_expr(argument, None);
                }
                for ty in types.iter() {
                    self.visit_ty(ty);
                }
            }
3016

B
Brian Anderson 已提交
3017
            _ => {
3018
                visit::walk_expr(self, expr);
3019 3020 3021 3022
            }
        }
    }

E
Eduard Burtescu 已提交
3023
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3024
        match expr.node {
3025
            ExprKind::Field(_, name) => {
3026 3027 3028 3029
                // 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.
3030
                let traits = self.get_traits_containing_item(name.node.name);
3031
                self.trait_map.insert(expr.id, traits);
3032
            }
3033
            ExprKind::MethodCall(name, _, _) => {
C
corentih 已提交
3034
                debug!("(recording candidate traits for expr) recording traits for {}",
3035
                       expr.id);
3036
                let traits = self.get_traits_containing_item(name.node.name);
3037
                self.trait_map.insert(expr.id, traits);
3038
            }
3039
            _ => {
3040 3041 3042 3043 3044
                // Nothing to do.
            }
        }
    }

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

S
Seo Sanghyeon 已提交
3048 3049 3050 3051
        fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
                          trait_def_id: DefId,
                          import_id: Option<NodeId>,
                          name: Name) {
3052
            debug!("(adding trait info) found trait {:?} for method '{}'",
C
corentih 已提交
3053 3054
                   trait_def_id,
                   name);
S
Seo Sanghyeon 已提交
3055 3056 3057 3058
            found_traits.push(TraitCandidate {
                def_id: trait_def_id,
                import_id: import_id,
            });
E
Eduard Burtescu 已提交
3059
        }
3060

3061
        let mut found_traits = Vec::new();
J
Jeffrey Seyfried 已提交
3062 3063 3064
        // Look for the current trait.
        if let Some((trait_def_id, _)) = self.current_trait_ref {
            if self.trait_item_map.contains_key(&(name, trait_def_id)) {
S
Seo Sanghyeon 已提交
3065
                add_trait_info(&mut found_traits, trait_def_id, None, name);
E
Eduard Burtescu 已提交
3066
            }
J
Jeffrey Seyfried 已提交
3067
        }
3068

J
Jeffrey Seyfried 已提交
3069 3070
        let mut search_module = self.current_module;
        loop {
E
Eduard Burtescu 已提交
3071
            // Look for trait children.
3072
            let mut search_in_module = |this: &mut Self, module: Module<'a>| {
J
Jeffrey Seyfried 已提交
3073 3074 3075
                let mut traits = module.traits.borrow_mut();
                if traits.is_none() {
                    let mut collected_traits = Vec::new();
3076
                    module.for_each_child(|name, ns, binding| {
J
Jeffrey Seyfried 已提交
3077 3078
                        if ns != TypeNS { return }
                        if let Some(Def::Trait(_)) = binding.def() {
3079
                            collected_traits.push((name, binding));
J
Jeffrey Seyfried 已提交
3080 3081 3082
                        }
                    });
                    *traits = Some(collected_traits.into_boxed_slice());
3083
                }
J
Jeffrey Seyfried 已提交
3084

3085
                for &(trait_name, binding) in traits.as_ref().unwrap().iter() {
J
Jeffrey Seyfried 已提交
3086
                    let trait_def_id = binding.def().unwrap().def_id();
3087
                    if this.trait_item_map.contains_key(&(name, trait_def_id)) {
S
Seo Sanghyeon 已提交
3088 3089 3090
                        let mut import_id = None;
                        if let NameBindingKind::Import { directive, .. } = binding.kind {
                            let id = directive.id;
3091
                            this.maybe_unused_trait_imports.insert(id);
S
Seo Sanghyeon 已提交
3092 3093 3094
                            import_id = Some(id);
                        }
                        add_trait_info(&mut found_traits, trait_def_id, import_id, name);
3095
                        this.record_use(trait_name, binding);
J
Jeffrey Seyfried 已提交
3096 3097 3098
                    }
                }
            };
3099
            search_in_module(self, search_module);
3100

3101
            match search_module.parent_link {
3102
                NoParentLink | ModuleParentLink(..) => {
3103 3104 3105
                    if !search_module.no_implicit_prelude.get() {
                        self.prelude.map(|prelude| search_in_module(self, prelude));
                    }
3106 3107
                    break;
                }
E
Eduard Burtescu 已提交
3108
                BlockParentLink(parent_module, _) => {
3109
                    search_module = parent_module;
3110
                }
E
Eduard Burtescu 已提交
3111
            }
3112 3113
        }

E
Eduard Burtescu 已提交
3114
        found_traits
3115 3116
    }

3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136
    /// When name resolution fails, this method can be used to look up candidate
    /// entities with the expected name. It allows filtering them using the
    /// supplied predicate (which should be used to only accept the types of
    /// definitions expected e.g. traits). The lookup spans across all crates.
    ///
    /// NOTE: The method does not look into imports, but this is not a problem,
    /// since we report the definitions (thus, the de-aliased imports).
    fn lookup_candidates<FilterFn>(&mut self,
                                   lookup_name: Name,
                                   namespace: Namespace,
                                   filter_fn: FilterFn) -> SuggestedCandidates
        where FilterFn: Fn(Def) -> bool {

        let mut lookup_results = Vec::new();
        let mut worklist = Vec::new();
        worklist.push((self.graph_root, Vec::new(), false));

        while let Some((in_module,
                        path_segments,
                        in_module_is_extern)) = worklist.pop() {
3137
            self.populate_module_if_necessary(in_module);
3138 3139 3140 3141 3142 3143 3144 3145 3146 3147

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

                // avoid imports entirely
                if name_binding.is_import() { return; }

                // collect results based on the filter function
                if let Some(def) = name_binding.def() {
                    if name == lookup_name && ns == namespace && filter_fn(def) {
                        // create the path
3148
                        let ident = ast::Ident::with_empty_ctxt(name);
3149 3150 3151 3152 3153
                        let params = PathParameters::none();
                        let segment = PathSegment {
                            identifier: ident,
                            parameters: params,
                        };
3154
                        let span = name_binding.span;
3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168
                        let mut segms = path_segments.clone();
                        segms.push(segment);
                        let path = Path {
                            span: span,
                            global: true,
                            segments: segms,
                        };
                        // the entity is accessible in the following cases:
                        // 1. if it's defined in the same crate, it's always
                        // accessible (since private entities can be made public)
                        // 2. if it's defined in another crate, it's accessible
                        // only if both the module is public and the entity is
                        // declared as public (due to pruning, we don't explore
                        // outside crate private modules => no need to check this)
3169
                        if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181
                            lookup_results.push(path);
                        }
                    }
                }

                // collect submodules to explore
                if let Some(module) = name_binding.module() {
                    // form the path
                    let path_segments = match module.parent_link {
                        NoParentLink => path_segments.clone(),
                        ModuleParentLink(_, name) => {
                            let mut paths = path_segments.clone();
3182
                            let ident = ast::Ident::with_empty_ctxt(name);
3183 3184 3185 3186 3187 3188 3189 3190
                            let params = PathParameters::none();
                            let segm = PathSegment {
                                identifier: ident,
                                parameters: params,
                            };
                            paths.push(segm);
                            paths
                        }
3191
                        _ => bug!(),
3192 3193
                    };

3194
                    if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
3195
                        // add the module to the lookup
3196
                        let is_extern = in_module_is_extern || name_binding.is_extern_crate();
3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208
                        worklist.push((module, path_segments, is_extern));
                    }
                }
            })
        }

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

3209 3210
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
3211
        if let Some(prev_res) = self.def_map.insert(node_id, resolution) {
3212
            panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution);
3213
        }
3214 3215
    }

3216
    fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
3217
        let (path, id) = match *vis {
3218 3219 3220 3221
            ast::Visibility::Public => return ty::Visibility::Public,
            ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID),
            ast::Visibility::Restricted { ref path, id } => (path, id),
            ast::Visibility::Inherited => {
3222 3223
                let current_module =
                    self.get_nearest_normal_module_parent_or_self(self.current_module);
3224 3225
                let id =
                    self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
3226 3227 3228 3229 3230
                return ty::Visibility::Restricted(id);
            }
        };

        let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect();
3231
        let mut path_resolution = err_path_resolution();
3232 3233 3234
        let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, path.span) {
            Success(module) => {
                let def = module.def.unwrap();
3235
                path_resolution = PathResolution::new(def);
3236
                ty::Visibility::Restricted(self.definitions.as_local_node_id(def.def_id()).unwrap())
3237 3238 3239 3240 3241 3242 3243 3244 3245 3246
            }
            Failed(Some((span, msg))) => {
                self.session.span_err(span, &format!("failed to resolve module path. {}", msg));
                ty::Visibility::Public
            }
            _ => {
                self.session.span_err(path.span, "unresolved module path");
                ty::Visibility::Public
            }
        };
3247
        self.def_map.insert(id, path_resolution);
3248 3249 3250 3251 3252 3253 3254
        if !self.is_accessible(vis) {
            let msg = format!("visibilities can only be restricted to ancestor modules");
            self.session.span_err(path.span, &msg);
        }
        vis
    }

3255 3256
    fn is_accessible(&self, vis: ty::Visibility) -> bool {
        let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
3257
        let node_id = self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap();
3258
        vis.is_accessible_from(node_id, self)
3259 3260
    }

3261 3262
    fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
        if !self.is_accessible(binding.vis) {
3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282
            self.privacy_errors.push(PrivacyError(span, name, binding));
        }
    }

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

3284 3285 3286 3287 3288 3289 3290
    fn report_conflict(&self,
                       parent: Module,
                       name: Name,
                       ns: Namespace,
                       binding: &NameBinding,
                       old_binding: &NameBinding) {
        // Error on the second of two conflicting names
3291
        if old_binding.span.lo > binding.span.lo {
3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306
            return self.report_conflict(parent, name, ns, old_binding, binding);
        }

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

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

3307
        let span = binding.span;
3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327
        let msg = {
            let kind = match (ns, old_binding.module()) {
                (ValueNS, _) => "a value",
                (TypeNS, Some(module)) if module.extern_crate_id.is_some() => "an extern crate",
                (TypeNS, Some(module)) if module.is_normal() => "a module",
                (TypeNS, Some(module)) if module.is_trait() => "a trait",
                (TypeNS, _) => "a type",
            };
            format!("{} named `{}` has already been {} in this {}",
                    kind, name, participle, container)
        };

        let mut err = match (old_binding.is_extern_crate(), binding.is_extern_crate()) {
            (true, true) => struct_span_err!(self.session, span, E0259, "{}", msg),
            (true, _) | (_, true) if binding.is_import() || old_binding.is_import() =>
                struct_span_err!(self.session, span, E0254, "{}", msg),
            (true, _) | (_, true) => struct_span_err!(self.session, span, E0260, "{}", msg),
            _ => match (old_binding.is_import(), binding.is_import()) {
                (false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
                (true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
3328
                _ => {
3329 3330 3331
                    let mut e = struct_span_err!(self.session, span, E0255, "{}", msg);
                    e.span_label(span, &format!("`{}` was already imported", name));
                    e
3332
                }
3333 3334 3335
            },
        };

3336
        if old_binding.span != syntax_pos::DUMMY_SP {
3337
            err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
3338 3339 3340 3341
        }
        err.emit();
    }
}
3342 3343 3344 3345 3346 3347 3348 3349 3350 3351

fn names_to_string(names: &[Name]) -> String {
    let mut first = true;
    let mut result = String::new();
    for name in names {
        if first {
            first = false
        } else {
            result.push_str("::")
        }
3352
        result.push_str(&name.as_str());
C
corentih 已提交
3353
    }
3354 3355 3356 3357
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
C
corentih 已提交
3358
    let names: Vec<ast::Name> = path.segments[..path.segments.len() - depth]
3359 3360 3361 3362 3363 3364
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387
/// When an entity with a given name is not available in scope, we search for
/// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way
fn show_candidates(session: &mut DiagnosticBuilder,
                   candidates: &SuggestedCandidates) {

    let paths = &candidates.candidates;

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

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

        // behave differently based on how many candidates we have:
        if !paths.is_empty() {
            if paths.len() == 1 {
3388
                session.help(
T
tiehuis 已提交
3389
                    &format!("you can import it into scope: `use {};`.",
3390 3391 3392
                        &path_strings[0]),
                );
            } else {
3393
                session.help("you can import several candidates \
3394 3395 3396 3397 3398
                    into scope (`use ...;`):");
                let count = path_strings.len() as isize - MAX_CANDIDATES as isize + 1;

                for (idx, path_string) in path_strings.iter().enumerate() {
                    if idx == MAX_CANDIDATES - 1 && count > 1 {
3399
                        session.help(
3400 3401 3402 3403
                            &format!("  and {} other candidates", count).to_string(),
                        );
                        break;
                    } else {
3404
                        session.help(
3405 3406 3407 3408 3409 3410 3411 3412
                            &format!("  `{}`", path_string).to_string(),
                        );
                    }
                }
            }
        }
    } else {
        // nothing found:
3413
        session.help(
3414 3415 3416 3417 3418 3419 3420
            &format!("no candidates by the name of `{}` found in your \
            project; maybe you misspelled the name or forgot to import \
            an external crate?", candidates.name.to_string()),
        );
    };
}

3421
/// A somewhat inefficient routine to obtain the name of a module.
3422
fn module_to_string(module: Module) -> String {
3423 3424
    let mut names = Vec::new();

3425
    fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
3426 3427 3428 3429
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
3430
                collect_mod(names, module);
3431 3432 3433
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
3434
                names.push(token::intern("<opaque>"));
3435
                collect_mod(names, module);
3436 3437 3438 3439 3440
            }
        }
    }
    collect_mod(&mut names, module);

3441
    if names.is_empty() {
3442 3443 3444 3445 3446
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}

3447
fn err_path_resolution() -> PathResolution {
3448
    PathResolution::new(Def::Err)
3449 3450
}

N
Niko Matsakis 已提交
3451
#[derive(PartialEq,Copy, Clone)]
3452 3453
pub enum MakeGlobMap {
    Yes,
C
corentih 已提交
3454
    No,
3455 3456
}

3457
/// Entry point to crate resolution.
3458
pub fn resolve_crate<'a, 'b>(resolver: &'b mut Resolver<'a>, krate: &'b Crate) {
3459 3460 3461 3462 3463 3464 3465
    // Currently, we ignore the name resolution data structures for
    // the purposes of dependency tracking. Instead we will run name
    // resolution and include its output in the hash of each item,
    // much like we do for macro expansion. In other words, the hash
    // reflects not just its contents but the results of name
    // resolution on those contents. Hopefully we'll push this back at
    // some point.
3466
    let _ignore = resolver.session.dep_graph.in_ignore();
3467

3468 3469
    resolver.build_reduced_graph(krate);
    resolve_imports::resolve_imports(resolver);
3470 3471
    resolver.resolve_crate(krate);

3472
    check_unused::check_crate(resolver, krate);
3473
    resolver.report_privacy_errors();
3474
}
3475

3476
pub fn with_resolver<'a, T, F>(session: &'a Session,
3477
                               definitions: &'a mut Definitions,
3478 3479 3480 3481 3482 3483 3484
                               make_glob_map: MakeGlobMap,
                               f: F) -> T
    where F: for<'b> FnOnce(Resolver<'b>) -> T,
{
    let arenas = Resolver::arenas();
    let resolver = Resolver::new(session, definitions, make_glob_map, &arenas);
    f(resolver)
G
Garming Sam 已提交
3485 3486
}

3487
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }