1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![crate_name = "rustc_resolve"]
13 #![crate_type = "dylib"]
14 #![crate_type = "rlib"]
15 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
16 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
17 html_root_url = "http://doc.rust-lang.org/nightly/")]
19 #![feature(globs, phase, slicing_syntax)]
20 #![feature(rustc_diagnostic_macros)]
22 #[phase(plugin, link)] extern crate log;
23 #[phase(plugin, link)] extern crate syntax;
27 use self::PatternBindingMode::*;
28 use self::Namespace::*;
29 use self::NamespaceError::*;
30 use self::NamespaceResult::*;
31 use self::NameDefinition::*;
32 use self::ImportDirectiveSubclass::*;
33 use self::ReducedGraphParent::*;
34 use self::ResolveResult::*;
35 use self::FallbackSuggestion::*;
36 use self::TypeParameters::*;
38 use self::MethodSort::*;
39 use self::UseLexicalScopeFlag::*;
40 use self::ModulePrefixResult::*;
41 use self::NameSearchType::*;
42 use self::BareIdentifierPatternResolution::*;
43 use self::DuplicateCheckingMode::*;
44 use self::ParentLink::*;
45 use self::ModuleKind::*;
46 use self::TraitReferenceType::*;
47 use self::FallbackChecks::*;
49 use rustc::session::Session;
51 use rustc::metadata::csearch;
52 use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
53 use rustc::middle::def::*;
54 use rustc::middle::lang_items::LanguageItems;
55 use rustc::middle::pat_util::pat_bindings;
56 use rustc::middle::privacy::*;
57 use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
58 use rustc::middle::ty::{CaptureModeMap, Freevar, FreevarMap, TraitMap, GlobMap};
59 use rustc::util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
60 use rustc::util::lev_distance::lev_distance;
62 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
63 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
64 use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
65 use syntax::ast::{ExprPath, ExprStruct, FnDecl};
66 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
67 use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
68 use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
69 use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
70 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
71 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
72 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
73 use syntax::ast::{PolyTraitRef, PrimTy, Public, SelfExplicit, SelfStatic};
74 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
75 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
76 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
77 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt, TyObjectSum};
78 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyPolyTraitRef, TyQPath};
79 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
80 use syntax::ast::{TypeImplItem, UnnamedField};
81 use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
82 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
83 use syntax::ast::{Visibility};
86 use syntax::ast_util::{mod, PostExpansionMethod, local_def, walk_pat};
87 use syntax::attr::AttrMetaMethods;
88 use syntax::ext::mtwt;
89 use syntax::parse::token::{mod, special_names, special_idents};
90 use syntax::codemap::{Span, DUMMY_SP, Pos};
91 use syntax::owned_slice::OwnedSlice;
92 use syntax::visit::{mod, Visitor};
94 use std::collections::{HashMap, HashSet};
95 use std::collections::hash_map::Entry::{Occupied, Vacant};
96 use std::cell::{Cell, RefCell};
97 use std::mem::replace;
98 use std::rc::{Rc, Weak};
107 binding_mode: BindingMode,
110 // Map from the name in a pattern to its binding mode.
111 type BindingMap = HashMap<Name, BindingInfo>;
113 #[deriving(Copy, PartialEq)]
114 enum PatternBindingMode {
116 LocalIrrefutableMode,
117 ArgumentIrrefutableMode,
120 #[deriving(Copy, PartialEq, Eq, Hash, Show)]
126 #[deriving(Copy, PartialEq)]
127 enum NamespaceError {
134 /// A NamespaceResult represents the result of resolving an import in
135 /// a particular namespace. The result is either definitely-resolved,
136 /// definitely- unresolved, or unknown.
138 enum NamespaceResult {
139 /// Means that resolve hasn't gathered enough information yet to determine
140 /// whether the name is bound in this namespace. (That is, it hasn't
141 /// resolved all `use` directives yet.)
143 /// Means that resolve has determined that the name is definitely
144 /// not bound in the namespace.
146 /// Means that resolve has determined that the name is bound in the Module
147 /// argument, and specified by the NameBindings argument.
148 BoundResult(Rc<Module>, Rc<NameBindings>)
151 impl NamespaceResult {
152 fn is_unknown(&self) -> bool {
154 UnknownResult => true,
158 fn is_unbound(&self) -> bool {
160 UnboundResult => true,
166 enum NameDefinition {
167 NoNameDefinition, //< The name was unbound.
168 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
169 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
172 impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
173 fn visit_item(&mut self, item: &Item) {
174 self.resolve_item(item);
176 fn visit_arm(&mut self, arm: &Arm) {
177 self.resolve_arm(arm);
179 fn visit_block(&mut self, block: &Block) {
180 self.resolve_block(block);
182 fn visit_expr(&mut self, expr: &Expr) {
183 self.resolve_expr(expr);
185 fn visit_local(&mut self, local: &Local) {
186 self.resolve_local(local);
188 fn visit_ty(&mut self, ty: &Ty) {
189 self.resolve_type(ty);
193 /// Contains data for specific types of import directives.
195 enum ImportDirectiveSubclass {
196 SingleImport(Name /* target */, Name /* source */),
200 /// The context that we thread through while building the reduced graph.
202 enum ReducedGraphParent {
203 ModuleReducedGraphParent(Rc<Module>)
206 impl ReducedGraphParent {
207 fn module(&self) -> Rc<Module> {
209 ModuleReducedGraphParent(ref m) => {
216 type ErrorMessage = Option<(Span, String)>;
218 enum ResolveResult<T> {
219 Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
220 Indeterminate, // Couldn't determine due to unresolved globs.
221 Success(T) // Successfully resolved the import.
224 impl<T> ResolveResult<T> {
225 fn indeterminate(&self) -> bool {
226 match *self { Indeterminate => true, _ => false }
230 enum FallbackSuggestion {
235 StaticMethod(String),
240 enum TypeParameters<'a> {
246 // Identifies the things that these parameters
247 // were declared on (type, fn, etc)
250 // ID of the enclosing item.
253 // The kind of the rib used for type parameters.
257 // The rib kind controls the translation of local
258 // definitions (`DefLocal`) to upvars (`DefUpvar`).
259 #[deriving(Copy, Show)]
261 // No translation needs to be applied.
264 // We passed through a closure scope at the given node ID.
265 // Translate upvars as appropriate.
266 ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
268 // We passed through an impl or trait and are now in one of its
269 // methods. Allow references to ty params that impl or trait
270 // binds. Disallow any other upvars (including other ty params that are
272 // parent; method itself
273 MethodRibKind(NodeId, MethodSort),
275 // We passed through an item scope. Disallow upvars.
278 // We're in a constant item. Can't refer to dynamic stuff.
282 // Methods can be required or provided. RequiredMethod methods only occur in traits.
283 #[deriving(Copy, Show)]
286 ProvidedMethod(NodeId)
290 enum UseLexicalScopeFlag {
295 enum ModulePrefixResult {
297 PrefixFound(Rc<Module>, uint)
300 #[deriving(Copy, PartialEq)]
301 enum NameSearchType {
302 /// We're doing a name search in order to resolve a `use` directive.
305 /// We're doing a name search in order to resolve a path type, a path
306 /// expression, or a path pattern.
311 enum BareIdentifierPatternResolution {
312 FoundStructOrEnumVariant(Def, LastPrivate),
313 FoundConst(Def, LastPrivate),
314 BareIdentifierPatternUnresolved
317 // Specifies how duplicates should be handled when adding a child item if
318 // another item exists with the same name in some namespace.
319 #[deriving(Copy, PartialEq)]
320 enum DuplicateCheckingMode {
321 ForbidDuplicateModules,
322 ForbidDuplicateTypesAndModules,
323 ForbidDuplicateValues,
324 ForbidDuplicateTypesAndValues,
331 bindings: HashMap<Name, DefLike>,
336 fn new(kind: RibKind) -> Rib {
338 bindings: HashMap::new(),
344 /// Whether an import can be shadowed by another import.
345 #[deriving(Show,PartialEq,Clone,Copy)]
348 /// Means that the recorded import obeys the glob shadowing rules, i.e., can
349 /// only be shadowed by another glob import.
354 /// One import directive.
355 struct ImportDirective {
356 module_path: Vec<Name>,
357 subclass: ImportDirectiveSubclass,
360 is_public: bool, // see note in ImportResolution about how to use this
361 shadowable: Shadowable,
364 impl ImportDirective {
365 fn new(module_path: Vec<Name> ,
366 subclass: ImportDirectiveSubclass,
370 shadowable: Shadowable)
373 module_path: module_path,
377 is_public: is_public,
378 shadowable: shadowable,
383 /// The item that an import resolves to.
386 target_module: Rc<Module>,
387 bindings: Rc<NameBindings>,
388 shadowable: Shadowable,
392 fn new(target_module: Rc<Module>,
393 bindings: Rc<NameBindings>,
394 shadowable: Shadowable)
397 target_module: target_module,
399 shadowable: shadowable,
404 /// An ImportResolution represents a particular `use` directive.
405 struct ImportResolution {
406 /// Whether this resolution came from a `use` or a `pub use`. Note that this
407 /// should *not* be used whenever resolution is being performed, this is
408 /// only looked at for glob imports statements currently. Privacy testing
409 /// occurs during a later phase of compilation.
412 // The number of outstanding references to this name. When this reaches
413 // zero, outside modules can count on the targets being correct. Before
414 // then, all bets are off; future imports could override this name.
415 outstanding_references: uint,
417 /// The value that this `use` directive names, if there is one.
418 value_target: Option<Target>,
419 /// The source node of the `use` directive leading to the value target
423 /// The type that this `use` directive names, if there is one.
424 type_target: Option<Target>,
425 /// The source node of the `use` directive leading to the type target
430 impl ImportResolution {
431 fn new(id: NodeId, is_public: bool) -> ImportResolution {
435 outstanding_references: 0,
438 is_public: is_public,
442 fn target_for_namespace(&self, namespace: Namespace)
445 TypeNS => self.type_target.clone(),
446 ValueNS => self.value_target.clone(),
450 fn id(&self, namespace: Namespace) -> NodeId {
452 TypeNS => self.type_id,
453 ValueNS => self.value_id,
457 fn shadowable(&self, namespace: Namespace) -> Shadowable {
458 let target = self.target_for_namespace(namespace);
459 if target.is_none() {
460 return Shadowable::Always;
463 target.unwrap().shadowable
467 /// The link from a module up to its nearest parent node.
471 ModuleParentLink(Weak<Module>, Name),
472 BlockParentLink(Weak<Module>, NodeId)
475 /// The type of module this is.
476 #[deriving(Copy, PartialEq)]
485 /// One node in the tree of modules.
487 parent_link: ParentLink,
488 def_id: Cell<Option<DefId>>,
489 kind: Cell<ModuleKind>,
492 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
493 imports: RefCell<Vec<ImportDirective>>,
495 // The external module children of this node that were declared with
497 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
499 // The anonymous children of this node. Anonymous children are pseudo-
500 // modules that are implicitly created around items contained within
503 // For example, if we have this:
511 // There will be an anonymous module created around `g` with the ID of the
512 // entry block for `f`.
513 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
515 // The status of resolving each import in this module.
516 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
518 // The number of unresolved globs that this module exports.
519 glob_count: Cell<uint>,
521 // The index of the import we're resolving.
522 resolved_import_count: Cell<uint>,
524 // Whether this module is populated. If not populated, any attempt to
525 // access the children must be preceded with a
526 // `populate_module_if_necessary` call.
527 populated: Cell<bool>,
531 fn new(parent_link: ParentLink,
532 def_id: Option<DefId>,
538 parent_link: parent_link,
539 def_id: Cell::new(def_id),
540 kind: Cell::new(kind),
541 is_public: is_public,
542 children: RefCell::new(HashMap::new()),
543 imports: RefCell::new(Vec::new()),
544 external_module_children: RefCell::new(HashMap::new()),
545 anonymous_children: RefCell::new(NodeMap::new()),
546 import_resolutions: RefCell::new(HashMap::new()),
547 glob_count: Cell::new(0),
548 resolved_import_count: Cell::new(0),
549 populated: Cell::new(!external),
553 fn all_imports_resolved(&self) -> bool {
554 self.imports.borrow().len() == self.resolved_import_count.get()
560 flags DefModifiers: u8 {
561 const PUBLIC = 0b0000_0001,
562 const IMPORTABLE = 0b0000_0010,
566 // Records a possibly-private type definition.
569 modifiers: DefModifiers, // see note in ImportResolution about how to use this
570 module_def: Option<Rc<Module>>,
571 type_def: Option<Def>,
572 type_span: Option<Span>
575 // Records a possibly-private value definition.
576 #[deriving(Clone, Copy, Show)]
578 modifiers: DefModifiers, // see note in ImportResolution about how to use this
580 value_span: Option<Span>,
583 // Records the definitions (at most one for each namespace) that a name is
585 struct NameBindings {
586 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
587 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
590 /// Ways in which a trait can be referenced
592 enum TraitReferenceType {
593 TraitImplementation, // impl SomeTrait for T { ... }
594 TraitDerivation, // trait T : SomeTrait { ... }
595 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
596 TraitObject, // Box<for<'a> SomeTrait>
597 TraitQPath, // <T as SomeTrait>::
601 fn new() -> NameBindings {
603 type_def: RefCell::new(None),
604 value_def: RefCell::new(None),
608 /// Creates a new module in this set of name bindings.
609 fn define_module(&self,
610 parent_link: ParentLink,
611 def_id: Option<DefId>,
616 // Merges the module with the existing type def or creates a new one.
617 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
618 let module_ = Rc::new(Module::new(parent_link,
623 let type_def = self.type_def.borrow().clone();
626 *self.type_def.borrow_mut() = Some(TypeNsDef {
627 modifiers: modifiers,
628 module_def: Some(module_),
634 *self.type_def.borrow_mut() = Some(TypeNsDef {
635 modifiers: modifiers,
636 module_def: Some(module_),
638 type_def: type_def.type_def
644 /// Sets the kind of the module, creating a new one if necessary.
645 fn set_module_kind(&self,
646 parent_link: ParentLink,
647 def_id: Option<DefId>,
652 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
653 let type_def = self.type_def.borrow().clone();
656 let module = Module::new(parent_link,
661 *self.type_def.borrow_mut() = Some(TypeNsDef {
662 modifiers: modifiers,
663 module_def: Some(Rc::new(module)),
669 match type_def.module_def {
671 let module = Module::new(parent_link,
676 *self.type_def.borrow_mut() = Some(TypeNsDef {
677 modifiers: modifiers,
678 module_def: Some(Rc::new(module)),
679 type_def: type_def.type_def,
683 Some(module_def) => module_def.kind.set(kind),
689 /// Records a type definition.
690 fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
691 debug!("defining type for def {} with modifiers {}", def, modifiers);
692 // Merges the type with the existing type def or creates a new one.
693 let type_def = self.type_def.borrow().clone();
696 *self.type_def.borrow_mut() = Some(TypeNsDef {
700 modifiers: modifiers,
704 *self.type_def.borrow_mut() = Some(TypeNsDef {
705 module_def: type_def.module_def,
708 modifiers: modifiers,
714 /// Records a value definition.
715 fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
716 debug!("defining value for def {} with modifiers {}", def, modifiers);
717 *self.value_def.borrow_mut() = Some(ValueNsDef {
719 value_span: Some(sp),
720 modifiers: modifiers,
724 /// Returns the module node if applicable.
725 fn get_module_if_available(&self) -> Option<Rc<Module>> {
726 match *self.type_def.borrow() {
727 Some(ref type_def) => type_def.module_def.clone(),
732 /// Returns the module node. Panics if this node does not have a module
734 fn get_module(&self) -> Rc<Module> {
735 match self.get_module_if_available() {
737 panic!("get_module called on a node with no module \
740 Some(module_def) => module_def
744 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
746 TypeNS => return self.type_def.borrow().is_some(),
747 ValueNS => return self.value_def.borrow().is_some()
751 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
752 self.defined_in_namespace_with(namespace, PUBLIC)
755 fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
757 TypeNS => match *self.type_def.borrow() {
758 Some(ref def) => def.modifiers.contains(modifiers), None => false
760 ValueNS => match *self.value_def.borrow() {
761 Some(ref def) => def.modifiers.contains(modifiers), None => false
766 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
769 match *self.type_def.borrow() {
771 Some(ref type_def) => {
772 match type_def.type_def {
773 Some(type_def) => Some(type_def),
775 match type_def.module_def {
776 Some(ref module) => {
777 match module.def_id.get() {
778 Some(did) => Some(DefMod(did)),
790 match *self.value_def.borrow() {
792 Some(value_def) => Some(value_def.def)
798 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
799 if self.defined_in_namespace(namespace) {
802 match *self.type_def.borrow() {
804 Some(ref type_def) => type_def.type_span
808 match *self.value_def.borrow() {
810 Some(ref value_def) => value_def.value_span
820 /// Interns the names of the primitive types.
821 struct PrimitiveTypeTable {
822 primitive_types: HashMap<Name, PrimTy>,
825 impl PrimitiveTypeTable {
826 fn new() -> PrimitiveTypeTable {
827 let mut table = PrimitiveTypeTable {
828 primitive_types: HashMap::new()
831 table.intern("bool", TyBool);
832 table.intern("char", TyChar);
833 table.intern("f32", TyFloat(TyF32));
834 table.intern("f64", TyFloat(TyF64));
835 table.intern("int", TyInt(TyI));
836 table.intern("i8", TyInt(TyI8));
837 table.intern("i16", TyInt(TyI16));
838 table.intern("i32", TyInt(TyI32));
839 table.intern("i64", TyInt(TyI64));
840 table.intern("str", TyStr);
841 table.intern("uint", TyUint(TyU));
842 table.intern("u8", TyUint(TyU8));
843 table.intern("u16", TyUint(TyU16));
844 table.intern("u32", TyUint(TyU32));
845 table.intern("u64", TyUint(TyU64));
850 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
851 self.primitive_types.insert(token::intern(string), primitive_type);
856 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
859 ModuleError | TypeError => "type or module",
860 ValueError => "value",
864 /// The main resolver class.
865 struct Resolver<'a, 'tcx:'a> {
866 session: &'a Session,
868 ast_map: &'a ast_map::Map<'tcx>,
870 graph_root: NameBindings,
872 trait_item_map: FnvHashMap<(Name, DefId), TraitItemKind>,
874 structs: FnvHashMap<DefId, Vec<Name>>,
876 // The number of imports that are currently unresolved.
877 unresolved_imports: uint,
879 // The module that represents the current item scope.
880 current_module: Rc<Module>,
882 // The current set of local scopes, for values.
883 // FIXME #4948: Reuse ribs to avoid allocation.
884 value_ribs: Vec<Rib>,
886 // The current set of local scopes, for types.
889 // The current set of local scopes, for labels.
890 label_ribs: Vec<Rib>,
892 // The trait that the current context can refer to.
893 current_trait_ref: Option<(DefId, TraitRef)>,
895 // The current self type if inside an impl (used for better errors).
896 current_self_type: Option<Ty>,
898 // The ident for the keyword "self".
900 // The ident for the non-keyword "Self".
901 type_self_name: Name,
903 // The idents for the primitive types.
904 primitive_type_table: PrimitiveTypeTable,
907 freevars: RefCell<FreevarMap>,
908 freevars_seen: RefCell<NodeMap<NodeSet>>,
909 capture_mode_map: CaptureModeMap,
910 export_map: ExportMap,
912 external_exports: ExternalExports,
913 last_private: LastPrivateMap,
915 // Whether or not to print error messages. Can be set to true
916 // when getting additional info for error message suggestions,
917 // so as to avoid printing duplicate errors
921 // Maps imports to the names of items actually imported (this actually maps
922 // all imports, but only glob imports are actually interesting).
925 used_imports: HashSet<(NodeId, Namespace)>,
926 used_crates: HashSet<CrateNum>,
929 struct BuildReducedGraphVisitor<'a, 'b:'a, 'tcx:'b> {
930 resolver: &'a mut Resolver<'b, 'tcx>,
931 parent: ReducedGraphParent
934 impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
936 fn visit_item(&mut self, item: &Item) {
937 let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
938 let old_parent = replace(&mut self.parent, p);
939 visit::walk_item(self, item);
940 self.parent = old_parent;
943 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
944 let parent = self.parent.clone();
945 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
948 let mut v = BuildReducedGraphVisitor {
950 parent: parent.clone()
952 visit::walk_foreign_item(&mut v, foreign_item);
956 fn visit_view_item(&mut self, view_item: &ViewItem) {
957 self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
960 fn visit_block(&mut self, block: &Block) {
961 let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
962 let old_parent = replace(&mut self.parent, np);
963 visit::walk_block(self, block);
964 self.parent = old_parent;
969 #[deriving(PartialEq)]
970 enum FallbackChecks {
976 impl<'a, 'tcx> Resolver<'a, 'tcx> {
977 fn new(session: &'a Session,
978 ast_map: &'a ast_map::Map<'tcx>,
980 make_glob_map: MakeGlobMap) -> Resolver<'a, 'tcx> {
981 let graph_root = NameBindings::new();
983 graph_root.define_module(NoParentLink,
984 Some(DefId { krate: 0, node: 0 }),
990 let current_module = graph_root.get_module();
997 // The outermost module has def ID 0; this is not reflected in the
1000 graph_root: graph_root,
1002 trait_item_map: FnvHashMap::new(),
1003 structs: FnvHashMap::new(),
1005 unresolved_imports: 0,
1007 current_module: current_module,
1008 value_ribs: Vec::new(),
1009 type_ribs: Vec::new(),
1010 label_ribs: Vec::new(),
1012 current_trait_ref: None,
1013 current_self_type: None,
1015 self_name: special_names::self_,
1016 type_self_name: special_names::type_self,
1018 primitive_type_table: PrimitiveTypeTable::new(),
1020 def_map: RefCell::new(NodeMap::new()),
1021 freevars: RefCell::new(NodeMap::new()),
1022 freevars_seen: RefCell::new(NodeMap::new()),
1023 capture_mode_map: NodeMap::new(),
1024 export_map: NodeMap::new(),
1025 trait_map: NodeMap::new(),
1026 used_imports: HashSet::new(),
1027 used_crates: HashSet::new(),
1028 external_exports: DefIdSet::new(),
1029 last_private: NodeMap::new(),
1032 make_glob_map: make_glob_map == MakeGlobMap::Yes,
1033 glob_map: HashMap::new(),
1038 // Reduced graph building
1040 // Here we build the "reduced graph": the graph of the module tree without
1041 // any imports resolved.
1044 /// Constructs the reduced graph for the entire crate.
1045 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1046 let parent = ModuleReducedGraphParent(self.graph_root.get_module());
1047 let mut visitor = BuildReducedGraphVisitor {
1051 visit::walk_crate(&mut visitor, krate);
1054 /// Adds a new child item to the module definition of the parent node and
1055 /// returns its corresponding name bindings as well as the current parent.
1056 /// Or, if we're inside a block, creates (or reuses) an anonymous module
1057 /// corresponding to the innermost block ID and returns the name bindings
1058 /// as well as the newly-created parent.
1062 /// Panics if this node does not have a module definition and we are not inside
1066 reduced_graph_parent: ReducedGraphParent,
1067 duplicate_checking_mode: DuplicateCheckingMode,
1068 // For printing errors
1070 -> Rc<NameBindings> {
1071 // If this is the immediate descendant of a module, then we add the
1072 // child name directly. Otherwise, we create or reuse an anonymous
1073 // module and add the child to that.
1075 let module_ = reduced_graph_parent.module();
1077 self.check_for_conflicts_between_external_crates_and_items(&*module_,
1081 // Add or reuse the child.
1082 let child = module_.children.borrow().get(&name).cloned();
1085 let child = Rc::new(NameBindings::new());
1086 module_.children.borrow_mut().insert(name, child.clone());
1090 // Enforce the duplicate checking mode:
1092 // * If we're requesting duplicate module checking, check that
1093 // there isn't a module in the module with the same name.
1095 // * If we're requesting duplicate type checking, check that
1096 // there isn't a type in the module with the same name.
1098 // * If we're requesting duplicate value checking, check that
1099 // there isn't a value in the module with the same name.
1101 // * If we're requesting duplicate type checking and duplicate
1102 // value checking, check that there isn't a duplicate type
1103 // and a duplicate value with the same name.
1105 // * If no duplicate checking was requested at all, do
1108 let mut duplicate_type = NoError;
1109 let ns = match duplicate_checking_mode {
1110 ForbidDuplicateModules => {
1111 if child.get_module_if_available().is_some() {
1112 duplicate_type = ModuleError;
1116 ForbidDuplicateTypesAndModules => {
1117 match child.def_for_namespace(TypeNS) {
1119 Some(_) if child.get_module_if_available()
1120 .map(|m| m.kind.get()) ==
1121 Some(ImplModuleKind) => {}
1122 Some(_) => duplicate_type = TypeError
1126 ForbidDuplicateValues => {
1127 if child.defined_in_namespace(ValueNS) {
1128 duplicate_type = ValueError;
1132 ForbidDuplicateTypesAndValues => {
1134 match child.def_for_namespace(TypeNS) {
1135 Some(DefMod(_)) | None => {}
1138 duplicate_type = TypeError;
1141 if child.defined_in_namespace(ValueNS) {
1142 duplicate_type = ValueError;
1147 OverwriteDuplicates => None
1149 if duplicate_type != NoError {
1150 // Return an error here by looking up the namespace that
1151 // had the duplicate.
1152 let ns = ns.unwrap();
1153 self.resolve_error(sp,
1154 format!("duplicate definition of {} `{}`",
1155 namespace_error_to_string(duplicate_type),
1156 token::get_name(name))[]);
1158 let r = child.span_for_namespace(ns);
1159 for sp in r.iter() {
1160 self.session.span_note(*sp,
1161 format!("first definition of {} `{}` here",
1162 namespace_error_to_string(duplicate_type),
1163 token::get_name(name))[]);
1172 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1173 // If the block has view items, we need an anonymous module.
1174 if block.view_items.len() > 0 {
1178 // Check each statement.
1179 for statement in block.stmts.iter() {
1180 match statement.node {
1181 StmtDecl(ref declaration, _) => {
1182 match declaration.node {
1197 // If we found neither view items nor items, we don't need to create
1198 // an anonymous module.
1203 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Name)
1206 ModuleReducedGraphParent(module_) => {
1207 return ModuleParentLink(module_.downgrade(), name);
1212 /// Constructs the reduced graph for one item.
1213 fn build_reduced_graph_for_item(&mut self,
1215 parent: ReducedGraphParent)
1216 -> ReducedGraphParent
1218 let name = item.ident.name;
1220 let is_public = item.vis == ast::Public;
1221 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1226 self.add_child(name, parent.clone(), ForbidDuplicateModules, sp);
1228 let parent_link = self.get_parent_link(parent, name);
1229 let def_id = DefId { krate: 0, node: item.id };
1230 name_bindings.define_module(parent_link,
1234 item.vis == ast::Public,
1237 ModuleReducedGraphParent(name_bindings.get_module())
1240 ItemForeignMod(..) => parent,
1242 // These items live in the value namespace.
1243 ItemStatic(_, m, _) => {
1245 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1246 let mutbl = m == ast::MutMutable;
1248 name_bindings.define_value
1249 (DefStatic(local_def(item.id), mutbl), sp, modifiers);
1252 ItemConst(_, _) => {
1253 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
1254 .define_value(DefConst(local_def(item.id)),
1258 ItemFn(_, _, _, _, _) => {
1260 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
1262 let def = DefFn(local_def(item.id), false);
1263 name_bindings.define_value(def, sp, modifiers);
1267 // These items live in the type namespace.
1270 self.add_child(name,
1272 ForbidDuplicateTypesAndModules,
1275 name_bindings.define_type
1276 (DefTy(local_def(item.id), false), sp, modifiers);
1280 ItemEnum(ref enum_definition, _) => {
1282 self.add_child(name,
1284 ForbidDuplicateTypesAndModules,
1287 name_bindings.define_type
1288 (DefTy(local_def(item.id), true), sp, modifiers);
1290 let parent_link = self.get_parent_link(parent.clone(), name);
1291 // We want to make sure the module type is EnumModuleKind
1292 // even if there's already an ImplModuleKind module defined,
1293 // since that's how we prevent duplicate enum definitions
1294 name_bindings.set_module_kind(parent_link,
1295 Some(local_def(item.id)),
1301 for variant in (*enum_definition).variants.iter() {
1302 self.build_reduced_graph_for_variant(
1305 ModuleReducedGraphParent(name_bindings.get_module()));
1310 // These items live in both the type and value namespaces.
1311 ItemStruct(ref struct_def, _) => {
1312 // Adding to both Type and Value namespaces or just Type?
1313 let (forbid, ctor_id) = match struct_def.ctor_id {
1314 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1315 None => (ForbidDuplicateTypesAndModules, None)
1318 let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
1320 // Define a name in the type namespace.
1321 name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
1323 // If this is a newtype or unit-like struct, define a name
1324 // in the value namespace as well
1327 name_bindings.define_value(DefStruct(local_def(cid)),
1333 // Record the def ID and fields of this struct.
1334 let named_fields = struct_def.fields.iter().filter_map(|f| {
1336 NamedField(ident, _) => Some(ident.name),
1337 UnnamedField(_) => None
1340 self.structs.insert(local_def(item.id), named_fields);
1345 ItemImpl(_, _, None, ref ty, ref impl_items) => {
1346 // If this implements an anonymous trait, then add all the
1347 // methods within to a new module, if the type was defined
1348 // within this module.
1350 let mod_name = match ty.node {
1351 TyPath(ref path, _) if path.segments.len() == 1 => {
1352 // FIXME(18446) we should distinguish between the name of
1353 // a trait and the name of an impl of that trait.
1354 Some(path.segments.last().unwrap().identifier.name)
1356 TyObjectSum(ref lhs_ty, _) => {
1358 TyPath(ref path, _) if path.segments.len() == 1 => {
1359 Some(path.segments.last().unwrap().identifier.name)
1373 self.resolve_error(ty.span,
1374 "inherent implementations may \
1375 only be implemented in the same \
1376 module as the type they are \
1380 // Create the module and add all methods.
1381 let parent_opt = parent.module().children.borrow()
1382 .get(&mod_name).cloned();
1383 let new_parent = match parent_opt {
1384 // It already exists
1385 Some(ref child) if child.get_module_if_available()
1387 (child.get_module().kind.get() == ImplModuleKind ||
1388 child.get_module().kind.get() == TraitModuleKind) => {
1389 ModuleReducedGraphParent(child.get_module())
1391 Some(ref child) if child.get_module_if_available()
1393 child.get_module().kind.get() ==
1395 ModuleReducedGraphParent(child.get_module())
1397 // Create the module
1400 self.add_child(mod_name,
1402 ForbidDuplicateModules,
1406 self.get_parent_link(parent.clone(), name);
1407 let def_id = local_def(item.id);
1410 !name_bindings.defined_in_namespace(ns) ||
1411 name_bindings.defined_in_public_namespace(ns);
1413 name_bindings.define_module(parent_link,
1420 ModuleReducedGraphParent(
1421 name_bindings.get_module())
1425 // For each implementation item...
1426 for impl_item in impl_items.iter() {
1428 MethodImplItem(ref method) => {
1429 // Add the method to the module.
1430 let name = method.pe_ident().name;
1431 let method_name_bindings =
1432 self.add_child(name,
1434 ForbidDuplicateValues,
1436 let def = match method.pe_explicit_self()
1439 // Static methods become
1440 // `DefStaticMethod`s.
1441 DefStaticMethod(local_def(method.id),
1442 FromImpl(local_def(item.id)))
1445 // Non-static methods become
1447 DefMethod(local_def(method.id),
1449 FromImpl(local_def(item.id)))
1453 // NB: not IMPORTABLE
1454 let modifiers = if method.pe_vis() == ast::Public {
1457 DefModifiers::empty()
1459 method_name_bindings.define_value(
1464 TypeImplItem(ref typedef) => {
1465 // Add the typedef to the module.
1466 let name = typedef.ident.name;
1467 let typedef_name_bindings =
1471 ForbidDuplicateTypesAndModules,
1473 let def = DefAssociatedTy(local_def(
1475 // NB: not IMPORTABLE
1476 let modifiers = if typedef.vis == ast::Public {
1479 DefModifiers::empty()
1481 typedef_name_bindings.define_type(
1494 ItemImpl(_, _, Some(_), _, _) => parent,
1496 ItemTrait(_, _, _, ref items) => {
1498 self.add_child(name,
1500 ForbidDuplicateTypesAndModules,
1503 // Add all the items within to a new module.
1504 let parent_link = self.get_parent_link(parent.clone(), name);
1505 name_bindings.define_module(parent_link,
1506 Some(local_def(item.id)),
1509 item.vis == ast::Public,
1511 let module_parent = ModuleReducedGraphParent(name_bindings.
1514 let def_id = local_def(item.id);
1516 // Add the names of all the items to the trait info.
1517 for trait_item in items.iter() {
1518 let (name, kind) = match *trait_item {
1519 ast::RequiredMethod(_) |
1520 ast::ProvidedMethod(_) => {
1521 let ty_m = ast_util::trait_item_to_ty_method(trait_item);
1523 let name = ty_m.ident.name;
1525 // Add it as a name in the trait module.
1526 let (def, static_flag) = match ty_m.explicit_self
1529 // Static methods become `DefStaticMethod`s.
1532 FromTrait(local_def(item.id))),
1533 StaticMethodTraitItemKind)
1536 // Non-static methods become `DefMethod`s.
1537 (DefMethod(local_def(ty_m.id),
1538 Some(local_def(item.id)),
1539 FromTrait(local_def(item.id))),
1540 NonstaticMethodTraitItemKind)
1544 let method_name_bindings =
1545 self.add_child(name,
1546 module_parent.clone(),
1547 ForbidDuplicateTypesAndValues,
1549 // NB: not IMPORTABLE
1550 method_name_bindings.define_value(def,
1556 ast::TypeTraitItem(ref associated_type) => {
1557 let def = DefAssociatedTy(local_def(
1558 associated_type.ty_param.id));
1561 self.add_child(associated_type.ty_param.ident.name,
1562 module_parent.clone(),
1563 ForbidDuplicateTypesAndValues,
1564 associated_type.ty_param.span);
1565 // NB: not IMPORTABLE
1566 name_bindings.define_type(def,
1567 associated_type.ty_param.span,
1570 (associated_type.ty_param.ident.name, TypeTraitItemKind)
1574 self.trait_item_map.insert((name, def_id), kind);
1577 name_bindings.define_type(DefTrait(def_id), sp, modifiers);
1580 ItemMac(..) => parent
1584 // Constructs the reduced graph for one variant. Variants exist in the
1585 // type and value namespaces.
1586 fn build_reduced_graph_for_variant(&mut self,
1589 parent: ReducedGraphParent) {
1590 let name = variant.node.name.name;
1591 let is_exported = match variant.node.kind {
1592 TupleVariantKind(_) => false,
1593 StructVariantKind(_) => {
1594 // Not adding fields for variants as they are not accessed with a self receiver
1595 self.structs.insert(local_def(variant.node.id), Vec::new());
1600 let child = self.add_child(name, parent,
1601 ForbidDuplicateTypesAndValues,
1603 // variants are always treated as importable to allow them to be glob
1605 child.define_value(DefVariant(item_id,
1606 local_def(variant.node.id), is_exported),
1607 variant.span, PUBLIC | IMPORTABLE);
1608 child.define_type(DefVariant(item_id,
1609 local_def(variant.node.id), is_exported),
1610 variant.span, PUBLIC | IMPORTABLE);
1613 /// Constructs the reduced graph for one 'view item'. View items consist
1614 /// of imports and use directives.
1615 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1616 parent: ReducedGraphParent) {
1617 match view_item.node {
1618 ViewItemUse(ref view_path) => {
1619 // Extract and intern the module part of the path. For
1620 // globs and lists, the path is found directly in the AST;
1621 // for simple paths we have to munge the path a little.
1622 let module_path = match view_path.node {
1623 ViewPathSimple(_, ref full_path, _) => {
1626 .iter().map(|ident| ident.identifier.name)
1630 ViewPathGlob(ref module_ident_path, _) |
1631 ViewPathList(ref module_ident_path, _, _) => {
1632 module_ident_path.segments
1633 .iter().map(|ident| ident.identifier.name).collect()
1637 // Build up the import directives.
1638 let module_ = parent.module();
1639 let is_public = view_item.vis == ast::Public;
1644 attr.name() == token::get_name(
1645 special_idents::prelude_import.name)
1647 let shadowable = if shadowable {
1653 match view_path.node {
1654 ViewPathSimple(binding, ref full_path, id) => {
1656 full_path.segments.last().unwrap().identifier.name;
1657 if token::get_name(source_name).get() == "mod" {
1658 self.resolve_error(view_path.span,
1659 "`mod` imports are only allowed within a { } list");
1662 let subclass = SingleImport(binding.name,
1664 self.build_import_directive(&*module_,
1672 ViewPathList(_, ref source_items, _) => {
1673 // Make sure there's at most one `mod` import in the list.
1674 let mod_spans = source_items.iter().filter_map(|item| match item.node {
1675 PathListMod { .. } => Some(item.span),
1677 }).collect::<Vec<Span>>();
1678 if mod_spans.len() > 1 {
1679 self.resolve_error(mod_spans[0],
1680 "`mod` import can only appear once in the list");
1681 for other_span in mod_spans.iter().skip(1) {
1682 self.session.span_note(*other_span,
1683 "another `mod` import appears here");
1687 for source_item in source_items.iter() {
1688 let (module_path, name) = match source_item.node {
1689 PathListIdent { name, .. } =>
1690 (module_path.clone(), name.name),
1691 PathListMod { .. } => {
1692 let name = match module_path.last() {
1693 Some(name) => *name,
1695 self.resolve_error(source_item.span,
1696 "`mod` import can only appear in an import list \
1697 with a non-empty prefix");
1701 let module_path = module_path.init();
1702 (module_path.to_vec(), name)
1705 self.build_import_directive(
1708 SingleImport(name, name),
1710 source_item.node.id(),
1715 ViewPathGlob(_, id) => {
1716 self.build_import_directive(&*module_,
1722 if shadowable == Shadowable::Never {
1731 ViewItemExternCrate(name, _, node_id) => {
1732 // n.b. we don't need to look at the path option here, because cstore already did
1733 for &crate_id in self.session.cstore
1734 .find_extern_mod_stmt_cnum(node_id).iter() {
1735 let def_id = DefId { krate: crate_id, node: 0 };
1736 self.external_exports.insert(def_id);
1738 ModuleParentLink(parent.module().downgrade(), name.name);
1739 let external_module = Rc::new(Module::new(parent_link,
1744 debug!("(build reduced graph for item) found extern `{}`",
1745 self.module_to_string(&*external_module));
1746 self.check_for_conflicts_between_external_crates(
1750 parent.module().external_module_children.borrow_mut()
1751 .insert(name.name, external_module.clone());
1752 self.build_reduced_graph_for_external_crate(external_module);
1758 /// Constructs the reduced graph for one foreign item.
1759 fn build_reduced_graph_for_foreign_item<F>(&mut self,
1760 foreign_item: &ForeignItem,
1761 parent: ReducedGraphParent,
1763 F: FnOnce(&mut Resolver),
1765 let name = foreign_item.ident.name;
1766 let is_public = foreign_item.vis == ast::Public;
1767 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1769 self.add_child(name, parent, ForbidDuplicateValues,
1772 match foreign_item.node {
1773 ForeignItemFn(_, ref generics) => {
1774 let def = DefFn(local_def(foreign_item.id), false);
1775 name_bindings.define_value(def, foreign_item.span, modifiers);
1777 self.with_type_parameter_rib(
1778 HasTypeParameters(generics,
1784 ForeignItemStatic(_, m) => {
1785 let def = DefStatic(local_def(foreign_item.id), m);
1786 name_bindings.define_value(def, foreign_item.span, modifiers);
1793 fn build_reduced_graph_for_block(&mut self,
1795 parent: ReducedGraphParent)
1796 -> ReducedGraphParent
1798 if self.block_needs_anonymous_module(block) {
1799 let block_id = block.id;
1801 debug!("(building reduced graph for block) creating a new \
1802 anonymous module for block {}",
1805 let parent_module = parent.module();
1806 let new_module = Rc::new(Module::new(
1807 BlockParentLink(parent_module.downgrade(), block_id),
1809 AnonymousModuleKind,
1812 parent_module.anonymous_children.borrow_mut()
1813 .insert(block_id, new_module.clone());
1814 ModuleReducedGraphParent(new_module)
1820 fn handle_external_def(&mut self,
1823 child_name_bindings: &NameBindings,
1826 new_parent: ReducedGraphParent) {
1827 debug!("(building reduced graph for \
1828 external crate) building external def, priv {}",
1830 let is_public = vis == ast::Public;
1831 let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
1832 let is_exported = is_public && match new_parent {
1833 ModuleReducedGraphParent(ref module) => {
1834 match module.def_id.get() {
1836 Some(did) => self.external_exports.contains(&did)
1841 self.external_exports.insert(def.def_id());
1844 let kind = match def {
1845 DefTy(_, true) => EnumModuleKind,
1846 DefStruct(..) | DefTy(..) => ImplModuleKind,
1847 _ => NormalModuleKind
1851 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1852 DefTy(def_id, _) => {
1853 let type_def = child_name_bindings.type_def.borrow().clone();
1855 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1856 debug!("(building reduced graph for external crate) \
1857 already created module");
1858 module_def.def_id.set(Some(def_id));
1861 debug!("(building reduced graph for \
1862 external crate) building module \
1864 let parent_link = self.get_parent_link(new_parent.clone(), name);
1866 child_name_bindings.define_module(parent_link,
1879 DefMod(_) | DefForeignMod(_) => {}
1880 DefVariant(_, variant_id, is_struct) => {
1881 debug!("(building reduced graph for external crate) building \
1884 // variants are always treated as importable to allow them to be
1886 let modifiers = PUBLIC | IMPORTABLE;
1888 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1889 // Not adding fields for variants as they are not accessed with a self receiver
1890 self.structs.insert(variant_id, Vec::new());
1892 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1895 DefFn(ctor_id, true) => {
1896 child_name_bindings.define_value(
1897 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
1898 .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
1900 DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) | DefMethod(..) => {
1901 debug!("(building reduced graph for external \
1902 crate) building value (fn/static) {}", final_ident);
1903 // impl methods have already been defined with the correct importability modifier
1904 let mut modifiers = match *child_name_bindings.value_def.borrow() {
1905 Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
1908 if new_parent.module().kind.get() != NormalModuleKind {
1909 modifiers = modifiers & !IMPORTABLE;
1911 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1913 DefTrait(def_id) => {
1914 debug!("(building reduced graph for external \
1915 crate) building type {}", final_ident);
1917 // If this is a trait, add all the trait item names to the trait
1920 let trait_item_def_ids =
1921 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1922 for trait_item_def_id in trait_item_def_ids.iter() {
1923 let (trait_item_name, trait_item_kind) =
1924 csearch::get_trait_item_name_and_kind(
1925 &self.session.cstore,
1926 trait_item_def_id.def_id());
1928 debug!("(building reduced graph for external crate) ... \
1929 adding trait item '{}'",
1930 token::get_name(trait_item_name));
1932 self.trait_item_map.insert((trait_item_name, def_id), trait_item_kind);
1935 self.external_exports
1936 .insert(trait_item_def_id.def_id());
1940 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1942 // Define a module if necessary.
1943 let parent_link = self.get_parent_link(new_parent, name);
1944 child_name_bindings.set_module_kind(parent_link,
1951 DefTy(..) | DefAssociatedTy(..) | DefAssociatedPath(..) => {
1952 debug!("(building reduced graph for external \
1953 crate) building type {}", final_ident);
1955 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1957 DefStruct(def_id) => {
1958 debug!("(building reduced graph for external \
1959 crate) building type and value for {}",
1961 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
1962 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
1964 }).collect::<Vec<_>>();
1966 if fields.len() == 0 {
1967 child_name_bindings.define_value(def, DUMMY_SP, modifiers);
1970 // Record the def ID and fields of this struct.
1971 self.structs.insert(def_id, fields);
1973 DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
1974 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1975 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1976 panic!("didn't expect `{}`", def);
1981 /// Builds the reduced graph for a single item in an external crate.
1982 fn build_reduced_graph_for_external_crate_def(&mut self,
1986 visibility: Visibility) {
1989 // Add the new child item, if necessary.
1991 DefForeignMod(def_id) => {
1992 // Foreign modules have no names. Recur and populate
1994 csearch::each_child_of_item(&self.session.cstore,
1999 self.build_reduced_graph_for_external_crate_def(
2007 let child_name_bindings =
2008 self.add_child(name,
2009 ModuleReducedGraphParent(root.clone()),
2010 OverwriteDuplicates,
2013 self.handle_external_def(def,
2015 &*child_name_bindings,
2016 token::get_name(name).get(),
2018 ModuleReducedGraphParent(root));
2023 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
2025 Some(final_name) => {
2027 csearch::get_methods_if_impl(&self.session.cstore, def);
2029 Some(ref methods) if
2030 methods.len() >= 1 => {
2031 debug!("(building reduced graph for \
2032 external crate) processing \
2033 static methods for type name {}",
2034 token::get_name(final_name));
2036 let child_name_bindings =
2039 ModuleReducedGraphParent(root.clone()),
2040 OverwriteDuplicates,
2043 // Process the static methods. First,
2044 // create the module.
2046 let type_def = child_name_bindings.type_def.borrow().clone();
2049 module_def: Some(module_def),
2052 // We already have a module. This
2054 type_module = module_def;
2056 // Mark it as an impl module if
2058 type_module.kind.set(ImplModuleKind);
2062 self.get_parent_link(ModuleReducedGraphParent(root),
2064 child_name_bindings.define_module(
2072 child_name_bindings.
2077 // Add each static method to the module.
2079 ModuleReducedGraphParent(type_module);
2080 for method_info in methods.iter() {
2081 let name = method_info.name;
2082 debug!("(building reduced graph for \
2083 external crate) creating \
2084 static method '{}'",
2085 token::get_name(name));
2087 let method_name_bindings =
2088 self.add_child(name,
2090 OverwriteDuplicates,
2092 let def = DefFn(method_info.def_id, false);
2094 // NB: not IMPORTABLE
2095 let modifiers = if visibility == ast::Public {
2098 DefModifiers::empty()
2100 method_name_bindings.define_value(
2101 def, DUMMY_SP, modifiers);
2105 // Otherwise, do nothing.
2106 Some(_) | None => {}
2112 debug!("(building reduced graph for external crate) \
2118 /// Builds the reduced graph rooted at the given external module.
2119 fn populate_external_module(&mut self, module: Rc<Module>) {
2120 debug!("(populating external module) attempting to populate {}",
2121 self.module_to_string(&*module));
2123 let def_id = match module.def_id.get() {
2125 debug!("(populating external module) ... no def ID!");
2128 Some(def_id) => def_id,
2131 csearch::each_child_of_item(&self.session.cstore,
2133 |def_like, child_name, visibility| {
2134 debug!("(populating external module) ... found ident: {}",
2135 token::get_name(child_name));
2136 self.build_reduced_graph_for_external_crate_def(module.clone(),
2141 module.populated.set(true)
2144 /// Ensures that the reduced graph rooted at the given external module
2145 /// is built, building it if it is not.
2146 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2147 if !module.populated.get() {
2148 self.populate_external_module(module.clone())
2150 assert!(module.populated.get())
2153 /// Builds the reduced graph rooted at the 'use' directive for an external
2155 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2156 csearch::each_top_level_item_of_crate(&self.session.cstore,
2161 |def_like, name, visibility| {
2162 self.build_reduced_graph_for_external_crate_def(root.clone(),
2169 /// Creates and adds an import directive to the given module.
2170 fn build_import_directive(&mut self,
2172 module_path: Vec<Name>,
2173 subclass: ImportDirectiveSubclass,
2177 shadowable: Shadowable) {
2178 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2184 self.unresolved_imports += 1;
2185 // Bump the reference count on the name. Or, if this is a glob, set
2186 // the appropriate flag.
2189 SingleImport(target, _) => {
2190 debug!("(building import directive) building import \
2192 self.names_to_string(module_.imports.borrow().last().unwrap()
2194 token::get_name(target));
2196 let mut import_resolutions = module_.import_resolutions
2198 match import_resolutions.get_mut(&target) {
2199 Some(resolution) => {
2200 debug!("(building import directive) bumping \
2202 resolution.outstanding_references += 1;
2204 // the source of this name is different now
2205 resolution.type_id = id;
2206 resolution.value_id = id;
2207 resolution.is_public = is_public;
2212 debug!("(building import directive) creating new");
2213 let mut resolution = ImportResolution::new(id, is_public);
2214 resolution.outstanding_references = 1;
2215 import_resolutions.insert(target, resolution);
2218 // Set the glob flag. This tells us that we don't know the
2219 // module's exports ahead of time.
2221 module_.glob_count.set(module_.glob_count.get() + 1);
2226 // Import resolution
2228 // This is a fixed-point algorithm. We resolve imports until our efforts
2229 // are stymied by an unresolved import; then we bail out of the current
2230 // module and continue. We terminate successfully once no more imports
2231 // remain or unsuccessfully when no forward progress in resolving imports
2234 /// Resolves all imports for the crate. This method performs the fixed-
2235 /// point iteration.
2236 fn resolve_imports(&mut self) {
2238 let mut prev_unresolved_imports = 0;
2240 debug!("(resolving imports) iteration {}, {} imports left",
2241 i, self.unresolved_imports);
2243 let module_root = self.graph_root.get_module();
2244 self.resolve_imports_for_module_subtree(module_root.clone());
2246 if self.unresolved_imports == 0 {
2247 debug!("(resolving imports) success");
2251 if self.unresolved_imports == prev_unresolved_imports {
2252 self.report_unresolved_imports(module_root);
2257 prev_unresolved_imports = self.unresolved_imports;
2261 /// Attempts to resolve imports for the given module and all of its
2263 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2264 debug!("(resolving imports for module subtree) resolving {}",
2265 self.module_to_string(&*module_));
2266 let orig_module = replace(&mut self.current_module, module_.clone());
2267 self.resolve_imports_for_module(module_.clone());
2268 self.current_module = orig_module;
2270 self.populate_module_if_necessary(&module_);
2271 for (_, child_node) in module_.children.borrow().iter() {
2272 match child_node.get_module_if_available() {
2276 Some(child_module) => {
2277 self.resolve_imports_for_module_subtree(child_module);
2282 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2283 self.resolve_imports_for_module_subtree(child_module.clone());
2287 /// Attempts to resolve imports for the given module only.
2288 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2289 if module.all_imports_resolved() {
2290 debug!("(resolving imports for module) all imports resolved for \
2292 self.module_to_string(&*module));
2296 let imports = module.imports.borrow();
2297 let import_count = imports.len();
2298 while module.resolved_import_count.get() < import_count {
2299 let import_index = module.resolved_import_count.get();
2300 let import_directive = &(*imports)[import_index];
2301 match self.resolve_import_for_module(module.clone(),
2304 let (span, help) = match err {
2305 Some((span, msg)) => (span, format!(". {}", msg)),
2306 None => (import_directive.span, String::new())
2308 let msg = format!("unresolved import `{}`{}",
2309 self.import_path_to_string(
2310 import_directive.module_path
2312 import_directive.subclass),
2314 self.resolve_error(span, msg[]);
2316 Indeterminate => break, // Bail out. We'll come around next time.
2317 Success(()) => () // Good. Continue.
2320 module.resolved_import_count
2321 .set(module.resolved_import_count.get() + 1);
2325 fn names_to_string(&self, names: &[Name]) -> String {
2326 let mut first = true;
2327 let mut result = String::new();
2328 for name in names.iter() {
2332 result.push_str("::")
2334 result.push_str(token::get_name(*name).get());
2339 fn path_names_to_string(&self, path: &Path) -> String {
2340 let names: Vec<ast::Name> = path.segments
2342 .map(|seg| seg.identifier.name)
2344 self.names_to_string(names[])
2347 fn import_directive_subclass_to_string(&mut self,
2348 subclass: ImportDirectiveSubclass)
2351 SingleImport(_, source) => {
2352 token::get_name(source).get().to_string()
2354 GlobImport => "*".to_string()
2358 fn import_path_to_string(&mut self,
2360 subclass: ImportDirectiveSubclass)
2362 if names.is_empty() {
2363 self.import_directive_subclass_to_string(subclass)
2366 self.names_to_string(names),
2367 self.import_directive_subclass_to_string(
2368 subclass))).to_string()
2373 fn record_import_use(&mut self, import_id: NodeId, name: Name) {
2374 if !self.make_glob_map {
2377 if self.glob_map.contains_key(&import_id) {
2378 self.glob_map[import_id].insert(name);
2382 let mut new_set = HashSet::new();
2383 new_set.insert(name);
2384 self.glob_map.insert(import_id, new_set);
2387 fn get_trait_name(&self, did: DefId) -> Name {
2388 if did.krate == LOCAL_CRATE {
2389 self.ast_map.expect_item(did.node).ident.name
2391 csearch::get_trait_name(&self.session.cstore, did)
2395 /// Attempts to resolve the given import. The return value indicates
2396 /// failure if we're certain the name does not exist, indeterminate if we
2397 /// don't know whether the name exists at the moment due to other
2398 /// currently-unresolved imports, or success if we know the name exists.
2399 /// If successful, the resolved bindings are written into the module.
2400 fn resolve_import_for_module(&mut self,
2401 module_: Rc<Module>,
2402 import_directive: &ImportDirective)
2403 -> ResolveResult<()> {
2404 let mut resolution_result = Failed(None);
2405 let module_path = &import_directive.module_path;
2407 debug!("(resolving import for module) resolving import `{}::...` in `{}`",
2408 self.names_to_string(module_path[]),
2409 self.module_to_string(&*module_));
2411 // First, resolve the module path for the directive, if necessary.
2412 let container = if module_path.len() == 0 {
2413 // Use the crate root.
2414 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2416 match self.resolve_module_path(module_.clone(),
2418 DontUseLexicalScope,
2419 import_directive.span,
2422 resolution_result = Failed(err);
2426 resolution_result = Indeterminate;
2429 Success(container) => Some(container),
2435 Some((containing_module, lp)) => {
2436 // We found the module that the target is contained
2437 // within. Attempt to resolve the import within it.
2439 match import_directive.subclass {
2440 SingleImport(target, source) => {
2442 self.resolve_single_import(&*module_,
2451 self.resolve_glob_import(&*module_,
2460 // Decrement the count of unresolved imports.
2461 match resolution_result {
2463 assert!(self.unresolved_imports >= 1);
2464 self.unresolved_imports -= 1;
2467 // Nothing to do here; just return the error.
2471 // Decrement the count of unresolved globs if necessary. But only if
2472 // the resolution result is indeterminate -- otherwise we'll stop
2473 // processing imports here. (See the loop in
2474 // resolve_imports_for_module.)
2476 if !resolution_result.indeterminate() {
2477 match import_directive.subclass {
2479 assert!(module_.glob_count.get() >= 1);
2480 module_.glob_count.set(module_.glob_count.get() - 1);
2482 SingleImport(..) => {
2488 return resolution_result;
2491 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2493 type_def: RefCell::new(Some(TypeNsDef {
2494 modifiers: IMPORTABLE,
2495 module_def: Some(module),
2499 value_def: RefCell::new(None),
2503 fn resolve_single_import(&mut self,
2505 containing_module: Rc<Module>,
2508 directive: &ImportDirective,
2510 -> ResolveResult<()> {
2511 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2512 `{}` id {}, last private {}",
2513 token::get_name(target),
2514 self.module_to_string(&*containing_module),
2515 token::get_name(source),
2516 self.module_to_string(module_),
2522 LastImport {..} => {
2524 .span_bug(directive.span,
2525 "not expecting Import here, must be LastMod")
2529 // We need to resolve both namespaces for this to succeed.
2532 let mut value_result = UnknownResult;
2533 let mut type_result = UnknownResult;
2535 // Search for direct children of the containing module.
2536 self.populate_module_if_necessary(&containing_module);
2538 match containing_module.children.borrow().get(&source) {
2542 Some(ref child_name_bindings) => {
2543 if child_name_bindings.defined_in_namespace(ValueNS) {
2544 debug!("(resolving single import) found value binding");
2545 value_result = BoundResult(containing_module.clone(),
2546 (*child_name_bindings).clone());
2548 if child_name_bindings.defined_in_namespace(TypeNS) {
2549 debug!("(resolving single import) found type binding");
2550 type_result = BoundResult(containing_module.clone(),
2551 (*child_name_bindings).clone());
2556 // Unless we managed to find a result in both namespaces (unlikely),
2557 // search imports as well.
2558 let mut value_used_reexport = false;
2559 let mut type_used_reexport = false;
2560 match (value_result.clone(), type_result.clone()) {
2561 (BoundResult(..), BoundResult(..)) => {} // Continue.
2563 // If there is an unresolved glob at this point in the
2564 // containing module, bail out. We don't know enough to be
2565 // able to resolve this import.
2567 if containing_module.glob_count.get() > 0 {
2568 debug!("(resolving single import) unresolved glob; \
2570 return Indeterminate;
2573 // Now search the exported imports within the containing module.
2574 match containing_module.import_resolutions.borrow().get(&source) {
2576 debug!("(resolving single import) no import");
2577 // The containing module definitely doesn't have an
2578 // exported import with the name in question. We can
2579 // therefore accurately report that the names are
2582 if value_result.is_unknown() {
2583 value_result = UnboundResult;
2585 if type_result.is_unknown() {
2586 type_result = UnboundResult;
2589 Some(import_resolution)
2590 if import_resolution.outstanding_references == 0 => {
2592 fn get_binding(this: &mut Resolver,
2593 import_resolution: &ImportResolution,
2594 namespace: Namespace,
2596 -> NamespaceResult {
2598 // Import resolutions must be declared with "pub"
2599 // in order to be exported.
2600 if !import_resolution.is_public {
2601 return UnboundResult;
2604 match import_resolution.
2605 target_for_namespace(namespace) {
2607 return UnboundResult;
2614 debug!("(resolving single import) found \
2615 import in ns {}", namespace);
2616 let id = import_resolution.id(namespace);
2617 // track used imports and extern crates as well
2618 this.used_imports.insert((id, namespace));
2619 this.record_import_use(id, *source);
2620 match target_module.def_id.get() {
2621 Some(DefId{krate: kid, ..}) => {
2622 this.used_crates.insert(kid);
2626 return BoundResult(target_module, bindings);
2631 // The name is an import which has been fully
2632 // resolved. We can, therefore, just follow it.
2633 if value_result.is_unknown() {
2634 value_result = get_binding(self,
2638 value_used_reexport = import_resolution.is_public;
2640 if type_result.is_unknown() {
2641 type_result = get_binding(self,
2645 type_used_reexport = import_resolution.is_public;
2650 // If containing_module is the same module whose import we are resolving
2651 // and there it has an unresolved import with the same name as `source`,
2652 // then the user is actually trying to import an item that is declared
2653 // in the same scope
2656 // use self::submodule;
2657 // pub mod submodule;
2659 // In this case we continue as if we resolved the import and let the
2660 // check_for_conflicts_between_imports_and_items call below handle
2662 match (module_.def_id.get(), containing_module.def_id.get()) {
2663 (Some(id1), Some(id2)) if id1 == id2 => {
2664 if value_result.is_unknown() {
2665 value_result = UnboundResult;
2667 if type_result.is_unknown() {
2668 type_result = UnboundResult;
2672 // The import is unresolved. Bail out.
2673 debug!("(resolving single import) unresolved import; \
2675 return Indeterminate;
2683 // If we didn't find a result in the type namespace, search the
2684 // external modules.
2685 let mut value_used_public = false;
2686 let mut type_used_public = false;
2688 BoundResult(..) => {}
2690 match containing_module.external_module_children.borrow_mut()
2691 .get(&source).cloned() {
2692 None => {} // Continue.
2694 debug!("(resolving single import) found external \
2696 // track the module as used.
2697 match module.def_id.get() {
2698 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
2702 Rc::new(Resolver::create_name_bindings_from_module(
2704 type_result = BoundResult(containing_module.clone(),
2706 type_used_public = true;
2712 // We've successfully resolved the import. Write the results in.
2713 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2714 let import_resolution = &mut (*import_resolutions)[target];
2716 match value_result {
2717 BoundResult(ref target_module, ref name_bindings) => {
2718 debug!("(resolving single import) found value target: {}",
2719 { name_bindings.value_def.borrow().clone().unwrap().def });
2720 self.check_for_conflicting_import(
2721 &import_resolution.value_target,
2726 self.check_that_import_is_importable(
2732 import_resolution.value_target =
2733 Some(Target::new(target_module.clone(),
2734 name_bindings.clone(),
2735 directive.shadowable));
2736 import_resolution.value_id = directive.id;
2737 import_resolution.is_public = directive.is_public;
2738 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2740 UnboundResult => { /* Continue. */ }
2742 panic!("value result should be known at this point");
2746 BoundResult(ref target_module, ref name_bindings) => {
2747 debug!("(resolving single import) found type target: {}",
2748 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2749 self.check_for_conflicting_import(
2750 &import_resolution.type_target,
2755 self.check_that_import_is_importable(
2761 import_resolution.type_target =
2762 Some(Target::new(target_module.clone(),
2763 name_bindings.clone(),
2764 directive.shadowable));
2765 import_resolution.type_id = directive.id;
2766 import_resolution.is_public = directive.is_public;
2767 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2769 UnboundResult => { /* Continue. */ }
2771 panic!("type result should be known at this point");
2775 self.check_for_conflicts_between_imports_and_items(
2781 if value_result.is_unbound() && type_result.is_unbound() {
2782 let msg = format!("There is no `{}` in `{}`",
2783 token::get_name(source),
2784 self.module_to_string(&*containing_module));
2785 return Failed(Some((directive.span, msg)));
2787 let value_used_public = value_used_reexport || value_used_public;
2788 let type_used_public = type_used_reexport || type_used_public;
2790 assert!(import_resolution.outstanding_references >= 1);
2791 import_resolution.outstanding_references -= 1;
2793 // record what this import resolves to for later uses in documentation,
2794 // this may resolve to either a value or a type, but for documentation
2795 // purposes it's good enough to just favor one over the other.
2796 let value_private = match import_resolution.value_target {
2797 Some(ref target) => {
2798 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2799 self.def_map.borrow_mut().insert(directive.id, def);
2800 let did = def.def_id();
2801 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2803 // AllPublic here and below is a dummy value, it should never be used because
2804 // _exists is false.
2807 let type_private = match import_resolution.type_target {
2808 Some(ref target) => {
2809 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2810 self.def_map.borrow_mut().insert(directive.id, def);
2811 let did = def.def_id();
2812 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2817 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2819 type_priv: type_private,
2822 debug!("(resolving single import) successfully resolved import");
2826 // Resolves a glob import. Note that this function cannot fail; it either
2827 // succeeds or bails out (as importing * from an empty module or a module
2828 // that exports nothing is valid).
2829 fn resolve_glob_import(&mut self,
2831 containing_module: Rc<Module>,
2832 import_directive: &ImportDirective,
2834 -> ResolveResult<()> {
2835 let id = import_directive.id;
2836 let is_public = import_directive.is_public;
2838 // This function works in a highly imperative manner; it eagerly adds
2839 // everything it can to the list of import resolutions of the module
2841 debug!("(resolving glob import) resolving glob import {}", id);
2843 // We must bail out if the node has unresolved imports of any kind
2844 // (including globs).
2845 if !(*containing_module).all_imports_resolved() {
2846 debug!("(resolving glob import) target module has unresolved \
2847 imports; bailing out");
2848 return Indeterminate;
2851 assert_eq!(containing_module.glob_count.get(), 0);
2853 // Add all resolved imports from the containing module.
2854 let import_resolutions = containing_module.import_resolutions
2856 for (ident, target_import_resolution) in import_resolutions.iter() {
2857 debug!("(resolving glob import) writing module resolution \
2859 target_import_resolution.type_target.is_none(),
2860 self.module_to_string(module_));
2862 if !target_import_resolution.is_public {
2863 debug!("(resolving glob import) nevermind, just kidding");
2867 // Here we merge two import resolutions.
2868 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2869 match import_resolutions.get_mut(ident) {
2870 Some(dest_import_resolution) => {
2871 // Merge the two import resolutions at a finer-grained
2874 match target_import_resolution.value_target {
2878 Some(ref value_target) => {
2879 dest_import_resolution.value_target =
2880 Some(value_target.clone());
2883 match target_import_resolution.type_target {
2887 Some(ref type_target) => {
2888 dest_import_resolution.type_target =
2889 Some(type_target.clone());
2892 dest_import_resolution.is_public = is_public;
2898 // Simple: just copy the old import resolution.
2899 let mut new_import_resolution = ImportResolution::new(id, is_public);
2900 new_import_resolution.value_target =
2901 target_import_resolution.value_target.clone();
2902 new_import_resolution.type_target =
2903 target_import_resolution.type_target.clone();
2905 import_resolutions.insert(*ident, new_import_resolution);
2908 // Add all children from the containing module.
2909 self.populate_module_if_necessary(&containing_module);
2911 for (&name, name_bindings) in containing_module.children
2913 self.merge_import_resolution(module_,
2914 containing_module.clone(),
2917 name_bindings.clone());
2921 // Add external module children from the containing module.
2922 for (&name, module) in containing_module.external_module_children
2925 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2926 self.merge_import_resolution(module_,
2927 containing_module.clone(),
2933 // Record the destination of this import
2934 match containing_module.def_id.get() {
2936 self.def_map.borrow_mut().insert(id, DefMod(did));
2937 self.last_private.insert(id, lp);
2942 debug!("(resolving glob import) successfully resolved import");
2946 fn merge_import_resolution(&mut self,
2948 containing_module: Rc<Module>,
2949 import_directive: &ImportDirective,
2951 name_bindings: Rc<NameBindings>) {
2952 let id = import_directive.id;
2953 let is_public = import_directive.is_public;
2955 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2956 let dest_import_resolution = match import_resolutions.entry(name) {
2957 Occupied(entry) => {
2961 // Create a new import resolution from this child.
2962 entry.set(ImportResolution::new(id, is_public))
2966 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2968 token::get_name(name).get().to_string(),
2969 self.module_to_string(&*containing_module),
2970 self.module_to_string(module_));
2972 // Merge the child item into the import resolution.
2973 if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
2974 debug!("(resolving glob import) ... for value target");
2975 if dest_import_resolution.shadowable(ValueNS) == Shadowable::Never {
2976 let msg = format!("a value named `{}` has already been imported \
2978 token::get_name(name).get());
2979 self.session.span_err(import_directive.span, msg.as_slice());
2981 dest_import_resolution.value_target =
2982 Some(Target::new(containing_module.clone(),
2983 name_bindings.clone(),
2984 import_directive.shadowable));
2985 dest_import_resolution.value_id = id;
2988 if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
2989 debug!("(resolving glob import) ... for type target");
2990 if dest_import_resolution.shadowable(TypeNS) == Shadowable::Never {
2991 let msg = format!("a type named `{}` has already been imported \
2993 token::get_name(name).get());
2994 self.session.span_err(import_directive.span, msg.as_slice());
2996 dest_import_resolution.type_target =
2997 Some(Target::new(containing_module,
2998 name_bindings.clone(),
2999 import_directive.shadowable));
3000 dest_import_resolution.type_id = id;
3003 dest_import_resolution.is_public = is_public;
3005 self.check_for_conflicts_between_imports_and_items(
3007 dest_import_resolution,
3008 import_directive.span,
3012 /// Checks that imported names and items don't have the same name.
3013 fn check_for_conflicting_import(&mut self,
3014 target: &Option<Target>,
3017 namespace: Namespace) {
3018 if self.session.features.borrow().import_shadowing {
3023 Some(ref target) if target.shadowable != Shadowable::Always => {
3024 let msg = format!("a {} named `{}` has already been imported \
3030 token::get_name(name).get());
3031 self.session.span_err(import_span, msg[]);
3033 Some(_) | None => {}
3037 /// Checks that an import is actually importable
3038 fn check_that_import_is_importable(&mut self,
3039 name_bindings: &NameBindings,
3042 namespace: Namespace) {
3043 if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
3044 let msg = format!("`{}` is not directly importable",
3045 token::get_name(name));
3046 self.session.span_err(import_span, msg[]);
3050 /// Checks that imported names and items don't have the same name.
3051 fn check_for_conflicts_between_imports_and_items(&mut self,
3057 if self.session.features.borrow().import_shadowing {
3061 // First, check for conflicts between imports and `extern crate`s.
3062 if module.external_module_children
3064 .contains_key(&name) {
3065 match import_resolution.type_target {
3066 Some(ref target) if target.shadowable != Shadowable::Always => {
3067 let msg = format!("import `{0}` conflicts with imported \
3068 crate in this module \
3069 (maybe you meant `use {0}::*`?)",
3070 token::get_name(name).get());
3071 self.session.span_err(import_span, msg[]);
3073 Some(_) | None => {}
3077 // Check for item conflicts.
3078 let children = module.children.borrow();
3079 let name_bindings = match children.get(&name) {
3081 // There can't be any conflicts.
3084 Some(ref name_bindings) => (*name_bindings).clone(),
3087 match import_resolution.value_target {
3088 Some(ref target) if target.shadowable != Shadowable::Always => {
3089 if let Some(ref value) = *name_bindings.value_def.borrow() {
3090 let msg = format!("import `{}` conflicts with value \
3092 token::get_name(name).get());
3093 self.session.span_err(import_span, msg[]);
3094 if let Some(span) = value.value_span {
3095 self.session.span_note(span,
3096 "conflicting value here");
3100 Some(_) | None => {}
3103 match import_resolution.type_target {
3104 Some(ref target) if target.shadowable != Shadowable::Always => {
3105 if let Some(ref ty) = *name_bindings.type_def.borrow() {
3106 match ty.module_def {
3108 let msg = format!("import `{}` conflicts with type in \
3110 token::get_name(name).get());
3111 self.session.span_err(import_span, msg[]);
3112 if let Some(span) = ty.type_span {
3113 self.session.span_note(span,
3114 "note conflicting type here")
3117 Some(ref module_def) => {
3118 match module_def.kind.get() {
3120 if let Some(span) = ty.type_span {
3121 let msg = format!("inherent implementations \
3122 are only allowed on types \
3123 defined in the current module");
3124 self.session.span_err(span, msg[]);
3125 self.session.span_note(import_span,
3126 "import from other module here")
3130 let msg = format!("import `{}` conflicts with existing \
3132 token::get_name(name).get());
3133 self.session.span_err(import_span, msg[]);
3134 if let Some(span) = ty.type_span {
3135 self.session.span_note(span,
3136 "note conflicting module here")
3144 Some(_) | None => {}
3148 /// Checks that the names of external crates don't collide with other
3149 /// external crates.
3150 fn check_for_conflicts_between_external_crates(&self,
3154 if self.session.features.borrow().import_shadowing {
3158 if module.external_module_children.borrow().contains_key(&name) {
3161 format!("an external crate named `{}` has already \
3162 been imported into this module",
3163 token::get_name(name).get())[]);
3167 /// Checks that the names of items don't collide with external crates.
3168 fn check_for_conflicts_between_external_crates_and_items(&self,
3172 if self.session.features.borrow().import_shadowing {
3176 if module.external_module_children.borrow().contains_key(&name) {
3179 format!("the name `{}` conflicts with an external \
3180 crate that has been imported into this \
3182 token::get_name(name).get())[]);
3186 /// Resolves the given module path from the given root `module_`.
3187 fn resolve_module_path_from_root(&mut self,
3188 module_: Rc<Module>,
3189 module_path: &[Name],
3192 name_search_type: NameSearchType,
3194 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3195 fn search_parent_externals(needle: Name, module: &Rc<Module>)
3196 -> Option<Rc<Module>> {
3197 module.external_module_children.borrow()
3198 .get(&needle).cloned()
3199 .map(|_| module.clone())
3201 match module.parent_link.clone() {
3202 ModuleParentLink(parent, _) => {
3203 search_parent_externals(needle,
3204 &parent.upgrade().unwrap())
3211 let mut search_module = module_;
3212 let mut index = index;
3213 let module_path_len = module_path.len();
3214 let mut closest_private = lp;
3216 // Resolve the module part of the path. This does not involve looking
3217 // upward though scope chains; we simply resolve names directly in
3218 // modules as we go.
3219 while index < module_path_len {
3220 let name = module_path[index];
3221 match self.resolve_name_in_module(search_module.clone(),
3227 let segment_name = token::get_name(name);
3228 let module_name = self.module_to_string(&*search_module);
3229 let mut span = span;
3230 let msg = if "???" == module_name[] {
3231 span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3233 match search_parent_externals(name,
3234 &self.current_module) {
3236 let path_str = self.names_to_string(module_path);
3237 let target_mod_str = self.module_to_string(&*module);
3238 let current_mod_str =
3239 self.module_to_string(&*self.current_module);
3241 let prefix = if target_mod_str == current_mod_str {
3242 "self::".to_string()
3244 format!("{}::", target_mod_str)
3247 format!("Did you mean `{}{}`?", prefix, path_str)
3249 None => format!("Maybe a missing `extern crate {}`?",
3253 format!("Could not find `{}` in `{}`",
3258 return Failed(Some((span, msg)));
3260 Failed(err) => return Failed(err),
3262 debug!("(resolving module path for import) module \
3263 resolution is indeterminate: {}",
3264 token::get_name(name));
3265 return Indeterminate;
3267 Success((target, used_proxy)) => {
3268 // Check to see whether there are type bindings, and, if
3269 // so, whether there is a module within.
3270 match *target.bindings.type_def.borrow() {
3271 Some(ref type_def) => {
3272 match type_def.module_def {
3274 let msg = format!("Not a module `{}`",
3275 token::get_name(name));
3277 return Failed(Some((span, msg)));
3279 Some(ref module_def) => {
3280 search_module = module_def.clone();
3282 // track extern crates for unused_extern_crate lint
3283 if let Some(did) = module_def.def_id.get() {
3284 self.used_crates.insert(did.krate);
3287 // Keep track of the closest
3288 // private module used when
3289 // resolving this import chain.
3290 if !used_proxy && !search_module.is_public {
3291 if let Some(did) = search_module.def_id.get() {
3292 closest_private = LastMod(DependsOn(did));
3299 // There are no type bindings at all.
3300 let msg = format!("Not a module `{}`",
3301 token::get_name(name));
3302 return Failed(Some((span, msg)));
3311 return Success((search_module, closest_private));
3314 /// Attempts to resolve the module part of an import directive or path
3315 /// rooted at the given module.
3317 /// On success, returns the resolved module, and the closest *private*
3318 /// module found to the destination when resolving this path.
3319 fn resolve_module_path(&mut self,
3320 module_: Rc<Module>,
3321 module_path: &[Name],
3322 use_lexical_scope: UseLexicalScopeFlag,
3324 name_search_type: NameSearchType)
3325 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3326 let module_path_len = module_path.len();
3327 assert!(module_path_len > 0);
3329 debug!("(resolving module path for import) processing `{}` rooted at `{}`",
3330 self.names_to_string(module_path),
3331 self.module_to_string(&*module_));
3333 // Resolve the module prefix, if any.
3334 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3340 match module_prefix_result {
3342 let mpath = self.names_to_string(module_path);
3343 let mpath = mpath[];
3344 match mpath.rfind(':') {
3346 let msg = format!("Could not find `{}` in `{}`",
3347 // idx +- 1 to account for the
3348 // colons on either side
3351 return Failed(Some((span, msg)));
3358 Failed(err) => return Failed(err),
3360 debug!("(resolving module path for import) indeterminate; \
3362 return Indeterminate;
3364 Success(NoPrefixFound) => {
3365 // There was no prefix, so we're considering the first element
3366 // of the path. How we handle this depends on whether we were
3367 // instructed to use lexical scope or not.
3368 match use_lexical_scope {
3369 DontUseLexicalScope => {
3370 // This is a crate-relative path. We will start the
3371 // resolution process at index zero.
3372 search_module = self.graph_root.get_module();
3374 last_private = LastMod(AllPublic);
3376 UseLexicalScope => {
3377 // This is not a crate-relative path. We resolve the
3378 // first component of the path in the current lexical
3379 // scope and then proceed to resolve below that.
3380 match self.resolve_module_in_lexical_scope(module_,
3382 Failed(err) => return Failed(err),
3384 debug!("(resolving module path for import) \
3385 indeterminate; bailing");
3386 return Indeterminate;
3388 Success(containing_module) => {
3389 search_module = containing_module;
3391 last_private = LastMod(AllPublic);
3397 Success(PrefixFound(ref containing_module, index)) => {
3398 search_module = containing_module.clone();
3399 start_index = index;
3400 last_private = LastMod(DependsOn(containing_module.def_id
3406 self.resolve_module_path_from_root(search_module,
3414 /// Invariant: This must only be called during main resolution, not during
3415 /// import resolution.
3416 fn resolve_item_in_lexical_scope(&mut self,
3417 module_: Rc<Module>,
3419 namespace: Namespace)
3420 -> ResolveResult<(Target, bool)> {
3421 debug!("(resolving item in lexical scope) resolving `{}` in \
3422 namespace {} in `{}`",
3423 token::get_name(name),
3425 self.module_to_string(&*module_));
3427 // The current module node is handled specially. First, check for
3428 // its immediate children.
3429 self.populate_module_if_necessary(&module_);
3431 match module_.children.borrow().get(&name) {
3433 if name_bindings.defined_in_namespace(namespace) => {
3434 debug!("top name bindings succeeded");
3435 return Success((Target::new(module_.clone(),
3436 name_bindings.clone(),
3440 Some(_) | None => { /* Not found; continue. */ }
3443 // Now check for its import directives. We don't have to have resolved
3444 // all its imports in the usual way; this is because chains of
3445 // adjacent import statements are processed as though they mutated the
3447 if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
3448 match (*import_resolution).target_for_namespace(namespace) {
3450 // Not found; continue.
3451 debug!("(resolving item in lexical scope) found \
3452 import resolution, but not in namespace {}",
3456 debug!("(resolving item in lexical scope) using \
3457 import resolution");
3458 // track used imports and extern crates as well
3459 let id = import_resolution.id(namespace);
3460 self.used_imports.insert((id, namespace));
3461 self.record_import_use(id, name);
3462 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3463 self.used_crates.insert(kid);
3465 return Success((target, false));
3470 // Search for external modules.
3471 if namespace == TypeNS {
3472 if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3474 Rc::new(Resolver::create_name_bindings_from_module(module));
3475 debug!("lower name bindings succeeded");
3476 return Success((Target::new(module_,
3483 // Finally, proceed up the scope chain looking for parent modules.
3484 let mut search_module = module_;
3486 // Go to the next parent.
3487 match search_module.parent_link.clone() {
3489 // No more parents. This module was unresolved.
3490 debug!("(resolving item in lexical scope) unresolved \
3492 return Failed(None);
3494 ModuleParentLink(parent_module_node, _) => {
3495 match search_module.kind.get() {
3496 NormalModuleKind => {
3497 // We stop the search here.
3498 debug!("(resolving item in lexical \
3499 scope) unresolved module: not \
3500 searching through module \
3502 return Failed(None);
3507 AnonymousModuleKind => {
3508 search_module = parent_module_node.upgrade().unwrap();
3512 BlockParentLink(ref parent_module_node, _) => {
3513 search_module = parent_module_node.upgrade().unwrap();
3517 // Resolve the name in the parent module.
3518 match self.resolve_name_in_module(search_module.clone(),
3523 Failed(Some((span, msg))) =>
3524 self.resolve_error(span, format!("failed to resolve. {}",
3526 Failed(None) => (), // Continue up the search chain.
3528 // We couldn't see through the higher scope because of an
3529 // unresolved import higher up. Bail.
3531 debug!("(resolving item in lexical scope) indeterminate \
3532 higher scope; bailing");
3533 return Indeterminate;
3535 Success((target, used_reexport)) => {
3536 // We found the module.
3537 debug!("(resolving item in lexical scope) found name \
3539 return Success((target, used_reexport));
3545 /// Resolves a module name in the current lexical scope.
3546 fn resolve_module_in_lexical_scope(&mut self,
3547 module_: Rc<Module>,
3549 -> ResolveResult<Rc<Module>> {
3550 // If this module is an anonymous module, resolve the item in the
3551 // lexical scope. Otherwise, resolve the item from the crate root.
3552 let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS);
3553 match resolve_result {
3554 Success((target, _)) => {
3555 let bindings = &*target.bindings;
3556 match *bindings.type_def.borrow() {
3557 Some(ref type_def) => {
3558 match type_def.module_def {
3560 debug!("!!! (resolving module in lexical \
3561 scope) module wasn't actually a \
3563 return Failed(None);
3565 Some(ref module_def) => {
3566 return Success(module_def.clone());
3571 debug!("!!! (resolving module in lexical scope) module
3572 wasn't actually a module!");
3573 return Failed(None);
3578 debug!("(resolving module in lexical scope) indeterminate; \
3580 return Indeterminate;
3583 debug!("(resolving module in lexical scope) failed to resolve");
3589 /// Returns the nearest normal module parent of the given module.
3590 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3591 -> Option<Rc<Module>> {
3592 let mut module_ = module_;
3594 match module_.parent_link.clone() {
3595 NoParentLink => return None,
3596 ModuleParentLink(new_module, _) |
3597 BlockParentLink(new_module, _) => {
3598 let new_module = new_module.upgrade().unwrap();
3599 match new_module.kind.get() {
3600 NormalModuleKind => return Some(new_module),
3604 AnonymousModuleKind => module_ = new_module,
3611 /// Returns the nearest normal module parent of the given module, or the
3612 /// module itself if it is a normal module.
3613 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3615 match module_.kind.get() {
3616 NormalModuleKind => return module_,
3620 AnonymousModuleKind => {
3621 match self.get_nearest_normal_module_parent(module_.clone()) {
3623 Some(new_module) => new_module
3629 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3630 /// (b) some chain of `super::`.
3631 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3632 fn resolve_module_prefix(&mut self,
3633 module_: Rc<Module>,
3634 module_path: &[Name])
3635 -> ResolveResult<ModulePrefixResult> {
3636 // Start at the current module if we see `self` or `super`, or at the
3637 // top of the crate otherwise.
3638 let mut containing_module;
3640 let first_module_path_string = token::get_name(module_path[0]);
3641 if "self" == first_module_path_string.get() {
3643 self.get_nearest_normal_module_parent_or_self(module_);
3645 } else if "super" == first_module_path_string.get() {
3647 self.get_nearest_normal_module_parent_or_self(module_);
3648 i = 0; // We'll handle `super` below.
3650 return Success(NoPrefixFound);
3653 // Now loop through all the `super`s we find.
3654 while i < module_path.len() {
3655 let string = token::get_name(module_path[i]);
3656 if "super" != string.get() {
3659 debug!("(resolving module prefix) resolving `super` at {}",
3660 self.module_to_string(&*containing_module));
3661 match self.get_nearest_normal_module_parent(containing_module) {
3662 None => return Failed(None),
3663 Some(new_module) => {
3664 containing_module = new_module;
3670 debug!("(resolving module prefix) finished resolving prefix at {}",
3671 self.module_to_string(&*containing_module));
3673 return Success(PrefixFound(containing_module, i));
3676 /// Attempts to resolve the supplied name in the given module for the
3677 /// given namespace. If successful, returns the target corresponding to
3680 /// The boolean returned on success is an indicator of whether this lookup
3681 /// passed through a public re-export proxy.
3682 fn resolve_name_in_module(&mut self,
3683 module_: Rc<Module>,
3685 namespace: Namespace,
3686 name_search_type: NameSearchType,
3687 allow_private_imports: bool)
3688 -> ResolveResult<(Target, bool)> {
3689 debug!("(resolving name in module) resolving `{}` in `{}`",
3690 token::get_name(name).get(),
3691 self.module_to_string(&*module_));
3693 // First, check the direct children of the module.
3694 self.populate_module_if_necessary(&module_);
3696 match module_.children.borrow().get(&name) {
3698 if name_bindings.defined_in_namespace(namespace) => {
3699 debug!("(resolving name in module) found node as child");
3700 return Success((Target::new(module_.clone(),
3701 name_bindings.clone(),
3710 // Next, check the module's imports if necessary.
3712 // If this is a search of all imports, we should be done with glob
3713 // resolution at this point.
3714 if name_search_type == PathSearch {
3715 assert_eq!(module_.glob_count.get(), 0);
3718 // Check the list of resolved imports.
3719 match module_.import_resolutions.borrow().get(&name) {
3720 Some(import_resolution) if allow_private_imports ||
3721 import_resolution.is_public => {
3723 if import_resolution.is_public &&
3724 import_resolution.outstanding_references != 0 {
3725 debug!("(resolving name in module) import \
3726 unresolved; bailing out");
3727 return Indeterminate;
3729 match import_resolution.target_for_namespace(namespace) {
3731 debug!("(resolving name in module) name found, \
3732 but not in namespace {}",
3736 debug!("(resolving name in module) resolved to \
3738 // track used imports and extern crates as well
3739 let id = import_resolution.id(namespace);
3740 self.used_imports.insert((id, namespace));
3741 self.record_import_use(id, name);
3742 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
3743 self.used_crates.insert(kid);
3745 return Success((target, true));
3749 Some(..) | None => {} // Continue.
3752 // Finally, search through external children.
3753 if namespace == TypeNS {
3754 if let Some(module) = module_.external_module_children.borrow().get(&name).cloned() {
3756 Rc::new(Resolver::create_name_bindings_from_module(module));
3757 return Success((Target::new(module_,
3764 // We're out of luck.
3765 debug!("(resolving name in module) failed to resolve `{}`",
3766 token::get_name(name).get());
3767 return Failed(None);
3770 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3771 let index = module_.resolved_import_count.get();
3772 let imports = module_.imports.borrow();
3773 let import_count = imports.len();
3774 if index != import_count {
3775 let sn = self.session
3777 .span_to_snippet((*imports)[index].span)
3779 if sn.contains("::") {
3780 self.resolve_error((*imports)[index].span,
3781 "unresolved import");
3783 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3785 self.resolve_error((*imports)[index].span, err[]);
3789 // Descend into children and anonymous children.
3790 self.populate_module_if_necessary(&module_);
3792 for (_, child_node) in module_.children.borrow().iter() {
3793 match child_node.get_module_if_available() {
3797 Some(child_module) => {
3798 self.report_unresolved_imports(child_module);
3803 for (_, module_) in module_.anonymous_children.borrow().iter() {
3804 self.report_unresolved_imports(module_.clone());
3810 // We maintain a list of value ribs and type ribs.
3812 // Simultaneously, we keep track of the current position in the module
3813 // graph in the `current_module` pointer. When we go to resolve a name in
3814 // the value or type namespaces, we first look through all the ribs and
3815 // then query the module graph. When we resolve a name in the module
3816 // namespace, we can skip all the ribs (since nested modules are not
3817 // allowed within blocks in Rust) and jump straight to the current module
3820 // Named implementations are handled separately. When we find a method
3821 // call, we consult the module node to find all of the implementations in
3822 // scope. This information is lazily cached in the module node. We then
3823 // generate a fake "implementation scope" containing all the
3824 // implementations thus found, for compatibility with old resolve pass.
3826 fn with_scope<F>(&mut self, name: Option<Name>, f: F) where
3827 F: FnOnce(&mut Resolver),
3829 let orig_module = self.current_module.clone();
3831 // Move down in the graph.
3837 self.populate_module_if_necessary(&orig_module);
3839 match orig_module.children.borrow().get(&name) {
3841 debug!("!!! (with scope) didn't find `{}` in `{}`",
3842 token::get_name(name),
3843 self.module_to_string(&*orig_module));
3845 Some(name_bindings) => {
3846 match (*name_bindings).get_module_if_available() {
3848 debug!("!!! (with scope) didn't find module \
3850 token::get_name(name),
3851 self.module_to_string(&*orig_module));
3854 self.current_module = module_;
3864 self.current_module = orig_module;
3867 /// Wraps the given definition in the appropriate number of `DefUpvar`
3873 -> Option<DefLike> {
3875 DlDef(d @ DefUpvar(..)) => {
3876 self.session.span_bug(span,
3877 format!("unexpected {} in bindings", d)[])
3879 DlDef(d @ DefLocal(_)) => {
3880 let node_id = d.def_id().node;
3882 let mut last_proc_body_id = ast::DUMMY_NODE_ID;
3883 for rib in ribs.iter() {
3886 // Nothing to do. Continue.
3888 ClosureRibKind(function_id, maybe_proc_body) => {
3890 if maybe_proc_body != ast::DUMMY_NODE_ID {
3891 last_proc_body_id = maybe_proc_body;
3893 def = DefUpvar(node_id, function_id, last_proc_body_id);
3895 let mut seen = self.freevars_seen.borrow_mut();
3896 let seen = match seen.entry(function_id) {
3897 Occupied(v) => v.into_mut(),
3898 Vacant(v) => v.set(NodeSet::new()),
3900 if seen.contains(&node_id) {
3903 match self.freevars.borrow_mut().entry(function_id) {
3904 Occupied(v) => v.into_mut(),
3905 Vacant(v) => v.set(vec![]),
3906 }.push(Freevar { def: prev_def, span: span });
3907 seen.insert(node_id);
3909 MethodRibKind(item_id, _) => {
3910 // If the def is a ty param, and came from the parent
3913 DefTyParam(_, did, _) if {
3914 self.def_map.borrow().get(&did.node).cloned()
3915 == Some(DefTyParamBinder(item_id))
3917 DefSelfTy(did) if did == item_id => {} // ok
3919 // This was an attempt to access an upvar inside a
3920 // named function item. This is not allowed, so we
3925 "can't capture dynamic environment in a fn item; \
3926 use the || { ... } closure form instead");
3933 // This was an attempt to access an upvar inside a
3934 // named function item. This is not allowed, so we
3939 "can't capture dynamic environment in a fn item; \
3940 use the || { ... } closure form instead");
3944 ConstantItemRibKind => {
3945 // Still doesn't deal with upvars
3946 self.resolve_error(span,
3947 "attempt to use a non-constant \
3948 value in a constant");
3955 DlDef(def @ DefTyParam(..)) |
3956 DlDef(def @ DefSelfTy(..)) => {
3957 for rib in ribs.iter() {
3959 NormalRibKind | ClosureRibKind(..) => {
3960 // Nothing to do. Continue.
3962 MethodRibKind(item_id, _) => {
3963 // If the def is a ty param, and came from the parent
3966 DefTyParam(_, did, _) if {
3967 self.def_map.borrow().get(&did.node).cloned()
3968 == Some(DefTyParamBinder(item_id))
3970 DefSelfTy(did) if did == item_id => {} // ok
3973 // This was an attempt to use a type parameter outside
3976 self.resolve_error(span,
3977 "can't use type parameters from \
3978 outer function; try using a local \
3979 type parameter instead");
3986 // This was an attempt to use a type parameter outside
3989 self.resolve_error(span,
3990 "can't use type parameters from \
3991 outer function; try using a local \
3992 type parameter instead");
3996 ConstantItemRibKind => {
3998 self.resolve_error(span,
3999 "cannot use an outer type \
4000 parameter in this context");
4011 /// Searches the current set of local scopes and
4012 /// applies translations for closures.
4013 fn search_ribs(&self,
4017 -> Option<DefLike> {
4018 // FIXME #4950: Try caching?
4020 for (i, rib) in ribs.iter().enumerate().rev() {
4021 match rib.bindings.get(&name).cloned() {
4023 return self.upvarify(ribs[i + 1..], def_like, span);
4034 /// Searches the current set of local scopes for labels.
4035 /// Stops after meeting a closure.
4036 fn search_label(&self, name: Name) -> Option<DefLike> {
4037 for rib in self.label_ribs.iter().rev() {
4043 // Do not resolve labels across function boundary
4047 let result = rib.bindings.get(&name).cloned();
4048 if result.is_some() {
4055 fn resolve_crate(&mut self, krate: &ast::Crate) {
4056 debug!("(resolving crate) starting");
4058 visit::walk_crate(self, krate);
4061 fn resolve_item(&mut self, item: &Item) {
4062 let name = item.ident.name;
4064 debug!("(resolving item) resolving {}",
4065 token::get_name(name));
4069 // enum item: resolve all the variants' discrs,
4070 // then resolve the ty params
4071 ItemEnum(ref enum_def, ref generics) => {
4072 for variant in (*enum_def).variants.iter() {
4073 for dis_expr in variant.node.disr_expr.iter() {
4074 // resolve the discriminator expr
4076 self.with_constant_rib(|this| {
4077 this.resolve_expr(&**dis_expr);
4082 // n.b. the discr expr gets visited twice.
4083 // but maybe it's okay since the first time will signal an
4084 // error if there is one? -- tjc
4085 self.with_type_parameter_rib(HasTypeParameters(generics,
4090 this.resolve_type_parameters(&generics.ty_params);
4091 this.resolve_where_clause(&generics.where_clause);
4092 visit::walk_item(this, item);
4096 ItemTy(_, ref generics) => {
4097 self.with_type_parameter_rib(HasTypeParameters(generics,
4102 this.resolve_type_parameters(&generics.ty_params);
4103 visit::walk_item(this, item);
4109 ref implemented_traits,
4111 ref impl_items) => {
4112 self.resolve_implementation(item.id,
4119 ItemTrait(_, ref generics, ref bounds, ref trait_items) => {
4120 // Create a new rib for the self type.
4121 let mut self_type_rib = Rib::new(ItemRibKind);
4123 // plain insert (no renaming, types are not currently hygienic....)
4124 let name = self.type_self_name;
4125 self_type_rib.bindings.insert(name, DlDef(DefSelfTy(item.id)));
4126 self.type_ribs.push(self_type_rib);
4128 // Create a new rib for the trait-wide type parameters.
4129 self.with_type_parameter_rib(HasTypeParameters(generics,
4134 this.resolve_type_parameters(&generics.ty_params);
4135 this.resolve_where_clause(&generics.where_clause);
4137 this.resolve_type_parameter_bounds(item.id, bounds,
4140 for trait_item in (*trait_items).iter() {
4141 // Create a new rib for the trait_item-specific type
4144 // FIXME #4951: Do we need a node ID here?
4147 ast::RequiredMethod(ref ty_m) => {
4148 this.with_type_parameter_rib
4149 (HasTypeParameters(&ty_m.generics,
4152 MethodRibKind(item.id, RequiredMethod)),
4155 // Resolve the method-specific type
4157 this.resolve_type_parameters(
4158 &ty_m.generics.ty_params);
4159 this.resolve_where_clause(&ty_m.generics
4162 for argument in ty_m.decl.inputs.iter() {
4163 this.resolve_type(&*argument.ty);
4166 if let SelfExplicit(ref typ, _) = ty_m.explicit_self.node {
4167 this.resolve_type(&**typ)
4170 if let ast::Return(ref ret_ty) = ty_m.decl.output {
4171 this.resolve_type(&**ret_ty);
4175 ast::ProvidedMethod(ref m) => {
4176 this.resolve_method(MethodRibKind(item.id,
4177 ProvidedMethod(m.id)),
4180 ast::TypeTraitItem(ref data) => {
4181 this.resolve_type_parameter(&data.ty_param);
4182 visit::walk_trait_item(this, trait_item);
4188 self.type_ribs.pop();
4191 ItemStruct(ref struct_def, ref generics) => {
4192 self.resolve_struct(item.id,
4194 struct_def.fields[]);
4197 ItemMod(ref module_) => {
4198 self.with_scope(Some(name), |this| {
4199 this.resolve_module(module_, item.span, name,
4204 ItemForeignMod(ref foreign_module) => {
4205 self.with_scope(Some(name), |this| {
4206 for foreign_item in foreign_module.items.iter() {
4207 match foreign_item.node {
4208 ForeignItemFn(_, ref generics) => {
4209 this.with_type_parameter_rib(
4211 generics, FnSpace, foreign_item.id,
4213 |this| visit::walk_foreign_item(this,
4216 ForeignItemStatic(..) => {
4217 visit::walk_foreign_item(this,
4225 ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4226 self.resolve_function(ItemRibKind,
4236 ItemConst(..) | ItemStatic(..) => {
4237 self.with_constant_rib(|this| {
4238 visit::walk_item(this, item);
4243 // do nothing, these are just around to be encoded
4248 fn with_type_parameter_rib<F>(&mut self, type_parameters: TypeParameters, f: F) where
4249 F: FnOnce(&mut Resolver),
4251 match type_parameters {
4252 HasTypeParameters(generics, space, node_id, rib_kind) => {
4253 let mut function_type_rib = Rib::new(rib_kind);
4254 let mut seen_bindings = HashSet::new();
4255 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4256 let name = type_parameter.ident.name;
4257 debug!("with_type_parameter_rib: {} {}", node_id,
4260 if seen_bindings.contains(&name) {
4261 self.resolve_error(type_parameter.span,
4262 format!("the name `{}` is already \
4264 parameter in this type \
4269 seen_bindings.insert(name);
4271 let def_like = DlDef(DefTyParam(space,
4272 local_def(type_parameter.id),
4274 // Associate this type parameter with
4275 // the item that bound it
4276 self.record_def(type_parameter.id,
4277 (DefTyParamBinder(node_id), LastMod(AllPublic)));
4278 // plain insert (no renaming)
4279 function_type_rib.bindings.insert(name, def_like);
4281 self.type_ribs.push(function_type_rib);
4284 NoTypeParameters => {
4291 match type_parameters {
4292 HasTypeParameters(..) => { self.type_ribs.pop(); }
4293 NoTypeParameters => { }
4297 fn with_label_rib<F>(&mut self, f: F) where
4298 F: FnOnce(&mut Resolver),
4300 self.label_ribs.push(Rib::new(NormalRibKind));
4302 self.label_ribs.pop();
4305 fn with_constant_rib<F>(&mut self, f: F) where
4306 F: FnOnce(&mut Resolver),
4308 self.value_ribs.push(Rib::new(ConstantItemRibKind));
4309 self.type_ribs.push(Rib::new(ConstantItemRibKind));
4311 self.type_ribs.pop();
4312 self.value_ribs.pop();
4315 fn resolve_function(&mut self,
4317 optional_declaration: Option<&FnDecl>,
4318 type_parameters: TypeParameters,
4320 // Create a value rib for the function.
4321 let function_value_rib = Rib::new(rib_kind);
4322 self.value_ribs.push(function_value_rib);
4324 // Create a label rib for the function.
4325 let function_label_rib = Rib::new(rib_kind);
4326 self.label_ribs.push(function_label_rib);
4328 // If this function has type parameters, add them now.
4329 self.with_type_parameter_rib(type_parameters, |this| {
4330 // Resolve the type parameters.
4331 match type_parameters {
4332 NoTypeParameters => {
4335 HasTypeParameters(ref generics, _, _, _) => {
4336 this.resolve_type_parameters(&generics.ty_params);
4337 this.resolve_where_clause(&generics.where_clause);
4341 // Add each argument to the rib.
4342 match optional_declaration {
4346 Some(declaration) => {
4347 let mut bindings_list = HashMap::new();
4348 for argument in declaration.inputs.iter() {
4349 this.resolve_pattern(&*argument.pat,
4350 ArgumentIrrefutableMode,
4351 &mut bindings_list);
4353 this.resolve_type(&*argument.ty);
4355 debug!("(resolving function) recorded argument");
4358 if let ast::Return(ref ret_ty) = declaration.output {
4359 this.resolve_type(&**ret_ty);
4364 // Resolve the function body.
4365 this.resolve_block(&*block);
4367 debug!("(resolving function) leaving function");
4370 self.label_ribs.pop();
4371 self.value_ribs.pop();
4374 fn resolve_type_parameters(&mut self,
4375 type_parameters: &OwnedSlice<TyParam>) {
4376 for type_parameter in type_parameters.iter() {
4377 self.resolve_type_parameter(type_parameter);
4381 fn resolve_type_parameter(&mut self,
4382 type_parameter: &TyParam) {
4383 for bound in type_parameter.bounds.iter() {
4384 self.resolve_type_parameter_bound(type_parameter.id, bound,
4385 TraitBoundingTypeParameter);
4387 match type_parameter.default {
4388 Some(ref ty) => self.resolve_type(&**ty),
4393 fn resolve_type_parameter_bounds(&mut self,
4395 type_parameter_bounds: &OwnedSlice<TyParamBound>,
4396 reference_type: TraitReferenceType) {
4397 for type_parameter_bound in type_parameter_bounds.iter() {
4398 self.resolve_type_parameter_bound(id, type_parameter_bound,
4403 fn resolve_type_parameter_bound(&mut self,
4405 type_parameter_bound: &TyParamBound,
4406 reference_type: TraitReferenceType) {
4407 match *type_parameter_bound {
4408 TraitTyParamBound(ref tref, _) => {
4409 self.resolve_poly_trait_reference(id, tref, reference_type)
4411 RegionTyParamBound(..) => {}
4415 fn resolve_poly_trait_reference(&mut self,
4417 poly_trait_reference: &PolyTraitRef,
4418 reference_type: TraitReferenceType) {
4419 self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
4422 fn resolve_trait_reference(&mut self,
4424 trait_reference: &TraitRef,
4425 reference_type: TraitReferenceType) {
4426 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4428 let path_str = self.path_names_to_string(&trait_reference.path);
4429 let usage_str = match reference_type {
4430 TraitBoundingTypeParameter => "bound type parameter with",
4431 TraitImplementation => "implement",
4432 TraitDerivation => "derive",
4433 TraitObject => "reference",
4434 TraitQPath => "extract an associated type from",
4437 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4438 self.resolve_error(trait_reference.path.span, msg[]);
4442 (DefTrait(_), _) => {
4443 debug!("(resolving trait) found trait def: {}", def);
4444 self.record_def(trait_reference.ref_id, def);
4447 self.resolve_error(trait_reference.path.span,
4448 format!("`{}` is not a trait",
4449 self.path_names_to_string(
4450 &trait_reference.path))[]);
4452 // If it's a typedef, give a note
4453 if let DefTy(..) = def {
4454 self.session.span_note(
4455 trait_reference.path.span,
4456 format!("`type` aliases cannot be used for traits")
4465 fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4466 for predicate in where_clause.predicates.iter() {
4468 &ast::WherePredicate::BoundPredicate(ref bound_pred) => {
4469 self.resolve_type(&*bound_pred.bounded_ty);
4471 for bound in bound_pred.bounds.iter() {
4472 self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
4473 TraitBoundingTypeParameter);
4476 &ast::WherePredicate::RegionPredicate(_) => {}
4477 &ast::WherePredicate::EqPredicate(ref eq_pred) => {
4478 match self.resolve_path(eq_pred.id, &eq_pred.path, TypeNS, true) {
4479 Some((def @ DefTyParam(..), last_private)) => {
4480 self.record_def(eq_pred.id, (def, last_private));
4483 self.resolve_error(eq_pred.path.span,
4484 "undeclared associated type");
4488 self.resolve_type(&*eq_pred.ty);
4494 fn resolve_struct(&mut self,
4496 generics: &Generics,
4497 fields: &[StructField]) {
4498 // If applicable, create a rib for the type parameters.
4499 self.with_type_parameter_rib(HasTypeParameters(generics,
4504 // Resolve the type parameters.
4505 this.resolve_type_parameters(&generics.ty_params);
4506 this.resolve_where_clause(&generics.where_clause);
4509 for field in fields.iter() {
4510 this.resolve_type(&*field.node.ty);
4515 // Does this really need to take a RibKind or is it always going
4516 // to be NormalRibKind?
4517 fn resolve_method(&mut self,
4519 method: &ast::Method) {
4520 let method_generics = method.pe_generics();
4521 let type_parameters = HasTypeParameters(method_generics,
4526 if let SelfExplicit(ref typ, _) = method.pe_explicit_self().node {
4527 self.resolve_type(&**typ);
4530 self.resolve_function(rib_kind,
4531 Some(method.pe_fn_decl()),
4536 fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
4537 F: FnOnce(&mut Resolver) -> T,
4539 // Handle nested impls (inside fn bodies)
4540 let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4541 let result = f(self);
4542 self.current_self_type = previous_value;
4546 fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
4547 opt_trait_ref: &Option<TraitRef>,
4549 F: FnOnce(&mut Resolver) -> T,
4551 let new_val = match *opt_trait_ref {
4552 Some(ref trait_ref) => {
4553 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4555 match self.def_map.borrow().get(&trait_ref.ref_id) {
4557 let did = def.def_id();
4558 Some((did, trait_ref.clone()))
4565 let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4566 let result = f(self);
4567 self.current_trait_ref = original_trait_ref;
4571 fn resolve_implementation(&mut self,
4573 generics: &Generics,
4574 opt_trait_reference: &Option<TraitRef>,
4576 impl_items: &[ImplItem]) {
4577 // If applicable, create a rib for the type parameters.
4578 self.with_type_parameter_rib(HasTypeParameters(generics,
4583 // Resolve the type parameters.
4584 this.resolve_type_parameters(&generics.ty_params);
4585 this.resolve_where_clause(&generics.where_clause);
4587 // Resolve the trait reference, if necessary.
4588 this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4589 // Resolve the self type.
4590 this.resolve_type(self_type);
4592 this.with_current_self_type(self_type, |this| {
4593 for impl_item in impl_items.iter() {
4595 MethodImplItem(ref method) => {
4596 // If this is a trait impl, ensure the method
4598 this.check_trait_item(method.pe_ident().name,
4601 // We also need a new scope for the method-
4602 // specific type parameters.
4603 this.resolve_method(
4604 MethodRibKind(id, ProvidedMethod(method.id)),
4607 TypeImplItem(ref typedef) => {
4608 // If this is a trait impl, ensure the method
4610 this.check_trait_item(typedef.ident.name,
4613 this.resolve_type(&*typedef.typ);
4621 // Check that the current type is indeed a type, if we have an anonymous impl
4622 if opt_trait_reference.is_none() {
4623 match self_type.node {
4624 // TyPath is the only thing that we handled in `build_reduced_graph_for_item`,
4625 // where we created a module with the name of the type in order to implement
4626 // an anonymous trait. In the case that the path does not resolve to an actual
4627 // type, the result will be that the type name resolves to a module but not
4628 // a type (shadowing any imported modules or types with this name), leading
4629 // to weird user-visible bugs. So we ward this off here. See #15060.
4630 TyPath(ref path, path_id) => {
4631 match self.def_map.borrow().get(&path_id) {
4632 // FIXME: should we catch other options and give more precise errors?
4633 Some(&DefMod(_)) => {
4634 self.resolve_error(path.span, "inherent implementations are not \
4635 allowed for types not defined in \
4636 the current module");
4646 fn check_trait_item(&self, name: Name, span: Span) {
4647 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4648 for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4649 if self.trait_item_map.get(&(name, did)).is_none() {
4650 let path_str = self.path_names_to_string(&trait_ref.path);
4651 self.resolve_error(span,
4652 format!("method `{}` is not a member of trait `{}`",
4653 token::get_name(name),
4659 fn resolve_module(&mut self, module: &Mod, _span: Span,
4660 _name: Name, id: NodeId) {
4661 // Write the implementations in scope into the module metadata.
4662 debug!("(resolving module) resolving module ID {}", id);
4663 visit::walk_mod(self, module);
4666 fn resolve_local(&mut self, local: &Local) {
4667 // Resolve the type.
4668 self.resolve_type(&*local.ty);
4670 // Resolve the initializer, if necessary.
4675 Some(ref initializer) => {
4676 self.resolve_expr(&**initializer);
4680 // Resolve the pattern.
4681 let mut bindings_list = HashMap::new();
4682 self.resolve_pattern(&*local.pat,
4683 LocalIrrefutableMode,
4684 &mut bindings_list);
4687 // build a map from pattern identifiers to binding-info's.
4688 // this is done hygienically. This could arise for a macro
4689 // that expands into an or-pattern where one 'x' was from the
4690 // user and one 'x' came from the macro.
4691 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4692 let mut result = HashMap::new();
4693 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4694 let name = mtwt::resolve(path1.node);
4695 result.insert(name, BindingInfo {
4697 binding_mode: binding_mode
4703 // check that all of the arms in an or-pattern have exactly the
4704 // same set of bindings, with the same binding modes for each.
4705 fn check_consistent_bindings(&mut self, arm: &Arm) {
4706 if arm.pats.len() == 0 {
4709 let map_0 = self.binding_mode_map(&*arm.pats[0]);
4710 for (i, p) in arm.pats.iter().enumerate() {
4711 let map_i = self.binding_mode_map(&**p);
4713 for (&key, &binding_0) in map_0.iter() {
4714 match map_i.get(&key) {
4718 format!("variable `{}` from pattern #1 is \
4719 not bound in pattern #{}",
4720 token::get_name(key),
4723 Some(binding_i) => {
4724 if binding_0.binding_mode != binding_i.binding_mode {
4727 format!("variable `{}` is bound with different \
4728 mode in pattern #{} than in pattern #1",
4729 token::get_name(key),
4736 for (&key, &binding) in map_i.iter() {
4737 if !map_0.contains_key(&key) {
4740 format!("variable `{}` from pattern {}{} is \
4741 not bound in pattern {}1",
4742 token::get_name(key),
4743 "#", i + 1, "#")[]);
4749 fn resolve_arm(&mut self, arm: &Arm) {
4750 self.value_ribs.push(Rib::new(NormalRibKind));
4752 let mut bindings_list = HashMap::new();
4753 for pattern in arm.pats.iter() {
4754 self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4757 // This has to happen *after* we determine which
4758 // pat_idents are variants
4759 self.check_consistent_bindings(arm);
4761 visit::walk_expr_opt(self, &arm.guard);
4762 self.resolve_expr(&*arm.body);
4764 self.value_ribs.pop();
4767 fn resolve_block(&mut self, block: &Block) {
4768 debug!("(resolving block) entering block");
4769 self.value_ribs.push(Rib::new(NormalRibKind));
4771 // Move down in the graph, if there's an anonymous module rooted here.
4772 let orig_module = self.current_module.clone();
4773 match orig_module.anonymous_children.borrow().get(&block.id) {
4774 None => { /* Nothing to do. */ }
4775 Some(anonymous_module) => {
4776 debug!("(resolving block) found anonymous module, moving \
4778 self.current_module = anonymous_module.clone();
4782 // Descend into the block.
4783 visit::walk_block(self, block);
4786 self.current_module = orig_module;
4788 self.value_ribs.pop();
4789 debug!("(resolving block) leaving block");
4792 fn resolve_type(&mut self, ty: &Ty) {
4794 // Like path expressions, the interpretation of path types depends
4795 // on whether the path has multiple elements in it or not.
4797 TyPath(ref path, path_id) => {
4798 // This is a path in the type namespace. Walk through scopes
4800 let mut result_def = None;
4802 // First, check to see whether the name is a primitive type.
4803 if path.segments.len() == 1 {
4804 let id = path.segments.last().unwrap().identifier;
4806 match self.primitive_type_table
4810 Some(&primitive_type) => {
4812 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4814 if path.segments[0].parameters.has_lifetimes() {
4815 span_err!(self.session, path.span, E0157,
4816 "lifetime parameters are not allowed on this type");
4817 } else if !path.segments[0].parameters.is_empty() {
4818 span_err!(self.session, path.span, E0153,
4819 "type parameters are not allowed on this type");
4830 match self.resolve_path(ty.id, path, TypeNS, true) {
4832 debug!("(resolving type) resolved `{}` to \
4834 token::get_ident(path.segments
4838 result_def = Some(def);
4845 Some(_) => {} // Continue.
4850 // Write the result into the def map.
4851 debug!("(resolving type) writing resolution for `{}` \
4853 self.path_names_to_string(path),
4855 self.record_def(path_id, def);
4858 let msg = format!("use of undeclared type name `{}`",
4859 self.path_names_to_string(path));
4860 self.resolve_error(ty.span, msg[]);
4865 TyObjectSum(ref ty, ref bound_vec) => {
4866 self.resolve_type(&**ty);
4867 self.resolve_type_parameter_bounds(ty.id, bound_vec,
4868 TraitBoundingTypeParameter);
4871 TyQPath(ref qpath) => {
4872 self.resolve_type(&*qpath.self_type);
4873 self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
4876 TyClosure(ref c) => {
4877 self.resolve_type_parameter_bounds(
4880 TraitBoundingTypeParameter);
4881 visit::walk_ty(self, ty);
4884 TyPolyTraitRef(ref bounds) => {
4885 self.resolve_type_parameter_bounds(
4889 visit::walk_ty(self, ty);
4892 // Just resolve embedded types.
4893 visit::walk_ty(self, ty);
4898 fn resolve_pattern(&mut self,
4900 mode: PatternBindingMode,
4901 // Maps idents to the node ID for the (outermost)
4902 // pattern that binds them
4903 bindings_list: &mut HashMap<Name, NodeId>) {
4904 let pat_id = pattern.id;
4905 walk_pat(pattern, |pattern| {
4906 match pattern.node {
4907 PatIdent(binding_mode, ref path1, _) => {
4909 // The meaning of pat_ident with no type parameters
4910 // depends on whether an enum variant or unit-like struct
4911 // with that name is in scope. The probing lookup has to
4912 // be careful not to emit spurious errors. Only matching
4913 // patterns (match) can match nullary variants or
4914 // unit-like structs. For binding patterns (let), matching
4915 // such a value is simply disallowed (since it's rarely
4918 let ident = path1.node;
4919 let renamed = mtwt::resolve(ident);
4921 match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
4922 FoundStructOrEnumVariant(ref def, lp)
4923 if mode == RefutableMode => {
4924 debug!("(resolving pattern) resolving `{}` to \
4925 struct or enum variant",
4926 token::get_name(renamed));
4928 self.enforce_default_binding_mode(
4932 self.record_def(pattern.id, (def.clone(), lp));
4934 FoundStructOrEnumVariant(..) => {
4937 format!("declaration of `{}` shadows an enum \
4938 variant or unit-like struct in \
4940 token::get_name(renamed))[]);
4942 FoundConst(ref def, lp) if mode == RefutableMode => {
4943 debug!("(resolving pattern) resolving `{}` to \
4945 token::get_name(renamed));
4947 self.enforce_default_binding_mode(
4951 self.record_def(pattern.id, (def.clone(), lp));
4954 self.resolve_error(pattern.span,
4955 "only irrefutable patterns \
4958 BareIdentifierPatternUnresolved => {
4959 debug!("(resolving pattern) binding `{}`",
4960 token::get_name(renamed));
4962 let def = DefLocal(pattern.id);
4964 // Record the definition so that later passes
4965 // will be able to distinguish variants from
4966 // locals in patterns.
4968 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4970 // Add the binding to the local ribs, if it
4971 // doesn't already exist in the bindings list. (We
4972 // must not add it if it's in the bindings list
4973 // because that breaks the assumptions later
4974 // passes make about or-patterns.)
4975 if !bindings_list.contains_key(&renamed) {
4976 let this = &mut *self;
4977 let last_rib = this.value_ribs.last_mut().unwrap();
4978 last_rib.bindings.insert(renamed, DlDef(def));
4979 bindings_list.insert(renamed, pat_id);
4980 } else if mode == ArgumentIrrefutableMode &&
4981 bindings_list.contains_key(&renamed) {
4982 // Forbid duplicate bindings in the same
4984 self.resolve_error(pattern.span,
4985 format!("identifier `{}` \
4993 } else if bindings_list.get(&renamed) ==
4995 // Then this is a duplicate variable in the
4996 // same disjunction, which is an error.
4997 self.resolve_error(pattern.span,
4998 format!("identifier `{}` is bound \
4999 more than once in the same \
5001 token::get_ident(ident))[]);
5003 // Else, not bound in the same pattern: do
5009 PatEnum(ref path, _) => {
5010 // This must be an enum variant, struct or const.
5011 match self.resolve_path(pat_id, path, ValueNS, false) {
5012 Some(def @ (DefVariant(..), _)) |
5013 Some(def @ (DefStruct(..), _)) |
5014 Some(def @ (DefConst(..), _)) => {
5015 self.record_def(pattern.id, def);
5017 Some((DefStatic(..), _)) => {
5018 self.resolve_error(path.span,
5019 "static variables cannot be \
5020 referenced in a pattern, \
5021 use a `const` instead");
5024 self.resolve_error(path.span,
5025 format!("`{}` is not an enum variant, struct or const",
5033 self.resolve_error(path.span,
5034 format!("unresolved enum variant, struct or const `{}`",
5043 // Check the types in the path pattern.
5044 for ty in path.segments
5046 .flat_map(|s| s.parameters.types().into_iter()) {
5047 self.resolve_type(&**ty);
5051 PatLit(ref expr) => {
5052 self.resolve_expr(&**expr);
5055 PatRange(ref first_expr, ref last_expr) => {
5056 self.resolve_expr(&**first_expr);
5057 self.resolve_expr(&**last_expr);
5060 PatStruct(ref path, _, _) => {
5061 match self.resolve_path(pat_id, path, TypeNS, false) {
5062 Some(definition) => {
5063 self.record_def(pattern.id, definition);
5066 debug!("(resolving pattern) didn't find struct \
5068 let msg = format!("`{}` does not name a structure",
5069 self.path_names_to_string(path));
5070 self.resolve_error(path.span, msg[]);
5083 fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
5084 -> BareIdentifierPatternResolution {
5085 let module = self.current_module.clone();
5086 match self.resolve_item_in_lexical_scope(module,
5089 Success((target, _)) => {
5090 debug!("(resolve bare identifier pattern) succeeded in \
5092 token::get_name(name),
5093 target.bindings.value_def.borrow());
5094 match *target.bindings.value_def.borrow() {
5096 panic!("resolved name in the value namespace to a \
5097 set of name bindings with no def?!");
5100 // For the two success cases, this lookup can be
5101 // considered as not having a private component because
5102 // the lookup happened only within the current module.
5104 def @ DefVariant(..) | def @ DefStruct(..) => {
5105 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5107 def @ DefConst(..) => {
5108 return FoundConst(def, LastMod(AllPublic));
5111 self.resolve_error(span,
5112 "static variables cannot be \
5113 referenced in a pattern, \
5114 use a `const` instead");
5115 return BareIdentifierPatternUnresolved;
5118 return BareIdentifierPatternUnresolved;
5126 panic!("unexpected indeterminate result");
5130 Some((span, msg)) => {
5131 self.resolve_error(span, format!("failed to resolve: {}",
5137 debug!("(resolve bare identifier pattern) failed to find {}",
5138 token::get_name(name));
5139 return BareIdentifierPatternUnresolved;
5144 /// If `check_ribs` is true, checks the local definitions first; i.e.
5145 /// doesn't skip straight to the containing module.
5146 fn resolve_path(&mut self,
5149 namespace: Namespace,
5150 check_ribs: bool) -> Option<(Def, LastPrivate)> {
5151 // First, resolve the types and associated type bindings.
5152 for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) {
5153 self.resolve_type(&**ty);
5155 for binding in path.segments.iter().flat_map(|s| s.parameters.bindings().into_iter()) {
5156 self.resolve_type(&*binding.ty);
5159 // A special case for sugared associated type paths `T::A` where `T` is
5160 // a type parameter and `A` is an associated type on some bound of `T`.
5161 if namespace == TypeNS && path.segments.len() == 2 {
5162 match self.resolve_identifier(path.segments[0].identifier,
5166 Some((def, last_private)) => {
5168 DefTyParam(_, did, _) => {
5169 let def = DefAssociatedPath(TyParamProvenance::FromParam(did),
5170 path.segments.last()
5171 .unwrap().identifier);
5172 return Some((def, last_private));
5175 let def = DefAssociatedPath(TyParamProvenance::FromSelf(local_def(nid)),
5176 path.segments.last()
5177 .unwrap().identifier);
5178 return Some((def, last_private));
5188 return self.resolve_crate_relative_path(path, namespace);
5191 // Try to find a path to an item in a module.
5192 let unqualified_def =
5193 self.resolve_identifier(path.segments
5200 if path.segments.len() > 1 {
5201 let def = self.resolve_module_relative_path(path, namespace);
5202 match (def, unqualified_def) {
5203 (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5205 .add_lint(lint::builtin::UNUSED_QUALIFICATIONS,
5208 "unnecessary qualification".to_string());
5216 return unqualified_def;
5219 // resolve a single identifier (used as a varref)
5220 fn resolve_identifier(&mut self,
5222 namespace: Namespace,
5225 -> Option<(Def, LastPrivate)> {
5227 match self.resolve_identifier_in_local_ribs(identifier,
5231 return Some((def, LastMod(AllPublic)));
5239 return self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace);
5242 // FIXME #4952: Merge me with resolve_name_in_module?
5243 fn resolve_definition_of_name_in_module(&mut self,
5244 containing_module: Rc<Module>,
5246 namespace: Namespace)
5248 // First, search children.
5249 self.populate_module_if_necessary(&containing_module);
5251 match containing_module.children.borrow().get(&name) {
5252 Some(child_name_bindings) => {
5253 match child_name_bindings.def_for_namespace(namespace) {
5255 // Found it. Stop the search here.
5256 let p = child_name_bindings.defined_in_public_namespace(
5258 let lp = if p {LastMod(AllPublic)} else {
5259 LastMod(DependsOn(def.def_id()))
5261 return ChildNameDefinition(def, lp);
5269 // Next, search import resolutions.
5270 match containing_module.import_resolutions.borrow().get(&name) {
5271 Some(import_resolution) if import_resolution.is_public => {
5272 if let Some(target) = (*import_resolution).target_for_namespace(namespace) {
5273 match target.bindings.def_for_namespace(namespace) {
5276 let id = import_resolution.id(namespace);
5277 // track imports and extern crates as well
5278 self.used_imports.insert((id, namespace));
5279 self.record_import_use(id, name);
5280 match target.target_module.def_id.get() {
5281 Some(DefId{krate: kid, ..}) => {
5282 self.used_crates.insert(kid);
5286 return ImportNameDefinition(def, LastMod(AllPublic));
5289 // This can happen with external impls, due to
5290 // the imperfect way we read the metadata.
5295 Some(..) | None => {} // Continue.
5298 // Finally, search through external children.
5299 if namespace == TypeNS {
5300 if let Some(module) = containing_module.external_module_children.borrow()
5301 .get(&name).cloned() {
5302 if let Some(def_id) = module.def_id.get() {
5303 // track used crates
5304 self.used_crates.insert(def_id.krate);
5305 let lp = if module.is_public {LastMod(AllPublic)} else {
5306 LastMod(DependsOn(def_id))
5308 return ChildNameDefinition(DefMod(def_id), lp);
5313 return NoNameDefinition;
5316 // resolve a "module-relative" path, e.g. a::b::c
5317 fn resolve_module_relative_path(&mut self,
5319 namespace: Namespace)
5320 -> Option<(Def, LastPrivate)> {
5321 let module_path = path.segments.init().iter()
5322 .map(|ps| ps.identifier.name)
5323 .collect::<Vec<_>>();
5325 let containing_module;
5327 let module = self.current_module.clone();
5328 match self.resolve_module_path(module,
5334 let (span, msg) = match err {
5335 Some((span, msg)) => (span, msg),
5337 let msg = format!("Use of undeclared type or module `{}`",
5338 self.names_to_string(module_path.as_slice()));
5343 self.resolve_error(span, format!("failed to resolve. {}",
5347 Indeterminate => panic!("indeterminate unexpected"),
5348 Success((resulting_module, resulting_last_private)) => {
5349 containing_module = resulting_module;
5350 last_private = resulting_last_private;
5354 let name = path.segments.last().unwrap().identifier.name;
5355 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5358 NoNameDefinition => {
5359 // We failed to resolve the name. Report an error.
5362 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5363 (def, last_private.or(lp))
5366 if let Some(DefId{krate: kid, ..}) = containing_module.def_id.get() {
5367 self.used_crates.insert(kid);
5372 /// Invariant: This must be called only during main resolution, not during
5373 /// import resolution.
5374 fn resolve_crate_relative_path(&mut self,
5376 namespace: Namespace)
5377 -> Option<(Def, LastPrivate)> {
5378 let module_path = path.segments.init().iter()
5379 .map(|ps| ps.identifier.name)
5380 .collect::<Vec<_>>();
5382 let root_module = self.graph_root.get_module();
5384 let containing_module;
5386 match self.resolve_module_path_from_root(root_module,
5391 LastMod(AllPublic)) {
5393 let (span, msg) = match err {
5394 Some((span, msg)) => (span, msg),
5396 let msg = format!("Use of undeclared module `::{}`",
5397 self.names_to_string(module_path[]));
5402 self.resolve_error(span, format!("failed to resolve. {}",
5408 panic!("indeterminate unexpected");
5411 Success((resulting_module, resulting_last_private)) => {
5412 containing_module = resulting_module;
5413 last_private = resulting_last_private;
5417 let name = path.segments.last().unwrap().identifier.name;
5418 match self.resolve_definition_of_name_in_module(containing_module,
5421 NoNameDefinition => {
5422 // We failed to resolve the name. Report an error.
5425 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5426 return Some((def, last_private.or(lp)));
5431 fn resolve_identifier_in_local_ribs(&mut self,
5433 namespace: Namespace,
5436 // Check the local set of ribs.
5437 let search_result = match namespace {
5439 let renamed = mtwt::resolve(ident);
5440 self.search_ribs(self.value_ribs.as_slice(), renamed, span)
5443 let name = ident.name;
5444 self.search_ribs(self.type_ribs[], name, span)
5448 match search_result {
5449 Some(DlDef(def)) => {
5450 debug!("(resolving path in local ribs) resolved `{}` to \
5452 token::get_ident(ident),
5456 Some(DlField) | Some(DlImpl(_)) | None => {
5462 fn resolve_item_by_name_in_lexical_scope(&mut self,
5464 namespace: Namespace)
5465 -> Option<(Def, LastPrivate)> {
5467 let module = self.current_module.clone();
5468 match self.resolve_item_in_lexical_scope(module,
5471 Success((target, _)) => {
5472 match (*target.bindings).def_for_namespace(namespace) {
5474 // This can happen if we were looking for a type and
5475 // found a module instead. Modules don't have defs.
5476 debug!("(resolving item path by identifier in lexical \
5477 scope) failed to resolve {} after success...",
5478 token::get_name(name));
5482 debug!("(resolving item path in lexical scope) \
5483 resolved `{}` to item",
5484 token::get_name(name));
5485 // This lookup is "all public" because it only searched
5486 // for one identifier in the current module (couldn't
5487 // have passed through reexports or anything like that.
5488 return Some((def, LastMod(AllPublic)));
5493 panic!("unexpected indeterminate result");
5497 Some((span, msg)) =>
5498 self.resolve_error(span, format!("failed to resolve. {}",
5503 debug!("(resolving item path by identifier in lexical scope) \
5504 failed to resolve {}", token::get_name(name));
5510 fn with_no_errors<T, F>(&mut self, f: F) -> T where
5511 F: FnOnce(&mut Resolver) -> T,
5513 self.emit_errors = false;
5515 self.emit_errors = true;
5519 fn resolve_error(&self, span: Span, s: &str) {
5520 if self.emit_errors {
5521 self.session.span_err(span, s);
5525 fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5526 fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5527 -> Option<(Path, NodeId, FallbackChecks)> {
5529 TyPath(ref path, node_id) => Some((path.clone(), node_id, allow)),
5530 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5531 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5532 // This doesn't handle the remaining `Ty` variants as they are not
5533 // that commonly the self_type, it might be interesting to provide
5534 // support for those in future.
5539 fn get_module(this: &mut Resolver, span: Span, name_path: &[ast::Name])
5540 -> Option<Rc<Module>> {
5541 let root = this.current_module.clone();
5542 let last_name = name_path.last().unwrap();
5544 if name_path.len() == 1 {
5545 match this.primitive_type_table.primitive_types.get(last_name) {
5548 match this.current_module.children.borrow().get(last_name) {
5549 Some(child) => child.get_module_if_available(),
5555 match this.resolve_module_path(root,
5560 Success((module, _)) => Some(module),
5566 let (path, node_id, allowed) = match self.current_self_type {
5567 Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5569 None => return NoSuggestion,
5571 None => return NoSuggestion,
5574 if allowed == Everything {
5575 // Look for a field with the same name in the current self_type.
5576 match self.def_map.borrow().get(&node_id) {
5577 Some(&DefTy(did, _))
5578 | Some(&DefStruct(did))
5579 | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
5582 if fields.iter().any(|&field_name| name == field_name) {
5587 _ => {} // Self type didn't resolve properly
5591 let name_path = path.segments.iter().map(|seg| seg.identifier.name).collect::<Vec<_>>();
5593 // Look for a method in the current self type's impl module.
5594 match get_module(self, path.span, name_path[]) {
5595 Some(module) => match module.children.borrow().get(&name) {
5597 let p_str = self.path_names_to_string(&path);
5598 match binding.def_for_namespace(ValueNS) {
5599 Some(DefStaticMethod(_, provenance)) => {
5601 FromImpl(_) => return StaticMethod(p_str),
5602 FromTrait(_) => unreachable!()
5605 Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
5606 Some(DefMethod(_, Some(_), _)) => return TraitItem,
5615 // Look for a method in the current trait.
5616 match self.current_trait_ref {
5617 Some((did, ref trait_ref)) => {
5618 let path_str = self.path_names_to_string(&trait_ref.path);
5620 match self.trait_item_map.get(&(name, did)) {
5621 Some(&StaticMethodTraitItemKind) => {
5622 return TraitMethod(path_str)
5624 Some(_) => return TraitItem,
5634 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5636 let this = &mut *self;
5638 let mut maybes: Vec<token::InternedString> = Vec::new();
5639 let mut values: Vec<uint> = Vec::new();
5641 for rib in this.value_ribs.iter().rev() {
5642 for (&k, _) in rib.bindings.iter() {
5643 maybes.push(token::get_name(k));
5644 values.push(uint::MAX);
5648 let mut smallest = 0;
5649 for (i, other) in maybes.iter().enumerate() {
5650 values[i] = lev_distance(name, other.get());
5652 if values[i] <= values[smallest] {
5657 if values.len() > 0 &&
5658 values[smallest] != uint::MAX &&
5659 values[smallest] < name.len() + 2 &&
5660 values[smallest] <= max_distance &&
5661 name != maybes[smallest].get() {
5663 Some(maybes[smallest].get().to_string())
5670 fn resolve_expr(&mut self, expr: &Expr) {
5671 // First, record candidate traits for this expression if it could
5672 // result in the invocation of a method call.
5674 self.record_candidate_traits_for_expr_if_necessary(expr);
5676 // Next, resolve the node.
5678 // The interpretation of paths depends on whether the path has
5679 // multiple elements in it or not.
5681 ExprPath(ref path) => {
5682 // This is a local path in the value namespace. Walk through
5683 // scopes looking for it.
5685 let path_name = self.path_names_to_string(path);
5687 match self.resolve_path(expr.id, path, ValueNS, true) {
5688 // Check if struct variant
5689 Some((DefVariant(_, _, true), _)) => {
5690 self.resolve_error(expr.span,
5691 format!("`{}` is a struct variant name, but \
5693 uses it like a function name",
5694 path_name).as_slice());
5696 self.session.span_help(expr.span,
5697 format!("Did you mean to write: \
5698 `{} {{ /* fields */ }}`?",
5699 path_name).as_slice());
5702 // Write the result into the def map.
5703 debug!("(resolving expr) resolved `{}`",
5706 self.record_def(expr.id, def);
5709 // Be helpful if the name refers to a struct
5710 // (The pattern matching def_tys where the id is in self.structs
5711 // matches on regular structs while excluding tuple- and enum-like
5712 // structs, which wouldn't result in this error.)
5713 match self.with_no_errors(|this|
5714 this.resolve_path(expr.id, path, TypeNS, false)) {
5715 Some((DefTy(struct_id, _), _))
5716 if self.structs.contains_key(&struct_id) => {
5717 self.resolve_error(expr.span,
5718 format!("`{}` is a structure name, but \
5720 uses it like a function name",
5721 path_name).as_slice());
5723 self.session.span_help(expr.span,
5724 format!("Did you mean to write: \
5725 `{} {{ /* fields */ }}`?",
5726 path_name).as_slice());
5730 let mut method_scope = false;
5731 self.value_ribs.iter().rev().all(|rib| {
5732 let res = match *rib {
5733 Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5734 Rib { bindings: _, kind: ItemRibKind } => false,
5735 _ => return true, // Keep advancing
5739 false // Stop advancing
5742 if method_scope && token::get_name(self.self_name).get()
5746 "`self` is not available \
5747 in a static method. Maybe a \
5748 `self` argument is missing?");
5750 let last_name = path.segments.last().unwrap().identifier.name;
5751 let mut msg = match self.find_fallback_in_self_type(last_name) {
5753 // limit search to 5 to reduce the number
5754 // of stupid suggestions
5755 self.find_best_match_for_name(path_name.as_slice(), 5)
5756 .map_or("".to_string(),
5757 |x| format!("`{}`", x))
5760 format!("`self.{}`", path_name),
5763 format!("to call `self.{}`", path_name),
5764 TraitMethod(path_str)
5765 | StaticMethod(path_str) =>
5766 format!("to call `{}::{}`", path_str, path_name)
5770 msg = format!(". Did you mean {}?", msg)
5775 format!("unresolved name `{}`{}",
5784 visit::walk_expr(self, expr);
5787 ExprClosure(capture_clause, _, ref fn_decl, ref block) => {
5788 self.capture_mode_map.insert(expr.id, capture_clause);
5789 self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
5790 Some(&**fn_decl), NoTypeParameters,
5794 ExprStruct(ref path, _, _) => {
5795 // Resolve the path to the structure it goes to. We don't
5796 // check to ensure that the path is actually a structure; that
5797 // is checked later during typeck.
5798 match self.resolve_path(expr.id, path, TypeNS, false) {
5799 Some(definition) => self.record_def(expr.id, definition),
5801 debug!("(resolving expression) didn't find struct \
5803 let msg = format!("`{}` does not name a structure",
5804 self.path_names_to_string(path));
5805 self.resolve_error(path.span, msg[]);
5809 visit::walk_expr(self, expr);
5812 ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5813 self.with_label_rib(|this| {
5814 let def_like = DlDef(DefLabel(expr.id));
5817 let rib = this.label_ribs.last_mut().unwrap();
5818 let renamed = mtwt::resolve(label);
5819 rib.bindings.insert(renamed, def_like);
5822 visit::walk_expr(this, expr);
5826 ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5827 self.resolve_expr(&**head);
5829 self.value_ribs.push(Rib::new(NormalRibKind));
5831 self.resolve_pattern(&**pattern,
5832 LocalIrrefutableMode,
5833 &mut HashMap::new());
5835 match optional_label {
5839 .push(Rib::new(NormalRibKind));
5840 let def_like = DlDef(DefLabel(expr.id));
5843 let rib = self.label_ribs.last_mut().unwrap();
5844 let renamed = mtwt::resolve(label);
5845 rib.bindings.insert(renamed, def_like);
5850 self.resolve_block(&**body);
5852 if optional_label.is_some() {
5853 drop(self.label_ribs.pop())
5856 self.value_ribs.pop();
5859 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5860 let renamed = mtwt::resolve(label);
5861 match self.search_label(renamed) {
5865 format!("use of undeclared label `{}`",
5866 token::get_ident(label))[])
5868 Some(DlDef(def @ DefLabel(_))) => {
5869 // Since this def is a label, it is never read.
5870 self.record_def(expr.id, (def, LastMod(AllPublic)))
5873 self.session.span_bug(expr.span,
5874 "label wasn't mapped to a \
5881 visit::walk_expr(self, expr);
5886 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5888 ExprField(_, ident) => {
5889 // FIXME(#6890): Even though you can't treat a method like a
5890 // field, we need to add any trait methods we find that match
5891 // the field name so that we can do some nice error reporting
5892 // later on in typeck.
5893 let traits = self.search_for_traits_containing_method(ident.node.name);
5894 self.trait_map.insert(expr.id, traits);
5896 ExprMethodCall(ident, _, _) => {
5897 debug!("(recording candidate traits for expr) recording \
5900 let traits = self.search_for_traits_containing_method(ident.node.name);
5901 self.trait_map.insert(expr.id, traits);
5909 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5910 debug!("(searching for traits containing method) looking for '{}'",
5911 token::get_name(name));
5913 fn add_trait_info(found_traits: &mut Vec<DefId>,
5914 trait_def_id: DefId,
5916 debug!("(adding trait info) found trait {}:{} for method '{}'",
5919 token::get_name(name));
5920 found_traits.push(trait_def_id);
5923 let mut found_traits = Vec::new();
5924 let mut search_module = self.current_module.clone();
5926 // Look for the current trait.
5927 match self.current_trait_ref {
5928 Some((trait_def_id, _)) => {
5929 if self.trait_item_map.contains_key(&(name, trait_def_id)) {
5930 add_trait_info(&mut found_traits, trait_def_id, name);
5933 None => {} // Nothing to do.
5936 // Look for trait children.
5937 self.populate_module_if_necessary(&search_module);
5940 for (_, child_names) in search_module.children.borrow().iter() {
5941 let def = match child_names.def_for_namespace(TypeNS) {
5945 let trait_def_id = match def {
5946 DefTrait(trait_def_id) => trait_def_id,
5949 if self.trait_item_map.contains_key(&(name, trait_def_id)) {
5950 add_trait_info(&mut found_traits, trait_def_id, name);
5955 // Look for imports.
5956 for (_, import) in search_module.import_resolutions.borrow().iter() {
5957 let target = match import.target_for_namespace(TypeNS) {
5959 Some(target) => target,
5961 let did = match target.bindings.def_for_namespace(TypeNS) {
5962 Some(DefTrait(trait_def_id)) => trait_def_id,
5963 Some(..) | None => continue,
5965 if self.trait_item_map.contains_key(&(name, did)) {
5966 add_trait_info(&mut found_traits, did, name);
5967 let id = import.type_id;
5968 self.used_imports.insert((id, TypeNS));
5969 let trait_name = self.get_trait_name(did);
5970 self.record_import_use(id, trait_name);
5971 if let Some(DefId{krate: kid, ..}) = target.target_module.def_id.get() {
5972 self.used_crates.insert(kid);
5977 match search_module.parent_link.clone() {
5978 NoParentLink | ModuleParentLink(..) => break,
5979 BlockParentLink(parent_module, _) => {
5980 search_module = parent_module.upgrade().unwrap();
5988 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5989 debug!("(recording def) recording {} for {}, last private {}",
5991 assert!(match lp {LastImport{..} => false, _ => true},
5992 "Import should only be used for `use` directives");
5993 self.last_private.insert(node_id, lp);
5995 match self.def_map.borrow_mut().entry(node_id) {
5996 // Resolve appears to "resolve" the same ID multiple
5997 // times, so here is a sanity check it at least comes to
5998 // the same conclusion! - nmatsakis
5999 Occupied(entry) => if def != *entry.get() {
6001 .bug(format!("node_id {} resolved first to {} and \
6007 Vacant(entry) => { entry.set(def); },
6011 fn enforce_default_binding_mode(&mut self,
6013 pat_binding_mode: BindingMode,
6015 match pat_binding_mode {
6016 BindByValue(_) => {}
6018 self.resolve_error(pat.span,
6019 format!("cannot use `ref` binding mode \
6029 // Diagnostics are not particularly efficient, because they're rarely
6033 /// A somewhat inefficient routine to obtain the name of a module.
6034 fn module_to_string(&self, module: &Module) -> String {
6035 let mut names = Vec::new();
6037 fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
6038 match module.parent_link {
6040 ModuleParentLink(ref module, name) => {
6042 collect_mod(names, &*module.upgrade().unwrap());
6044 BlockParentLink(ref module, _) => {
6045 // danger, shouldn't be ident?
6046 names.push(special_idents::opaque.name);
6047 collect_mod(names, &*module.upgrade().unwrap());
6051 collect_mod(&mut names, module);
6053 if names.len() == 0 {
6054 return "???".to_string();
6056 self.names_to_string(names.into_iter().rev()
6057 .collect::<Vec<ast::Name>>()[])
6060 #[allow(dead_code)] // useful for debugging
6061 fn dump_module(&mut self, module_: Rc<Module>) {
6062 debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6064 debug!("Children:");
6065 self.populate_module_if_necessary(&module_);
6066 for (&name, _) in module_.children.borrow().iter() {
6067 debug!("* {}", token::get_name(name));
6070 debug!("Import resolutions:");
6071 let import_resolutions = module_.import_resolutions.borrow();
6072 for (&name, import_resolution) in import_resolutions.iter() {
6074 match import_resolution.target_for_namespace(ValueNS) {
6075 None => { value_repr = "".to_string(); }
6077 value_repr = " value:?".to_string();
6083 match import_resolution.target_for_namespace(TypeNS) {
6084 None => { type_repr = "".to_string(); }
6086 type_repr = " type:?".to_string();
6091 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6096 pub struct CrateMap {
6097 pub def_map: DefMap,
6098 pub freevars: RefCell<FreevarMap>,
6099 pub capture_mode_map: RefCell<CaptureModeMap>,
6100 pub export_map: ExportMap,
6101 pub trait_map: TraitMap,
6102 pub external_exports: ExternalExports,
6103 pub last_private_map: LastPrivateMap,
6104 pub glob_map: Option<GlobMap>
6107 #[deriving(PartialEq,Copy)]
6108 pub enum MakeGlobMap {
6113 /// Entry point to crate resolution.
6114 pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
6115 ast_map: &'a ast_map::Map<'tcx>,
6118 make_glob_map: MakeGlobMap)
6120 let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
6122 resolver.build_reduced_graph(krate);
6123 session.abort_if_errors();
6125 resolver.resolve_imports();
6126 session.abort_if_errors();
6128 record_exports::record(&mut resolver);
6129 session.abort_if_errors();
6131 resolver.resolve_crate(krate);
6132 session.abort_if_errors();
6134 check_unused::check_crate(&mut resolver, krate);
6137 def_map: resolver.def_map,
6138 freevars: resolver.freevars,
6139 capture_mode_map: RefCell::new(resolver.capture_mode_map),
6140 export_map: resolver.export_map,
6141 trait_map: resolver.trait_map,
6142 external_exports: resolver.external_exports,
6143 last_private_map: resolver.last_private,
6144 glob_map: if resolver.make_glob_map {
6145 Some(resolver.glob_map)