lib.rs 164.1 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 12
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
13
#![crate_name = "rustc_resolve"]
14
#![unstable(feature = "rustc_private")]
B
Brian Anderson 已提交
15
#![staged_api]
16 17 18
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
A
Alex Crichton 已提交
19
      html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
20 21
      html_root_url = "http://doc.rust-lang.org/nightly/")]

T
Fallout  
Tamir Duberstein 已提交
22
#![feature(associated_consts)]
23
#![feature(rc_weak)]
A
Alex Crichton 已提交
24
#![feature(rustc_diagnostic_macros)]
25
#![feature(rustc_private)]
26
#![feature(slice_extras)]
A
Alex Crichton 已提交
27
#![feature(staged_api)]
28

A
Alex Crichton 已提交
29 30
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
31
#[macro_use] #[no_link] extern crate rustc_bitflags;
32 33 34

extern crate rustc;

S
Steven Fackler 已提交
35 36 37 38 39 40 41 42 43 44
use self::PatternBindingMode::*;
use self::Namespace::*;
use self::NamespaceResult::*;
use self::NameDefinition::*;
use self::ResolveResult::*;
use self::FallbackSuggestion::*;
use self::TypeParameters::*;
use self::RibKind::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
45
use self::AssocItemResolveResult::*;
S
Steven Fackler 已提交
46 47 48 49 50 51
use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;
use self::ModuleKind::*;
use self::FallbackChecks::*;

52
use rustc::ast_map;
53 54 55 56 57 58 59 60
use rustc::session::Session;
use rustc::lint;
use rustc::metadata::csearch;
use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use rustc::middle::def::*;
use rustc::middle::pat_util::pat_bindings;
use rustc::middle::privacy::*;
use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
61
use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
62
use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
A
Alex Crichton 已提交
63
use rustc::util::lev_distance::lev_distance;
64

65 66
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block};
use syntax::ast::{ConstImplItem, Crate, CrateNum};
67
use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
68
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
69
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
70
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
71
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
F
Flavio Percoco 已提交
72
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
73
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
74
use syntax::ast::{Local, MethodImplItem, Name, NodeId};
75
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
76 77 78
use syntax::ast::{PatRange, PatStruct, Path, PrimTy};
use syntax::ast::{TraitRef, Ty, TyBool, TyChar, TyF32};
use syntax::ast::{TyF64, TyFloat, TyIs, TyI8, TyI16, TyI32, TyI64, TyInt};
79
use syntax::ast::{TyPath, TyPtr};
80
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
81
use syntax::ast::TypeImplItem;
P
Patrick Walton 已提交
82
use syntax::ast;
83
use syntax::ast_util::{local_def, walk_pat};
84
use syntax::attr::AttrMetaMethods;
85
use syntax::ext::mtwt;
86
use syntax::parse::token::{self, special_names, special_idents};
87
use syntax::ptr::P;
88
use syntax::codemap::{self, Span, Pos};
89
use syntax::visit::{self, Visitor};
90

91
use std::collections::{HashMap, HashSet};
C
Corey Farwell 已提交
92
use std::collections::hash_map::Entry::{Occupied, Vacant};
93
use std::cell::{Cell, RefCell};
94
use std::fmt;
95
use std::mem::replace;
E
Eduard Burtescu 已提交
96
use std::rc::{Rc, Weak};
97
use std::usize;
98

99 100 101
use resolve_imports::{Target, ImportDirective, ImportResolution};
use resolve_imports::Shadowable;

102 103 104 105
// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
pub mod diagnostics;

G
Guillaume Gomez 已提交
106 107 108 109 110 111 112 113
macro_rules! resolve_err {
    ($this:expr, $span:expr, $code:ident, $($rest:tt)*) => {
        if $this.emit_errors {
            span_err!($this.session, $span, $code, $($rest)*);
        }
    }
}

A
Alex Crichton 已提交
114 115
mod check_unused;
mod record_exports;
116
mod build_reduced_graph;
117
mod resolve_imports;
118

119
pub enum ResolutionError<'b, 'a:'b, 'tcx:'a> {
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    /// error E0401: can't use type parameters from outer function
    TypeParametersFromOuterFunction(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0402: cannot use an outer type parameter in this context
    OuterTypeParameterContext(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0403: the name is already used for a type parameter in this type parameter list
    NameAlreadyUsedInTypeParameterList(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                       syntax::ast::Name),
    /// error E0404: is not a trait
    IsNotATrait(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0405: use of undeclared trait name
    UndeclaredTraitName(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0406: undeclared associated type
    UndeclaredAssociatedType(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0407: method is not a member of trait
    MethodNotMemberOfTrait(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, syntax::ast::Name,
                           &'b str),
    /// error E0408: variable `{}` from pattern #1 is not bound in pattern
    VariableNotBoundInPattern(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, syntax::ast::Name,
                              usize),
    /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
    VariableBoundWithDifferentMode(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                   syntax::ast::Name, usize),
    /// error E0410: variable from pattern is not bound in pattern #1
    VariableNotBoundInParentPattern(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                    syntax::ast::Name, usize),
    /// error E0411: use of `Self` outside of an impl or trait
    SelfUsedOutsideImplOrTrait(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0412: use of undeclared
    UseOfUndeclared(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str, &'b str),
    /// error E0413: declaration shadows an enum variant or unit-like struct in scope
    DeclarationShadowsEnumVariantOrUnitLikeStruct(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                                  syntax::ast::Name),
    /// error E0414: only irrefutable patterns allowed here
    OnlyIrrefutablePatternsAllowedHere(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0415: identifier is bound more than once in this parameter list
    IdentifierBoundMoreThanOnceInParameterList(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                               &'b str),
    /// error E0416: identifier is bound more than once in the same pattern
    IdentifierBoundMoreThanOnceInSamePattern(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                                             &'b str),
    /// error E0417: static variables cannot be referenced in a pattern
161
    StaticVariableReference(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
    /// error E0418: is not an enum variant, struct or const
    NotAnEnumVariantStructOrConst(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0419: unresolved enum variant, struct or const
    UnresolvedEnumVariantStructOrConst(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0420: is not an associated const
    NotAnAssociatedConst(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0421: unresolved associated const
    UnresolvedAssociatedConst(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0422: does not name a struct
    DoesNotNameAStruct(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0423: is a struct variant name, but this expression uses it like a function name
    StructVariantUsedAsFunction(&'a Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0424: `self` is not available in a static method
    SelfNotAvailableInStaticMethod(&'a Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0425: unresolved name
    UnresolvedName(&'a Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str, &'b str),
    /// error E0426: use of undeclared label
    UndeclaredLabel(&'a Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0427: cannot use `ref` binding mode with ...
    CannotUseRefBindingModeWith(&'a Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0428: duplicate definition
    DuplicateDefinition(&'a Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str, &'b str),
    /// error E0429: `self` imports are only allowed within a { } list
    SelfImportsOnlyAllowedWithin(&'a Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0430: `self` import can only appear once in the list
    SelfImportCanOnlyAppearOnceInTheList(&'a Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0431: `self` import can only appear in an import list with a non-empty prefix
    SelfImportOnlyInImportListWithNonEmptyPrefix(&'a Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0432: unresolved import
    UnresolvedImport(&'b Resolver<'a, 'tcx>, syntax::codemap::Span,
                     Option<(&'b str, Option<&'b str>)>),
    /// error E0433: failed to resolve
    FailedToResolve(&'b Resolver<'a, 'tcx>, syntax::codemap::Span, &'b str),
    /// error E0434: can't capture dynamic environment in a fn item
    CannotCaptureDynamicEnvironmentInFnItem(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
    /// error E0435: attempt to use a non-constant value in a constant
    AttemptToUseNonConstantValueInConstant(&'b Resolver<'a, 'tcx>, syntax::codemap::Span),
199 200
}

201
fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolution_error: &ResolutionError<'b, 'a, 'tcx>) {
202
    match resolution_error {
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
        &ResolutionError::TypeParametersFromOuterFunction(resolver, span) => {
            resolve_err!(resolver, span, E0401, "can't use type parameters from \
                                                 outer function; try using a local \
                                                 type parameter instead");
        },
        &ResolutionError::OuterTypeParameterContext(resolver, span) => {
            resolve_err!(resolver, span, E0402,
                         "cannot use an outer type parameter in this context");
        },
        &ResolutionError::NameAlreadyUsedInTypeParameterList(resolver, span, name) => {
            resolve_err!(resolver, span, E0403,
                         "the name `{}` is already used for a type \
                          parameter in this type parameter list", name);
        },
        &ResolutionError::IsNotATrait(resolver, span, name) => {
            resolve_err!(resolver, span, E0404,
                         "`{}` is not a trait",
                         name);
        },
        &ResolutionError::UndeclaredTraitName(resolver, span, name) => {
            resolve_err!(resolver, span, E0405,
                         "use of undeclared trait name `{}`",
                         name);
        },
        &ResolutionError::UndeclaredAssociatedType(resolver, span) => {
            resolve_err!(resolver, span, E0406, "undeclared associated type");
        },
        &ResolutionError::MethodNotMemberOfTrait(resolver, span, method, trait_) => {
            resolve_err!(resolver, span, E0407,
                         "method `{}` is not a member of trait `{}`",
                         method,
                         trait_);
        },
        &ResolutionError::VariableNotBoundInPattern(resolver, span, variable_name,
                                                    pattern_number) => {
            resolve_err!(resolver, span, E0408,
                         "variable `{}` from pattern #1 is not bound in pattern #{}",
                         variable_name,
                         pattern_number);
        },
        &ResolutionError::VariableBoundWithDifferentMode(resolver, span, variable_name,
                                                         pattern_number) => {
            resolve_err!(resolver, span, E0409,
                         "variable `{}` is bound with different \
                         mode in pattern #{} than in pattern #1",
                         variable_name,
                         pattern_number);
        },
        &ResolutionError::VariableNotBoundInParentPattern(resolver, span, variable_name,
                                                          pattern_number) => {
            resolve_err!(resolver, span, E0410,
                         "variable `{}` from pattern #{} is not bound in pattern #1",
                         variable_name,
                         pattern_number);
        },
        &ResolutionError::SelfUsedOutsideImplOrTrait(resolver, span) => {
            resolve_err!(resolver, span, E0411, "use of `Self` outside of an impl or trait");
        },
        &ResolutionError::UseOfUndeclared(resolver, span, kind, name) => {
            resolve_err!(resolver, span, E0412,
                         "use of undeclared {} `{}`",
                         kind,
                         name);
        },
        &ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(resolver, span, name) => {
            resolve_err!(resolver, span, E0413,
                         "declaration of `{}` shadows an enum variant or unit-like struct in \
                          scope",
                         name);
        },
        &ResolutionError::OnlyIrrefutablePatternsAllowedHere(resolver, span) => {
            resolve_err!(resolver, span, E0414, "only irrefutable patterns allowed here");
        },
        &ResolutionError::IdentifierBoundMoreThanOnceInParameterList(resolver, span,
                                                                     identifier) => {
            resolve_err!(resolver, span, E0415,
                         "identifier `{}` is bound more than once in this parameter list",
                         identifier);
        },
        &ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(resolver, span, identifier) => {
            resolve_err!(resolver, span, E0416,
                         "identifier `{}` is bound more than once in the same pattern",
                         identifier);
        },
287
        &ResolutionError::StaticVariableReference(resolver, span) => {
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
            resolve_err!(resolver, span, E0417, "static variables cannot be \
                                                 referenced in a pattern, \
                                                 use a `const` instead");
        },
        &ResolutionError::NotAnEnumVariantStructOrConst(resolver, span, name) => {
            resolve_err!(resolver, span, E0418,
                         "`{}` is not an enum variant, struct or const",
                         name);
        },
        &ResolutionError::UnresolvedEnumVariantStructOrConst(resolver, span, name) => {
            resolve_err!(resolver, span, E0419,
                         "unresolved enum variant, struct or const `{}`",
                         name);
        },
        &ResolutionError::NotAnAssociatedConst(resolver, span, name) => {
            resolve_err!(resolver, span, E0420,
                         "`{}` is not an associated const",
                         name);
306
        },
307 308 309 310
        &ResolutionError::UnresolvedAssociatedConst(resolver, span, name) => {
            resolve_err!(resolver, span, E0421,
                         "unresolved associated const `{}`",
                         name);
311
        },
312 313
        &ResolutionError::DoesNotNameAStruct(resolver, span, name) => {
            resolve_err!(resolver, span, E0422, "`{}` does not name a structure", name);
314
        },
315 316 317 318 319 320
        &ResolutionError::StructVariantUsedAsFunction(resolver, span, path_name) => {
            resolve_err!(resolver, span, E0423,
                         "`{}` is a struct variant name, but \
                          this expression \
                          uses it like a function name",
                          path_name);
321
        },
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
        &ResolutionError::SelfNotAvailableInStaticMethod(resolver, span) => {
            resolve_err!(resolver, span, E0424, "`self` is not available in a static method. \
                                                 Maybe a `self` argument is missing?");
        },
        &ResolutionError::UnresolvedName(resolver, span, path, name) => {
            resolve_err!(resolver, span, E0425,
                         "unresolved name `{}`{}",
                         path,
                         name);
        },
        &ResolutionError::UndeclaredLabel(resolver, span, name) => {
            resolve_err!(resolver, span, E0426,
                         "use of undeclared label `{}`",
                         name);
        },
        &ResolutionError::CannotUseRefBindingModeWith(resolver, span, descr) => {
            resolve_err!(resolver, span, E0427,
                         "cannot use `ref` binding mode with {}",
                         descr);
        },
        &ResolutionError::DuplicateDefinition(resolver, span, namespace, name) => {
            resolve_err!(resolver, span, E0428,
                         "duplicate definition of {} `{}`",
                         namespace,
                         name);
        },
        &ResolutionError::SelfImportsOnlyAllowedWithin(resolver, span) => {
            resolve_err!(resolver, span, E0429, "{}",
                         "`self` imports are only allowed within a { } list");
        },
        &ResolutionError::SelfImportCanOnlyAppearOnceInTheList(resolver, span) => {
            resolve_err!(resolver, span, E0430,
                         "`self` import can only appear once in the list");
        },
        &ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix(resolver, span) => {
            resolve_err!(resolver, span, E0431,
                         "`self` import can only appear in an import list with a \
                          non-empty prefix");
        }
        &ResolutionError::UnresolvedImport(resolver, span, name) => {
            let msg = match name {
                Some((n, Some(p))) => format!("unresolved import `{}`{}", n, p),
                Some((n, None)) => format!("unresolved import (maybe you meant `{}::*`?)", n),
                None => "unresolved import".to_owned()
            };
            resolve_err!(resolver, span, E0432, "{}", msg);
        },
        &ResolutionError::FailedToResolve(resolver, span, msg) => {
            resolve_err!(resolver, span, E0433, "failed to resolve. {}", msg);
        },
        &ResolutionError::CannotCaptureDynamicEnvironmentInFnItem(resolver, span) => {
            resolve_err!(resolver, span, E0434, "{}",
                         "can't capture dynamic environment in a fn item; \
                          use the || { ... } closure form instead");
        },
        &ResolutionError::AttemptToUseNonConstantValueInConstant(resolver, span) =>{
            resolve_err!(resolver, span, E0435,
                         "attempt to use a non-constant value in a constant");
380 381
        },
    }
382 383
}

N
Niko Matsakis 已提交
384
#[derive(Copy, Clone)]
385
struct BindingInfo {
386
    span: Span,
387
    binding_mode: BindingMode,
388 389 390
}

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

N
Niko Matsakis 已提交
393
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
394
enum PatternBindingMode {
395
    RefutableMode,
396
    LocalIrrefutableMode,
397
    ArgumentIrrefutableMode,
398 399
}

N
Niko Matsakis 已提交
400
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
F
Felix S. Klock II 已提交
401
enum Namespace {
402
    TypeNS,
403
    ValueNS
404 405
}

B
Brian Anderson 已提交
406 407 408
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
409
#[derive(Clone)]
F
Felix S. Klock II 已提交
410
enum NamespaceResult {
T
Tim Chevalier 已提交
411 412 413
    /// Means that resolve hasn't gathered enough information yet to determine
    /// whether the name is bound in this namespace. (That is, it hasn't
    /// resolved all `use` directives yet.)
414
    UnknownResult,
B
Brian Anderson 已提交
415 416
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
417
    UnboundResult,
T
Tim Chevalier 已提交
418 419
    /// Means that resolve has determined that the name is bound in the Module
    /// argument, and specified by the NameBindings argument.
E
Eduard Burtescu 已提交
420
    BoundResult(Rc<Module>, Rc<NameBindings>)
421 422
}

423
impl NamespaceResult {
F
Felix S. Klock II 已提交
424
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
425
        match *self {
426 427 428 429
            UnknownResult => true,
            _ => false
        }
    }
430 431 432 433 434 435
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
            _ => false
        }
    }
436 437
}

F
Felix S. Klock II 已提交
438
enum NameDefinition {
N
Nick Cameron 已提交
439 440 441 442 443 444
    // The name was unbound.
    NoNameDefinition,
    // The name identifies an immediate child.
    ChildNameDefinition(Def, LastPrivate),
    // The name identifies an import.
    ImportNameDefinition(Def, LastPrivate),
445 446
}

447
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
448
    fn visit_item(&mut self, item: &Item) {
A
Alex Crichton 已提交
449
        self.resolve_item(item);
450
    }
451
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
452
        self.resolve_arm(arm);
453
    }
454
    fn visit_block(&mut self, block: &Block) {
A
Alex Crichton 已提交
455
        self.resolve_block(block);
456
    }
457
    fn visit_expr(&mut self, expr: &Expr) {
A
Alex Crichton 已提交
458
        self.resolve_expr(expr);
459
    }
460
    fn visit_local(&mut self, local: &Local) {
A
Alex Crichton 已提交
461
        self.resolve_local(local);
462
    }
463
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
464
        self.resolve_type(ty);
465
    }
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
    fn visit_generics(&mut self, generics: &Generics) {
        self.resolve_generics(generics);
    }
    fn visit_poly_trait_ref(&mut self,
                            tref: &ast::PolyTraitRef,
                            m: &ast::TraitBoundModifier) {
        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),
            Err(_) => { /* error already reported */ }
        }
        visit::walk_poly_trait_ref(self, tref, m);
    }
    fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) {
        if let Some(ref dis_expr) = variant.node.disr_expr {
            // resolve the discriminator expr as a constant
            self.with_constant_rib(|this| {
                this.visit_expr(&**dis_expr);
            });
        }

        // `visit::walk_variant` without the discriminant expression.
        match variant.node.kind {
            ast::TupleVariantKind(ref variant_arguments) => {
489
                for variant_argument in variant_arguments {
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
                    self.visit_ty(&*variant_argument.ty);
                }
            }
            ast::StructVariantKind(ref struct_definition) => {
                self.visit_struct_def(&**struct_definition,
                                      variant.node.name,
                                      generics,
                                      variant.node.id);
            }
        }
    }
    fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) {
        let type_parameters = match foreign_item.node {
            ForeignItemFn(_, ref generics) => {
                HasTypeParameters(generics, FnSpace, ItemRibKind)
            }
            ForeignItemStatic(..) => NoTypeParameters
        };
        self.with_type_parameter_rib(type_parameters, |this| {
            visit::walk_foreign_item(this, foreign_item);
        });
    }
    fn visit_fn(&mut self,
                function_kind: visit::FnKind<'v>,
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
N
Niko Matsakis 已提交
519
            visit::FkItemFn(_, generics, _, _, _, _) => {
520 521 522
                self.visit_generics(generics);
                ItemRibKind
            }
523
            visit::FkMethod(_, sig, _) => {
524 525
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
526 527 528 529 530 531
                MethodRibKind
            }
            visit::FkFnBlock(..) => ClosureRibKind(node_id)
        };
        self.resolve_function(rib_kind, declaration, block);
    }
532
}
533

534 535
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
536
enum ResolveResult<T> {
537 538 539
    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.
540 541
}

542
impl<T> ResolveResult<T> {
F
Felix S. Klock II 已提交
543
    fn indeterminate(&self) -> bool {
B
Ben Striegel 已提交
544
        match *self { Indeterminate => true, _ => false }
545 546 547
    }
}

548 549 550 551
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
552
    TraitItem,
553
    StaticMethod(String),
554
    TraitMethod(String),
555 556
}

N
Niko Matsakis 已提交
557
#[derive(Copy, Clone)]
E
Erik Price 已提交
558
enum TypeParameters<'a> {
559 560 561 562 563 564 565 566 567 568 569
    NoTypeParameters,
    HasTypeParameters(
        // Type parameters.
        &'a Generics,

        // Identifies the things that these parameters
        // were declared on (type, fn, etc)
        ParamSpace,

        // The kind of the rib used for type parameters.
        RibKind)
570 571
}

572 573
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
574
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
575
enum RibKind {
576 577
    // No translation needs to be applied.
    NormalRibKind,
578

579 580
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
581
    ClosureRibKind(NodeId /* func id */),
582

583
    // We passed through an impl or trait and are now in one of its
584
    // methods. Allow references to ty params that impl or trait
585 586
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
587
    MethodRibKind,
588

589 590
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
591 592 593

    // We're in a constant item. Can't refer to dynamic stuff.
    ConstantItemRibKind
594 595
}

N
Niko Matsakis 已提交
596
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
597
enum UseLexicalScopeFlag {
598 599 600 601
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
602
enum ModulePrefixResult {
603
    NoPrefixFound,
604
    PrefixFound(Rc<Module>, usize)
605 606
}

607 608 609 610 611 612 613 614 615
#[derive(Copy, Clone)]
enum AssocItemResolveResult {
    /// Syntax such as `<T>::item`, which can't be resolved until type
    /// checking.
    TypecheckRequired,
    /// We should have been able to resolve the associated item.
    ResolveAttempt(Option<PathResolution>),
}

N
Niko Matsakis 已提交
616
#[derive(Copy, Clone, PartialEq)]
617
enum NameSearchType {
618 619 620 621
    /// We're doing a name search in order to resolve a `use` directive.
    ImportSearch,

    /// We're doing a name search in order to resolve a path type, a path
622 623
    /// expression, or a path pattern.
    PathSearch,
624 625
}

N
Niko Matsakis 已提交
626
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
627
enum BareIdentifierPatternResolution {
628 629
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
630
    BareIdentifierPatternUnresolved
631 632
}

633
/// One local scope.
J
Jorge Aparicio 已提交
634
#[derive(Debug)]
F
Felix S. Klock II 已提交
635
struct Rib {
636
    bindings: HashMap<Name, DefLike>,
637
    kind: RibKind,
B
Brian Anderson 已提交
638
}
639

640
impl Rib {
F
Felix S. Klock II 已提交
641
    fn new(kind: RibKind) -> Rib {
642
        Rib {
643
            bindings: HashMap::new(),
644 645
            kind: kind
        }
646 647 648
    }
}

649
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
650
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
651
enum ParentLink {
652
    NoParentLink,
653
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
654
    BlockParentLink(Weak<Module>, NodeId)
655 656
}

657
/// The type of module this is.
N
Niko Matsakis 已提交
658
#[derive(Copy, Clone, PartialEq, Debug)]
F
Felix S. Klock II 已提交
659
enum ModuleKind {
660 661
    NormalModuleKind,
    TraitModuleKind,
662
    EnumModuleKind,
663
    TypeModuleKind,
664 665 666
    AnonymousModuleKind,
}

667
/// One node in the tree of modules.
668
pub struct Module {
669
    parent_link: ParentLink,
670
    def_id: Cell<Option<DefId>>,
671
    kind: Cell<ModuleKind>,
672
    is_public: bool,
673

E
Eduard Burtescu 已提交
674 675
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
676

677
    // The external module children of this node that were declared with
A
Alex Crichton 已提交
678
    // `extern crate`.
E
Eduard Burtescu 已提交
679
    external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
680

681 682 683 684 685 686 687 688 689 690 691 692 693 694
    // The anonymous children of this node. Anonymous children 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`.
E
Eduard Burtescu 已提交
695
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
696 697

    // The status of resolving each import in this module.
E
Eduard Burtescu 已提交
698
    import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
699 700

    // The number of unresolved globs that this module exports.
701
    glob_count: Cell<usize>,
702 703

    // The index of the import we're resolving.
704
    resolved_import_count: Cell<usize>,
705 706 707 708

    // Whether this module is populated. If not populated, any attempt to
    // access the children must be preceded with a
    // `populate_module_if_necessary` call.
709
    populated: Cell<bool>,
710 711
}

712
impl Module {
F
Felix S. Klock II 已提交
713
    fn new(parent_link: ParentLink,
714 715 716 717
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
718
           -> Module {
719 720
        Module {
            parent_link: parent_link,
721
            def_id: Cell::new(def_id),
722
            kind: Cell::new(kind),
723
            is_public: is_public,
724
            children: RefCell::new(HashMap::new()),
725
            imports: RefCell::new(Vec::new()),
726
            external_module_children: RefCell::new(HashMap::new()),
727
            anonymous_children: RefCell::new(NodeMap()),
728
            import_resolutions: RefCell::new(HashMap::new()),
729
            glob_count: Cell::new(0),
730
            resolved_import_count: Cell::new(0),
731
            populated: Cell::new(!external),
732
        }
B
Brian Anderson 已提交
733 734
    }

F
Felix S. Klock II 已提交
735
    fn all_imports_resolved(&self) -> bool {
736
        self.imports.borrow().len() == self.resolved_import_count.get()
737 738 739
    }
}

740
impl fmt::Debug for Module {
741
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
742
        write!(f, "{:?}, kind: {:?}, {}",
743 744 745 746 747 748
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

749
bitflags! {
J
Jorge Aparicio 已提交
750
    #[derive(Debug)]
751
    flags DefModifiers: u8 {
T
Fallout  
Tamir Duberstein 已提交
752 753
        const PUBLIC     = 1 << 0,
        const IMPORTABLE = 1 << 1,
754 755 756
    }
}

757
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
758
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
759
struct TypeNsDef {
760
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
761
    module_def: Option<Rc<Module>>,
762
    type_def: Option<Def>,
763
    type_span: Option<Span>
764 765 766
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
767
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
768
struct ValueNsDef {
769
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
770
    def: Def,
771
    value_span: Option<Span>,
772 773
}

774 775
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
776
#[derive(Debug)]
777
pub struct NameBindings {
778
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
779
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
780 781
}

782
impl NameBindings {
K
Kevin Butler 已提交
783 784 785 786 787 788 789
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

790
    /// Creates a new module in this set of name bindings.
791
    fn define_module(&self,
792 793 794 795 796 797
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
798
        // Merges the module with the existing type def or creates a new one.
T
Fallout  
Tamir Duberstein 已提交
799 800 801 802 803
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
804 805 806 807
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
808
                                          is_public));
E
Erick Tryzelaar 已提交
809 810
        let type_def = self.type_def.borrow().clone();
        match type_def {
811
            None => {
E
Erick Tryzelaar 已提交
812
                *self.type_def.borrow_mut() = Some(TypeNsDef {
813
                    modifiers: modifiers,
814
                    module_def: Some(module_),
815 816
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
817
                });
818
            }
819
            Some(type_def) => {
E
Erick Tryzelaar 已提交
820
                *self.type_def.borrow_mut() = Some(TypeNsDef {
821
                    modifiers: modifiers,
822
                    module_def: Some(module_),
823
                    type_span: Some(sp),
824
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
825
                });
826
            }
827 828 829
        }
    }

830
    /// Sets the kind of the module, creating a new one if necessary.
831
    fn set_module_kind(&self,
832 833 834 835 836 837
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
T
Fallout  
Tamir Duberstein 已提交
838 839 840 841 842
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
E
Erick Tryzelaar 已提交
843 844
        let type_def = self.type_def.borrow().clone();
        match type_def {
845
            None => {
846 847 848 849 850
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
851
                *self.type_def.borrow_mut() = Some(TypeNsDef {
852
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
853
                    module_def: Some(Rc::new(module)),
854 855
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
856
                });
857 858 859 860
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
861 862 863 864 865
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
866
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
867
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
868
                            module_def: Some(Rc::new(module)),
869 870
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
871
                        });
872
                    }
873
                    Some(module_def) => module_def.kind.set(kind),
874 875 876 877 878
                }
            }
        }
    }

879
    /// Records a type definition.
880
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
881
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
882
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
883 884
        let type_def = self.type_def.borrow().clone();
        match type_def {
885
            None => {
E
Erick Tryzelaar 已提交
886
                *self.type_def.borrow_mut() = Some(TypeNsDef {
887
                    module_def: None,
888
                    type_def: Some(def),
889
                    type_span: Some(sp),
890
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
891
                });
892
            }
893
            Some(type_def) => {
E
Erick Tryzelaar 已提交
894
                *self.type_def.borrow_mut() = Some(TypeNsDef {
895
                    module_def: type_def.module_def,
896
                    type_def: Some(def),
897
                    type_span: Some(sp),
898
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
899
                });
900 901
            }
        }
902 903
    }

904
    /// Records a value definition.
905
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
906
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
907
        *self.value_def.borrow_mut() = Some(ValueNsDef {
908 909
            def: def,
            value_span: Some(sp),
910
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
911
        });
912 913
    }

914
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
915
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
916
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
917
            Some(ref type_def) => type_def.module_def.clone(),
918
            None => None
919 920 921
        }
    }

S
Steve Klabnik 已提交
922 923
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
924
    fn get_module(&self) -> Rc<Module> {
925 926
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
927
                panic!("get_module called on a node with no module \
928
                       definition!")
929
            }
930
            Some(module_def) => module_def
931 932 933
        }
    }

F
Felix S. Klock II 已提交
934
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
935
        match namespace {
E
Erick Tryzelaar 已提交
936 937
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
938 939 940
        }
    }

F
Felix S. Klock II 已提交
941
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
T
Fallout  
Tamir Duberstein 已提交
942
        self.defined_in_namespace_with(namespace, DefModifiers::PUBLIC)
943 944 945
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
946
        match namespace {
E
Erick Tryzelaar 已提交
947
            TypeNS => match *self.type_def.borrow() {
948
                Some(ref def) => def.modifiers.contains(modifiers), None => false
949
            },
E
Erick Tryzelaar 已提交
950
            ValueNS => match *self.value_def.borrow() {
951
                Some(ref def) => def.modifiers.contains(modifiers), None => false
952 953 954 955
            }
        }
    }

F
Felix S. Klock II 已提交
956
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
957
        match namespace {
958
            TypeNS => {
E
Erick Tryzelaar 已提交
959
                match *self.type_def.borrow() {
960
                    None => None,
E
Eduard Burtescu 已提交
961
                    Some(ref type_def) => {
962
                        match type_def.type_def {
963
                            Some(type_def) => Some(type_def),
964 965
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
966
                                    Some(ref module) => {
967
                                        match module.def_id.get() {
968
                                            Some(did) => Some(DefMod(did)),
969 970 971 972 973 974
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
975
                        }
976 977
                    }
                }
978 979
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
980
                match *self.value_def.borrow() {
981 982 983 984 985 986 987
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
988
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
989
        if self.defined_in_namespace(namespace) {
990
            match namespace {
991
                TypeNS  => {
E
Erick Tryzelaar 已提交
992
                    match *self.type_def.borrow() {
993
                        None => None,
E
Eduard Burtescu 已提交
994
                        Some(ref type_def) => type_def.type_span
995 996 997
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
998
                    match *self.value_def.borrow() {
999
                        None => None,
E
Eduard Burtescu 已提交
1000
                        Some(ref value_def) => value_def.value_span
1001 1002
                    }
                }
1003
            }
1004 1005
        } else {
            None
1006 1007
        }
    }
1008 1009 1010 1011 1012

    fn is_public(&self, namespace: Namespace) -> bool {
        match namespace {
            TypeNS  => {
                let type_def = self.type_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1013
                type_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1014 1015 1016
            }
            ValueNS => {
                let value_def = self.value_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1017
                value_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1018 1019 1020
            }
        }
    }
1021 1022
}

1023
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1024
struct PrimitiveTypeTable {
1025
    primitive_types: HashMap<Name, PrimTy>,
1026
}
1027

1028
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1029 1030 1031 1032 1033 1034 1035 1036 1037
    fn new() -> PrimitiveTypeTable {
        let mut table = PrimitiveTypeTable {
            primitive_types: HashMap::new()
        };

        table.intern("bool",    TyBool);
        table.intern("char",    TyChar);
        table.intern("f32",     TyFloat(TyF32));
        table.intern("f64",     TyFloat(TyF64));
1038
        table.intern("isize",   TyInt(TyIs));
K
Kevin Butler 已提交
1039 1040 1041 1042 1043
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
1044
        table.intern("usize",   TyUint(TyUs));
K
Kevin Butler 已提交
1045 1046 1047 1048 1049 1050 1051 1052
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

1053
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1054
        self.primitive_types.insert(token::intern(string), primitive_type);
1055 1056 1057
    }
}

1058
/// The main resolver class.
1059
pub struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
1060
    session: &'a Session,
1061

1062 1063
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
1064
    graph_root: NameBindings,
1065

1066
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1067

1068
    structs: FnvHashMap<DefId, Vec<Name>>,
1069

1070
    // The number of imports that are currently unresolved.
1071
    unresolved_imports: usize,
1072 1073

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
1074
    current_module: Rc<Module>,
1075 1076

    // The current set of local scopes, for values.
1077
    // FIXME #4948: Reuse ribs to avoid allocation.
1078
    value_ribs: Vec<Rib>,
1079 1080

    // The current set of local scopes, for types.
1081
    type_ribs: Vec<Rib>,
1082

1083
    // The current set of local scopes, for labels.
1084
    label_ribs: Vec<Rib>,
1085

1086
    // The trait that the current context can refer to.
1087 1088 1089 1090
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1092
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1093
    primitive_type_table: PrimitiveTypeTable,
1094

1095
    def_map: DefMap,
1096 1097
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
1098
    export_map: ExportMap,
1099
    trait_map: TraitMap,
1100
    external_exports: ExternalExports,
1101

1102 1103 1104 1105 1106
    // 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,

1107 1108 1109 1110 1111
    make_glob_map: bool,
    // Maps imports to the names of items actually imported (this actually maps
    // all imports, but only glob imports are actually interesting).
    glob_map: GlobMap,

1112
    used_imports: HashSet<(NodeId, Namespace)>,
1113
    used_crates: HashSet<CrateNum>,
1114 1115
}

1116
#[derive(PartialEq)]
S
Steven Fackler 已提交
1117 1118 1119 1120 1121
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}

1122 1123 1124 1125 1126
impl<'a, 'tcx> Resolver<'a, 'tcx> {
    fn new(session: &'a Session,
           ast_map: &'a ast_map::Map<'tcx>,
           crate_span: Span,
           make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> {
K
Kevin Butler 已提交
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
        let graph_root = NameBindings::new();

        graph_root.define_module(NoParentLink,
                                 Some(DefId { krate: 0, node: 0 }),
                                 NormalModuleKind,
                                 false,
                                 true,
                                 crate_span);

        let current_module = graph_root.get_module();

        Resolver {
            session: session,

1141 1142
            ast_map: ast_map,

K
Kevin Butler 已提交
1143 1144 1145 1146 1147
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

1148 1149
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1150 1151 1152 1153

            unresolved_imports: 0,

            current_module: current_module,
1154 1155 1156
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1157 1158 1159 1160 1161 1162

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1163 1164 1165 1166 1167
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1168
            used_imports: HashSet::new(),
1169
            used_crates: HashSet::new(),
1170
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1171 1172

            emit_errors: true,
1173 1174
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
K
Kevin Butler 已提交
1175 1176
        }
    }
1177

1178 1179 1180 1181 1182 1183
    #[inline]
    fn record_import_use(&mut self, import_id: NodeId, name: Name) {
        if !self.make_glob_map {
            return;
        }
        if self.glob_map.contains_key(&import_id) {
1184
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1185 1186 1187 1188 1189 1190 1191 1192 1193
            return;
        }

        let mut new_set = HashSet::new();
        new_set.insert(name);
        self.glob_map.insert(import_id, new_set);
    }

    fn get_trait_name(&self, did: DefId) -> Name {
1194
        if did.krate == ast::LOCAL_CRATE {
1195 1196 1197 1198 1199 1200
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

E
Eduard Burtescu 已提交
1201
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1202
        NameBindings {
1203
            type_def: RefCell::new(Some(TypeNsDef {
T
Fallout  
Tamir Duberstein 已提交
1204
                modifiers: DefModifiers::IMPORTABLE,
1205 1206
                module_def: Some(module),
                type_def: None,
1207
                type_span: None
1208
            })),
1209
            value_def: RefCell::new(None),
1210 1211 1212
        }
    }

1213 1214 1215 1216 1217 1218 1219
    /// Checks that the names of external crates don't collide with other
    /// external crates.
    fn check_for_conflicts_between_external_crates(&self,
                                                   module: &Module,
                                                   name: Name,
                                                   span: Span) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1220 1221
                span_err!(self.session, span, E0259,
                          "an external crate named `{}` has already \
1222 1223
                           been imported into this module",
                          name);
1224 1225 1226 1227 1228 1229 1230 1231 1232
        }
    }

    /// Checks that the names of items don't collide with external crates.
    fn check_for_conflicts_between_external_crates_and_items(&self,
                                                             module: &Module,
                                                             name: Name,
                                                             span: Span) {
        if module.external_module_children.borrow().contains_key(&name) {
B
Brian Anderson 已提交
1233 1234
                span_err!(self.session, span, E0260,
                          "the name `{}` conflicts with an external \
1235 1236 1237
                           crate that has been imported into this \
                           module",
                           name);
1238
        }
1239 1240
    }

1241
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1242
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1243
                                     module_: Rc<Module>,
1244
                                     module_path: &[Name],
1245
                                     index: usize,
1246 1247 1248
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
1249
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
1250 1251
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
1252 1253 1254 1255 1256
            match module.external_module_children.borrow().get(&needle) {
                Some(_) => Some(module.clone()),
                None => match module.parent_link {
                    ModuleParentLink(ref parent, _) => {
                        search_parent_externals(needle, &parent.upgrade().unwrap())
1257 1258 1259
                    }
                   _ => None
                }
1260
            }
1261 1262
        }

1263
        let mut search_module = module_;
1264
        let mut index = index;
A
Alex Crichton 已提交
1265
        let module_path_len = module_path.len();
1266
        let mut closest_private = lp;
1267 1268 1269 1270 1271

        // 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 已提交
1272
            let name = module_path[index];
E
Eduard Burtescu 已提交
1273
            match self.resolve_name_in_module(search_module.clone(),
1274
                                              name,
1275
                                              TypeNS,
1276 1277
                                              name_search_type,
                                              false) {
1278
                Failed(None) => {
1279
                    let segment_name = token::get_name(name);
1280
                    let module_name = module_to_string(&*search_module);
1281
                    let mut span = span;
1282
                    let msg = if "???" == &module_name[..] {
1283
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1284

1285
                        match search_parent_externals(name,
1286
                                                     &self.current_module) {
1287
                            Some(module) => {
1288 1289
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
1290
                                let current_mod_str =
1291
                                    module_to_string(&*self.current_module);
1292 1293 1294 1295 1296 1297 1298

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

1299
                                format!("Did you mean `{}{}`?", prefix, path_str)
1300
                            },
1301 1302
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
1303
                        }
1304
                    } else {
1305
                        format!("Could not find `{}` in `{}`",
1306 1307 1308
                                segment_name,
                                module_name)
                    };
1309

1310
                    return Failed(Some((span, msg)));
1311
                }
1312
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1313
                Indeterminate => {
1314
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
1315
                            resolution is indeterminate: {}",
1316
                            name);
B
Brian Anderson 已提交
1317
                    return Indeterminate;
1318
                }
1319
                Success((target, used_proxy)) => {
1320 1321
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
1322
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1323
                        Some(ref type_def) => {
1324 1325
                            match type_def.module_def {
                                None => {
1326
                                    let msg = format!("Not a module `{}`",
1327
                                                        name);
1328 1329

                                    return Failed(Some((span, msg)));
1330
                                }
E
Eduard Burtescu 已提交
1331
                                Some(ref module_def) => {
1332 1333 1334
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
1335 1336
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
1337
                                    }
1338

1339 1340 1341
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
1342 1343 1344
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
1345
                                        }
1346
                                    }
1347 1348 1349 1350 1351
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
1352
                            let msg = format!("Not a module `{}`",
1353
                                              name);
1354
                            return Failed(Some((span, msg)));
1355 1356 1357 1358 1359
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
1360
            index += 1;
1361 1362
        }

1363
        return Success((search_module, closest_private));
1364 1365
    }

1366 1367
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1368 1369 1370
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1371
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
1372
                           module_: Rc<Module>,
1373
                           module_path: &[Name],
1374 1375 1376
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1377
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
1378
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1379
        assert!(module_path_len > 0);
1380

1381
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1382 1383
               names_to_string(module_path),
               module_to_string(&*module_));
1384

1385
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
1386
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
1387
                                                              module_path);
1388

1389 1390
        let search_module;
        let start_index;
1391
        let last_private;
1392
        match module_prefix_result {
1393
            Failed(None) => {
1394
                let mpath = names_to_string(module_path);
1395
                let mpath = &mpath[..];
1396
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1397
                    Some(idx) => {
1398 1399 1400
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
1401 1402
                                            &mpath[idx + 1..],
                                            &mpath[..idx - 1]);
1403
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
1404
                    },
1405 1406 1407
                    None => {
                        return Failed(None)
                    }
1408
                }
1409
            }
1410
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1411
            Indeterminate => {
1412
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
1413
                        bailing");
B
Brian Anderson 已提交
1414
                return Indeterminate;
1415
            }
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
            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.
                        search_module = self.graph_root.get_module();
                        start_index = 0;
1426
                        last_private = LastMod(AllPublic);
1427 1428 1429 1430 1431
                    }
                    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.
1432 1433
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
1434
                            Failed(err) => return Failed(err),
1435
                            Indeterminate => {
1436
                                debug!("(resolving module path for import) \
1437 1438 1439 1440 1441 1442
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1443
                                last_private = LastMod(AllPublic);
1444 1445 1446 1447 1448
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1449 1450
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
1451
                start_index = index;
1452 1453 1454
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
1455 1456 1457
            }
        }

1458 1459 1460 1461
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1462 1463
                                           name_search_type,
                                           last_private)
1464 1465
    }

1466 1467
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1468
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1469
                                     module_: Rc<Module>,
1470
                                     name: Name,
1471
                                     namespace: Namespace)
1472
                                    -> ResolveResult<(Target, bool)> {
1473
        debug!("(resolving item in lexical scope) resolving `{}` in \
1474
                namespace {:?} in `{}`",
1475
               name,
1476
               namespace,
1477
               module_to_string(&*module_));
1478 1479 1480

        // The current module node is handled specially. First, check for
        // its immediate children.
1481
        build_reduced_graph::populate_module_if_necessary(self, &module_);
1482

1483
        match module_.children.borrow().get(&name) {
1484 1485 1486
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
1487 1488
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1489
                                            Shadowable::Never),
1490
                               false));
1491
            }
1492
            Some(_) | None => { /* Not found; continue. */ }
1493 1494 1495 1496 1497 1498
        }

        // Now check for its import directives. We don't have to have resolved
        // all its imports in the usual way; this is because chains of
        // adjacent import statements are processed as though they mutated the
        // current scope.
1499 1500 1501 1502 1503
        if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
            match (*import_resolution).target_for_namespace(namespace) {
                None => {
                    // Not found; continue.
                    debug!("(resolving item in lexical scope) found \
1504
                            import resolution, but not in namespace {:?}",
1505 1506 1507 1508 1509 1510
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
1511 1512 1513
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
1514
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
1515
                         self.used_crates.insert(kid);
1516
                    }
1517
                    return Success((target, false));
1518 1519 1520 1521
                }
            }
        }

1522 1523
        // Search for external modules.
        if namespace == TypeNS {
1524 1525 1526
            // FIXME (21114): In principle unclear `child` *has* to be lifted.
            let child = module_.external_module_children.borrow().get(&name).cloned();
            if let Some(module) = child {
1527 1528 1529
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
                debug!("lower name bindings succeeded");
1530 1531 1532
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1533
                                false));
1534 1535 1536
            }
        }

1537
        // Finally, proceed up the scope chain looking for parent modules.
1538
        let mut search_module = module_;
1539 1540
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
1541
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
1542
                NoParentLink => {
1543
                    // No more parents. This module was unresolved.
1544
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
1545
                            module");
1546
                    return Failed(None);
1547
                }
1548
                ModuleParentLink(parent_module_node, _) => {
1549 1550 1551 1552 1553 1554 1555
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
1556
                            return Failed(None);
1557
                        }
1558
                        TraitModuleKind |
1559
                        EnumModuleKind |
1560
                        TypeModuleKind |
1561
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1562
                            search_module = parent_module_node.upgrade().unwrap();
1563 1564 1565
                        }
                    }
                }
E
Eduard Burtescu 已提交
1566 1567
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
1568 1569 1570 1571
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
1572
            match self.resolve_name_in_module(search_module.clone(),
1573
                                              name,
1574
                                              namespace,
1575 1576
                                              PathSearch,
                                              true) {
1577
                Failed(Some((span, msg))) => {
1578
                    resolve_error(&ResolutionError::FailedToResolve(self, span, &*msg));
1579
                },
1580
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1581
                Indeterminate => {
1582 1583 1584
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

1585
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
1586
                            higher scope; bailing");
B
Brian Anderson 已提交
1587
                    return Indeterminate;
1588
                }
1589
                Success((target, used_reexport)) => {
1590
                    // We found the module.
1591
                    debug!("(resolving item in lexical scope) found name \
1592 1593
                            in module, done");
                    return Success((target, used_reexport));
1594 1595 1596 1597 1598
                }
            }
        }
    }

1599
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1600
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1601
                                       module_: Rc<Module>,
1602
                                       name: Name)
E
Eduard Burtescu 已提交
1603
                                -> ResolveResult<Rc<Module>> {
1604 1605
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1606
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
1607
        match resolve_result {
1608
            Success((target, _)) => {
1609
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
1610
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1611
                    Some(ref type_def) => {
1612
                        match type_def.module_def {
1613
                            None => {
1614
                                debug!("!!! (resolving module in lexical \
1615 1616
                                        scope) module wasn't actually a \
                                        module!");
1617
                                return Failed(None);
1618
                            }
E
Eduard Burtescu 已提交
1619 1620
                            Some(ref module_def) => {
                                return Success(module_def.clone());
1621 1622 1623 1624
                            }
                        }
                    }
                    None => {
1625
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
1626
                                wasn't actually a module!");
1627
                        return Failed(None);
1628 1629 1630
                    }
                }
            }
B
Brian Anderson 已提交
1631
            Indeterminate => {
1632
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
1633
                        bailing");
B
Brian Anderson 已提交
1634
                return Indeterminate;
1635
            }
1636 1637 1638
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1639 1640 1641 1642
            }
        }
    }

1643
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
1644 1645
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
1646 1647
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
1648
            match module_.parent_link.clone() {
1649 1650 1651
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
1652
                    let new_module = new_module.upgrade().unwrap();
1653
                    match new_module.kind.get() {
1654 1655
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
1656
                        EnumModuleKind |
1657
                        TypeModuleKind |
1658 1659 1660 1661 1662 1663 1664
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

1665 1666
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
1667 1668
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
1669
        match module_.kind.get() {
1670
            NormalModuleKind => return module_,
1671
            TraitModuleKind |
1672
            EnumModuleKind |
1673
            TypeModuleKind |
1674
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1675
                match self.get_nearest_normal_module_parent(module_.clone()) {
1676 1677 1678 1679 1680 1681 1682
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

1683
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1684
    /// (b) some chain of `super::`.
1685
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1686
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
1687
                             module_: Rc<Module>,
1688
                             module_path: &[Name])
1689
                                 -> ResolveResult<ModulePrefixResult> {
1690 1691 1692 1693
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
        let mut containing_module;
        let mut i;
1694
        let first_module_path_string = token::get_name(module_path[0]);
1695
        if "self" == &first_module_path_string[..] {
1696 1697 1698
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 1;
1699
        } else if "super" == &first_module_path_string[..] {
1700 1701 1702 1703 1704 1705 1706 1707
            containing_module =
                self.get_nearest_normal_module_parent_or_self(module_);
            i = 0;  // We'll handle `super` below.
        } else {
            return Success(NoPrefixFound);
        }

        // Now loop through all the `super`s we find.
1708
        while i < module_path.len() {
1709
            let string = token::get_name(module_path[i]);
1710
            if "super" != &string[..] {
1711 1712
                break
            }
1713
            debug!("(resolving module prefix) resolving `super` at {}",
1714
                   module_to_string(&*containing_module));
1715
            match self.get_nearest_normal_module_parent(containing_module) {
1716
                None => return Failed(None),
1717 1718 1719
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1720 1721 1722 1723
                }
            }
        }

1724
        debug!("(resolving module prefix) finished resolving prefix at {}",
1725
               module_to_string(&*containing_module));
1726 1727

        return Success(PrefixFound(containing_module, i));
1728 1729
    }

1730 1731 1732
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1733 1734 1735
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1736
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
1737
                              module_: Rc<Module>,
1738
                              name: Name,
1739
                              namespace: Namespace,
1740 1741
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1742
                              -> ResolveResult<(Target, bool)> {
1743
        debug!("(resolving name in module) resolving `{}` in `{}`",
1744
               name,
1745
               module_to_string(&*module_));
1746 1747

        // First, check the direct children of the module.
1748
        build_reduced_graph::populate_module_if_necessary(self, &module_);
1749

1750
        match module_.children.borrow().get(&name) {
1751 1752 1753
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
1754 1755
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1756
                                            Shadowable::Never),
1757 1758 1759 1760
                               false));
            }
            Some(_) | None => {
                // Continue.
1761 1762 1763
            }
        }

1764 1765 1766 1767
        // Next, check the module's imports if necessary.

        // If this is a search of all imports, we should be done with glob
        // resolution at this point.
1768
        if name_search_type == PathSearch {
1769
            assert_eq!(module_.glob_count.get(), 0);
1770 1771
        }

1772
        // Check the list of resolved imports.
1773
        match module_.import_resolutions.borrow().get(&name) {
1774
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
1775
                                       import_resolution.is_public => {
1776

E
Eduard Burtescu 已提交
1777 1778
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
1779
                    debug!("(resolving name in module) import \
1780
                           unresolved; bailing out");
B
Brian Anderson 已提交
1781
                    return Indeterminate;
1782
                }
1783
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1784
                    None => {
1785
                        debug!("(resolving name in module) name found, \
1786
                                but not in namespace {:?}",
P
Paul Stansifer 已提交
1787
                               namespace);
1788
                    }
1789
                    Some(target) => {
1790
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
1791
                                import");
1792
                        // track used imports and extern crates as well
1793 1794 1795
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1796 1797
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
1798
                        }
1799
                        return Success((target, true));
1800
                    }
1801 1802
                }
            }
1803
            Some(..) | None => {} // Continue.
1804 1805 1806 1807
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1808 1809 1810
            // FIXME (21114): In principle unclear `child` *has* to be lifted.
            let child = module_.external_module_children.borrow().get(&name).cloned();
            if let Some(module) = child {
1811 1812
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
1813 1814 1815
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1816
                                false));
1817 1818 1819 1820
            }
        }

        // We're out of luck.
1821
        debug!("(resolving name in module) failed to resolve `{}`",
1822
               name);
1823
        return Failed(None);
1824 1825
    }

E
Eduard Burtescu 已提交
1826
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
1827
        let index = module_.resolved_import_count.get();
1828 1829
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1830
        if index != import_count {
1831
            let sn = self.session
E
Eduard Burtescu 已提交
1832
                         .codemap()
1833
                         .span_to_snippet((*imports)[index].span)
1834
                         .unwrap();
1835
            if sn.contains("::") {
1836 1837 1838
                resolve_error(&ResolutionError::UnresolvedImport(self,
                                                                 (*imports)[index].span,
                                                                 None));
1839
            } else {
1840 1841 1842
                resolve_error(&ResolutionError::UnresolvedImport(self,
                                                                 (*imports)[index].span,
                                                                 Some((&*sn, None))));
1843
            }
1844 1845 1846
        }

        // Descend into children and anonymous children.
1847
        build_reduced_graph::populate_module_if_necessary(self, &module_);
1848

1849
        for (_, child_node) in module_.children.borrow().iter() {
1850 1851 1852 1853 1854 1855
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1856 1857 1858 1859
                }
            }
        }

1860
        for (_, module_) in module_.anonymous_children.borrow().iter() {
E
Eduard Burtescu 已提交
1861
            self.report_unresolved_imports(module_.clone());
1862 1863 1864 1865 1866
        }
    }

    // AST resolution
    //
1867
    // We maintain a list of value ribs and type ribs.
1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882
    //
    // 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.

J
Jorge Aparicio 已提交
1883 1884 1885
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
1886
        let orig_module = self.current_module.clone();
1887 1888

        // Move down in the graph.
1889
        match name {
B
Brian Anderson 已提交
1890
            None => {
1891 1892
                // Nothing to do.
            }
B
Brian Anderson 已提交
1893
            Some(name) => {
1894
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1895

1896
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
1897
                    None => {
1898
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
1899
                               name,
1900
                               module_to_string(&*orig_module));
1901
                    }
B
Brian Anderson 已提交
1902
                    Some(name_bindings) => {
1903
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
1904
                            None => {
1905
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
1906
                                        for `{}` in `{}`",
1907
                                       name,
1908
                                       module_to_string(&*orig_module));
1909
                            }
B
Brian Anderson 已提交
1910
                            Some(module_) => {
1911
                                self.current_module = module_;
1912 1913 1914 1915 1916 1917 1918
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
1919
        f(self);
1920 1921 1922 1923

        self.current_module = orig_module;
    }

1924
    /// Wraps the given definition in the appropriate number of `DefUpvar`
1925
    /// wrappers.
E
Eduard Burtescu 已提交
1926
    fn upvarify(&self,
E
Eduard Burtescu 已提交
1927
                ribs: &[Rib],
E
Eduard Burtescu 已提交
1928 1929 1930
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
1931 1932 1933 1934 1935 1936
        let mut def = match def_like {
            DlDef(def) => def,
            _ => return Some(def_like)
        };
        match def {
            DefUpvar(..) => {
1937
                self.session.span_bug(span,
1938
                    &format!("unexpected {:?} in bindings", def))
1939
            }
1940
            DefLocal(node_id) => {
1941
                for rib in ribs {
1942 1943 1944 1945
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
1946
                        ClosureRibKind(function_id) => {
1947
                            let prev_def = def;
1948
                            def = DefUpvar(node_id, function_id);
1949

1950
                            let mut seen = self.freevars_seen.borrow_mut();
1951
                            let seen = match seen.entry(function_id) {
1952
                                Occupied(v) => v.into_mut(),
1953
                                Vacant(v) => v.insert(NodeSet()),
1954
                            };
1955 1956 1957
                            if seen.contains(&node_id) {
                                continue;
                            }
1958
                            match self.freevars.borrow_mut().entry(function_id) {
1959
                                Occupied(v) => v.into_mut(),
1960
                                Vacant(v) => v.insert(vec![]),
1961
                            }.push(Freevar { def: prev_def, span: span });
1962 1963
                            seen.insert(node_id);
                        }
1964
                        ItemRibKind | MethodRibKind => {
1965 1966 1967
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
1968 1969 1970 1971 1972
                            resolve_error(
                                &ResolutionError::CannotCaptureDynamicEnvironmentInFnItem(
                                    self,
                                    span)
                            );
1973 1974 1975 1976
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
1977 1978 1979 1980 1981
                            resolve_error(
                                &ResolutionError::AttemptToUseNonConstantValueInConstant(
                                    self,
                                    span)
                            );
1982
                            return None;
1983
                        }
1984 1985
                    }
                }
1986
            }
1987
            DefTyParam(..) | DefSelfTy(..) => {
1988
                for rib in ribs {
1989
                    match rib.kind {
1990
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
1991 1992 1993 1994 1995
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
1996

1997 1998
                            resolve_error(&ResolutionError::TypeParametersFromOuterFunction(self,
                                                                                            span));
1999 2000 2001 2002
                            return None;
                        }
                        ConstantItemRibKind => {
                            // see #9186
2003
                            resolve_error(&ResolutionError::OuterTypeParameterContext(self, span));
2004
                            return None;
2005 2006
                        }
                    }
2007
                }
2008
            }
2009
            _ => {}
2010
        }
2011
        Some(DlDef(def))
2012 2013
    }

S
Seo Sanghyeon 已提交
2014 2015
    /// Searches the current set of local scopes and
    /// applies translations for closures.
E
Eduard Burtescu 已提交
2016
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
2017
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
2018 2019 2020
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
2021
        // FIXME #4950: Try caching?
2022

2023
        for (i, rib) in ribs.iter().enumerate().rev() {
2024 2025
            if let Some(def_like) = rib.bindings.get(&name).cloned() {
                return self.upvarify(&ribs[i + 1..], def_like, span);
2026 2027 2028
            }
        }

2029
        None
2030 2031
    }

S
Seo Sanghyeon 已提交
2032 2033
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045
    fn search_label(&self, name: Name) -> Option<DefLike> {
        for rib in self.label_ribs.iter().rev() {
            match rib.kind {
                NormalRibKind => {
                    // Continue
                }
                _ => {
                    // Do not resolve labels across function boundary
                    return None
                }
            }
            let result = rib.bindings.get(&name).cloned();
S
Seo Sanghyeon 已提交
2046 2047
            if result.is_some() {
                return result
2048 2049 2050 2051 2052
            }
        }
        None
    }

2053
    fn resolve_crate(&mut self, krate: &ast::Crate) {
2054
        debug!("(resolving crate) starting");
2055

2056
        visit::walk_crate(self, krate);
2057 2058
    }

W
we 已提交
2059 2060
    fn check_if_primitive_type_name(&self, name: Name, span: Span) {
        if let Some(_) = self.primitive_type_table.primitive_types.get(&name) {
V
Vadim Petrochenkov 已提交
2061
            span_err!(self.session, span, E0317,
W
we 已提交
2062 2063 2064 2065
                "user-defined types or type parameters cannot shadow the primitive types");
        }
    }

2066
    fn resolve_item(&mut self, item: &Item) {
2067 2068
        let name = item.ident.name;

2069
        debug!("(resolving item) resolving {}",
2070
               name);
2071

2072
        match item.node {
2073 2074 2075
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
2076 2077
                self.check_if_primitive_type_name(name, item.span);

2078
                self.with_type_parameter_rib(HasTypeParameters(generics,
2079
                                                               TypeSpace,
2080
                                                               ItemRibKind),
2081
                                             |this| visit::walk_item(this, item));
2082
            }
2083
            ItemFn(_, _, _, _, ref generics, _) => {
2084
                self.with_type_parameter_rib(HasTypeParameters(generics,
2085
                                                               FnSpace,
2086
                                                               ItemRibKind),
2087
                                             |this| visit::walk_item(this, item));
2088 2089
            }

F
Flavio Percoco 已提交
2090
            ItemDefaultImpl(_, ref trait_ref) => {
2091
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
2092
            }
2093 2094
            ItemImpl(_,
                     _,
2095
                     ref generics,
2096
                     ref opt_trait_ref,
2097
                     ref self_type,
2098
                     ref impl_items) => {
2099
                self.resolve_implementation(generics,
2100
                                            opt_trait_ref,
2101
                                            &**self_type,
2102
                                            item.id,
2103
                                            &impl_items[..]);
2104 2105
            }

N
Nick Cameron 已提交
2106
            ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
W
we 已提交
2107 2108
                self.check_if_primitive_type_name(name, item.span);

2109 2110 2111 2112 2113 2114
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
                    this.with_self_rib(DefSelfTy(Some(local_def(item.id)), None), |this| {
2115 2116 2117 2118 2119 2120 2121 2122 2123
                        this.visit_generics(generics);
                        visit::walk_ty_param_bounds_helper(this, bounds);

                        for trait_item in trait_items {
                            // Create a new rib for the trait_item-specific type
                            // parameters.
                            //
                            // FIXME #4951: Do we need a node ID here?

2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136
                            match trait_item.node {
                                ast::ConstTraitItem(_, ref default) => {
                                    // 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| {
                                            visit::walk_trait_item(this, trait_item)
                                        });
                                    } else {
                                        visit::walk_trait_item(this, trait_item)
                                    }
                                }
2137
                                ast::MethodTraitItem(ref sig, _) => {
2138 2139 2140 2141 2142 2143 2144
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
                                        visit::walk_trait_item(this, trait_item)
                                    });
2145 2146 2147 2148
                                }
                                ast::TypeTraitItem(..) => {
                                    this.check_if_primitive_type_name(trait_item.ident.name,
                                                                      trait_item.span);
2149 2150 2151
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
                                        visit::walk_trait_item(this, trait_item)
                                    });
2152 2153 2154 2155
                                }
                            };
                        }
                    });
2156
                });
2157 2158
            }

2159
            ItemMod(_) | ItemForeignMod(_) => {
2160
                self.with_scope(Some(name), |this| {
2161
                    visit::walk_item(this, item);
2162
                });
2163 2164
            }

2165
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2166
                self.with_constant_rib(|this| {
2167
                    visit::walk_item(this, item);
2168
                });
2169
            }
2170

W
we 已提交
2171 2172 2173
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
                if let ast::ViewPathSimple(ident, _) = view_path.node {
2174 2175
                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
W
we 已提交
2176 2177 2178 2179 2180 2181 2182 2183
                            self.check_if_primitive_type_name(ident.name, item.span);
                        }
                        _ => {}
                    }
                }
            }

            ItemExternCrate(_) | ItemMac(..) => {
2184
                // do nothing, these are just around to be encoded
2185
            }
2186 2187 2188
        }
    }

J
Jorge Aparicio 已提交
2189 2190 2191
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
2192
        match type_parameters {
2193
            HasTypeParameters(generics, space, rib_kind) => {
2194
                let mut function_type_rib = Rib::new(rib_kind);
2195
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2196
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2197
                    let name = type_parameter.ident.name;
2198
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2199

2200
                    if seen_bindings.contains(&name) {
2201 2202 2203 2204
                        resolve_error(&ResolutionError::NameAlreadyUsedInTypeParameterList(
                                                            self,
                                                            type_parameter.span,
                                                            name));
2205
                    }
2206
                    seen_bindings.insert(name);
2207

2208
                    // plain insert (no renaming)
2209 2210 2211 2212 2213
                    function_type_rib.bindings.insert(name,
                        DlDef(DefTyParam(space,
                                         index as u32,
                                         local_def(type_parameter.id),
                                         name)));
2214
                }
2215
                self.type_ribs.push(function_type_rib);
2216 2217
            }

B
Brian Anderson 已提交
2218
            NoTypeParameters => {
2219 2220 2221 2222
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2223
        f(self);
2224

2225
        match type_parameters {
2226
            HasTypeParameters(..) => { self.type_ribs.pop(); }
2227
            NoTypeParameters => { }
2228 2229 2230
        }
    }

J
Jorge Aparicio 已提交
2231 2232 2233
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2234
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2235
        f(self);
2236
        self.label_ribs.pop();
2237
    }
2238

J
Jorge Aparicio 已提交
2239 2240 2241
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2242 2243
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2244
        f(self);
2245 2246
        self.type_ribs.pop();
        self.value_ribs.pop();
2247 2248
    }

F
Felix S. Klock II 已提交
2249
    fn resolve_function(&mut self,
2250
                        rib_kind: RibKind,
2251
                        declaration: &FnDecl,
2252
                        block: &Block) {
2253
        // Create a value rib for the function.
2254
        self.value_ribs.push(Rib::new(rib_kind));
2255

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

2259 2260 2261 2262 2263 2264
        // Add each argument to the rib.
        let mut bindings_list = HashMap::new();
        for argument in &declaration.inputs {
            self.resolve_pattern(&*argument.pat,
                                 ArgumentIrrefutableMode,
                                 &mut bindings_list);
2265

2266
            self.visit_ty(&*argument.ty);
2267

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

2272 2273
        // Resolve the function body.
        self.visit_block(&*block);
2274

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

2277 2278
        self.label_ribs.pop();
        self.value_ribs.pop();
2279 2280
    }

F
Felix S. Klock II 已提交
2281
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2282
                               id: NodeId,
2283
                               trait_path: &Path,
2284
                               path_depth: usize)
2285 2286 2287 2288 2289 2290
                               -> Result<PathResolution, ()> {
        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
            if let DefTrait(_) = path_res.base_def {
                debug!("(resolving trait) found trait def: {:?}", path_res);
                Ok(path_res)
            } else {
2291 2292 2293 2294
                resolve_error(&ResolutionError::IsNotATrait(self, trait_path.span,
                                                            &*path_names_to_string(trait_path,
                                                                                 path_depth))
                             );
2295 2296

                // If it's a typedef, give a note
2297
                if let DefTy(..) = path_res.base_def {
2298 2299
                    self.session.span_note(trait_path.span,
                                           "`type` aliases cannot be used for traits");
2300
                }
2301 2302
                Err(())
            }
2303
        } else {
2304 2305 2306 2307
            resolve_error(&ResolutionError::UndeclaredTraitName(self,
                                                                trait_path.span,
                                                                &*path_names_to_string(trait_path,
                                                                                     path_depth)));
2308
            Err(())
2309 2310 2311
        }
    }

2312
    fn resolve_generics(&mut self, generics: &Generics) {
2313
        for type_parameter in generics.ty_params.iter() {
2314 2315 2316
            self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
        }
        for predicate in &generics.where_clause.predicates {
2317
            match predicate {
2318
                &ast::WherePredicate::BoundPredicate(_) |
2319
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
2320
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
2321 2322 2323 2324
                    let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
                        self.record_def(eq_pred.id, path_res.unwrap());
                    } else {
2325 2326
                        resolve_error(&ResolutionError::UndeclaredAssociatedType(self,
                                                                                 eq_pred.span));
2327 2328
                    }
                }
2329 2330
            }
        }
2331
        visit::walk_generics(self, generics);
2332 2333
    }

2334 2335
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2336
    {
2337 2338 2339 2340 2341 2342 2343
        // 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
    }

2344
    fn with_optional_trait_ref<T, F>(&mut self,
E
Eduard Burtescu 已提交
2345
                                     opt_trait_ref: Option<&TraitRef>,
N
Nick Cameron 已提交
2346 2347
                                     f: F)
                                     -> T
2348
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2349
    {
2350
        let mut new_val = None;
2351
        let mut new_id = None;
E
Eduard Burtescu 已提交
2352
        if let Some(trait_ref) = opt_trait_ref {
2353 2354 2355 2356 2357 2358
            if let Ok(path_res) = self.resolve_trait_reference(trait_ref.ref_id,
                                                               &trait_ref.path, 0) {
                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());
2359
            }
2360 2361
            visit::walk_trait_ref(self, trait_ref);
        }
2362
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2363
        let result = f(self, new_id);
2364 2365 2366 2367
        self.current_trait_ref = original_trait_ref;
        result
    }

2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380
    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....)
        let name = special_names::type_self;
        self_type_rib.bindings.insert(name, DlDef(self_def));
        self.type_ribs.push(self_type_rib);
        f(self);
        self.type_ribs.pop();
    }

F
Felix S. Klock II 已提交
2381
    fn resolve_implementation(&mut self,
2382 2383 2384
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2385
                              item_id: NodeId,
2386
                              impl_items: &[P<ImplItem>]) {
2387
        // If applicable, create a rib for the type parameters.
2388
        self.with_type_parameter_rib(HasTypeParameters(generics,
2389
                                                       TypeSpace,
2390
                                                       ItemRibKind),
2391
                                     |this| {
2392
            // Resolve the type parameters.
2393
            this.visit_generics(generics);
2394

2395
            // Resolve the trait reference, if necessary.
2396
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2397
                // Resolve the self type.
2398
                this.visit_ty(self_type);
2399

2400 2401 2402 2403
                this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
                    this.with_current_self_type(self_type, |this| {
                        for impl_item in impl_items {
                            match impl_item.node {
2404 2405 2406 2407 2408 2409 2410 2411 2412
                                ConstImplItem(..) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
                                                          impl_item.span);
                                    this.with_constant_rib(|this| {
                                        visit::walk_impl_item(this, impl_item);
                                    });
                                }
2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
                                MethodImplItem(ref sig, _) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
                                                          impl_item.span);

                                    // We also need a new scope for the method-
                                    // specific type parameters.
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
                                        visit::walk_impl_item(this, impl_item);
                                    });
                                }
                                TypeImplItem(ref ty) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
                                                          impl_item.span);
2434

2435 2436 2437
                                    this.visit_ty(ty);
                                }
                                ast::MacImplItem(_) => {}
2438
                            }
2439
                        }
2440
                    });
2441 2442
                });
            });
2443
        });
2444 2445
    }

2446
    fn check_trait_item(&self, name: Name, span: Span) {
2447
        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
2448
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2449
            if !self.trait_item_map.contains_key(&(name, did)) {
2450
                let path_str = path_names_to_string(&trait_ref.path, 0);
2451 2452 2453 2454
                resolve_error(&ResolutionError::MethodNotMemberOfTrait(self,
                                                                       span,
                                                                       name,
                                                                       &*path_str));
2455 2456 2457 2458
            }
        }
    }

E
Eduard Burtescu 已提交
2459
    fn resolve_local(&mut self, local: &Local) {
2460
        // Resolve the type.
2461
        visit::walk_ty_opt(self, &local.ty);
2462

2463 2464
        // Resolve the initializer.
        visit::walk_expr_opt(self, &local.init);
2465 2466

        // Resolve the pattern.
2467 2468
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
2469
                             &mut HashMap::new());
2470 2471
    }

J
John Clements 已提交
2472 2473 2474 2475
    // 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 已提交
2476
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2477
        let mut result = HashMap::new();
2478 2479
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
2480 2481 2482 2483
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
2484
        });
2485
        return result;
2486 2487
    }

J
John Clements 已提交
2488 2489
    // 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 已提交
2490
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2491
        if arm.pats.is_empty() {
2492 2493
            return
        }
2494
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2495
        for (i, p) in arm.pats.iter().enumerate() {
2496
            let map_i = self.binding_mode_map(&**p);
2497

2498
            for (&key, &binding_0) in &map_0 {
2499
                match map_i.get(&key) {
2500
                  None => {
2501 2502 2503 2504
                    resolve_error(&ResolutionError::VariableNotBoundInPattern(self,
                                                                              p.span,
                                                                              key,
                                                                              i + 1));
2505 2506 2507
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
2508 2509 2510 2511 2512 2513
                        resolve_error(&ResolutionError::VariableBoundWithDifferentMode(
                                                                        self,
                                                                        binding_i.span,
                                                                        key,
                                                                        i + 1)
                                     );
2514 2515
                    }
                  }
2516 2517 2518
                }
            }

2519
            for (&key, &binding) in &map_i {
2520
                if !map_0.contains_key(&key) {
2521 2522 2523 2524
                    resolve_error(&ResolutionError::VariableNotBoundInParentPattern(self,
                                                                                    binding.span,
                                                                                    key,
                                                                                    i + 1));
2525 2526 2527
                }
            }
        }
2528 2529
    }

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

2533
        let mut bindings_list = HashMap::new();
2534
        for pattern in &arm.pats {
2535
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2536 2537
        }

2538 2539 2540 2541
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2542
        visit::walk_expr_opt(self, &arm.guard);
2543
        self.visit_expr(&*arm.body);
2544

2545
        self.value_ribs.pop();
2546 2547
    }

E
Eduard Burtescu 已提交
2548
    fn resolve_block(&mut self, block: &Block) {
2549
        debug!("(resolving block) entering block");
2550
        self.value_ribs.push(Rib::new(NormalRibKind));
2551 2552

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
2553
        let orig_module = self.current_module.clone();
2554
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
2555
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
2556
            Some(anonymous_module) => {
2557
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
2558
                        down");
E
Eduard Burtescu 已提交
2559
                self.current_module = anonymous_module.clone();
2560 2561 2562
            }
        }

2563 2564
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2565
        for statement in &block.stmts {
2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582
            if let ast::StmtDecl(ref declaration, _) = statement.node {
                if let ast::DeclItem(ref i) = declaration.node {
                    match i.node {
                        ItemExternCrate(_) | ItemUse(_) if found_non_item => {
                            span_err!(self.session, i.span, E0154,
                                "imports are not allowed after non-item statements");
                        }
                        _ => {}
                    }
                } else {
                    found_non_item = true
                }
            } else {
                found_non_item = true;
            }
        }

2583
        // Descend into the block.
2584
        visit::walk_block(self, block);
2585 2586 2587 2588

        // Move back up.
        self.current_module = orig_module;

2589
        self.value_ribs.pop();
2590
        debug!("(resolving block) leaving block");
2591 2592
    }

F
Felix S. Klock II 已提交
2593
    fn resolve_type(&mut self, ty: &Ty) {
2594
        match ty.node {
2595
            TyPath(ref maybe_qself, ref path) => {
2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609
                let resolution =
                    match self.resolve_possibly_assoc_item(ty.id,
                                                           maybe_qself.as_ref(),
                                                           path,
                                                           TypeNS,
                                                           true) {
                        // `<T>::a::b::c` is resolved by typeck alone.
                        TypecheckRequired => {
                            // Resolve embedded types.
                            visit::walk_ty(self, ty);
                            return;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
2610 2611

                // This is a path in the type namespace. Walk through scopes
2612
                // looking for it.
2613
                match resolution {
B
Brian Anderson 已提交
2614
                    Some(def) => {
2615
                        // Write the result into the def map.
2616
                        debug!("(resolving type) writing resolution for `{}` \
2617
                                (id {}) = {:?}",
2618
                               path_names_to_string(path, 0),
2619 2620
                               ty.id, def);
                        self.record_def(ty.id, def);
2621
                    }
B
Brian Anderson 已提交
2622
                    None => {
2623 2624 2625
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2626 2627 2628 2629
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2630
                        };
2631

2632 2633 2634 2635 2636
                        let self_type_name = special_idents::type_self.name;
                        let is_invalid_self_type_name =
                            path.segments.len() > 0 &&
                            maybe_qself.is_none() &&
                            path.segments[0].identifier.name == self_type_name;
G
Guillaume Gomez 已提交
2637
                        if is_invalid_self_type_name {
2638 2639
                            resolve_error(&ResolutionError::SelfUsedOutsideImplOrTrait(self,
                                                                                       ty.span));
2640
                        } else {
2641 2642 2643 2644 2645 2646 2647
                            resolve_error(&ResolutionError::UseOfUndeclared(
                                                                    self,
                                                                    ty.span,
                                                                    kind,
                                                                    &*path_names_to_string(path,
                                                                                           0))
                                         );
G
Guillaume Gomez 已提交
2648
                        }
2649 2650
                    }
                }
2651
            }
2652
            _ => {}
2653
        }
2654 2655
        // Resolve embedded types.
        visit::walk_ty(self, ty);
2656 2657
    }

F
Felix S. Klock II 已提交
2658
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2659
                       pattern: &Pat,
2660 2661 2662
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2663
                       bindings_list: &mut HashMap<Name, NodeId>) {
2664
        let pat_id = pattern.id;
2665
        walk_pat(pattern, |pattern| {
2666
            match pattern.node {
2667
                PatIdent(binding_mode, ref path1, _) => {
2668 2669

                    // The meaning of pat_ident with no type parameters
2670 2671 2672 2673 2674 2675 2676
                    // depends on whether an enum variant or unit-like struct
                    // with that name is in scope. The probing lookup has to
                    // be careful not to emit spurious errors. Only matching
                    // patterns (match) can match nullary variants or
                    // unit-like structs. For binding patterns (let), matching
                    // such a value is simply disallowed (since it's rarely
                    // what you want).
2677

2678
                    let ident = path1.node;
2679
                    let renamed = mtwt::resolve(ident);
2680

2681
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
2682
                        FoundStructOrEnumVariant(def, lp)
2683
                                if mode == RefutableMode => {
2684
                            debug!("(resolving pattern) resolving `{}` to \
2685
                                    struct or enum variant",
2686
                                   renamed);
2687

2688 2689 2690 2691
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
2692 2693 2694 2695 2696
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2697
                        }
A
Alex Crichton 已提交
2698
                        FoundStructOrEnumVariant(..) => {
2699 2700 2701 2702 2703 2704
                            resolve_error(
                                &ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
                                    self,
                                    pattern.span,
                                    renamed)
                            );
2705
                        }
2706
                        FoundConst(def, lp) if mode == RefutableMode => {
2707
                            debug!("(resolving pattern) resolving `{}` to \
2708
                                    constant",
2709
                                   renamed);
2710

2711 2712 2713 2714
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
2715 2716 2717 2718 2719
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2720
                        }
A
Alex Crichton 已提交
2721
                        FoundConst(..) => {
2722 2723 2724 2725 2726
                            resolve_error(
                                &ResolutionError::OnlyIrrefutablePatternsAllowedHere(
                                    self,
                                    pattern.span)
                            );
2727
                        }
2728
                        BareIdentifierPatternUnresolved => {
2729
                            debug!("(resolving pattern) binding `{}`",
2730
                                   renamed);
2731

2732
                            let def = DefLocal(pattern.id);
2733 2734 2735 2736 2737

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

2738 2739 2740 2741 2742
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: LastMod(AllPublic),
                                depth: 0
                            });
2743 2744 2745 2746 2747 2748

                            // Add the binding to the local ribs, if it
                            // doesn't already exist in the bindings list. (We
                            // must not add it if it's in the bindings list
                            // because that breaks the assumptions later
                            // passes make about or-patterns.)
2749 2750
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2751 2752
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2753
                                bindings_list.insert(renamed, pat_id);
2754 2755 2756 2757
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
2758 2759 2760 2761 2762 2763
                                resolve_error(
                                    &ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
                                        self,
                                        pattern.span,
                                        &*token::get_ident(ident))
                                );
2764
                            } else if bindings_list.get(&renamed) ==
2765 2766 2767
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2768 2769 2770 2771 2772 2773
                                resolve_error(
                                    &ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
                                        self,
                                        pattern.span,
                                        &*token::get_ident(ident))
                                );
2774
                            }
2775 2776
                            // Else, not bound in the same pattern: do
                            // nothing.
2777 2778 2779 2780
                        }
                    }
                }

2781
                PatEnum(ref path, _) => {
2782
                    // This must be an enum variant, struct or const.
2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798
                    let resolution =
                        match self.resolve_possibly_assoc_item(pat_id, None,
                                                               path, ValueNS,
                                                               false) {
                            // The below shouldn't happen because all
                            // qualified paths should be in PatQPath.
                            TypecheckRequired =>
                                self.session.span_bug(
                                    path.span,
                                    "resolve_possibly_assoc_item claimed
                                     that a path in PatEnum requires typecheck
                                     to resolve, but qualified paths should be
                                     PatQPath"),
                            ResolveAttempt(resolution) => resolution,
                        };
                    if let Some(path_res) = resolution {
2799
                        match path_res.base_def {
2800
                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
2801 2802 2803
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
2804 2805
                                resolve_error(&ResolutionError::StaticVariableReference(&self,
                                              path.span));
2806
                            }
2807 2808 2809 2810
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2811
                                // be a `T::CONST` that typeck will resolve.
2812
                                if path_res.depth == 0 {
2813 2814 2815 2816 2817 2818 2819 2820
                                    resolve_error(
                                        &ResolutionError::NotAnEnumVariantStructOrConst(
                                            self,
                                            path.span,
                                            &*token::get_ident(
                                                path.segments.last().unwrap().identifier)
                                            )
                                    );
2821
                                } else {
2822 2823 2824 2825
                                    let const_name = path.segments.last().unwrap()
                                                         .identifier.name;
                                    let traits = self.get_traits_containing_item(const_name);
                                    self.trait_map.insert(pattern.id, traits);
2826 2827 2828 2829 2830
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2831 2832 2833 2834 2835 2836
                        resolve_error(
                            &ResolutionError::UnresolvedEnumVariantStructOrConst(
                                self,
                                path.span,
                                &*token::get_ident(path.segments.last().unwrap().identifier))
                        );
2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866
                    }
                    visit::walk_path(self, path);
                }

                PatQPath(ref qself, ref path) => {
                    // Associated constants only.
                    let resolution =
                        match self.resolve_possibly_assoc_item(pat_id, Some(qself),
                                                               path, ValueNS,
                                                               false) {
                            TypecheckRequired => {
                                // All `<T>::CONST` should end up here, and will
                                // require use of the trait map to resolve
                                // during typechecking.
                                let const_name = path.segments.last().unwrap()
                                                     .identifier.name;
                                let traits = self.get_traits_containing_item(const_name);
                                self.trait_map.insert(pattern.id, traits);
                                visit::walk_pat(self, pattern);
                                return true;
                            }
                            ResolveAttempt(resolution) => resolution,
                        };
                    if let Some(path_res) = resolution {
                        match path_res.base_def {
                            // All `<T as Trait>::CONST` should end up here, and
                            // have the trait already selected.
                            DefAssociatedConst(..) => {
                                self.record_def(pattern.id, path_res);
                            }
2867
                            _ => {
2868 2869 2870 2871 2872 2873 2874 2875
                                resolve_error(
                                    &ResolutionError::NotAnAssociatedConst(
                                        self,
                                        path.span,
                                        &*token::get_ident(
                                            path.segments.last().unwrap().identifier)
                                    )
                                );
2876
                            }
2877
                        }
2878
                    } else {
2879 2880 2881 2882 2883 2884 2885
                        resolve_error(
                            &ResolutionError::UnresolvedAssociatedConst(
                                self,
                                path.span,
                                &*token::get_ident(path.segments.last().unwrap().identifier)
                            )
                        );
2886
                    }
2887
                    visit::walk_pat(self, pattern);
2888 2889
                }

2890
                PatStruct(ref path, _, _) => {
2891
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2892
                        Some(definition) => {
2893 2894
                            self.record_def(pattern.id, definition);
                        }
2895
                        result => {
2896
                            debug!("(resolving pattern) didn't find struct \
2897
                                    def: {:?}", result);
2898 2899 2900 2901 2902
                            resolve_error(&ResolutionError::DoesNotNameAStruct(
                                                                self,
                                                                path.span,
                                                                &*path_names_to_string(path, 0))
                                         );
2903 2904
                        }
                    }
2905 2906 2907 2908 2909
                    visit::walk_path(self, path);
                }

                PatLit(_) | PatRange(..) => {
                    visit::walk_pat(self, pattern);
2910 2911
                }

2912
                _ => {
2913 2914 2915
                    // Nothing to do.
                }
            }
2916
            true
2917
        });
2918 2919
    }

2920
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
2921 2922 2923
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
2924
                                                 name,
2925
                                                 ValueNS) {
2926
            Success((target, _)) => {
2927
                debug!("(resolve bare identifier pattern) succeeded in \
2928
                         finding {} at {:?}",
2929
                        name,
E
Erick Tryzelaar 已提交
2930 2931
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
2932
                    None => {
S
Steve Klabnik 已提交
2933
                        panic!("resolved name in the value namespace to a \
2934
                              set of name bindings with no def?!");
2935
                    }
B
Brian Anderson 已提交
2936
                    Some(def) => {
2937 2938 2939
                        // For the two success cases, this lookup can be
                        // considered as not having a private component because
                        // the lookup happened only within the current module.
2940
                        match def.def {
A
Alex Crichton 已提交
2941
                            def @ DefVariant(..) | def @ DefStruct(..) => {
2942
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
2943
                            }
2944
                            def @ DefConst(..) | def @ DefAssociatedConst(..) => {
2945
                                return FoundConst(def, LastMod(AllPublic));
2946
                            }
2947
                            DefStatic(..) => {
2948 2949
                                resolve_error(&ResolutionError::StaticVariableReference(self,
                                                                                        span));
2950 2951
                                return BareIdentifierPatternUnresolved;
                            }
2952
                            _ => {
2953
                                return BareIdentifierPatternUnresolved;
2954 2955
                            }
                        }
2956 2957 2958 2959
                    }
                }
            }

B
Brian Anderson 已提交
2960
            Indeterminate => {
S
Steve Klabnik 已提交
2961
                panic!("unexpected indeterminate result");
2962
            }
2963 2964 2965
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
2966
                        resolve_error(&ResolutionError::FailedToResolve(self, span, &*msg));
2967 2968 2969
                    }
                    None => ()
                }
2970

2971
                debug!("(resolve bare identifier pattern) failed to find {}",
2972
                        name);
2973
                return BareIdentifierPatternUnresolved;
2974 2975 2976 2977
            }
        }
    }

2978 2979 2980 2981 2982 2983 2984 2985 2986
    /// Handles paths that may refer to associated items
    fn resolve_possibly_assoc_item(&mut self,
                                   id: NodeId,
                                   maybe_qself: Option<&ast::QSelf>,
                                   path: &Path,
                                   namespace: Namespace,
                                   check_ribs: bool)
                                   -> AssocItemResolveResult
    {
2987 2988
        let max_assoc_types;

2989
        match maybe_qself {
2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000
            Some(qself) => {
                if qself.position == 0 {
                    return TypecheckRequired;
                }
                max_assoc_types = path.segments.len() - qself.position;
                // Make sure the trait is valid.
                let _ = self.resolve_trait_reference(id, path, max_assoc_types);
            }
            None => {
                max_assoc_types = path.segments.len();
            }
3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021
        }

        let mut resolution = self.with_no_errors(|this| {
            this.resolve_path(id, path, 0, namespace, check_ribs)
        });
        for depth in 1..max_assoc_types {
            if resolution.is_some() {
                break;
            }
            self.with_no_errors(|this| {
                resolution = this.resolve_path(id, path, depth,
                                               TypeNS, true);
            });
        }
        if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
            // A module is not a valid type or value.
            resolution = None;
        }
        ResolveAttempt(resolution)
    }

3022 3023
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
3024 3025
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
F
Felix S. Klock II 已提交
3026
    fn resolve_path(&mut self,
3027 3028
                    id: NodeId,
                    path: &Path,
3029
                    path_depth: usize,
3030
                    namespace: Namespace,
3031
                    check_ribs: bool) -> Option<PathResolution> {
3032 3033 3034
        let span = path.span;
        let segments = &path.segments[..path.segments.len()-path_depth];

N
Nick Cameron 已提交
3035
        let mk_res = |(def, lp)| PathResolution::new(def, lp, path_depth);
3036

3037
        if path.global {
3038
            let def = self.resolve_crate_relative_path(span, segments, namespace);
3039
            return def.map(mk_res);
3040 3041
        }

3042
        // Try to find a path to an item in a module.
3043
        let unqualified_def =
3044
                self.resolve_identifier(segments.last().unwrap().identifier,
3045 3046
                                        namespace,
                                        check_ribs,
3047
                                        span);
3048

N
Nick Cameron 已提交
3049 3050 3051
        if segments.len() <= 1 {
            return unqualified_def.map(mk_res);
        }
3052

N
Nick Cameron 已提交
3053 3054 3055 3056 3057 3058 3059 3060 3061
        let def = self.resolve_module_relative_path(span, segments, namespace);
        match (def, unqualified_def) {
            (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
                self.session
                    .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
                              id, span,
                              "unnecessary qualification".to_string());
            }
            _ => {}
3062
        }
N
Nick Cameron 已提交
3063 3064

        def.map(mk_res)
3065 3066
    }

N
Nick Cameron 已提交
3067
    // Resolve a single identifier.
F
Felix S. Klock II 已提交
3068
    fn resolve_identifier(&mut self,
3069 3070 3071 3072 3073
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3074 3075 3076 3077 3078 3079 3080 3081 3082
        // First, check to see whether the name is a primitive type.
        if namespace == TypeNS {
            if let Some(&prim_ty) = self.primitive_type_table
                                        .primitive_types
                                        .get(&identifier.name) {
                return Some((DefPrimTy(prim_ty), LastMod(AllPublic)));
            }
        }

3083
        if check_ribs {
3084 3085 3086 3087
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier,
                                                                     namespace,
                                                                     span) {
                return Some((def, LastMod(AllPublic)));
3088 3089 3090
            }
        }

3091
        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
3092 3093
    }

3094
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3095
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3096
                                            containing_module: Rc<Module>,
3097
                                            name: Name,
3098
                                            namespace: Namespace)
3099
                                            -> NameDefinition {
3100
        // First, search children.
3101
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3102

3103
        match containing_module.children.borrow().get(&name) {
3104 3105 3106 3107
            Some(child_name_bindings) => {
                match child_name_bindings.def_for_namespace(namespace) {
                    Some(def) => {
                        // Found it. Stop the search here.
N
Nick Cameron 已提交
3108
                        let p = child_name_bindings.defined_in_public_namespace(namespace);
3109
                        let lp = if p {LastMod(AllPublic)} else {
3110
                            LastMod(DependsOn(def.def_id()))
3111 3112
                        };
                        return ChildNameDefinition(def, lp);
3113
                    }
3114
                    None => {}
3115 3116
                }
            }
3117
            None => {}
3118 3119 3120
        }

        // Next, search import resolutions.
3121
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3122
            Some(import_resolution) if import_resolution.is_public => {
3123 3124 3125 3126 3127 3128 3129
                if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
                    match target.bindings.def_for_namespace(namespace) {
                        Some(def) => {
                            // Found it.
                            let id = import_resolution.id(namespace);
                            // track imports and extern crates as well
                            self.used_imports.insert((id, namespace));
3130
                            self.record_import_use(id, name);
3131 3132 3133 3134 3135
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
3136
                            }
3137 3138 3139 3140 3141
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
3142 3143 3144 3145
                        }
                    }
                }
            }
A
Alex Crichton 已提交
3146
            Some(..) | None => {} // Continue.
3147 3148 3149 3150
        }

        // Finally, search through external children.
        if namespace == TypeNS {
3151 3152 3153 3154 3155 3156 3157 3158 3159
            if let Some(module) = containing_module.external_module_children.borrow()
                                                   .get(&name).cloned() {
                if let Some(def_id) = module.def_id.get() {
                    // track used crates
                    self.used_crates.insert(def_id.krate);
                    let lp = if module.is_public {LastMod(AllPublic)} else {
                        LastMod(DependsOn(def_id))
                    };
                    return ChildNameDefinition(DefMod(def_id), lp);
3160
                }
3161 3162
            }
        }
3163 3164

        return NoNameDefinition;
3165 3166
    }

3167
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3168
    fn resolve_module_relative_path(&mut self,
3169 3170
                                    span: Span,
                                    segments: &[ast::PathSegment],
3171 3172
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
3173 3174 3175
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3176

3177
        let containing_module;
3178
        let last_private;
N
Nick Cameron 已提交
3179 3180
        let current_module = self.current_module.clone();
        match self.resolve_module_path(current_module,
3181
                                       &module_path[..],
3182
                                       UseLexicalScope,
3183
                                       span,
3184
                                       PathSearch) {
3185 3186 3187 3188
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3189
                        let msg = format!("Use of undeclared type or module `{}`",
3190
                                          names_to_string(&module_path));
3191
                        (span, msg)
3192 3193
                    }
                };
3194

3195
                resolve_error(&ResolutionError::FailedToResolve(self, span, &*msg));
3196
                return None;
3197
            }
S
Steve Klabnik 已提交
3198
            Indeterminate => panic!("indeterminate unexpected"),
3199
            Success((resulting_module, resulting_last_private)) => {
3200
                containing_module = resulting_module;
3201
                last_private = resulting_last_private;
3202 3203 3204
            }
        }

3205
        let name = segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
3206
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
3207
                                                                  name,
3208
                                                                  namespace) {
B
Brian Anderson 已提交
3209
            NoNameDefinition => {
3210
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3211
                return None;
3212
            }
3213 3214
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
3215
            }
3216
        };
3217 3218
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
3219
        }
3220
        return Some(def);
3221 3222
    }

3223 3224
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3225
    fn resolve_crate_relative_path(&mut self,
3226 3227
                                   span: Span,
                                   segments: &[ast::PathSegment],
3228 3229
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
3230 3231 3232
        let module_path = segments.init().iter()
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3233

3234
        let root_module = self.graph_root.get_module();
3235

3236
        let containing_module;
3237
        let last_private;
3238
        match self.resolve_module_path_from_root(root_module,
3239
                                                 &module_path[..],
3240
                                                 0,
3241
                                                 span,
3242
                                                 PathSearch,
3243
                                                 LastMod(AllPublic)) {
3244 3245 3246 3247 3248
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3249
                                          names_to_string(&module_path[..]));
3250
                        (span, msg)
3251 3252 3253
                    }
                };

3254
                resolve_error(&ResolutionError::FailedToResolve(self, span, &*msg));
B
Brian Anderson 已提交
3255
                return None;
3256 3257
            }

B
Brian Anderson 已提交
3258
            Indeterminate => {
S
Steve Klabnik 已提交
3259
                panic!("indeterminate unexpected");
3260 3261
            }

3262
            Success((resulting_module, resulting_last_private)) => {
3263
                containing_module = resulting_module;
3264
                last_private = resulting_last_private;
3265 3266 3267
            }
        }

3268
        let name = segments.last().unwrap().identifier.name;
3269
        match self.resolve_definition_of_name_in_module(containing_module,
3270
                                                        name,
3271
                                                        namespace) {
B
Brian Anderson 已提交
3272
            NoNameDefinition => {
3273
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3274
                return None;
3275
            }
3276 3277
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
3278 3279 3280 3281
            }
        }
    }

F
Felix S. Klock II 已提交
3282
    fn resolve_identifier_in_local_ribs(&mut self,
3283 3284 3285 3286
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
3287
        // Check the local set of ribs.
3288
        let search_result = match namespace {
B
Brian Anderson 已提交
3289
            ValueNS => {
3290
                let renamed = mtwt::resolve(ident);
3291
                self.search_ribs(&self.value_ribs, renamed, span)
3292
            }
B
Brian Anderson 已提交
3293
            TypeNS => {
3294
                let name = ident.name;
3295
                self.search_ribs(&self.type_ribs, name, span)
3296
            }
3297
        };
3298

3299
        match search_result {
3300
            Some(DlDef(def)) => {
N
Nick Cameron 已提交
3301
                debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
3302
                       token::get_ident(ident),
P
Paul Stansifer 已提交
3303
                       def);
3304
                Some(def)
3305
            }
3306
            Some(DlField) | Some(DlImpl(_)) | None => {
3307
                None
3308 3309 3310 3311
            }
        }
    }

3312 3313 3314 3315
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
3316
        // Check the items.
E
Eduard Burtescu 已提交
3317 3318
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3319
                                                 name,
3320
                                                 namespace) {
3321
            Success((target, _)) => {
3322
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
3323
                    None => {
3324 3325
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
3326
                        debug!("(resolving item path by identifier in lexical \
3327
                                 scope) failed to resolve {} after success...",
3328
                                 name);
3329
                        return None;
3330
                    }
B
Brian Anderson 已提交
3331
                    Some(def) => {
3332
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
3333
                                resolved `{}` to item",
3334
                               name);
3335 3336 3337
                        // This lookup is "all public" because it only searched
                        // for one identifier in the current module (couldn't
                        // have passed through reexports or anything like that.
3338
                        return Some((def, LastMod(AllPublic)));
3339 3340 3341
                    }
                }
            }
B
Brian Anderson 已提交
3342
            Indeterminate => {
S
Steve Klabnik 已提交
3343
                panic!("unexpected indeterminate result");
3344
            }
3345
            Failed(err) => {
3346
                debug!("(resolving item path by identifier in lexical scope) \
3347
                         failed to resolve {}", name);
N
Nick Cameron 已提交
3348 3349

                if let Some((span, msg)) = err {
3350
                    resolve_error(&ResolutionError::FailedToResolve(self, span, &*msg))
N
Nick Cameron 已提交
3351 3352
                }

B
Brian Anderson 已提交
3353
                return None;
3354 3355 3356 3357
            }
        }
    }

J
Jorge Aparicio 已提交
3358 3359 3360
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3361
        self.emit_errors = false;
A
Alex Crichton 已提交
3362
        let rs = f(self);
3363 3364 3365 3366
        self.emit_errors = true;
        rs
    }

3367
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
3368 3369 3370
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
3371
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3372 3373
                TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
                TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
3374 3375 3376 3377 3378 3379 3380
                // 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,
            }
        }

3381
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
3382 3383
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
3384
            let last_name = name_path.last().unwrap();
3385

3386
            if name_path.len() == 1 {
3387
                match this.primitive_type_table.primitive_types.get(last_name) {
3388 3389
                    Some(_) => None,
                    None => {
3390
                        match this.current_module.children.borrow().get(last_name) {
3391 3392 3393 3394 3395 3396 3397
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
3398 3399 3400 3401
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
3402 3403 3404 3405 3406 3407
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

3408 3409
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
            if did.krate == ast::LOCAL_CRATE {
3410
                let sig = match this.ast_map.get(did.node) {
3411
                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
3412
                        ast::MethodTraitItem(ref sig, _) => sig,
3413 3414
                        _ => return false
                    },
3415
                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
3416
                        ast::MethodImplItem(ref sig, _) => sig,
3417 3418 3419 3420
                        _ => return false
                    },
                    _ => return false
                };
3421
                sig.explicit_self.node == ast::SelfStatic
3422 3423 3424 3425 3426
            } else {
                csearch::is_static_method(&this.session.cstore, did)
            }
        }

3427 3428 3429 3430
        let (path, node_id, allowed) = match self.current_self_type {
            Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
                Some(x) => x,
                None => return NoSuggestion,
3431 3432 3433 3434
            },
            None => return NoSuggestion,
        };

3435 3436
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3437 3438 3439 3440
            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
                Some(DefTy(did, _)) |
                Some(DefStruct(did)) |
                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
3441 3442 3443 3444 3445
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3446
                    }
3447 3448 3449
                },
                _ => {} // Self type didn't resolve properly
            }
3450 3451
        }

3452
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3453 3454

        // Look for a method in the current self type's impl module.
3455 3456 3457 3458
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
                if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
                    if is_static_method(self, did) {
3459
                        return StaticMethod(path_names_to_string(&path, 0))
3460 3461 3462 3463 3464
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3465 3466
                    }
                }
3467
            }
3468 3469 3470
        }

        // Look for a method in the current trait.
3471 3472 3473
        if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
            if let Some(&did) = self.trait_item_map.get(&(name, trait_did)) {
                if is_static_method(self, did) {
3474
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3475 3476
                } else {
                    return TraitItem;
3477 3478 3479 3480 3481 3482 3483
                }
            }
        }

        NoSuggestion
    }

3484
    fn find_best_match_for_name(&mut self, name: &str) -> Option<String> {
3485
        let mut maybes: Vec<token::InternedString> = Vec::new();
3486
        let mut values: Vec<usize> = Vec::new();
3487

3488
        for rib in self.value_ribs.iter().rev() {
3489
            for (&k, _) in &rib.bindings {
3490
                maybes.push(token::get_name(k));
3491
                values.push(usize::MAX);
3492 3493 3494 3495
            }
        }

        let mut smallest = 0;
P
Patrick Walton 已提交
3496
        for (i, other) in maybes.iter().enumerate() {
3497
            values[i] = lev_distance(name, &other);
3498

3499
            if values[i] <= values[smallest] {
3500 3501 3502 3503
                smallest = i;
            }
        }

3504 3505 3506 3507 3508
        // As a loose rule to avoid obviously incorrect suggestions, clamp the
        // maximum edit distance we will accept for a suggestion to one third of
        // the typo'd name's length.
        let max_distance = std::cmp::max(name.len(), 3) / 3;

3509
        if !values.is_empty() &&
3510
            values[smallest] <= max_distance &&
3511
            name != &maybes[smallest][..] {
3512

3513
            Some(maybes[smallest].to_string())
3514 3515 3516 3517 3518 3519

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
3520
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3521 3522
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3523 3524 3525

        self.record_candidate_traits_for_expr_if_necessary(expr);

3526
        // Next, resolve the node.
3527
        match expr.node {
3528
            ExprPath(ref maybe_qself, ref path) => {
3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544
                let resolution =
                    match self.resolve_possibly_assoc_item(expr.id,
                                                           maybe_qself.as_ref(),
                                                           path,
                                                           ValueNS,
                                                           true) {
                        // `<T>::a::b::c` is resolved by typeck alone.
                        TypecheckRequired => {
                            let method_name = path.segments.last().unwrap().identifier.name;
                            let traits = self.get_traits_containing_item(method_name);
                            self.trait_map.insert(expr.id, traits);
                            visit::walk_expr(self, expr);
                            return;
                        }
                        ResolveAttempt(resolution) => resolution,
                    };
3545

3546 3547
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3548
                if let Some(path_res) = resolution {
3549
                    // Check if struct variant
3550
                    if let DefVariant(_, _, true) = path_res.base_def {
3551
                        let path_name = path_names_to_string(path, 0);
3552

3553 3554 3555
                        resolve_error(&ResolutionError::StructVariantUsedAsFunction(self,
                                                                                    expr.span,
                                                                                    &*path_name));
3556

3557
                        let msg = format!("did you mean to write: \
3558 3559 3560 3561 3562 3563 3564
                                           `{} {{ /* fields */ }}`?",
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
3565
                    } else {
3566
                        // Write the result into the def map.
3567
                        debug!("(resolving expr) resolved `{}`",
3568
                               path_names_to_string(path, 0));
3569

3570 3571
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3572
                        if path_res.depth != 0 {
3573
                            let method_name = path.segments.last().unwrap().identifier.name;
3574
                            let traits = self.get_traits_containing_item(method_name);
3575 3576 3577
                            self.trait_map.insert(expr.id, traits);
                        }

3578
                        self.record_def(expr.id, path_res);
3579
                    }
3580 3581 3582 3583 3584
                } 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.)
3585
                    let path_name = path_names_to_string(path, 0);
3586 3587 3588 3589 3590 3591
                    let type_res = self.with_no_errors(|this| {
                        this.resolve_path(expr.id, path, 0, TypeNS, false)
                    });
                    match type_res.map(|r| r.base_def) {
                        Some(DefTy(struct_id, _))
                            if self.structs.contains_key(&struct_id) => {
3592 3593 3594
                                resolve_error(&ResolutionError::StructVariantUsedAsFunction(self,
                                                                                    expr.span,
                                                                                    &*path_name));
3595

3596
                                let msg = format!("did you mean to write: \
3597 3598 3599 3600 3601 3602 3603 3604
                                                     `{} {{ /* fields */ }}`?",
                                                    path_name);
                                if self.emit_errors {
                                    self.session.fileline_help(expr.span, &msg);
                                } else {
                                    self.session.span_help(expr.span, &msg);
                                }
                            }
3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617
                        _ => {
                            // Keep reporting some errors even if they're ignored above.
                            self.resolve_path(expr.id, path, 0, ValueNS, true);

                            let mut method_scope = false;
                            self.value_ribs.iter().rev().all(|rib| {
                                method_scope = match rib.kind {
                                    MethodRibKind => true,
                                    ItemRibKind | ConstantItemRibKind => false,
                                    _ => return true, // Keep advancing
                                };
                                false // Stop advancing
                            });
3618

N
Nick Cameron 已提交
3619 3620
                            if method_scope &&
                               &token::get_name(special_names::self_)[..] == path_name {
3621 3622 3623 3624 3625
                                resolve_error(
                                    &ResolutionError::SelfNotAvailableInStaticMethod(
                                        self,
                                        expr.span)
                                );
3626 3627 3628 3629 3630 3631
                            } else {
                                let last_name = path.segments.last().unwrap().identifier.name;
                                let mut msg = match self.find_fallback_in_self_type(last_name) {
                                    NoSuggestion => {
                                        // limit search to 5 to reduce the number
                                        // of stupid suggestions
3632
                                        self.find_best_match_for_name(&path_name)
3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644
                                                            .map_or("".to_string(),
                                                                    |x| format!("`{}`", x))
                                    }
                                    Field => format!("`self.{}`", path_name),
                                    Method |
                                    TraitItem =>
                                        format!("to call `self.{}`", path_name),
                                    TraitMethod(path_str) |
                                    StaticMethod(path_str) =>
                                        format!("to call `{}::{}`", path_str, path_name)
                                };

3645
                                if !msg.is_empty() {
3646
                                    msg = format!(". Did you mean {}?", msg)
3647
                                }
3648

3649 3650 3651 3652
                                resolve_error(&ResolutionError::UnresolvedName(self,
                                                                               expr.span,
                                                                               &*path_name,
                                                                               &*msg));
3653
                            }
V
Vincent Belliard 已提交
3654
                        }
3655 3656 3657
                    }
                }

3658
                visit::walk_expr(self, expr);
3659 3660
            }

3661
            ExprStruct(ref path, _, _) => {
3662 3663 3664
                // 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.
3665
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3666
                    Some(definition) => self.record_def(expr.id, definition),
3667 3668
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3669

3670 3671 3672 3673 3674
                        resolve_error(&ResolutionError::DoesNotNameAStruct(
                                                                self,
                                                                path.span,
                                                                &*path_names_to_string(path, 0))
                                     );
3675 3676 3677
                    }
                }

3678
                visit::walk_expr(self, expr);
3679 3680
            }

P
Pythoner6 已提交
3681
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3682
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3683
                    let def_like = DlDef(DefLabel(expr.id));
3684

3685
                    {
3686
                        let rib = this.label_ribs.last_mut().unwrap();
3687
                        let renamed = mtwt::resolve(label);
3688
                        rib.bindings.insert(renamed, def_like);
3689
                    }
3690

3691
                    visit::walk_expr(this, expr);
3692
                })
3693 3694
            }

3695
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3696
                let renamed = mtwt::resolve(label);
3697
                match self.search_label(renamed) {
3698
                    None => {
3699 3700 3701
                        resolve_error(&ResolutionError::UndeclaredLabel(self,
                                                                        expr.span,
                                                                        &*token::get_ident(label)))
3702
                    }
3703
                    Some(DlDef(def @ DefLabel(_))) => {
3704
                        // Since this def is a label, it is never read.
3705 3706 3707 3708 3709
                        self.record_def(expr.id, PathResolution {
                            base_def: def,
                            last_private: LastMod(AllPublic),
                            depth: 0
                        })
3710 3711
                    }
                    Some(_) => {
3712
                        self.session.span_bug(expr.span,
3713 3714
                                              "label wasn't mapped to a \
                                               label def!")
3715 3716 3717 3718
                    }
                }
            }

B
Brian Anderson 已提交
3719
            _ => {
3720
                visit::walk_expr(self, expr);
3721 3722 3723 3724
            }
        }
    }

E
Eduard Burtescu 已提交
3725
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3726
        match expr.node {
3727
            ExprField(_, ident) => {
3728 3729 3730 3731
                // 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.
3732
                let traits = self.get_traits_containing_item(ident.node.name);
3733
                self.trait_map.insert(expr.id, traits);
3734
            }
3735
            ExprMethodCall(ident, _, _) => {
3736
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
3737
                        traits for {}",
3738
                       expr.id);
3739
                let traits = self.get_traits_containing_item(ident.node.name);
3740
                self.trait_map.insert(expr.id, traits);
3741
            }
3742
            _ => {
3743 3744 3745 3746 3747
                // Nothing to do.
            }
        }
    }

3748 3749
    fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
        debug!("(getting traits containing item) looking for '{}'",
3750
               name);
E
Eduard Burtescu 已提交
3751 3752 3753 3754 3755 3756 3757

        fn add_trait_info(found_traits: &mut Vec<DefId>,
                          trait_def_id: DefId,
                          name: Name) {
            debug!("(adding trait info) found trait {}:{} for method '{}'",
                trait_def_id.krate,
                trait_def_id.node,
3758
                name);
E
Eduard Burtescu 已提交
3759 3760
            found_traits.push(trait_def_id);
        }
3761

3762
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
3763
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
3764 3765
        loop {
            // Look for the current trait.
3766 3767
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3768
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3769
                        add_trait_info(&mut found_traits, trait_def_id, name);
3770 3771
                    }
                }
3772
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3773
            }
3774

E
Eduard Burtescu 已提交
3775
            // Look for trait children.
3776
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3777

E
Eduard Burtescu 已提交
3778
            {
3779
                for (_, child_names) in search_module.children.borrow().iter() {
3780 3781 3782 3783 3784
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
                        None => continue
                    };
                    let trait_def_id = match def {
3785
                        DefTrait(trait_def_id) => trait_def_id,
3786 3787
                        _ => continue,
                    };
3788
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3789
                        add_trait_info(&mut found_traits, trait_def_id, name);
3790 3791
                    }
                }
E
Eduard Burtescu 已提交
3792
            }
3793

E
Eduard Burtescu 已提交
3794
            // Look for imports.
3795
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
3796 3797 3798 3799 3800
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
3801
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3802 3803
                    Some(..) | None => continue,
                };
3804
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3805
                    add_trait_info(&mut found_traits, did, name);
3806 3807 3808 3809
                    let id = import.type_id;
                    self.used_imports.insert((id, TypeNS));
                    let trait_name = self.get_trait_name(did);
                    self.record_import_use(id, trait_name);
3810 3811
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
3812
                    }
3813
                }
E
Eduard Burtescu 已提交
3814
            }
3815

E
Eduard Burtescu 已提交
3816
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
3817 3818
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
3819
                    search_module = parent_module.upgrade().unwrap();
3820
                }
E
Eduard Burtescu 已提交
3821
            }
3822 3823
        }

E
Eduard Burtescu 已提交
3824
        found_traits
3825 3826
    }

3827 3828 3829
    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
        debug!("(recording def) recording {:?} for {}", resolution, node_id);
        assert!(match resolution.last_private {LastImport{..} => false, _ => true},
3830
                "Import should only be used for `use` directives");
3831

3832 3833 3834 3835 3836
        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
            self.session.span_bug(span, &format!("path resolved multiple times \
                                                  ({:?} before, {:?} now)",
                                                 prev_res, resolution));
3837
        }
3838 3839
    }

F
Felix S. Klock II 已提交
3840
    fn enforce_default_binding_mode(&mut self,
3841
                                        pat: &Pat,
3842
                                        pat_binding_mode: BindingMode,
3843
                                        descr: &str) {
3844
        match pat_binding_mode {
3845
            BindByValue(_) => {}
A
Alex Crichton 已提交
3846
            BindByRef(..) => {
3847 3848 3849
                resolve_error(&ResolutionError::CannotUseRefBindingModeWith(self,
                                                                            pat.span,
                                                                            descr));
3850 3851 3852 3853
            }
        }
    }

3854 3855 3856 3857 3858 3859 3860
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

K
Kiet Tran 已提交
3861
    #[allow(dead_code)]   // useful for debugging
E
Eduard Burtescu 已提交
3862
    fn dump_module(&mut self, module_: Rc<Module>) {
3863
        debug!("Dump of module `{}`:", module_to_string(&*module_));
3864

3865
        debug!("Children:");
3866
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3867
        for (&name, _) in module_.children.borrow().iter() {
3868
            debug!("* {}", name);
3869 3870
        }

3871
        debug!("Import resolutions:");
3872
        let import_resolutions = module_.import_resolutions.borrow();
3873
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
3874
            let value_repr;
3875
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
3876
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3877
                Some(_) => {
R
Richo Healey 已提交
3878
                    value_repr = " value:?".to_string();
3879
                    // FIXME #4954
3880 3881 3882
                }
            }

N
Niko Matsakis 已提交
3883
            let type_repr;
3884
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
3885
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3886
                Some(_) => {
R
Richo Healey 已提交
3887
                    type_repr = " type:?".to_string();
3888
                    // FIXME #4954
3889 3890 3891
                }
            }

3892
            debug!("* {}:{}{}", name, value_repr, type_repr);
3893 3894 3895 3896
        }
    }
}

3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939

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("::")
        }
        result.push_str(&token::get_name(*name));
    };
    result
}

fn path_names_to_string(path: &Path, depth: usize) -> String {
    let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth]
                                    .iter()
                                    .map(|seg| seg.identifier.name)
                                    .collect();
    names_to_string(&names[..])
}

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

    fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
        match module.parent_link {
            NoParentLink => {}
            ModuleParentLink(ref module, name) => {
                names.push(name);
                collect_mod(names, &*module.upgrade().unwrap());
            }
            BlockParentLink(ref module, _) => {
                // danger, shouldn't be ident?
                names.push(special_idents::opaque.name);
                collect_mod(names, &*module.upgrade().unwrap());
            }
        }
    }
    collect_mod(&mut names, module);

3940
    if names.is_empty() {
3941 3942 3943 3944 3945 3946
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}


3947
pub struct CrateMap {
3948
    pub def_map: DefMap,
3949
    pub freevars: RefCell<FreevarMap>,
3950
    pub export_map: ExportMap,
3951 3952
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
3953 3954 3955
    pub glob_map: Option<GlobMap>
}

N
Niko Matsakis 已提交
3956
#[derive(PartialEq,Copy, Clone)]
3957 3958 3959
pub enum MakeGlobMap {
    Yes,
    No
3960 3961
}

3962
/// Entry point to crate resolution.
3963 3964 3965 3966
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                               ast_map: &'a ast_map::Map<'tcx>,
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
3967
    let krate = ast_map.krate();
3968
    let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
3969

3970
    build_reduced_graph::build_reduced_graph(&mut resolver, krate);
3971 3972
    session.abort_if_errors();

3973
    resolve_imports::resolve_imports(&mut resolver);
3974 3975
    session.abort_if_errors();

3976
    record_exports::record(&mut resolver);
3977 3978 3979 3980 3981 3982 3983
    session.abort_if_errors();

    resolver.resolve_crate(krate);
    session.abort_if_errors();

    check_unused::check_crate(&mut resolver, krate);

3984
    CrateMap {
3985 3986
        def_map: resolver.def_map,
        freevars: resolver.freevars,
3987
        export_map: resolver.export_map,
3988 3989
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
3990 3991 3992 3993 3994
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
3995
    }
3996
}
3997 3998

__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }