lib.rs 163.5 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", issue = "27812")]
B
Brian Anderson 已提交
15
#![staged_api]
16 17
#![crate_type = "dylib"]
#![crate_type = "rlib"]
18
#![doc(html_logo_url = "https://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
      html_root_url = "https://doc.rust-lang.org/nightly/")]
21

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

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

extern crate rustc;

S
Steven Fackler 已提交
36 37 38 39 40 41 42 43 44 45
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::*;
46
use self::AssocItemResolveResult::*;
S
Steven Fackler 已提交
47 48 49 50 51 52
use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;
use self::ModuleKind::*;
use self::FallbackChecks::*;

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

67 68
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block};
use syntax::ast::{ConstImplItem, Crate, CrateNum};
N
Niko Matsakis 已提交
69
use syntax::ast::{Expr, ExprAgain, ExprBreak, ExprField};
70
use syntax::ast::{ExprLoop, ExprWhile, ExprMethodCall};
71
use syntax::ast::{ExprPath, ExprStruct, FnDecl};
72
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
73
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
F
Flavio Percoco 已提交
74
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl};
75
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
76
use syntax::ast::{Local, MethodImplItem, Name, NodeId};
77
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit, PatQPath};
78 79 80
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};
81
use syntax::ast::{TyPath, TyPtr};
82
use syntax::ast::{TyRptr, TyStr, TyUs, TyU8, TyU16, TyU32, TyU64, TyUint};
83
use syntax::ast::TypeImplItem;
P
Patrick Walton 已提交
84
use syntax::ast;
N
Niko Matsakis 已提交
85
use syntax::ast_util::{walk_pat};
86
use syntax::attr::AttrMetaMethods;
87
use syntax::ext::mtwt;
88
use syntax::parse::token::{self, special_names, special_idents};
89
use syntax::ptr::P;
90
use syntax::codemap::{self, Span, Pos};
91
use syntax::visit::{self, FnKind, Visitor};
92

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

101 102 103
use resolve_imports::{Target, ImportDirective, ImportResolution};
use resolve_imports::Shadowable;

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

A
Alex Crichton 已提交
108 109
mod check_unused;
mod record_exports;
110
mod build_reduced_graph;
111
mod resolve_imports;
112

113 114 115 116 117 118 119 120 121 122 123
// Perform the callback, not walking deeper if the return is true
macro_rules! execute_callback {
    ($node: expr, $walker: expr) => (
        if let Some(ref callback) = $walker.callback {
            if callback($node, &mut $walker.resolved) {
                return;
            }
        }
    )
}

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

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

N
Niko Matsakis 已提交
395
#[derive(Copy, Clone)]
396
struct BindingInfo {
397
    span: Span,
398
    binding_mode: BindingMode,
399 400 401
}

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

N
Niko Matsakis 已提交
404
#[derive(Copy, Clone, PartialEq)]
F
Felix S. Klock II 已提交
405
enum PatternBindingMode {
406
    RefutableMode,
407
    LocalIrrefutableMode,
408
    ArgumentIrrefutableMode,
409 410
}

N
Niko Matsakis 已提交
411
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
G
Garming Sam 已提交
412
pub enum Namespace {
413
    TypeNS,
414
    ValueNS
415 416
}

B
Brian Anderson 已提交
417 418 419
/// A NamespaceResult represents the result of resolving an import in
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
420
#[derive(Clone)]
F
Felix S. Klock II 已提交
421
enum NamespaceResult {
T
Tim Chevalier 已提交
422 423 424
    /// 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.)
425
    UnknownResult,
B
Brian Anderson 已提交
426 427
    /// Means that resolve has determined that the name is definitely
    /// not bound in the namespace.
428
    UnboundResult,
T
Tim Chevalier 已提交
429 430
    /// Means that resolve has determined that the name is bound in the Module
    /// argument, and specified by the NameBindings argument.
E
Eduard Burtescu 已提交
431
    BoundResult(Rc<Module>, Rc<NameBindings>)
432 433
}

434
impl NamespaceResult {
F
Felix S. Klock II 已提交
435
    fn is_unknown(&self) -> bool {
B
Ben Striegel 已提交
436
        match *self {
437 438 439 440
            UnknownResult => true,
            _ => false
        }
    }
441 442 443 444 445 446
    fn is_unbound(&self) -> bool {
        match *self {
            UnboundResult => true,
            _ => false
        }
    }
447 448
}

F
Felix S. Klock II 已提交
449
enum NameDefinition {
N
Nick Cameron 已提交
450 451 452 453 454 455
    // The name was unbound.
    NoNameDefinition,
    // The name identifies an immediate child.
    ChildNameDefinition(Def, LastPrivate),
    // The name identifies an import.
    ImportNameDefinition(Def, LastPrivate),
456 457
}

458
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
459
    fn visit_item(&mut self, item: &Item) {
460
        execute_callback!(ast_map::Node::NodeItem(item), self);
A
Alex Crichton 已提交
461
        self.resolve_item(item);
462
    }
463
    fn visit_arm(&mut self, arm: &Arm) {
A
Alex Crichton 已提交
464
        self.resolve_arm(arm);
465
    }
466
    fn visit_block(&mut self, block: &Block) {
467
        execute_callback!(ast_map::Node::NodeBlock(block), self);
A
Alex Crichton 已提交
468
        self.resolve_block(block);
469
    }
470
    fn visit_expr(&mut self, expr: &Expr) {
471
        execute_callback!(ast_map::Node::NodeExpr(expr), self);
A
Alex Crichton 已提交
472
        self.resolve_expr(expr);
473
    }
474
    fn visit_local(&mut self, local: &Local) {
475
        execute_callback!(ast_map::Node::NodeLocal(&*local.pat), self);
A
Alex Crichton 已提交
476
        self.resolve_local(local);
477
    }
478
    fn visit_ty(&mut self, ty: &Ty) {
A
Alex Crichton 已提交
479
        self.resolve_type(ty);
480
    }
481 482 483 484 485 486 487 488 489 490 491 492 493
    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) {
494
        execute_callback!(ast_map::Node::NodeVariant(variant), self);
495 496 497 498 499 500 501 502 503 504
        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) => {
505
                for variant_argument in variant_arguments {
506 507 508 509 510 511 512 513 514 515 516 517
                    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) {
518
        execute_callback!(ast_map::Node::NodeForeignItem(foreign_item), self);
519 520 521 522 523 524 525 526 527 528 529
        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,
530
                function_kind: FnKind<'v>,
531 532 533 534 535
                declaration: &'v FnDecl,
                block: &'v Block,
                _: Span,
                node_id: NodeId) {
        let rib_kind = match function_kind {
536
            FnKind::ItemFn(_, generics, _, _, _, _) => {
537 538 539
                self.visit_generics(generics);
                ItemRibKind
            }
540
            FnKind::Method(_, sig, _) => {
541 542
                self.visit_generics(&sig.generics);
                self.visit_explicit_self(&sig.explicit_self);
543 544
                MethodRibKind
            }
545
            FnKind::Closure(..) => ClosureRibKind(node_id)
546 547 548
        };
        self.resolve_function(rib_kind, declaration, block);
    }
549
}
550

551 552
type ErrorMessage = Option<(Span, String)>;

F
Felix S. Klock II 已提交
553
enum ResolveResult<T> {
554 555 556
    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.
557 558
}

559
impl<T> ResolveResult<T> {
560 561
    fn success(&self) -> bool {
        match *self { Success(_) => true, _ => false }
562 563 564
    }
}

565 566 567 568
enum FallbackSuggestion {
    NoSuggestion,
    Field,
    Method,
569
    TraitItem,
570
    StaticMethod(String),
571
    TraitMethod(String),
572 573
}

N
Niko Matsakis 已提交
574
#[derive(Copy, Clone)]
E
Erik Price 已提交
575
enum TypeParameters<'a> {
576 577 578 579 580 581 582 583 584 585 586
    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)
587 588
}

589 590
// The rib kind controls the translation of local
// definitions (`DefLocal`) to upvars (`DefUpvar`).
N
Niko Matsakis 已提交
591
#[derive(Copy, Clone, Debug)]
F
Felix S. Klock II 已提交
592
enum RibKind {
593 594
    // No translation needs to be applied.
    NormalRibKind,
595

596 597
    // We passed through a closure scope at the given node ID.
    // Translate upvars as appropriate.
598
    ClosureRibKind(NodeId /* func id */),
599

600
    // We passed through an impl or trait and are now in one of its
601
    // methods. Allow references to ty params that impl or trait
602 603
    // binds. Disallow any other upvars (including other ty params that are
    // upvars).
604
    MethodRibKind,
605

606 607
    // We passed through an item scope. Disallow upvars.
    ItemRibKind,
608 609 610

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

N
Niko Matsakis 已提交
613
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
614
enum UseLexicalScopeFlag {
615 616 617 618
    DontUseLexicalScope,
    UseLexicalScope
}

F
Felix S. Klock II 已提交
619
enum ModulePrefixResult {
620
    NoPrefixFound,
621
    PrefixFound(Rc<Module>, usize)
622 623
}

624 625 626 627 628 629 630 631 632
#[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 已提交
633
#[derive(Copy, Clone, PartialEq)]
634
enum NameSearchType {
635 636 637 638
    /// 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
639 640
    /// expression, or a path pattern.
    PathSearch,
641 642
}

N
Niko Matsakis 已提交
643
#[derive(Copy, Clone)]
F
Felix S. Klock II 已提交
644
enum BareIdentifierPatternResolution {
645 646
    FoundStructOrEnumVariant(Def, LastPrivate),
    FoundConst(Def, LastPrivate),
647
    BareIdentifierPatternUnresolved
648 649
}

650
/// One local scope.
J
Jorge Aparicio 已提交
651
#[derive(Debug)]
F
Felix S. Klock II 已提交
652
struct Rib {
653
    bindings: HashMap<Name, DefLike>,
654
    kind: RibKind,
B
Brian Anderson 已提交
655
}
656

657
impl Rib {
F
Felix S. Klock II 已提交
658
    fn new(kind: RibKind) -> Rib {
659
        Rib {
660
            bindings: HashMap::new(),
661 662
            kind: kind
        }
663 664 665
    }
}

666
/// The link from a module up to its nearest parent node.
J
Jorge Aparicio 已提交
667
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
668
enum ParentLink {
669
    NoParentLink,
670
    ModuleParentLink(Weak<Module>, Name),
E
Eduard Burtescu 已提交
671
    BlockParentLink(Weak<Module>, NodeId)
672 673
}

674
/// The type of module this is.
N
Niko Matsakis 已提交
675
#[derive(Copy, Clone, PartialEq, Debug)]
F
Felix S. Klock II 已提交
676
enum ModuleKind {
677 678
    NormalModuleKind,
    TraitModuleKind,
679
    EnumModuleKind,
680
    TypeModuleKind,
681 682 683
    AnonymousModuleKind,
}

684
/// One node in the tree of modules.
685
pub struct Module {
686
    parent_link: ParentLink,
687
    def_id: Cell<Option<DefId>>,
688
    kind: Cell<ModuleKind>,
689
    is_public: bool,
690

E
Eduard Burtescu 已提交
691 692
    children: RefCell<HashMap<Name, Rc<NameBindings>>>,
    imports: RefCell<Vec<ImportDirective>>,
693

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

698 699 700 701 702 703 704 705 706 707 708 709 710 711
    // 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 已提交
712
    anonymous_children: RefCell<NodeMap<Rc<Module>>>,
713 714

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

    // The number of unresolved globs that this module exports.
718
    glob_count: Cell<usize>,
719

720 721 722 723 724 725
    // The number of unresolved pub imports (both regular and globs) in this module
    pub_count: Cell<usize>,

    // The number of unresolved pub glob imports in this module
    pub_glob_count: Cell<usize>,

726
    // The index of the import we're resolving.
727
    resolved_import_count: Cell<usize>,
728 729 730 731

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

735
impl Module {
F
Felix S. Klock II 已提交
736
    fn new(parent_link: ParentLink,
737 738 739 740
           def_id: Option<DefId>,
           kind: ModuleKind,
           external: bool,
           is_public: bool)
741
           -> Module {
742 743
        Module {
            parent_link: parent_link,
744
            def_id: Cell::new(def_id),
745
            kind: Cell::new(kind),
746
            is_public: is_public,
747
            children: RefCell::new(HashMap::new()),
748
            imports: RefCell::new(Vec::new()),
749
            external_module_children: RefCell::new(HashMap::new()),
750
            anonymous_children: RefCell::new(NodeMap()),
751
            import_resolutions: RefCell::new(HashMap::new()),
752
            glob_count: Cell::new(0),
753 754
            pub_count: Cell::new(0),
            pub_glob_count: Cell::new(0),
755
            resolved_import_count: Cell::new(0),
756
            populated: Cell::new(!external),
757
        }
B
Brian Anderson 已提交
758 759
    }

F
Felix S. Klock II 已提交
760
    fn all_imports_resolved(&self) -> bool {
761 762 763 764 765 766
        if self.imports.borrow_state() == ::std::cell::BorrowState::Writing {
            // it is currently being resolved ! so nope
            false
        } else {
            self.imports.borrow().len() == self.resolved_import_count.get()
        }
767 768 769
    }
}

V
Victor Berger 已提交
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
impl Module {
    pub fn inc_glob_count(&self) {
        self.glob_count.set(self.glob_count.get() + 1);
    }
    pub fn dec_glob_count(&self) {
        assert!(self.glob_count.get() > 0);
        self.glob_count.set(self.glob_count.get() - 1);
    }
    pub fn inc_pub_count(&self) {
        self.pub_count.set(self.pub_count.get() + 1);
    }
    pub fn dec_pub_count(&self) {
        assert!(self.pub_count.get() > 0);
        self.pub_count.set(self.pub_count.get() - 1);
    }
    pub fn inc_pub_glob_count(&self) {
        self.pub_glob_count.set(self.pub_glob_count.get() + 1);
    }
    pub fn dec_pub_glob_count(&self) {
        assert!(self.pub_glob_count.get() > 0);
        self.pub_glob_count.set(self.pub_glob_count.get() - 1);
    }
}

794
impl fmt::Debug for Module {
795
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
796
        write!(f, "{:?}, kind: {:?}, {}",
797 798 799 800 801 802
               self.def_id,
               self.kind,
               if self.is_public { "public" } else { "private" } )
    }
}

803
bitflags! {
J
Jorge Aparicio 已提交
804
    #[derive(Debug)]
805
    flags DefModifiers: u8 {
T
Fallout  
Tamir Duberstein 已提交
806 807
        const PUBLIC     = 1 << 0,
        const IMPORTABLE = 1 << 1,
808 809 810
    }
}

811
// Records a possibly-private type definition.
J
Jorge Aparicio 已提交
812
#[derive(Clone,Debug)]
F
Felix S. Klock II 已提交
813
struct TypeNsDef {
814
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
E
Eduard Burtescu 已提交
815
    module_def: Option<Rc<Module>>,
816
    type_def: Option<Def>,
817
    type_span: Option<Span>
818 819 820
}

// Records a possibly-private value definition.
J
Jorge Aparicio 已提交
821
#[derive(Clone, Copy, Debug)]
F
Felix S. Klock II 已提交
822
struct ValueNsDef {
823
    modifiers: DefModifiers, // see note in ImportResolution about how to use this
824
    def: Def,
825
    value_span: Option<Span>,
826 827
}

828 829
// Records the definitions (at most one for each namespace) that a name is
// bound to.
J
Jorge Aparicio 已提交
830
#[derive(Debug)]
831
pub struct NameBindings {
832
    type_def: RefCell<Option<TypeNsDef>>,   //< Meaning in type namespace.
833
    value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
834 835
}

836
impl NameBindings {
K
Kevin Butler 已提交
837 838 839 840 841 842 843
    fn new() -> NameBindings {
        NameBindings {
            type_def: RefCell::new(None),
            value_def: RefCell::new(None),
        }
    }

844
    /// Creates a new module in this set of name bindings.
845
    fn define_module(&self,
846 847 848 849 850 851
                     parent_link: ParentLink,
                     def_id: Option<DefId>,
                     kind: ModuleKind,
                     external: bool,
                     is_public: bool,
                     sp: Span) {
852
        // Merges the module with the existing type def or creates a new one.
T
Fallout  
Tamir Duberstein 已提交
853 854 855 856 857
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
858 859 860 861
        let module_ = Rc::new(Module::new(parent_link,
                                          def_id,
                                          kind,
                                          external,
E
Eduard Burtescu 已提交
862
                                          is_public));
E
Erick Tryzelaar 已提交
863 864
        let type_def = self.type_def.borrow().clone();
        match type_def {
865
            None => {
E
Erick Tryzelaar 已提交
866
                *self.type_def.borrow_mut() = Some(TypeNsDef {
867
                    modifiers: modifiers,
868
                    module_def: Some(module_),
869 870
                    type_def: None,
                    type_span: Some(sp)
E
Erick Tryzelaar 已提交
871
                });
872
            }
873
            Some(type_def) => {
E
Erick Tryzelaar 已提交
874
                *self.type_def.borrow_mut() = Some(TypeNsDef {
875
                    modifiers: modifiers,
876
                    module_def: Some(module_),
877
                    type_span: Some(sp),
878
                    type_def: type_def.type_def
E
Erick Tryzelaar 已提交
879
                });
880
            }
881 882 883
        }
    }

884
    /// Sets the kind of the module, creating a new one if necessary.
885
    fn set_module_kind(&self,
886 887 888 889 890 891
                       parent_link: ParentLink,
                       def_id: Option<DefId>,
                       kind: ModuleKind,
                       external: bool,
                       is_public: bool,
                       _sp: Span) {
T
Fallout  
Tamir Duberstein 已提交
892 893 894 895 896
        let modifiers = if is_public {
            DefModifiers::PUBLIC
        } else {
            DefModifiers::empty()
        } | DefModifiers::IMPORTABLE;
E
Erick Tryzelaar 已提交
897 898
        let type_def = self.type_def.borrow().clone();
        match type_def {
899
            None => {
900 901 902 903 904
                let module = Module::new(parent_link,
                                         def_id,
                                         kind,
                                         external,
                                         is_public);
E
Erick Tryzelaar 已提交
905
                *self.type_def.borrow_mut() = Some(TypeNsDef {
906
                    modifiers: modifiers,
E
Eduard Burtescu 已提交
907
                    module_def: Some(Rc::new(module)),
908 909
                    type_def: None,
                    type_span: None,
E
Erick Tryzelaar 已提交
910
                });
911 912 913 914
            }
            Some(type_def) => {
                match type_def.module_def {
                    None => {
E
Eduard Burtescu 已提交
915 916 917 918 919
                        let module = Module::new(parent_link,
                                                 def_id,
                                                 kind,
                                                 external,
                                                 is_public);
E
Erick Tryzelaar 已提交
920
                        *self.type_def.borrow_mut() = Some(TypeNsDef {
921
                            modifiers: modifiers,
E
Eduard Burtescu 已提交
922
                            module_def: Some(Rc::new(module)),
923 924
                            type_def: type_def.type_def,
                            type_span: None,
E
Erick Tryzelaar 已提交
925
                        });
926
                    }
927
                    Some(module_def) => module_def.kind.set(kind),
928 929 930 931 932
                }
            }
        }
    }

933
    /// Records a type definition.
934
    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
935
        debug!("defining type for def {:?} with modifiers {:?}", def, modifiers);
936
        // Merges the type with the existing type def or creates a new one.
E
Erick Tryzelaar 已提交
937 938
        let type_def = self.type_def.borrow().clone();
        match type_def {
939
            None => {
E
Erick Tryzelaar 已提交
940
                *self.type_def.borrow_mut() = Some(TypeNsDef {
941
                    module_def: None,
942
                    type_def: Some(def),
943
                    type_span: Some(sp),
944
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
945
                });
946
            }
947
            Some(type_def) => {
E
Erick Tryzelaar 已提交
948
                *self.type_def.borrow_mut() = Some(TypeNsDef {
949
                    module_def: type_def.module_def,
950
                    type_def: Some(def),
951
                    type_span: Some(sp),
952
                    modifiers: modifiers,
E
Erick Tryzelaar 已提交
953
                });
954 955
            }
        }
956 957
    }

958
    /// Records a value definition.
959
    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
960
        debug!("defining value for def {:?} with modifiers {:?}", def, modifiers);
E
Erick Tryzelaar 已提交
961
        *self.value_def.borrow_mut() = Some(ValueNsDef {
962 963
            def: def,
            value_span: Some(sp),
964
            modifiers: modifiers,
E
Erick Tryzelaar 已提交
965
        });
966 967
    }

968
    /// Returns the module node if applicable.
E
Eduard Burtescu 已提交
969
    fn get_module_if_available(&self) -> Option<Rc<Module>> {
970
        match *self.type_def.borrow() {
E
Eduard Burtescu 已提交
971
            Some(ref type_def) => type_def.module_def.clone(),
972
            None => None
973 974 975
        }
    }

S
Steve Klabnik 已提交
976 977
    /// Returns the module node. Panics if this node does not have a module
    /// definition.
E
Eduard Burtescu 已提交
978
    fn get_module(&self) -> Rc<Module> {
979 980
        match self.get_module_if_available() {
            None => {
S
Steve Klabnik 已提交
981
                panic!("get_module called on a node with no module \
982
                       definition!")
983
            }
984
            Some(module_def) => module_def
985 986 987
        }
    }

F
Felix S. Klock II 已提交
988
    fn defined_in_namespace(&self, namespace: Namespace) -> bool {
989
        match namespace {
E
Erick Tryzelaar 已提交
990 991
            TypeNS   => return self.type_def.borrow().is_some(),
            ValueNS  => return self.value_def.borrow().is_some()
992 993 994
        }
    }

F
Felix S. Klock II 已提交
995
    fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
T
Fallout  
Tamir Duberstein 已提交
996
        self.defined_in_namespace_with(namespace, DefModifiers::PUBLIC)
997 998 999
    }

    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
1000
        match namespace {
E
Erick Tryzelaar 已提交
1001
            TypeNS => match *self.type_def.borrow() {
1002
                Some(ref def) => def.modifiers.contains(modifiers), None => false
1003
            },
E
Erick Tryzelaar 已提交
1004
            ValueNS => match *self.value_def.borrow() {
1005
                Some(ref def) => def.modifiers.contains(modifiers), None => false
1006 1007 1008 1009
            }
        }
    }

F
Felix S. Klock II 已提交
1010
    fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
1011
        match namespace {
1012
            TypeNS => {
E
Erick Tryzelaar 已提交
1013
                match *self.type_def.borrow() {
1014
                    None => None,
E
Eduard Burtescu 已提交
1015
                    Some(ref type_def) => {
1016
                        match type_def.type_def {
1017
                            Some(type_def) => Some(type_def),
1018 1019
                            None => {
                                match type_def.module_def {
E
Eduard Burtescu 已提交
1020
                                    Some(ref module) => {
1021
                                        match module.def_id.get() {
1022
                                            Some(did) => Some(DefMod(did)),
1023 1024 1025 1026 1027 1028
                                            None => None,
                                        }
                                    }
                                    None => None,
                                }
                            }
1029
                        }
1030 1031
                    }
                }
1032 1033
            }
            ValueNS => {
E
Erick Tryzelaar 已提交
1034
                match *self.value_def.borrow() {
1035 1036 1037 1038 1039 1040 1041
                    None => None,
                    Some(value_def) => Some(value_def.def)
                }
            }
        }
    }

F
Felix S. Klock II 已提交
1042
    fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
1043
        if self.defined_in_namespace(namespace) {
1044
            match namespace {
1045
                TypeNS  => {
E
Erick Tryzelaar 已提交
1046
                    match *self.type_def.borrow() {
1047
                        None => None,
E
Eduard Burtescu 已提交
1048
                        Some(ref type_def) => type_def.type_span
1049 1050 1051
                    }
                }
                ValueNS => {
E
Erick Tryzelaar 已提交
1052
                    match *self.value_def.borrow() {
1053
                        None => None,
E
Eduard Burtescu 已提交
1054
                        Some(ref value_def) => value_def.value_span
1055 1056
                    }
                }
1057
            }
1058 1059
        } else {
            None
1060 1061
        }
    }
1062 1063 1064 1065 1066

    fn is_public(&self, namespace: Namespace) -> bool {
        match namespace {
            TypeNS  => {
                let type_def = self.type_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1067
                type_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1068 1069 1070
            }
            ValueNS => {
                let value_def = self.value_def.borrow();
T
Fallout  
Tamir Duberstein 已提交
1071
                value_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
1072 1073 1074
            }
        }
    }
1075 1076
}

1077
/// Interns the names of the primitive types.
F
Felix S. Klock II 已提交
1078
struct PrimitiveTypeTable {
1079
    primitive_types: HashMap<Name, PrimTy>,
1080
}
1081

1082
impl PrimitiveTypeTable {
K
Kevin Butler 已提交
1083 1084 1085 1086 1087 1088 1089 1090 1091
    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));
1092
        table.intern("isize",   TyInt(TyIs));
K
Kevin Butler 已提交
1093 1094 1095 1096 1097
        table.intern("i8",      TyInt(TyI8));
        table.intern("i16",     TyInt(TyI16));
        table.intern("i32",     TyInt(TyI32));
        table.intern("i64",     TyInt(TyI64));
        table.intern("str",     TyStr);
1098
        table.intern("usize",   TyUint(TyUs));
K
Kevin Butler 已提交
1099 1100 1101 1102 1103 1104 1105 1106
        table.intern("u8",      TyUint(TyU8));
        table.intern("u16",     TyUint(TyU16));
        table.intern("u32",     TyUint(TyU32));
        table.intern("u64",     TyUint(TyU64));

        table
    }

1107
    fn intern(&mut self, string: &str, primitive_type: PrimTy) {
1108
        self.primitive_types.insert(token::intern(string), primitive_type);
1109 1110 1111
    }
}

1112
/// The main resolver class.
1113
pub struct Resolver<'a, 'tcx:'a> {
E
Eduard Burtescu 已提交
1114
    session: &'a Session,
1115

1116 1117
    ast_map: &'a ast_map::Map<'tcx>,

E
Eduard Burtescu 已提交
1118
    graph_root: NameBindings,
1119

1120
    trait_item_map: FnvHashMap<(Name, DefId), DefId>,
1121

1122
    structs: FnvHashMap<DefId, Vec<Name>>,
1123

1124
    // The number of imports that are currently unresolved.
1125
    unresolved_imports: usize,
1126 1127

    // The module that represents the current item scope.
E
Eduard Burtescu 已提交
1128
    current_module: Rc<Module>,
1129 1130

    // The current set of local scopes, for values.
1131
    // FIXME #4948: Reuse ribs to avoid allocation.
1132
    value_ribs: Vec<Rib>,
1133 1134

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

1137
    // The current set of local scopes, for labels.
1138
    label_ribs: Vec<Rib>,
1139

1140
    // The trait that the current context can refer to.
1141 1142 1143 1144
    current_trait_ref: Option<(DefId, TraitRef)>,

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

1146
    // The idents for the primitive types.
E
Eduard Burtescu 已提交
1147
    primitive_type_table: PrimitiveTypeTable,
1148

1149
    def_map: DefMap,
1150 1151
    freevars: RefCell<FreevarMap>,
    freevars_seen: RefCell<NodeMap<NodeSet>>,
1152
    export_map: ExportMap,
1153
    trait_map: TraitMap,
1154
    external_exports: ExternalExports,
1155

1156 1157 1158 1159 1160
    // 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,

1161 1162 1163 1164 1165
    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,

1166
    used_imports: HashSet<(NodeId, Namespace)>,
1167
    used_crates: HashSet<CrateNum>,
G
Garming Sam 已提交
1168 1169 1170 1171 1172 1173 1174

    // Callback function for intercepting walks
    callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>,
    // The intention is that the callback modifies this flag.
    // Once set, the resolver falls out of the walk, preserving the ribs.
    resolved: bool,

1175 1176
}

1177
#[derive(PartialEq)]
S
Steven Fackler 已提交
1178 1179 1180 1181 1182
enum FallbackChecks {
    Everything,
    OnlyTraitAndStatics
}

1183 1184 1185 1186 1187
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 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
        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,

1202 1203
            ast_map: ast_map,

K
Kevin Butler 已提交
1204 1205 1206 1207 1208
            // The outermost module has def ID 0; this is not reflected in the
            // AST.

            graph_root: graph_root,

1209 1210
            trait_item_map: FnvHashMap(),
            structs: FnvHashMap(),
K
Kevin Butler 已提交
1211 1212 1213 1214

            unresolved_imports: 0,

            current_module: current_module,
1215 1216 1217
            value_ribs: Vec::new(),
            type_ribs: Vec::new(),
            label_ribs: Vec::new(),
K
Kevin Butler 已提交
1218 1219 1220 1221 1222 1223

            current_trait_ref: None,
            current_self_type: None,

            primitive_type_table: PrimitiveTypeTable::new(),

1224 1225 1226 1227 1228
            def_map: RefCell::new(NodeMap()),
            freevars: RefCell::new(NodeMap()),
            freevars_seen: RefCell::new(NodeMap()),
            export_map: NodeMap(),
            trait_map: NodeMap(),
K
Kevin Butler 已提交
1229
            used_imports: HashSet::new(),
1230
            used_crates: HashSet::new(),
1231
            external_exports: DefIdSet(),
K
Kevin Butler 已提交
1232 1233

            emit_errors: true,
1234 1235
            make_glob_map: make_glob_map == MakeGlobMap::Yes,
            glob_map: HashMap::new(),
G
Garming Sam 已提交
1236 1237 1238 1239

            callback: None,
            resolved: false,

K
Kevin Butler 已提交
1240 1241
        }
    }
1242

1243 1244 1245 1246 1247 1248
    #[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) {
1249
            self.glob_map.get_mut(&import_id).unwrap().insert(name);
1250 1251 1252 1253 1254 1255 1256 1257 1258
            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 {
1259
        if did.is_local() {
1260 1261 1262 1263 1264 1265
            self.ast_map.expect_item(did.node).ident.name
        } else {
            csearch::get_trait_name(&self.session.cstore, did)
        }
    }

E
Eduard Burtescu 已提交
1266
    fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
1267
        NameBindings {
1268
            type_def: RefCell::new(Some(TypeNsDef {
T
Fallout  
Tamir Duberstein 已提交
1269
                modifiers: DefModifiers::IMPORTABLE,
1270 1271
                module_def: Some(module),
                type_def: None,
1272
                type_span: None
1273
            })),
1274
            value_def: RefCell::new(None),
1275 1276 1277
        }
    }

1278 1279 1280 1281 1282 1283 1284
    /// 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 已提交
1285 1286
                span_err!(self.session, span, E0259,
                          "an external crate named `{}` has already \
1287 1288
                           been imported into this module",
                          name);
1289 1290 1291 1292 1293 1294 1295 1296 1297
        }
    }

    /// 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 已提交
1298 1299
                span_err!(self.session, span, E0260,
                          "the name `{}` conflicts with an external \
1300 1301 1302
                           crate that has been imported into this \
                           module",
                           name);
1303
        }
1304 1305
    }

1306
    /// Resolves the given module path from the given root `module_`.
F
Felix S. Klock II 已提交
1307
    fn resolve_module_path_from_root(&mut self,
E
Eduard Burtescu 已提交
1308
                                     module_: Rc<Module>,
1309
                                     module_path: &[Name],
1310
                                     index: usize,
1311 1312 1313
                                     span: Span,
                                     name_search_type: NameSearchType,
                                     lp: LastPrivate)
E
Eduard Burtescu 已提交
1314
                                -> ResolveResult<(Rc<Module>, LastPrivate)> {
1315 1316
        fn search_parent_externals(needle: Name, module: &Rc<Module>)
                                -> Option<Rc<Module>> {
1317 1318 1319 1320 1321
            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())
1322 1323 1324
                    }
                   _ => None
                }
1325
            }
1326 1327
        }

1328
        let mut search_module = module_;
1329
        let mut index = index;
A
Alex Crichton 已提交
1330
        let module_path_len = module_path.len();
1331
        let mut closest_private = lp;
1332 1333 1334 1335 1336

        // 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 已提交
1337
            let name = module_path[index];
E
Eduard Burtescu 已提交
1338
            match self.resolve_name_in_module(search_module.clone(),
1339
                                              name,
1340
                                              TypeNS,
1341 1342
                                              name_search_type,
                                              false) {
1343
                Failed(None) => {
1344
                    let segment_name = name.as_str();
1345
                    let module_name = module_to_string(&*search_module);
1346
                    let mut span = span;
1347
                    let msg = if "???" == &module_name[..] {
1348
                        span.hi = span.lo + Pos::from_usize(segment_name.len());
1349

1350
                        match search_parent_externals(name,
1351
                                                     &self.current_module) {
1352
                            Some(module) => {
1353 1354
                                let path_str = names_to_string(module_path);
                                let target_mod_str = module_to_string(&*module);
1355
                                let current_mod_str =
1356
                                    module_to_string(&*self.current_module);
1357 1358 1359 1360 1361 1362 1363

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

1364
                                format!("Did you mean `{}{}`?", prefix, path_str)
1365
                            },
1366 1367
                            None => format!("Maybe a missing `extern crate {}`?",
                                            segment_name),
1368
                        }
1369
                    } else {
1370
                        format!("Could not find `{}` in `{}`",
1371 1372 1373
                                segment_name,
                                module_name)
                    };
1374

1375
                    return Failed(Some((span, msg)));
1376
                }
1377
                Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1378
                Indeterminate => {
1379
                    debug!("(resolving module path for import) module \
A
Alex Crichton 已提交
1380
                            resolution is indeterminate: {}",
1381
                            name);
B
Brian Anderson 已提交
1382
                    return Indeterminate;
1383
                }
1384
                Success((target, used_proxy)) => {
1385 1386
                    // Check to see whether there are type bindings, and, if
                    // so, whether there is a module within.
E
Erick Tryzelaar 已提交
1387
                    match *target.bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1388
                        Some(ref type_def) => {
1389 1390
                            match type_def.module_def {
                                None => {
1391
                                    let msg = format!("Not a module `{}`",
1392
                                                        name);
1393 1394

                                    return Failed(Some((span, msg)));
1395
                                }
E
Eduard Burtescu 已提交
1396
                                Some(ref module_def) => {
1397 1398 1399
                                    search_module = module_def.clone();

                                    // track extern crates for unused_extern_crate lint
1400 1401
                                    if let Some(did) = module_def.def_id.get() {
                                        self.used_crates.insert(did.krate);
1402
                                    }
1403

1404 1405 1406
                                    // Keep track of the closest
                                    // private module used when
                                    // resolving this import chain.
1407 1408 1409
                                    if !used_proxy && !search_module.is_public {
                                        if let Some(did) = search_module.def_id.get() {
                                            closest_private = LastMod(DependsOn(did));
1410
                                        }
1411
                                    }
1412 1413 1414 1415 1416
                                }
                            }
                        }
                        None => {
                            // There are no type bindings at all.
1417
                            let msg = format!("Not a module `{}`",
1418
                                              name);
1419
                            return Failed(Some((span, msg)));
1420 1421 1422 1423 1424
                        }
                    }
                }
            }

T
Tim Chevalier 已提交
1425
            index += 1;
1426 1427
        }

1428
        return Success((search_module, closest_private));
1429 1430
    }

1431 1432
    /// Attempts to resolve the module part of an import directive or path
    /// rooted at the given module.
1433 1434 1435
    ///
    /// On success, returns the resolved module, and the closest *private*
    /// module found to the destination when resolving this path.
F
Felix S. Klock II 已提交
1436
    fn resolve_module_path(&mut self,
E
Eduard Burtescu 已提交
1437
                           module_: Rc<Module>,
1438
                           module_path: &[Name],
1439 1440 1441
                           use_lexical_scope: UseLexicalScopeFlag,
                           span: Span,
                           name_search_type: NameSearchType)
1442
                           -> ResolveResult<(Rc<Module>, LastPrivate)> {
1443
        let module_path_len = module_path.len();
P
Patrick Walton 已提交
1444
        assert!(module_path_len > 0);
1445

1446
        debug!("(resolving module path for import) processing `{}` rooted at `{}`",
1447 1448
               names_to_string(module_path),
               module_to_string(&*module_));
1449

1450
        // Resolve the module prefix, if any.
E
Eduard Burtescu 已提交
1451
        let module_prefix_result = self.resolve_module_prefix(module_.clone(),
1452
                                                              module_path);
1453

1454 1455
        let search_module;
        let start_index;
1456
        let last_private;
1457
        match module_prefix_result {
1458
            Failed(None) => {
1459
                let mpath = names_to_string(module_path);
1460
                let mpath = &mpath[..];
1461
                match mpath.rfind(':') {
C
Fix ICE  
Corey Richardson 已提交
1462
                    Some(idx) => {
1463 1464 1465
                        let msg = format!("Could not find `{}` in `{}`",
                                            // idx +- 1 to account for the
                                            // colons on either side
1466 1467
                                            &mpath[idx + 1..],
                                            &mpath[..idx - 1]);
1468
                        return Failed(Some((span, msg)));
C
Fix ICE  
Corey Richardson 已提交
1469
                    },
1470 1471 1472
                    None => {
                        return Failed(None)
                    }
1473
                }
1474
            }
1475
            Failed(err) => return Failed(err),
B
Brian Anderson 已提交
1476
            Indeterminate => {
1477
                debug!("(resolving module path for import) indeterminate; \
P
Paul Stansifer 已提交
1478
                        bailing");
B
Brian Anderson 已提交
1479
                return Indeterminate;
1480
            }
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
            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;
1491
                        last_private = LastMod(AllPublic);
1492 1493 1494 1495 1496
                    }
                    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.
1497 1498
                        match self.resolve_module_in_lexical_scope(module_,
                                                                   module_path[0]) {
1499
                            Failed(err) => return Failed(err),
1500
                            Indeterminate => {
1501
                                debug!("(resolving module path for import) \
1502 1503 1504 1505 1506 1507
                                        indeterminate; bailing");
                                return Indeterminate;
                            }
                            Success(containing_module) => {
                                search_module = containing_module;
                                start_index = 1;
1508
                                last_private = LastMod(AllPublic);
1509 1510 1511 1512 1513
                            }
                        }
                    }
                }
            }
E
Eduard Burtescu 已提交
1514 1515
            Success(PrefixFound(ref containing_module, index)) => {
                search_module = containing_module.clone();
1516
                start_index = index;
1517 1518 1519
                last_private = LastMod(DependsOn(containing_module.def_id
                                                                  .get()
                                                                  .unwrap()));
1520 1521 1522
            }
        }

1523 1524 1525 1526
        self.resolve_module_path_from_root(search_module,
                                           module_path,
                                           start_index,
                                           span,
1527 1528
                                           name_search_type,
                                           last_private)
1529 1530
    }

1531 1532
    /// Invariant: This must only be called during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
1533
    fn resolve_item_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1534
                                     module_: Rc<Module>,
1535
                                     name: Name,
1536
                                     namespace: Namespace)
1537
                                    -> ResolveResult<(Target, bool)> {
1538
        debug!("(resolving item in lexical scope) resolving `{}` in \
1539
                namespace {:?} in `{}`",
1540
               name,
1541
               namespace,
1542
               module_to_string(&*module_));
1543 1544 1545

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

1548
        match module_.children.borrow().get(&name) {
1549 1550 1551
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("top name bindings succeeded");
1552 1553
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1554
                                            Shadowable::Never),
1555
                               false));
1556
            }
1557
            Some(_) | None => { /* Not found; continue. */ }
1558 1559 1560 1561 1562 1563
        }

        // 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.
1564 1565 1566 1567 1568
        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 \
1569
                            import resolution, but not in namespace {:?}",
1570 1571 1572 1573 1574 1575
                           namespace);
                }
                Some(target) => {
                    debug!("(resolving item in lexical scope) using \
                            import resolution");
                    // track used imports and extern crates as well
1576 1577 1578
                    let id = import_resolution.id(namespace);
                    self.used_imports.insert((id, namespace));
                    self.record_import_use(id, name);
1579
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
1580
                         self.used_crates.insert(kid);
1581
                    }
1582
                    return Success((target, false));
1583 1584 1585 1586
                }
            }
        }

1587 1588
        // Search for external modules.
        if namespace == TypeNS {
1589 1590 1591
            // 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 {
1592 1593 1594
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
                debug!("lower name bindings succeeded");
1595 1596 1597
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1598
                                false));
1599 1600 1601
            }
        }

1602
        // Finally, proceed up the scope chain looking for parent modules.
1603
        let mut search_module = module_;
1604 1605
        loop {
            // Go to the next parent.
E
Eduard Burtescu 已提交
1606
            match search_module.parent_link.clone() {
B
Brian Anderson 已提交
1607
                NoParentLink => {
1608
                    // No more parents. This module was unresolved.
1609
                    debug!("(resolving item in lexical scope) unresolved \
P
Paul Stansifer 已提交
1610
                            module");
1611
                    return Failed(None);
1612
                }
1613
                ModuleParentLink(parent_module_node, _) => {
1614 1615 1616 1617 1618 1619 1620
                    match search_module.kind.get() {
                        NormalModuleKind => {
                            // We stop the search here.
                            debug!("(resolving item in lexical \
                                    scope) unresolved module: not \
                                    searching through module \
                                    parents");
1621
                            return Failed(None);
1622
                        }
1623
                        TraitModuleKind |
1624
                        EnumModuleKind |
1625
                        TypeModuleKind |
1626
                        AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1627
                            search_module = parent_module_node.upgrade().unwrap();
1628 1629 1630
                        }
                    }
                }
E
Eduard Burtescu 已提交
1631 1632
                BlockParentLink(ref parent_module_node, _) => {
                    search_module = parent_module_node.upgrade().unwrap();
1633 1634 1635 1636
                }
            }

            // Resolve the name in the parent module.
E
Eduard Burtescu 已提交
1637
            match self.resolve_name_in_module(search_module.clone(),
1638
                                              name,
1639
                                              namespace,
1640 1641
                                              PathSearch,
                                              true) {
1642
                Failed(Some((span, msg))) => {
1643
                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
1644
                },
1645
                Failed(None) => (), // Continue up the search chain.
B
Brian Anderson 已提交
1646
                Indeterminate => {
1647 1648 1649
                    // We couldn't see through the higher scope because of an
                    // unresolved import higher up. Bail.

1650
                    debug!("(resolving item in lexical scope) indeterminate \
P
Paul Stansifer 已提交
1651
                            higher scope; bailing");
B
Brian Anderson 已提交
1652
                    return Indeterminate;
1653
                }
1654
                Success((target, used_reexport)) => {
1655
                    // We found the module.
1656
                    debug!("(resolving item in lexical scope) found name \
1657 1658
                            in module, done");
                    return Success((target, used_reexport));
1659 1660 1661 1662 1663
                }
            }
        }
    }

1664
    /// Resolves a module name in the current lexical scope.
F
Felix S. Klock II 已提交
1665
    fn resolve_module_in_lexical_scope(&mut self,
E
Eduard Burtescu 已提交
1666
                                       module_: Rc<Module>,
1667
                                       name: Name)
E
Eduard Burtescu 已提交
1668
                                -> ResolveResult<Rc<Module>> {
1669 1670
        // If this module is an anonymous module, resolve the item in the
        // lexical scope. Otherwise, resolve the item from the crate root.
1671
        let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
1672
        match resolve_result {
1673
            Success((target, _)) => {
1674
                let bindings = &*target.bindings;
E
Erick Tryzelaar 已提交
1675
                match *bindings.type_def.borrow() {
E
Eduard Burtescu 已提交
1676
                    Some(ref type_def) => {
1677
                        match type_def.module_def {
1678
                            None => {
1679
                                debug!("!!! (resolving module in lexical \
1680 1681
                                        scope) module wasn't actually a \
                                        module!");
1682
                                return Failed(None);
1683
                            }
E
Eduard Burtescu 已提交
1684 1685
                            Some(ref module_def) => {
                                return Success(module_def.clone());
1686 1687 1688 1689
                            }
                        }
                    }
                    None => {
1690
                        debug!("!!! (resolving module in lexical scope) module
P
Paul Stansifer 已提交
1691
                                wasn't actually a module!");
1692
                        return Failed(None);
1693 1694 1695
                    }
                }
            }
B
Brian Anderson 已提交
1696
            Indeterminate => {
1697
                debug!("(resolving module in lexical scope) indeterminate; \
P
Paul Stansifer 已提交
1698
                        bailing");
B
Brian Anderson 已提交
1699
                return Indeterminate;
1700
            }
1701 1702 1703
            Failed(err) => {
                debug!("(resolving module in lexical scope) failed to resolve");
                return Failed(err);
1704 1705 1706 1707
            }
        }
    }

1708
    /// Returns the nearest normal module parent of the given module.
E
Eduard Burtescu 已提交
1709 1710
    fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
                                            -> Option<Rc<Module>> {
1711 1712
        let mut module_ = module_;
        loop {
E
Eduard Burtescu 已提交
1713
            match module_.parent_link.clone() {
1714 1715 1716
                NoParentLink => return None,
                ModuleParentLink(new_module, _) |
                BlockParentLink(new_module, _) => {
E
Eduard Burtescu 已提交
1717
                    let new_module = new_module.upgrade().unwrap();
1718
                    match new_module.kind.get() {
1719 1720
                        NormalModuleKind => return Some(new_module),
                        TraitModuleKind |
1721
                        EnumModuleKind |
1722
                        TypeModuleKind |
1723 1724 1725 1726 1727 1728 1729
                        AnonymousModuleKind => module_ = new_module,
                    }
                }
            }
        }
    }

1730 1731
    /// Returns the nearest normal module parent of the given module, or the
    /// module itself if it is a normal module.
E
Eduard Burtescu 已提交
1732 1733
    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
                                                -> Rc<Module> {
1734
        match module_.kind.get() {
1735
            NormalModuleKind => return module_,
1736
            TraitModuleKind |
1737
            EnumModuleKind |
1738
            TypeModuleKind |
1739
            AnonymousModuleKind => {
E
Eduard Burtescu 已提交
1740
                match self.get_nearest_normal_module_parent(module_.clone()) {
1741 1742 1743 1744 1745 1746 1747
                    None => module_,
                    Some(new_module) => new_module
                }
            }
        }
    }

1748
    /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
1749
    /// (b) some chain of `super::`.
1750
    /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
F
Felix S. Klock II 已提交
1751
    fn resolve_module_prefix(&mut self,
E
Eduard Burtescu 已提交
1752
                             module_: Rc<Module>,
1753
                             module_path: &[Name])
1754
                                 -> ResolveResult<ModulePrefixResult> {
1755 1756
        // Start at the current module if we see `self` or `super`, or at the
        // top of the crate otherwise.
1757 1758 1759 1760 1761 1762
        let mut i = match &*module_path[0].as_str() {
            "self" => 1,
            "super" => 0,
            _ => return Success(NoPrefixFound),
        };
        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
1763 1764

        // Now loop through all the `super`s we find.
1765
        while i < module_path.len() && "super" == module_path[i].as_str() {
1766
            debug!("(resolving module prefix) resolving `super` at {}",
1767
                   module_to_string(&*containing_module));
1768
            match self.get_nearest_normal_module_parent(containing_module) {
1769
                None => return Failed(None),
1770 1771 1772
                Some(new_module) => {
                    containing_module = new_module;
                    i += 1;
1773 1774 1775 1776
                }
            }
        }

1777
        debug!("(resolving module prefix) finished resolving prefix at {}",
1778
               module_to_string(&*containing_module));
1779 1780

        return Success(PrefixFound(containing_module, i));
1781 1782
    }

1783 1784 1785
    /// Attempts to resolve the supplied name in the given module for the
    /// given namespace. If successful, returns the target corresponding to
    /// the name.
1786 1787 1788
    ///
    /// The boolean returned on success is an indicator of whether this lookup
    /// passed through a public re-export proxy.
F
Felix S. Klock II 已提交
1789
    fn resolve_name_in_module(&mut self,
E
Eduard Burtescu 已提交
1790
                              module_: Rc<Module>,
1791
                              name: Name,
1792
                              namespace: Namespace,
1793 1794
                              name_search_type: NameSearchType,
                              allow_private_imports: bool)
1795
                              -> ResolveResult<(Target, bool)> {
1796
        debug!("(resolving name in module) resolving `{}` in `{}`",
1797
               name,
1798
               module_to_string(&*module_));
1799 1800

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

1803
        match module_.children.borrow().get(&name) {
1804 1805 1806
            Some(name_bindings)
                    if name_bindings.defined_in_namespace(namespace) => {
                debug!("(resolving name in module) found node as child");
1807 1808
                return Success((Target::new(module_.clone(),
                                            name_bindings.clone(),
1809
                                            Shadowable::Never),
1810 1811 1812 1813
                               false));
            }
            Some(_) | None => {
                // Continue.
1814 1815 1816
            }
        }

1817 1818 1819 1820
        // 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.
1821
        if name_search_type == PathSearch {
1822
            assert_eq!(module_.glob_count.get(), 0);
1823 1824
        }

1825
        // Check the list of resolved imports.
1826
        match module_.import_resolutions.borrow().get(&name) {
1827
            Some(import_resolution) if allow_private_imports ||
E
Eduard Burtescu 已提交
1828
                                       import_resolution.is_public => {
1829

E
Eduard Burtescu 已提交
1830 1831
                if import_resolution.is_public &&
                        import_resolution.outstanding_references != 0 {
1832
                    debug!("(resolving name in module) import \
1833
                           unresolved; bailing out");
B
Brian Anderson 已提交
1834
                    return Indeterminate;
1835
                }
1836
                match import_resolution.target_for_namespace(namespace) {
B
Brian Anderson 已提交
1837
                    None => {
1838
                        debug!("(resolving name in module) name found, \
1839
                                but not in namespace {:?}",
P
Paul Stansifer 已提交
1840
                               namespace);
1841
                    }
1842
                    Some(target) => {
1843
                        debug!("(resolving name in module) resolved to \
P
Paul Stansifer 已提交
1844
                                import");
1845
                        // track used imports and extern crates as well
1846 1847 1848
                        let id = import_resolution.id(namespace);
                        self.used_imports.insert((id, namespace));
                        self.record_import_use(id, name);
1849 1850
                        if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                            self.used_crates.insert(kid);
1851
                        }
1852
                        return Success((target, true));
1853
                    }
1854 1855
                }
            }
1856
            Some(..) | None => {} // Continue.
1857 1858 1859 1860
        }

        // Finally, search through external children.
        if namespace == TypeNS {
1861 1862 1863
            // 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 {
1864 1865
                let name_bindings =
                    Rc::new(Resolver::create_name_bindings_from_module(module));
1866 1867 1868
                return Success((Target::new(module_,
                                            name_bindings,
                                            Shadowable::Never),
1869
                                false));
1870 1871 1872 1873
            }
        }

        // We're out of luck.
1874
        debug!("(resolving name in module) failed to resolve `{}`",
1875
               name);
1876
        return Failed(None);
1877 1878
    }

E
Eduard Burtescu 已提交
1879
    fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
1880
        let index = module_.resolved_import_count.get();
1881 1882
        let imports = module_.imports.borrow();
        let import_count = imports.len();
1883
        if index != import_count {
1884 1885 1886
            resolve_error(self,
                          (*imports)[index].span,
                          ResolutionError::UnresolvedImport(None));
1887 1888 1889
        }

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

1892
        for (_, child_node) in module_.children.borrow().iter() {
1893 1894 1895 1896 1897 1898
            match child_node.get_module_if_available() {
                None => {
                    // Continue.
                }
                Some(child_module) => {
                    self.report_unresolved_imports(child_module);
1899 1900 1901 1902
                }
            }
        }

1903
        for (_, module_) in module_.anonymous_children.borrow().iter() {
E
Eduard Burtescu 已提交
1904
            self.report_unresolved_imports(module_.clone());
1905 1906 1907 1908 1909
        }
    }

    // AST resolution
    //
1910
    // We maintain a list of value ribs and type ribs.
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925
    //
    // 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 已提交
1926 1927 1928
    fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
        F: FnOnce(&mut Resolver),
    {
E
Eduard Burtescu 已提交
1929
        let orig_module = self.current_module.clone();
1930 1931

        // Move down in the graph.
1932
        match name {
B
Brian Anderson 已提交
1933
            None => {
1934 1935
                // Nothing to do.
            }
B
Brian Anderson 已提交
1936
            Some(name) => {
1937
                build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1938

1939
                match orig_module.children.borrow().get(&name) {
B
Brian Anderson 已提交
1940
                    None => {
1941
                        debug!("!!! (with scope) didn't find `{}` in `{}`",
1942
                               name,
1943
                               module_to_string(&*orig_module));
1944
                    }
B
Brian Anderson 已提交
1945
                    Some(name_bindings) => {
1946
                        match (*name_bindings).get_module_if_available() {
B
Brian Anderson 已提交
1947
                            None => {
1948
                                debug!("!!! (with scope) didn't find module \
A
Alex Crichton 已提交
1949
                                        for `{}` in `{}`",
1950
                                       name,
1951
                                       module_to_string(&*orig_module));
1952
                            }
B
Brian Anderson 已提交
1953
                            Some(module_) => {
1954
                                self.current_module = module_;
1955 1956 1957 1958 1959 1960 1961
                            }
                        }
                    }
                }
            }
        }

A
Alex Crichton 已提交
1962
        f(self);
1963 1964 1965 1966

        self.current_module = orig_module;
    }

1967
    /// Wraps the given definition in the appropriate number of `DefUpvar`
1968
    /// wrappers.
E
Eduard Burtescu 已提交
1969
    fn upvarify(&self,
E
Eduard Burtescu 已提交
1970
                ribs: &[Rib],
E
Eduard Burtescu 已提交
1971 1972 1973
                def_like: DefLike,
                span: Span)
                -> Option<DefLike> {
1974 1975 1976 1977 1978 1979
        let mut def = match def_like {
            DlDef(def) => def,
            _ => return Some(def_like)
        };
        match def {
            DefUpvar(..) => {
1980
                self.session.span_bug(span,
1981
                    &format!("unexpected {:?} in bindings", def))
1982
            }
1983
            DefLocal(node_id) => {
1984
                for rib in ribs {
1985 1986 1987 1988
                    match rib.kind {
                        NormalRibKind => {
                            // Nothing to do. Continue.
                        }
1989
                        ClosureRibKind(function_id) => {
1990
                            let prev_def = def;
1991
                            def = DefUpvar(node_id, function_id);
1992

1993
                            let mut seen = self.freevars_seen.borrow_mut();
1994
                            let seen = match seen.entry(function_id) {
1995
                                Occupied(v) => v.into_mut(),
1996
                                Vacant(v) => v.insert(NodeSet()),
1997
                            };
1998 1999 2000
                            if seen.contains(&node_id) {
                                continue;
                            }
2001
                            match self.freevars.borrow_mut().entry(function_id) {
2002
                                Occupied(v) => v.into_mut(),
2003
                                Vacant(v) => v.insert(vec![]),
2004
                            }.push(Freevar { def: prev_def, span: span });
2005 2006
                            seen.insert(node_id);
                        }
2007
                        ItemRibKind | MethodRibKind => {
2008 2009 2010
                            // This was an attempt to access an upvar inside a
                            // named function item. This is not allowed, so we
                            // report an error.
2011
                            resolve_error(
2012 2013
                                self,
                                span,
2014
                                ResolutionError::CannotCaptureDynamicEnvironmentInFnItem
2015
                            );
2016 2017 2018 2019
                            return None;
                        }
                        ConstantItemRibKind => {
                            // Still doesn't deal with upvars
2020
                            resolve_error(
2021 2022
                                self,
                                span,
2023
                                ResolutionError::AttemptToUseNonConstantValueInConstant
2024
                            );
2025
                            return None;
2026
                        }
2027 2028
                    }
                }
2029
            }
2030
            DefTyParam(..) | DefSelfTy(..) => {
2031
                for rib in ribs {
2032
                    match rib.kind {
2033
                        NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
2034 2035 2036 2037 2038
                            // Nothing to do. Continue.
                        }
                        ItemRibKind => {
                            // This was an attempt to use a type parameter outside
                            // its scope.
2039

2040 2041
                            resolve_error(self,
                                          span,
2042
                                          ResolutionError::TypeParametersFromOuterFunction);
2043 2044 2045 2046
                            return None;
                        }
                        ConstantItemRibKind => {
                            // see #9186
2047
                            resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
2048
                            return None;
2049 2050
                        }
                    }
2051
                }
2052
            }
2053
            _ => {}
2054
        }
2055
        Some(DlDef(def))
2056 2057
    }

S
Seo Sanghyeon 已提交
2058 2059
    /// Searches the current set of local scopes and
    /// applies translations for closures.
E
Eduard Burtescu 已提交
2060
    fn search_ribs(&self,
E
Eduard Burtescu 已提交
2061
                   ribs: &[Rib],
E
Eduard Burtescu 已提交
2062 2063 2064
                   name: Name,
                   span: Span)
                   -> Option<DefLike> {
2065
        // FIXME #4950: Try caching?
2066

2067
        for (i, rib) in ribs.iter().enumerate().rev() {
2068 2069
            if let Some(def_like) = rib.bindings.get(&name).cloned() {
                return self.upvarify(&ribs[i + 1..], def_like, span);
2070 2071 2072
            }
        }

2073
        None
2074 2075
    }

S
Seo Sanghyeon 已提交
2076 2077
    /// Searches the current set of local scopes for labels.
    /// Stops after meeting a closure.
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089
    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 已提交
2090 2091
            if result.is_some() {
                return result
2092 2093 2094 2095 2096
            }
        }
        None
    }

2097
    fn resolve_crate(&mut self, krate: &ast::Crate) {
2098
        debug!("(resolving crate) starting");
2099

2100
        visit::walk_crate(self, krate);
2101 2102
    }

W
we 已提交
2103 2104
    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 已提交
2105
            span_err!(self.session, span, E0317,
W
we 已提交
2106 2107 2108 2109
                "user-defined types or type parameters cannot shadow the primitive types");
        }
    }

2110
    fn resolve_item(&mut self, item: &Item) {
2111 2112
        let name = item.ident.name;

2113
        debug!("(resolving item) resolving {}",
2114
               name);
2115

2116
        match item.node {
2117 2118 2119
            ItemEnum(_, ref generics) |
            ItemTy(_, ref generics) |
            ItemStruct(_, ref generics) => {
W
we 已提交
2120 2121
                self.check_if_primitive_type_name(name, item.span);

2122
                self.with_type_parameter_rib(HasTypeParameters(generics,
2123
                                                               TypeSpace,
2124
                                                               ItemRibKind),
2125
                                             |this| visit::walk_item(this, item));
2126
            }
2127
            ItemFn(_, _, _, _, ref generics, _) => {
2128
                self.with_type_parameter_rib(HasTypeParameters(generics,
2129
                                                               FnSpace,
2130
                                                               ItemRibKind),
2131
                                             |this| visit::walk_item(this, item));
2132 2133
            }

F
Flavio Percoco 已提交
2134
            ItemDefaultImpl(_, ref trait_ref) => {
2135
                self.with_optional_trait_ref(Some(trait_ref), |_, _| {});
2136
            }
2137 2138
            ItemImpl(_,
                     _,
2139
                     ref generics,
2140
                     ref opt_trait_ref,
2141
                     ref self_type,
2142
                     ref impl_items) => {
2143
                self.resolve_implementation(generics,
2144
                                            opt_trait_ref,
2145
                                            &**self_type,
2146
                                            item.id,
2147
                                            &impl_items[..]);
2148 2149
            }

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

2153 2154 2155 2156 2157
                // Create a new rib for the trait-wide type parameters.
                self.with_type_parameter_rib(HasTypeParameters(generics,
                                                               TypeSpace,
                                                               ItemRibKind),
                                             |this| {
N
Niko Matsakis 已提交
2158
                    this.with_self_rib(DefSelfTy(Some(DefId::local(item.id)), None), |this| {
2159 2160 2161 2162
                        this.visit_generics(generics);
                        visit::walk_ty_param_bounds_helper(this, bounds);

                        for trait_item in trait_items {
2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
                            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)
                                    }
                                }
2176
                                ast::MethodTraitItem(ref sig, _) => {
2177 2178 2179 2180 2181 2182 2183
                                    let type_parameters =
                                        HasTypeParameters(&sig.generics,
                                                          FnSpace,
                                                          MethodRibKind);
                                    this.with_type_parameter_rib(type_parameters, |this| {
                                        visit::walk_trait_item(this, trait_item)
                                    });
2184 2185 2186 2187
                                }
                                ast::TypeTraitItem(..) => {
                                    this.check_if_primitive_type_name(trait_item.ident.name,
                                                                      trait_item.span);
2188 2189 2190
                                    this.with_type_parameter_rib(NoTypeParameters, |this| {
                                        visit::walk_trait_item(this, trait_item)
                                    });
2191 2192 2193 2194
                                }
                            };
                        }
                    });
2195
                });
2196 2197
            }

2198
            ItemMod(_) | ItemForeignMod(_) => {
2199
                self.with_scope(Some(name), |this| {
2200
                    visit::walk_item(this, item);
2201
                });
2202 2203
            }

2204
            ItemConst(..) | ItemStatic(..) => {
A
Alex Crichton 已提交
2205
                self.with_constant_rib(|this| {
2206
                    visit::walk_item(this, item);
2207
                });
2208
            }
2209

W
we 已提交
2210 2211 2212
            ItemUse(ref view_path) => {
                // check for imports shadowing primitive types
                if let ast::ViewPathSimple(ident, _) = view_path.node {
2213 2214
                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
W
we 已提交
2215 2216 2217 2218 2219 2220 2221 2222
                            self.check_if_primitive_type_name(ident.name, item.span);
                        }
                        _ => {}
                    }
                }
            }

            ItemExternCrate(_) | ItemMac(..) => {
2223
                // do nothing, these are just around to be encoded
2224
            }
2225 2226 2227
        }
    }

J
Jorge Aparicio 已提交
2228 2229 2230
    fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
        F: FnOnce(&mut Resolver),
    {
2231
        match type_parameters {
2232
            HasTypeParameters(generics, space, rib_kind) => {
2233
                let mut function_type_rib = Rib::new(rib_kind);
2234
                let mut seen_bindings = HashSet::new();
D
Daniel Micay 已提交
2235
                for (index, type_parameter) in generics.ty_params.iter().enumerate() {
2236
                    let name = type_parameter.ident.name;
2237
                    debug!("with_type_parameter_rib: {}", type_parameter.id);
2238

2239
                    if seen_bindings.contains(&name) {
2240 2241
                        resolve_error(self,
                                      type_parameter.span,
2242
                                      ResolutionError::NameAlreadyUsedInTypeParameterList(
2243 2244
                                        name)
                        );
2245
                    }
2246
                    seen_bindings.insert(name);
2247

2248
                    // plain insert (no renaming)
2249 2250 2251
                    function_type_rib.bindings.insert(name,
                        DlDef(DefTyParam(space,
                                         index as u32,
N
Niko Matsakis 已提交
2252
                                         DefId::local(type_parameter.id),
2253
                                         name)));
2254
                }
2255
                self.type_ribs.push(function_type_rib);
2256 2257
            }

B
Brian Anderson 已提交
2258
            NoTypeParameters => {
2259 2260 2261 2262
                // Nothing to do.
            }
        }

A
Alex Crichton 已提交
2263
        f(self);
2264

2265
        match type_parameters {
G
Garming Sam 已提交
2266
            HasTypeParameters(..) => { if !self.resolved { self.type_ribs.pop(); } }
2267
            NoTypeParameters => { }
2268 2269 2270
        }
    }

J
Jorge Aparicio 已提交
2271 2272 2273
    fn with_label_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2274
        self.label_ribs.push(Rib::new(NormalRibKind));
A
Alex Crichton 已提交
2275
        f(self);
G
Garming Sam 已提交
2276 2277 2278
        if !self.resolved {
            self.label_ribs.pop();
        }
2279
    }
2280

J
Jorge Aparicio 已提交
2281 2282 2283
    fn with_constant_rib<F>(&mut self, f: F) where
        F: FnOnce(&mut Resolver),
    {
2284 2285
        self.value_ribs.push(Rib::new(ConstantItemRibKind));
        self.type_ribs.push(Rib::new(ConstantItemRibKind));
A
Alex Crichton 已提交
2286
        f(self);
G
Garming Sam 已提交
2287 2288 2289 2290
        if !self.resolved {
            self.type_ribs.pop();
            self.value_ribs.pop();
        }
2291 2292
    }

F
Felix S. Klock II 已提交
2293
    fn resolve_function(&mut self,
2294
                        rib_kind: RibKind,
2295
                        declaration: &FnDecl,
2296
                        block: &Block) {
2297
        // Create a value rib for the function.
2298
        self.value_ribs.push(Rib::new(rib_kind));
2299

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

2303 2304 2305 2306 2307 2308
        // 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);
2309

2310
            self.visit_ty(&*argument.ty);
2311

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

2316 2317
        // Resolve the function body.
        self.visit_block(&*block);
2318

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

G
Garming Sam 已提交
2321 2322 2323 2324
        if !self.resolved {
            self.label_ribs.pop();
            self.value_ribs.pop();
        }
2325 2326
    }

F
Felix S. Klock II 已提交
2327
    fn resolve_trait_reference(&mut self,
N
Nick Cameron 已提交
2328
                               id: NodeId,
2329
                               trait_path: &Path,
2330
                               path_depth: usize)
2331 2332 2333 2334 2335 2336
                               -> 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 {
2337 2338
                resolve_error(self,
                              trait_path.span,
2339
                              ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
2340
                                                                                   path_depth))
2341
                             );
2342 2343

                // If it's a typedef, give a note
2344
                if let DefTy(..) = path_res.base_def {
2345 2346
                    self.session.span_note(trait_path.span,
                                           "`type` aliases cannot be used for traits");
2347
                }
2348 2349
                Err(())
            }
2350
        } else {
2351 2352
            resolve_error(self,
                          trait_path.span,
2353
                          ResolutionError::UndeclaredTraitName(
2354 2355
                            &*path_names_to_string(trait_path, path_depth))
                         );
2356
            Err(())
2357 2358 2359
        }
    }

2360
    fn resolve_generics(&mut self, generics: &Generics) {
2361
        for type_parameter in generics.ty_params.iter() {
2362 2363 2364
            self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
        }
        for predicate in &generics.where_clause.predicates {
2365
            match predicate {
2366
                &ast::WherePredicate::BoundPredicate(_) |
2367
                &ast::WherePredicate::RegionPredicate(_) => {}
N
Nick Cameron 已提交
2368
                &ast::WherePredicate::EqPredicate(ref eq_pred) => {
2369 2370 2371 2372
                    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 {
2373 2374
                        resolve_error(self,
                                      eq_pred.span,
2375
                                      ResolutionError::UndeclaredAssociatedType);
2376 2377
                    }
                }
2378 2379
            }
        }
2380
        visit::walk_generics(self, generics);
2381 2382
    }

2383 2384
    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
        where F: FnOnce(&mut Resolver) -> T
J
Jorge Aparicio 已提交
2385
    {
2386 2387 2388 2389 2390 2391 2392
        // 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
    }

2393
    fn with_optional_trait_ref<T, F>(&mut self,
E
Eduard Burtescu 已提交
2394
                                     opt_trait_ref: Option<&TraitRef>,
N
Nick Cameron 已提交
2395 2396
                                     f: F)
                                     -> T
2397
        where F: FnOnce(&mut Resolver, Option<DefId>) -> T
J
Jorge Aparicio 已提交
2398
    {
2399
        let mut new_val = None;
2400
        let mut new_id = None;
E
Eduard Burtescu 已提交
2401
        if let Some(trait_ref) = opt_trait_ref {
2402 2403 2404 2405 2406 2407
            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());
2408
            }
2409 2410
            visit::walk_trait_ref(self, trait_ref);
        }
2411
        let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
2412
        let result = f(self, new_id);
2413 2414 2415 2416
        self.current_trait_ref = original_trait_ref;
        result
    }

2417 2418 2419 2420 2421 2422 2423 2424 2425 2426
    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);
G
Garming Sam 已提交
2427 2428 2429
        if !self.resolved {
            self.type_ribs.pop();
        }
2430 2431
    }

F
Felix S. Klock II 已提交
2432
    fn resolve_implementation(&mut self,
2433 2434 2435
                              generics: &Generics,
                              opt_trait_reference: &Option<TraitRef>,
                              self_type: &Ty,
2436
                              item_id: NodeId,
2437
                              impl_items: &[P<ImplItem>]) {
2438
        // If applicable, create a rib for the type parameters.
2439
        self.with_type_parameter_rib(HasTypeParameters(generics,
2440
                                                       TypeSpace,
2441
                                                       ItemRibKind),
2442
                                     |this| {
2443
            // Resolve the type parameters.
2444
            this.visit_generics(generics);
2445

2446
            // Resolve the trait reference, if necessary.
2447
            this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| {
2448
                // Resolve the self type.
2449
                this.visit_ty(self_type);
2450

2451 2452 2453 2454
                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 {
2455
                                ConstImplItem(..) => {
2456
                                    // If this is a trait impl, ensure the const
2457 2458
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
2459 2460
                                                          impl_item.span,
                                        |n, s| ResolutionError::ConstNotMemberOfTrait(n, s));
2461 2462 2463 2464
                                    this.with_constant_rib(|this| {
                                        visit::walk_impl_item(this, impl_item);
                                    });
                                }
2465 2466 2467 2468
                                MethodImplItem(ref sig, _) => {
                                    // If this is a trait impl, ensure the method
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
2469 2470
                                                          impl_item.span,
                                        |n, s| ResolutionError::MethodNotMemberOfTrait(n, s));
2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482

                                    // 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) => {
2483
                                    // If this is a trait impl, ensure the type
2484 2485
                                    // exists in trait
                                    this.check_trait_item(impl_item.ident.name,
2486 2487
                                                          impl_item.span,
                                        |n, s| ResolutionError::TypeNotMemberOfTrait(n, s));
2488

2489 2490 2491
                                    this.visit_ty(ty);
                                }
                                ast::MacImplItem(_) => {}
2492
                            }
2493
                        }
2494
                    });
2495 2496
                });
            });
2497
        });
2498 2499
    }

2500 2501
    fn check_trait_item<F>(&self, name: Name, span: Span, err: F)
        where F: FnOnce(Name, &str) -> ResolutionError {
2502
        // If there is a TraitRef in scope for an impl, then the method must be in the trait.
2503
        if let Some((did, ref trait_ref)) = self.current_trait_ref {
2504
            if !self.trait_item_map.contains_key(&(name, did)) {
2505
                let path_str = path_names_to_string(&trait_ref.path, 0);
2506 2507
                resolve_error(self,
                              span,
2508
                              err(name, &*path_str));
2509 2510 2511 2512
            }
        }
    }

E
Eduard Burtescu 已提交
2513
    fn resolve_local(&mut self, local: &Local) {
2514
        // Resolve the type.
2515
        visit::walk_ty_opt(self, &local.ty);
2516

2517 2518
        // Resolve the initializer.
        visit::walk_expr_opt(self, &local.init);
2519 2520

        // Resolve the pattern.
2521 2522
        self.resolve_pattern(&*local.pat,
                             LocalIrrefutableMode,
2523
                             &mut HashMap::new());
2524 2525
    }

J
John Clements 已提交
2526 2527 2528 2529
    // 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 已提交
2530
    fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
2531
        let mut result = HashMap::new();
2532 2533
        pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
            let name = mtwt::resolve(path1.node);
2534 2535 2536 2537
            result.insert(name, BindingInfo {
                span: sp,
                binding_mode: binding_mode
            });
2538
        });
2539
        return result;
2540 2541
    }

J
John Clements 已提交
2542 2543
    // 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 已提交
2544
    fn check_consistent_bindings(&mut self, arm: &Arm) {
2545
        if arm.pats.is_empty() {
2546 2547
            return
        }
2548
        let map_0 = self.binding_mode_map(&*arm.pats[0]);
D
Daniel Micay 已提交
2549
        for (i, p) in arm.pats.iter().enumerate() {
2550
            let map_i = self.binding_mode_map(&**p);
2551

2552
            for (&key, &binding_0) in &map_0 {
2553
                match map_i.get(&key) {
2554
                  None => {
2555 2556
                    resolve_error(self,
                                  p.span,
2557
                                  ResolutionError::VariableNotBoundInPattern(key,
2558
                                                                              i + 1));
2559 2560 2561
                  }
                  Some(binding_i) => {
                    if binding_0.binding_mode != binding_i.binding_mode {
2562 2563
                        resolve_error(self,
                                      binding_i.span,
2564
                                      ResolutionError::VariableBoundWithDifferentMode(key,
2565
                                                                                       i + 1)
2566
                                     );
2567 2568
                    }
                  }
2569 2570 2571
                }
            }

2572
            for (&key, &binding) in &map_i {
2573
                if !map_0.contains_key(&key) {
2574 2575
                    resolve_error(self,
                                  binding.span,
2576
                                  ResolutionError::VariableNotBoundInParentPattern(key,
2577
                                                                                    i + 1));
2578 2579 2580
                }
            }
        }
2581 2582
    }

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

2586
        let mut bindings_list = HashMap::new();
2587
        for pattern in &arm.pats {
2588
            self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
2589 2590
        }

2591 2592 2593 2594
        // This has to happen *after* we determine which
        // pat_idents are variants
        self.check_consistent_bindings(arm);

2595
        visit::walk_expr_opt(self, &arm.guard);
2596
        self.visit_expr(&*arm.body);
2597

G
Garming Sam 已提交
2598 2599 2600
        if !self.resolved {
            self.value_ribs.pop();
        }
2601 2602
    }

E
Eduard Burtescu 已提交
2603
    fn resolve_block(&mut self, block: &Block) {
2604
        debug!("(resolving block) entering block");
2605
        self.value_ribs.push(Rib::new(NormalRibKind));
2606 2607

        // Move down in the graph, if there's an anonymous module rooted here.
E
Eduard Burtescu 已提交
2608
        let orig_module = self.current_module.clone();
2609
        match orig_module.anonymous_children.borrow().get(&block.id) {
B
Brian Anderson 已提交
2610
            None => { /* Nothing to do. */ }
E
Eduard Burtescu 已提交
2611
            Some(anonymous_module) => {
2612
                debug!("(resolving block) found anonymous module, moving \
P
Paul Stansifer 已提交
2613
                        down");
E
Eduard Burtescu 已提交
2614
                self.current_module = anonymous_module.clone();
2615 2616 2617
            }
        }

2618 2619
        // Check for imports appearing after non-item statements.
        let mut found_non_item = false;
2620
        for statement in &block.stmts {
2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637
            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;
            }
        }

2638
        // Descend into the block.
2639
        visit::walk_block(self, block);
2640 2641

        // Move back up.
G
Garming Sam 已提交
2642
        if !self.resolved {
2643
            self.current_module = orig_module;
G
Garming Sam 已提交
2644 2645
            self.value_ribs.pop();
        }
2646
        debug!("(resolving block) leaving block");
2647 2648
    }

F
Felix S. Klock II 已提交
2649
    fn resolve_type(&mut self, ty: &Ty) {
2650
        match ty.node {
2651
            TyPath(ref maybe_qself, ref path) => {
2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665
                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,
                    };
2666 2667

                // This is a path in the type namespace. Walk through scopes
2668
                // looking for it.
2669
                match resolution {
B
Brian Anderson 已提交
2670
                    Some(def) => {
2671
                        // Write the result into the def map.
2672
                        debug!("(resolving type) writing resolution for `{}` \
2673
                                (id {}) = {:?}",
2674
                               path_names_to_string(path, 0),
2675 2676
                               ty.id, def);
                        self.record_def(ty.id, def);
2677
                    }
B
Brian Anderson 已提交
2678
                    None => {
2679 2680 2681
                        // Keep reporting some errors even if they're ignored above.
                        self.resolve_path(ty.id, path, 0, TypeNS, true);

2682 2683 2684 2685
                        let kind = if maybe_qself.is_some() {
                            "associated type"
                        } else {
                            "type name"
2686
                        };
2687

2688 2689 2690 2691 2692
                        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 已提交
2693
                        if is_invalid_self_type_name {
2694 2695
                            resolve_error(self,
                                          ty.span,
2696
                                          ResolutionError::SelfUsedOutsideImplOrTrait);
2697
                        } else {
2698 2699
                            resolve_error(self,
                                          ty.span,
2700
                                          ResolutionError::UseOfUndeclared(
2701 2702 2703 2704
                                                                    kind,
                                                                    &*path_names_to_string(path,
                                                                                           0))
                                         );
G
Guillaume Gomez 已提交
2705
                        }
2706 2707
                    }
                }
2708
            }
2709
            _ => {}
2710
        }
2711 2712
        // Resolve embedded types.
        visit::walk_ty(self, ty);
2713 2714
    }

F
Felix S. Klock II 已提交
2715
    fn resolve_pattern(&mut self,
E
Eduard Burtescu 已提交
2716
                       pattern: &Pat,
2717 2718 2719
                       mode: PatternBindingMode,
                       // Maps idents to the node ID for the (outermost)
                       // pattern that binds them
2720
                       bindings_list: &mut HashMap<Name, NodeId>) {
2721
        let pat_id = pattern.id;
2722
        walk_pat(pattern, |pattern| {
2723
            match pattern.node {
2724 2725
                PatIdent(binding_mode, ref path1, ref at_rhs) => {
                    // The meaning of PatIdent with no type parameters
2726 2727 2728 2729
                    // 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
2730 2731 2732 2733
                    // unit-like structs. For binding patterns (let
                    // and the LHS of @-patterns), matching such a value is
                    // simply disallowed (since it's rarely what you want).
                    let const_ok = mode == RefutableMode && at_rhs.is_none();
2734

2735
                    let ident = path1.node;
2736
                    let renamed = mtwt::resolve(ident);
2737

2738
                    match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
2739
                        FoundStructOrEnumVariant(def, lp) if const_ok => {
2740
                            debug!("(resolving pattern) resolving `{}` to \
2741
                                    struct or enum variant",
2742
                                   renamed);
2743

2744 2745 2746 2747
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "an enum variant");
2748 2749 2750 2751 2752
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2753
                        }
A
Alex Crichton 已提交
2754
                        FoundStructOrEnumVariant(..) => {
2755
                            resolve_error(
2756
                                self,
2757
                                pattern.span,
2758
                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
2759 2760
                                    renamed)
                            );
2761
                        }
2762
                        FoundConst(def, lp) if const_ok => {
2763
                            debug!("(resolving pattern) resolving `{}` to \
2764
                                    constant",
2765
                                   renamed);
2766

2767 2768 2769 2770
                            self.enforce_default_binding_mode(
                                pattern,
                                binding_mode,
                                "a constant");
2771 2772 2773 2774 2775
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: lp,
                                depth: 0
                            });
2776
                        }
A
Alex Crichton 已提交
2777
                        FoundConst(..) => {
2778
                            resolve_error(
2779 2780
                                self,
                                pattern.span,
2781
                                ResolutionError::OnlyIrrefutablePatternsAllowedHere
2782
                            );
2783
                        }
2784
                        BareIdentifierPatternUnresolved => {
2785
                            debug!("(resolving pattern) binding `{}`",
2786
                                   renamed);
2787

2788
                            let def = DefLocal(pattern.id);
2789 2790 2791 2792 2793

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

2794 2795 2796 2797 2798
                            self.record_def(pattern.id, PathResolution {
                                base_def: def,
                                last_private: LastMod(AllPublic),
                                depth: 0
                            });
2799 2800 2801 2802 2803 2804

                            // 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.)
2805 2806
                            if !bindings_list.contains_key(&renamed) {
                                let this = &mut *self;
2807 2808
                                let last_rib = this.value_ribs.last_mut().unwrap();
                                last_rib.bindings.insert(renamed, DlDef(def));
2809
                                bindings_list.insert(renamed, pat_id);
2810 2811 2812 2813
                            } else if mode == ArgumentIrrefutableMode &&
                                    bindings_list.contains_key(&renamed) {
                                // Forbid duplicate bindings in the same
                                // parameter list.
2814
                                resolve_error(
2815 2816
                                    self,
                                    pattern.span,
2817
                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
2818
                                        &ident.name.as_str())
2819
                                );
2820
                            } else if bindings_list.get(&renamed) ==
2821 2822 2823
                                    Some(&pat_id) {
                                // Then this is a duplicate variable in the
                                // same disjunction, which is an error.
2824
                                resolve_error(
2825 2826
                                    self,
                                    pattern.span,
2827
                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
2828
                                        &ident.name.as_str())
2829
                                );
2830
                            }
2831 2832
                            // Else, not bound in the same pattern: do
                            // nothing.
2833 2834 2835 2836
                        }
                    }
                }

2837
                PatEnum(ref path, _) => {
2838
                    // This must be an enum variant, struct or const.
2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854
                    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 {
2855
                        match path_res.base_def {
2856
                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
2857 2858 2859
                                self.record_def(pattern.id, path_res);
                            }
                            DefStatic(..) => {
2860 2861
                                resolve_error(&self,
                                              path.span,
2862
                                              ResolutionError::StaticVariableReference);
2863
                            }
2864 2865 2866 2867
                            _ => {
                                // If anything ends up here entirely resolved,
                                // it's an error. If anything ends up here
                                // partially resolved, that's OK, because it may
2868
                                // be a `T::CONST` that typeck will resolve.
2869
                                if path_res.depth == 0 {
2870
                                    resolve_error(
2871
                                        self,
2872
                                        path.span,
2873
                                        ResolutionError::NotAnEnumVariantStructOrConst(
2874 2875 2876 2877 2878 2879
                                            &path.segments
                                                 .last()
                                                 .unwrap()
                                                 .identifier
                                                 .name
                                                 .as_str())
2880
                                    );
2881
                                } else {
2882 2883 2884 2885
                                    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);
2886 2887 2888 2889 2890
                                    self.record_def(pattern.id, path_res);
                                }
                            }
                        }
                    } else {
2891
                        resolve_error(
2892 2893
                            self,
                            path.span,
2894
                            ResolutionError::UnresolvedEnumVariantStructOrConst(
2895
                                &path.segments.last().unwrap().identifier.name.as_str())
2896
                        );
2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926
                    }
                    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);
                            }
2927
                            _ => {
2928
                                resolve_error(
2929 2930
                                    self,
                                    path.span,
2931
                                    ResolutionError::NotAnAssociatedConst(
2932
                                        &path.segments.last().unwrap().identifier.name.as_str()
2933 2934
                                    )
                                );
2935
                            }
2936
                        }
2937
                    } else {
2938
                        resolve_error(
2939 2940
                            self,
                            path.span,
2941
                            ResolutionError::UnresolvedAssociatedConst(
2942
                                &path.segments.last().unwrap().identifier.name.as_str()
2943 2944
                            )
                        );
2945
                    }
2946
                    visit::walk_pat(self, pattern);
2947 2948
                }

2949
                PatStruct(ref path, _, _) => {
2950
                    match self.resolve_path(pat_id, path, 0, TypeNS, false) {
2951
                        Some(definition) => {
2952 2953
                            self.record_def(pattern.id, definition);
                        }
2954
                        result => {
2955
                            debug!("(resolving pattern) didn't find struct \
2956
                                    def: {:?}", result);
2957 2958 2959
                            resolve_error(
                                self,
                                path.span,
2960
                                ResolutionError::DoesNotNameAStruct(
2961 2962
                                    &*path_names_to_string(path, 0))
                            );
2963 2964
                        }
                    }
2965 2966 2967 2968 2969
                    visit::walk_path(self, path);
                }

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

2972
                _ => {
2973 2974 2975
                    // Nothing to do.
                }
            }
2976
            true
2977
        });
2978 2979
    }

2980
    fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
E
Eduard Burtescu 已提交
2981 2982 2983
                                       -> BareIdentifierPatternResolution {
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
2984
                                                 name,
2985
                                                 ValueNS) {
2986
            Success((target, _)) => {
2987
                debug!("(resolve bare identifier pattern) succeeded in \
2988
                         finding {} at {:?}",
2989
                        name,
E
Erick Tryzelaar 已提交
2990 2991
                        target.bindings.value_def.borrow());
                match *target.bindings.value_def.borrow() {
B
Brian Anderson 已提交
2992
                    None => {
S
Steve Klabnik 已提交
2993
                        panic!("resolved name in the value namespace to a \
2994
                              set of name bindings with no def?!");
2995
                    }
B
Brian Anderson 已提交
2996
                    Some(def) => {
2997 2998 2999
                        // 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.
3000
                        match def.def {
A
Alex Crichton 已提交
3001
                            def @ DefVariant(..) | def @ DefStruct(..) => {
3002
                                return FoundStructOrEnumVariant(def, LastMod(AllPublic));
3003
                            }
3004
                            def @ DefConst(..) | def @ DefAssociatedConst(..) => {
3005
                                return FoundConst(def, LastMod(AllPublic));
3006
                            }
3007
                            DefStatic(..) => {
3008 3009
                                resolve_error(self,
                                              span,
3010
                                              ResolutionError::StaticVariableReference);
3011 3012
                                return BareIdentifierPatternUnresolved;
                            }
3013
                            _ => {
3014
                                return BareIdentifierPatternUnresolved;
3015 3016
                            }
                        }
3017 3018 3019 3020
                    }
                }
            }

B
Brian Anderson 已提交
3021
            Indeterminate => {
S
Steve Klabnik 已提交
3022
                panic!("unexpected indeterminate result");
3023
            }
3024 3025 3026
            Failed(err) => {
                match err {
                    Some((span, msg)) => {
3027
                        resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3028 3029 3030
                    }
                    None => ()
                }
3031

3032
                debug!("(resolve bare identifier pattern) failed to find {}",
3033
                        name);
3034
                return BareIdentifierPatternUnresolved;
3035 3036 3037 3038
            }
        }
    }

3039 3040 3041 3042 3043 3044 3045 3046 3047
    /// 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
    {
3048 3049
        let max_assoc_types;

3050
        match maybe_qself {
3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061
            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();
            }
3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082
        }

        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)
    }

3083 3084
    /// If `check_ribs` is true, checks the local definitions first; i.e.
    /// doesn't skip straight to the containing module.
3085 3086
    /// Skips `path_depth` trailing segments, which is also reflected in the
    /// returned value. See `middle::def::PathResolution` for more info.
G
Garming Sam 已提交
3087 3088 3089 3090 3091 3092
    pub fn resolve_path(&mut self,
                        id: NodeId,
                        path: &Path,
                        path_depth: usize,
                        namespace: Namespace,
                        check_ribs: bool) -> Option<PathResolution> {
3093 3094 3095
        let span = path.span;
        let segments = &path.segments[..path.segments.len()-path_depth];

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

3098
        if path.global {
3099
            let def = self.resolve_crate_relative_path(span, segments, namespace);
3100
            return def.map(mk_res);
3101 3102
        }

3103
        // Try to find a path to an item in a module.
3104
        let unqualified_def =
3105
                self.resolve_identifier(segments.last().unwrap().identifier,
3106 3107
                                        namespace,
                                        check_ribs,
3108
                                        span);
3109

N
Nick Cameron 已提交
3110 3111 3112
        if segments.len() <= 1 {
            return unqualified_def.map(mk_res);
        }
3113

N
Nick Cameron 已提交
3114 3115 3116 3117 3118 3119 3120 3121 3122
        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());
            }
            _ => {}
3123
        }
N
Nick Cameron 已提交
3124 3125

        def.map(mk_res)
3126 3127
    }

N
Nick Cameron 已提交
3128
    // Resolve a single identifier.
F
Felix S. Klock II 已提交
3129
    fn resolve_identifier(&mut self,
3130 3131 3132 3133 3134
                          identifier: Ident,
                          namespace: Namespace,
                          check_ribs: bool,
                          span: Span)
                          -> Option<(Def, LastPrivate)> {
3135 3136 3137 3138 3139 3140 3141 3142 3143
        // 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)));
            }
        }

3144
        if check_ribs {
3145 3146 3147 3148
            if let Some(def) = self.resolve_identifier_in_local_ribs(identifier,
                                                                     namespace,
                                                                     span) {
                return Some((def, LastMod(AllPublic)));
3149 3150 3151
            }
        }

3152
        self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace)
3153 3154
    }

3155
    // FIXME #4952: Merge me with resolve_name_in_module?
F
Felix S. Klock II 已提交
3156
    fn resolve_definition_of_name_in_module(&mut self,
E
Eduard Burtescu 已提交
3157
                                            containing_module: Rc<Module>,
3158
                                            name: Name,
3159
                                            namespace: Namespace)
3160
                                            -> NameDefinition {
3161
        // First, search children.
3162
        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
3163

3164
        match containing_module.children.borrow().get(&name) {
3165 3166 3167 3168
            Some(child_name_bindings) => {
                match child_name_bindings.def_for_namespace(namespace) {
                    Some(def) => {
                        // Found it. Stop the search here.
N
Nick Cameron 已提交
3169
                        let p = child_name_bindings.defined_in_public_namespace(namespace);
3170
                        let lp = if p {LastMod(AllPublic)} else {
3171
                            LastMod(DependsOn(def.def_id()))
3172 3173
                        };
                        return ChildNameDefinition(def, lp);
3174
                    }
3175
                    None => {}
3176 3177
                }
            }
3178
            None => {}
3179 3180 3181
        }

        // Next, search import resolutions.
3182
        match containing_module.import_resolutions.borrow().get(&name) {
E
Eduard Burtescu 已提交
3183
            Some(import_resolution) if import_resolution.is_public => {
3184 3185 3186 3187 3188 3189 3190
                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));
3191
                            self.record_import_use(id, name);
3192 3193 3194 3195 3196
                            match target.target_module.def_id.get() {
                                Some(DefId{krate: kid, ..}) => {
                                    self.used_crates.insert(kid);
                                },
                                _ => {}
3197
                            }
3198 3199 3200 3201 3202
                            return ImportNameDefinition(def, LastMod(AllPublic));
                        }
                        None => {
                            // This can happen with external impls, due to
                            // the imperfect way we read the metadata.
3203 3204 3205 3206
                        }
                    }
                }
            }
A
Alex Crichton 已提交
3207
            Some(..) | None => {} // Continue.
3208 3209 3210 3211
        }

        // Finally, search through external children.
        if namespace == TypeNS {
3212 3213 3214 3215 3216 3217 3218 3219 3220
            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);
3221
                }
3222 3223
            }
        }
3224 3225

        return NoNameDefinition;
3226 3227
    }

3228
    // resolve a "module-relative" path, e.g. a::b::c
F
Felix S. Klock II 已提交
3229
    fn resolve_module_relative_path(&mut self,
3230 3231
                                    span: Span,
                                    segments: &[ast::PathSegment],
3232 3233
                                    namespace: Namespace)
                                    -> Option<(Def, LastPrivate)> {
S
Simonas Kazlauskas 已提交
3234
        let module_path = segments.split_last().unwrap().1.iter()
3235 3236
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3237

3238
        let containing_module;
3239
        let last_private;
N
Nick Cameron 已提交
3240 3241
        let current_module = self.current_module.clone();
        match self.resolve_module_path(current_module,
3242
                                       &module_path[..],
3243
                                       UseLexicalScope,
3244
                                       span,
3245
                                       PathSearch) {
3246 3247 3248 3249
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
3250
                        let msg = format!("Use of undeclared type or module `{}`",
3251
                                          names_to_string(&module_path));
3252
                        (span, msg)
3253 3254
                    }
                };
3255

3256
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
3257
                return None;
3258
            }
S
Steve Klabnik 已提交
3259
            Indeterminate => panic!("indeterminate unexpected"),
3260
            Success((resulting_module, resulting_last_private)) => {
3261
                containing_module = resulting_module;
3262
                last_private = resulting_last_private;
3263 3264 3265
            }
        }

3266
        let name = segments.last().unwrap().identifier.name;
E
Eduard Burtescu 已提交
3267
        let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
3268
                                                                  name,
3269
                                                                  namespace) {
B
Brian Anderson 已提交
3270
            NoNameDefinition => {
3271
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3272
                return None;
3273
            }
3274 3275
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                (def, last_private.or(lp))
3276
            }
3277
        };
3278 3279
        if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
            self.used_crates.insert(kid);
3280
        }
3281
        return Some(def);
3282 3283
    }

3284 3285
    /// Invariant: This must be called only during main resolution, not during
    /// import resolution.
F
Felix S. Klock II 已提交
3286
    fn resolve_crate_relative_path(&mut self,
3287 3288
                                   span: Span,
                                   segments: &[ast::PathSegment],
3289 3290
                                   namespace: Namespace)
                                       -> Option<(Def, LastPrivate)> {
S
Simonas Kazlauskas 已提交
3291
        let module_path = segments.split_last().unwrap().1.iter()
3292 3293
                                         .map(|ps| ps.identifier.name)
                                         .collect::<Vec<_>>();
3294

3295
        let root_module = self.graph_root.get_module();
3296

3297
        let containing_module;
3298
        let last_private;
3299
        match self.resolve_module_path_from_root(root_module,
3300
                                                 &module_path[..],
3301
                                                 0,
3302
                                                 span,
3303
                                                 PathSearch,
3304
                                                 LastMod(AllPublic)) {
3305 3306 3307 3308 3309
            Failed(err) => {
                let (span, msg) = match err {
                    Some((span, msg)) => (span, msg),
                    None => {
                        let msg = format!("Use of undeclared module `::{}`",
3310
                                          names_to_string(&module_path[..]));
3311
                        (span, msg)
3312 3313 3314
                    }
                };

3315
                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
B
Brian Anderson 已提交
3316
                return None;
3317 3318
            }

B
Brian Anderson 已提交
3319
            Indeterminate => {
S
Steve Klabnik 已提交
3320
                panic!("indeterminate unexpected");
3321 3322
            }

3323
            Success((resulting_module, resulting_last_private)) => {
3324
                containing_module = resulting_module;
3325
                last_private = resulting_last_private;
3326 3327 3328
            }
        }

3329
        let name = segments.last().unwrap().identifier.name;
3330
        match self.resolve_definition_of_name_in_module(containing_module,
3331
                                                        name,
3332
                                                        namespace) {
B
Brian Anderson 已提交
3333
            NoNameDefinition => {
3334
                // We failed to resolve the name. Report an error.
B
Brian Anderson 已提交
3335
                return None;
3336
            }
3337 3338
            ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
                return Some((def, last_private.or(lp)));
3339 3340 3341 3342
            }
        }
    }

F
Felix S. Klock II 已提交
3343
    fn resolve_identifier_in_local_ribs(&mut self,
3344 3345 3346 3347
                                        ident: Ident,
                                        namespace: Namespace,
                                        span: Span)
                                        -> Option<Def> {
3348
        // Check the local set of ribs.
3349
        let search_result = match namespace {
B
Brian Anderson 已提交
3350
            ValueNS => {
3351
                let renamed = mtwt::resolve(ident);
3352
                self.search_ribs(&self.value_ribs, renamed, span)
3353
            }
B
Brian Anderson 已提交
3354
            TypeNS => {
3355
                let name = ident.name;
3356
                self.search_ribs(&self.type_ribs, name, span)
3357
            }
3358
        };
3359

3360
        match search_result {
3361
            Some(DlDef(def)) => {
N
Nick Cameron 已提交
3362
                debug!("(resolving path in local ribs) resolved `{}` to local: {:?}",
3363
                       ident,
P
Paul Stansifer 已提交
3364
                       def);
3365
                Some(def)
3366
            }
3367
            Some(DlField) | Some(DlImpl(_)) | None => {
3368
                None
3369 3370 3371 3372
            }
        }
    }

3373 3374 3375 3376
    fn resolve_item_by_name_in_lexical_scope(&mut self,
                                             name: Name,
                                             namespace: Namespace)
                                            -> Option<(Def, LastPrivate)> {
3377
        // Check the items.
E
Eduard Burtescu 已提交
3378 3379
        let module = self.current_module.clone();
        match self.resolve_item_in_lexical_scope(module,
3380
                                                 name,
3381
                                                 namespace) {
3382
            Success((target, _)) => {
3383
                match (*target.bindings).def_for_namespace(namespace) {
B
Brian Anderson 已提交
3384
                    None => {
3385 3386
                        // This can happen if we were looking for a type and
                        // found a module instead. Modules don't have defs.
3387
                        debug!("(resolving item path by identifier in lexical \
3388
                                 scope) failed to resolve {} after success...",
3389
                                 name);
3390
                        return None;
3391
                    }
B
Brian Anderson 已提交
3392
                    Some(def) => {
3393
                        debug!("(resolving item path in lexical scope) \
A
Alex Crichton 已提交
3394
                                resolved `{}` to item",
3395
                               name);
3396 3397 3398
                        // 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.
3399
                        return Some((def, LastMod(AllPublic)));
3400 3401 3402
                    }
                }
            }
B
Brian Anderson 已提交
3403
            Indeterminate => {
S
Steve Klabnik 已提交
3404
                panic!("unexpected indeterminate result");
3405
            }
3406
            Failed(err) => {
3407
                debug!("(resolving item path by identifier in lexical scope) \
3408
                         failed to resolve {}", name);
N
Nick Cameron 已提交
3409 3410

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

B
Brian Anderson 已提交
3414
                return None;
3415 3416 3417 3418
            }
        }
    }

J
Jorge Aparicio 已提交
3419 3420 3421
    fn with_no_errors<T, F>(&mut self, f: F) -> T where
        F: FnOnce(&mut Resolver) -> T,
    {
3422
        self.emit_errors = false;
A
Alex Crichton 已提交
3423
        let rs = f(self);
3424 3425 3426 3427
        self.emit_errors = true;
        rs
    }

3428
    fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
3429 3430 3431
        fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                    -> Option<(Path, NodeId, FallbackChecks)> {
            match t.node {
3432
                TyPath(None, ref path) => Some((path.clone(), t.id, allow)),
3433 3434
                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),
3435 3436 3437 3438 3439 3440 3441
                // 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,
            }
        }

3442
        fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
3443 3444
                            -> Option<Rc<Module>> {
            let root = this.current_module.clone();
3445
            let last_name = name_path.last().unwrap();
3446

3447
            if name_path.len() == 1 {
3448
                match this.primitive_type_table.primitive_types.get(last_name) {
3449 3450
                    Some(_) => None,
                    None => {
3451
                        match this.current_module.children.borrow().get(last_name) {
3452 3453 3454 3455 3456 3457 3458
                            Some(child) => child.get_module_if_available(),
                            None => None
                        }
                    }
                }
            } else {
                match this.resolve_module_path(root,
N
Nick Cameron 已提交
3459 3460 3461 3462
                                               &name_path[..],
                                               UseLexicalScope,
                                               span,
                                               PathSearch) {
3463 3464 3465 3466 3467 3468
                    Success((module, _)) => Some(module),
                    _ => None
                }
            }
        }

3469
        fn is_static_method(this: &Resolver, did: DefId) -> bool {
3470
            if did.is_local() {
3471
                let sig = match this.ast_map.get(did.node) {
3472
                    ast_map::NodeTraitItem(trait_item) => match trait_item.node {
3473
                        ast::MethodTraitItem(ref sig, _) => sig,
3474 3475
                        _ => return false
                    },
3476
                    ast_map::NodeImplItem(impl_item) => match impl_item.node {
3477
                        ast::MethodImplItem(ref sig, _) => sig,
3478 3479 3480 3481
                        _ => return false
                    },
                    _ => return false
                };
3482
                sig.explicit_self.node == ast::SelfStatic
3483 3484 3485 3486 3487
            } else {
                csearch::is_static_method(&this.session.cstore, did)
            }
        }

3488 3489 3490 3491
        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,
3492 3493 3494 3495
            },
            None => return NoSuggestion,
        };

3496 3497
        if allowed == Everything {
            // Look for a field with the same name in the current self_type.
3498 3499 3500 3501
            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) {
3502 3503 3504 3505 3506
                    None => {}
                    Some(fields) => {
                        if fields.iter().any(|&field_name| name == field_name) {
                            return Field;
                        }
3507
                    }
3508 3509 3510
                },
                _ => {} // Self type didn't resolve properly
            }
3511 3512
        }

3513
        let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
3514 3515

        // Look for a method in the current self type's impl module.
3516 3517
        if let Some(module) = get_module(self, path.span, &name_path) {
            if let Some(binding) = module.children.borrow().get(&name) {
3518
                if let Some(DefMethod(did)) = binding.def_for_namespace(ValueNS) {
3519
                    if is_static_method(self, did) {
3520
                        return StaticMethod(path_names_to_string(&path, 0))
3521 3522 3523 3524 3525
                    }
                    if self.current_trait_ref.is_some() {
                        return TraitItem;
                    } else if allowed == Everything {
                        return Method;
3526 3527
                    }
                }
3528
            }
3529 3530 3531
        }

        // Look for a method in the current trait.
3532 3533 3534
        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) {
3535
                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
3536 3537
                } else {
                    return TraitItem;
3538 3539 3540 3541 3542 3543 3544
                }
            }
        }

        NoSuggestion
    }

3545
    fn find_best_match_for_name(&mut self, name: &str) -> Option<String> {
3546
        let mut maybes: Vec<token::InternedString> = Vec::new();
3547
        let mut values: Vec<usize> = Vec::new();
3548

3549
        for rib in self.value_ribs.iter().rev() {
3550
            for (&k, _) in &rib.bindings {
3551
                maybes.push(k.as_str());
3552
                values.push(usize::MAX);
3553 3554 3555 3556
            }
        }

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

3560
            if values[i] <= values[smallest] {
3561 3562 3563 3564
                smallest = i;
            }
        }

3565 3566 3567 3568 3569
        // 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;

3570
        if !values.is_empty() &&
3571
            values[smallest] <= max_distance &&
3572
            name != &maybes[smallest][..] {
3573

3574
            Some(maybes[smallest].to_string())
3575 3576 3577 3578 3579 3580

        } else {
            None
        }
    }

E
Eduard Burtescu 已提交
3581
    fn resolve_expr(&mut self, expr: &Expr) {
P
Patrick Walton 已提交
3582 3583
        // First, record candidate traits for this expression if it could
        // result in the invocation of a method call.
3584 3585 3586

        self.record_candidate_traits_for_expr_if_necessary(expr);

3587
        // Next, resolve the node.
3588
        match expr.node {
3589
            ExprPath(ref maybe_qself, ref path) => {
3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605
                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,
                    };
3606

3607 3608
                // This is a local path in the value namespace. Walk through
                // scopes looking for it.
3609
                if let Some(path_res) = resolution {
3610
                    // Check if struct variant
3611
                    if let DefVariant(_, _, true) = path_res.base_def {
3612
                        let path_name = path_names_to_string(path, 0);
3613

3614 3615
                        resolve_error(self,
                                      expr.span,
3616
                                      ResolutionError::StructVariantUsedAsFunction(&*path_name));
3617

3618
                        let msg = format!("did you mean to write: \
3619 3620 3621 3622 3623 3624 3625
                                           `{} {{ /* fields */ }}`?",
                                          path_name);
                        if self.emit_errors {
                            self.session.fileline_help(expr.span, &msg);
                        } else {
                            self.session.span_help(expr.span, &msg);
                        }
3626
                    } else {
3627
                        // Write the result into the def map.
3628
                        debug!("(resolving expr) resolved `{}`",
3629
                               path_names_to_string(path, 0));
3630

3631 3632
                        // Partial resolutions will need the set of traits in scope,
                        // so they can be completed during typeck.
3633
                        if path_res.depth != 0 {
3634
                            let method_name = path.segments.last().unwrap().identifier.name;
3635
                            let traits = self.get_traits_containing_item(method_name);
3636 3637 3638
                            self.trait_map.insert(expr.id, traits);
                        }

3639
                        self.record_def(expr.id, path_res);
3640
                    }
3641 3642 3643 3644 3645
                } 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.)
3646
                    let path_name = path_names_to_string(path, 0);
3647 3648 3649 3650 3651 3652
                    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) => {
3653 3654 3655
                                resolve_error(
                                    self,
                                    expr.span,
3656
                                    ResolutionError::StructVariantUsedAsFunction(
3657 3658
                                        &*path_name)
                                );
3659

3660
                                let msg = format!("did you mean to write: \
3661 3662 3663 3664 3665 3666 3667 3668
                                                     `{} {{ /* fields */ }}`?",
                                                    path_name);
                                if self.emit_errors {
                                    self.session.fileline_help(expr.span, &msg);
                                } else {
                                    self.session.span_help(expr.span, &msg);
                                }
                            }
3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681
                        _ => {
                            // 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
                            });
3682

3683
                            if method_scope && special_names::self_ == path_name {
3684
                                resolve_error(
3685 3686
                                    self,
                                    expr.span,
3687
                                    ResolutionError::SelfNotAvailableInStaticMethod
3688
                                );
3689 3690 3691 3692 3693 3694
                            } 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
3695
                                        self.find_best_match_for_name(&path_name)
3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707
                                                            .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)
                                };

3708
                                if !msg.is_empty() {
3709
                                    msg = format!(". Did you mean {}?", msg)
3710
                                }
3711

3712 3713
                                resolve_error(self,
                                              expr.span,
3714
                                              ResolutionError::UnresolvedName(&*path_name,
3715
                                                                               &*msg));
3716
                            }
V
Vincent Belliard 已提交
3717
                        }
3718 3719 3720
                    }
                }

3721
                visit::walk_expr(self, expr);
3722 3723
            }

3724
            ExprStruct(ref path, _, _) => {
3725 3726 3727
                // 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.
3728
                match self.resolve_path(expr.id, path, 0, TypeNS, false) {
3729
                    Some(definition) => self.record_def(expr.id, definition),
3730 3731
                    None => {
                        debug!("(resolving expression) didn't find struct def",);
3732

3733 3734
                        resolve_error(self,
                                      path.span,
3735
                                      ResolutionError::DoesNotNameAStruct(
3736 3737
                                                                &*path_names_to_string(path, 0))
                                     );
3738 3739 3740
                    }
                }

3741
                visit::walk_expr(self, expr);
3742 3743
            }

P
Pythoner6 已提交
3744
            ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
3745
                self.with_label_rib(|this| {
A
Alex Crichton 已提交
3746
                    let def_like = DlDef(DefLabel(expr.id));
3747

3748
                    {
3749
                        let rib = this.label_ribs.last_mut().unwrap();
3750
                        let renamed = mtwt::resolve(label);
3751
                        rib.bindings.insert(renamed, def_like);
3752
                    }
3753

3754
                    visit::walk_expr(this, expr);
3755
                })
3756 3757
            }

3758
            ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
3759
                let renamed = mtwt::resolve(label);
3760
                match self.search_label(renamed) {
3761
                    None => {
3762 3763
                        resolve_error(self,
                                      expr.span,
3764
                                      ResolutionError::UndeclaredLabel(&label.name.as_str()))
3765
                    }
3766
                    Some(DlDef(def @ DefLabel(_))) => {
3767
                        // Since this def is a label, it is never read.
3768 3769 3770 3771 3772
                        self.record_def(expr.id, PathResolution {
                            base_def: def,
                            last_private: LastMod(AllPublic),
                            depth: 0
                        })
3773 3774
                    }
                    Some(_) => {
3775
                        self.session.span_bug(expr.span,
3776 3777
                                              "label wasn't mapped to a \
                                               label def!")
3778 3779 3780 3781
                    }
                }
            }

B
Brian Anderson 已提交
3782
            _ => {
3783
                visit::walk_expr(self, expr);
3784 3785 3786 3787
            }
        }
    }

E
Eduard Burtescu 已提交
3788
    fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
3789
        match expr.node {
3790
            ExprField(_, ident) => {
3791 3792 3793 3794
                // 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.
3795
                let traits = self.get_traits_containing_item(ident.node.name);
3796
                self.trait_map.insert(expr.id, traits);
3797
            }
3798
            ExprMethodCall(ident, _, _) => {
3799
                debug!("(recording candidate traits for expr) recording \
A
Alex Crichton 已提交
3800
                        traits for {}",
3801
                       expr.id);
3802
                let traits = self.get_traits_containing_item(ident.node.name);
3803
                self.trait_map.insert(expr.id, traits);
3804
            }
3805
            _ => {
3806 3807 3808 3809 3810
                // Nothing to do.
            }
        }
    }

3811 3812
    fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
        debug!("(getting traits containing item) looking for '{}'",
3813
               name);
E
Eduard Burtescu 已提交
3814 3815 3816 3817 3818 3819 3820

        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,
3821
                name);
E
Eduard Burtescu 已提交
3822 3823
            found_traits.push(trait_def_id);
        }
3824

3825
        let mut found_traits = Vec::new();
E
Eduard Burtescu 已提交
3826
        let mut search_module = self.current_module.clone();
E
Eduard Burtescu 已提交
3827 3828
        loop {
            // Look for the current trait.
3829 3830
            match self.current_trait_ref {
                Some((trait_def_id, _)) => {
3831
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
3832
                        add_trait_info(&mut found_traits, trait_def_id, name);
3833 3834
                    }
                }
3835
                None => {} // Nothing to do.
E
Eduard Burtescu 已提交
3836
            }
3837

E
Eduard Burtescu 已提交
3838
            // Look for trait children.
3839
            build_reduced_graph::populate_module_if_necessary(self, &search_module);
3840

E
Eduard Burtescu 已提交
3841
            {
3842
                for (_, child_names) in search_module.children.borrow().iter() {
3843 3844 3845 3846 3847
                    let def = match child_names.def_for_namespace(TypeNS) {
                        Some(def) => def,
                        None => continue
                    };
                    let trait_def_id = match def {
3848
                        DefTrait(trait_def_id) => trait_def_id,
3849 3850
                        _ => continue,
                    };
3851
                    if self.trait_item_map.contains_key(&(name, trait_def_id)) {
E
Eduard Burtescu 已提交
3852
                        add_trait_info(&mut found_traits, trait_def_id, name);
3853 3854
                    }
                }
E
Eduard Burtescu 已提交
3855
            }
3856

E
Eduard Burtescu 已提交
3857
            // Look for imports.
3858
            for (_, import) in search_module.import_resolutions.borrow().iter() {
E
Eduard Burtescu 已提交
3859 3860 3861 3862 3863
                let target = match import.target_for_namespace(TypeNS) {
                    None => continue,
                    Some(target) => target,
                };
                let did = match target.bindings.def_for_namespace(TypeNS) {
3864
                    Some(DefTrait(trait_def_id)) => trait_def_id,
E
Eduard Burtescu 已提交
3865 3866
                    Some(..) | None => continue,
                };
3867
                if self.trait_item_map.contains_key(&(name, did)) {
E
Eduard Burtescu 已提交
3868
                    add_trait_info(&mut found_traits, did, name);
3869 3870 3871 3872
                    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);
3873 3874
                    if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
                        self.used_crates.insert(kid);
3875
                    }
3876
                }
E
Eduard Burtescu 已提交
3877
            }
3878

E
Eduard Burtescu 已提交
3879
            match search_module.parent_link.clone() {
E
Eduard Burtescu 已提交
3880 3881
                NoParentLink | ModuleParentLink(..) => break,
                BlockParentLink(parent_module, _) => {
E
Eduard Burtescu 已提交
3882
                    search_module = parent_module.upgrade().unwrap();
3883
                }
E
Eduard Burtescu 已提交
3884
            }
3885 3886
        }

E
Eduard Burtescu 已提交
3887
        found_traits
3888 3889
    }

3890 3891 3892
    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},
3893
                "Import should only be used for `use` directives");
3894

3895 3896 3897 3898 3899
        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));
3900
        }
3901 3902
    }

F
Felix S. Klock II 已提交
3903
    fn enforce_default_binding_mode(&mut self,
3904
                                        pat: &Pat,
3905
                                        pat_binding_mode: BindingMode,
3906
                                        descr: &str) {
3907
        match pat_binding_mode {
3908
            BindByValue(_) => {}
A
Alex Crichton 已提交
3909
            BindByRef(..) => {
3910 3911
                resolve_error(self,
                              pat.span,
3912
                              ResolutionError::CannotUseRefBindingModeWith(descr));
3913 3914 3915 3916
            }
        }
    }

3917 3918 3919 3920 3921 3922 3923
    //
    // Diagnostics
    //
    // Diagnostics are not particularly efficient, because they're rarely
    // hit.
    //

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

3928
        debug!("Children:");
3929
        build_reduced_graph::populate_module_if_necessary(self, &module_);
3930
        for (&name, _) in module_.children.borrow().iter() {
3931
            debug!("* {}", name);
3932 3933
        }

3934
        debug!("Import resolutions:");
3935
        let import_resolutions = module_.import_resolutions.borrow();
3936
        for (&name, import_resolution) in import_resolutions.iter() {
N
Niko Matsakis 已提交
3937
            let value_repr;
3938
            match import_resolution.target_for_namespace(ValueNS) {
R
Richo Healey 已提交
3939
                None => { value_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3940
                Some(_) => {
R
Richo Healey 已提交
3941
                    value_repr = " value:?".to_string();
3942
                    // FIXME #4954
3943 3944 3945
                }
            }

N
Niko Matsakis 已提交
3946
            let type_repr;
3947
            match import_resolution.target_for_namespace(TypeNS) {
R
Richo Healey 已提交
3948
                None => { type_repr = "".to_string(); }
E
Erick Tryzelaar 已提交
3949
                Some(_) => {
R
Richo Healey 已提交
3950
                    type_repr = " type:?".to_string();
3951
                    // FIXME #4954
3952 3953 3954
                }
            }

3955
            debug!("* {}:{}{}", name, value_repr, type_repr);
3956 3957 3958 3959
        }
    }
}

3960 3961 3962 3963 3964 3965 3966 3967 3968 3969

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("::")
        }
3970
        result.push_str(&name.as_str());
3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002
    };
    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);

4003
    if names.is_empty() {
4004 4005 4006 4007 4008 4009
        return "???".to_string();
    }
    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}


4010
pub struct CrateMap {
4011
    pub def_map: DefMap,
4012
    pub freevars: RefCell<FreevarMap>,
4013
    pub export_map: ExportMap,
4014 4015
    pub trait_map: TraitMap,
    pub external_exports: ExternalExports,
4016 4017 4018
    pub glob_map: Option<GlobMap>
}

N
Niko Matsakis 已提交
4019
#[derive(PartialEq,Copy, Clone)]
4020 4021 4022
pub enum MakeGlobMap {
    Yes,
    No
4023 4024
}

4025
/// Entry point to crate resolution.
4026 4027 4028 4029
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
                               ast_map: &'a ast_map::Map<'tcx>,
                               make_glob_map: MakeGlobMap)
                               -> CrateMap {
4030
    let krate = ast_map.krate();
4031
    let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
4032 4033 4034 4035 4036 4037

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

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

4038
    CrateMap {
4039 4040
        def_map: resolver.def_map,
        freevars: resolver.freevars,
4041
        export_map: resolver.export_map,
4042 4043
        trait_map: resolver.trait_map,
        external_exports: resolver.external_exports,
4044 4045 4046 4047 4048
        glob_map: if resolver.make_glob_map {
                        Some(resolver.glob_map)
                    } else {
                        None
                    },
4049
    }
4050
}
4051

4052 4053 4054 4055 4056 4057 4058 4059
/// Builds a name resolution walker to be used within this module,
/// or used externally, with an optional callback function.
///
/// The callback takes a &mut bool which allows callbacks to end a
/// walk when set to true, passing through the rest of the walk, while
/// preserving the ribs + current module. This allows resolve_path
/// calls to be made with the correct scope info. The node in the
/// callback corresponds to the current node in the walk.
G
Garming Sam 已提交
4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
                                 ast_map: &'a ast_map::Map<'tcx>,
                                 krate: &'a Crate,
                                 make_glob_map: MakeGlobMap,
                                 callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>)
                                 -> Resolver<'a, 'tcx> {
    let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);

    resolver.callback = callback;

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

    resolve_imports::resolve_imports(&mut resolver);
    session.abort_if_errors();

    record_exports::record(&mut resolver);
    session.abort_if_errors();

    resolver
}

4082
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }