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 #![allow(non_camel_case_types)]
13 use driver::session::Session;
15 use metadata::csearch;
16 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
18 use middle::lang_items::LanguageItems;
19 use middle::pat_util::pat_bindings;
20 use middle::subst::{ParamSpace, FnSpace, TypeSpace};
21 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
22 use middle::ty::{CaptureModeMap, Freevar, FreevarMap};
23 use util::nodemap::{NodeMap, NodeSet, DefIdSet, FnvHashMap};
25 use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
26 use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
27 use syntax::ast::{ExprFnBlock, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
28 use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
29 use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic, Generics};
30 use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
31 use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
32 use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local};
33 use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
34 use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
35 use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
36 use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
37 use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
38 use syntax::ast::{StructVariantKind, TraitRef, TraitTyParamBound};
39 use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32};
40 use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt};
41 use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyQPath};
42 use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint};
43 use syntax::ast::{TypeImplItem, UnboxedFnTyParamBound, UnnamedField};
44 use syntax::ast::{UnsafeFn, Variant, ViewItem, ViewItemExternCrate};
45 use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
46 use syntax::ast::{Visibility};
48 use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
50 use syntax::attr::AttrMetaMethods;
51 use syntax::ext::mtwt;
52 use syntax::parse::token::special_names;
53 use syntax::parse::token::special_idents;
54 use syntax::parse::token;
55 use syntax::codemap::{Span, DUMMY_SP, Pos};
56 use syntax::owned_slice::OwnedSlice;
59 use syntax::visit::Visitor;
61 use std::collections::{HashMap, HashSet};
62 use std::cell::{Cell, RefCell};
63 use std::mem::replace;
64 use std::rc::{Rc, Weak};
68 pub type DefMap = RefCell<NodeMap<Def>>;
72 binding_mode: BindingMode,
75 // Map from the name in a pattern to its binding mode.
76 type BindingMap = HashMap<Name,binding_info>;
78 // Trait method resolution
79 pub type TraitMap = NodeMap<Vec<DefId> >;
81 // This is the replacement export map. It maps a module to all of the exports
83 pub type ExportMap2 = RefCell<NodeMap<Vec<Export2> >>;
86 pub name: String, // The name of the target.
87 pub def_id: DefId, // The definition of the target.
90 // This set contains all exported definitions from external crates. The set does
91 // not contain any entries from local crates.
92 pub type ExternalExports = DefIdSet;
95 pub type LastPrivateMap = NodeMap<LastPrivate>;
97 pub enum LastPrivate {
99 // `use` directives (imports) can refer to two separate definitions in the
100 // type and value namespaces. We record here the last private node for each
101 // and whether the import is in fact used for each.
102 // If the Option<PrivateDep> fields are None, it means there is no definition
103 // in that namespace.
104 LastImport{pub value_priv: Option<PrivateDep>,
105 pub value_used: ImportUse,
106 pub type_priv: Option<PrivateDep>,
107 pub type_used: ImportUse},
110 pub enum PrivateDep {
115 // How an import is used.
116 #[deriving(PartialEq)]
118 Unused, // The import is not used.
119 Used, // The import is used.
123 fn or(self, other: LastPrivate) -> LastPrivate {
124 match (self, other) {
125 (me, LastMod(AllPublic)) => me,
131 #[deriving(PartialEq)]
132 enum PatternBindingMode {
134 LocalIrrefutableMode,
135 ArgumentIrrefutableMode,
138 #[deriving(PartialEq, Eq, Hash)]
144 #[deriving(PartialEq)]
145 enum NamespaceError {
152 /// A NamespaceResult represents the result of resolving an import in
153 /// a particular namespace. The result is either definitely-resolved,
154 /// definitely- unresolved, or unknown.
156 enum NamespaceResult {
157 /// Means that resolve hasn't gathered enough information yet to determine
158 /// whether the name is bound in this namespace. (That is, it hasn't
159 /// resolved all `use` directives yet.)
161 /// Means that resolve has determined that the name is definitely
162 /// not bound in the namespace.
164 /// Means that resolve has determined that the name is bound in the Module
165 /// argument, and specified by the NameBindings argument.
166 BoundResult(Rc<Module>, Rc<NameBindings>)
169 impl NamespaceResult {
170 fn is_unknown(&self) -> bool {
172 UnknownResult => true,
176 fn is_unbound(&self) -> bool {
178 UnboundResult => true,
184 enum NameDefinition {
185 NoNameDefinition, //< The name was unbound.
186 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
187 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
190 impl<'a, 'v> Visitor<'v> for Resolver<'a> {
191 fn visit_item(&mut self, item: &Item) {
192 self.resolve_item(item);
194 fn visit_arm(&mut self, arm: &Arm) {
195 self.resolve_arm(arm);
197 fn visit_block(&mut self, block: &Block) {
198 self.resolve_block(block);
200 fn visit_expr(&mut self, expr: &Expr) {
201 self.resolve_expr(expr);
203 fn visit_local(&mut self, local: &Local) {
204 self.resolve_local(local);
206 fn visit_ty(&mut self, ty: &Ty) {
207 self.resolve_type(ty);
211 /// Contains data for specific types of import directives.
212 enum ImportDirectiveSubclass {
213 SingleImport(Ident /* target */, Ident /* source */),
217 /// The context that we thread through while building the reduced graph.
219 enum ReducedGraphParent {
220 ModuleReducedGraphParent(Rc<Module>)
223 impl ReducedGraphParent {
224 fn module(&self) -> Rc<Module> {
226 ModuleReducedGraphParent(ref m) => {
233 type ErrorMessage = Option<(Span, String)>;
235 enum ResolveResult<T> {
236 Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
237 Indeterminate, // Couldn't determine due to unresolved globs.
238 Success(T) // Successfully resolved the import.
241 impl<T> ResolveResult<T> {
242 fn indeterminate(&self) -> bool {
243 match *self { Indeterminate => true, _ => false }
247 enum FallbackSuggestion {
252 StaticMethod(String),
253 StaticTraitMethod(String),
256 enum TypeParameters<'a> {
262 // Identifies the things that these parameters
263 // were declared on (type, fn, etc)
266 // ID of the enclosing item.
269 // The kind of the rib used for type parameters.
273 // The rib kind controls the translation of local
274 // definitions (`DefLocal`) to upvars (`DefUpvar`).
277 // No translation needs to be applied.
280 // We passed through a closure scope at the given node ID.
281 // Translate upvars as appropriate.
282 ClosureRibKind(NodeId /* func id */, NodeId /* body id if proc or unboxed */),
284 // We passed through an impl or trait and are now in one of its
285 // methods. Allow references to ty params that impl or trait
286 // binds. Disallow any other upvars (including other ty params that are
288 // parent; method itself
289 MethodRibKind(NodeId, MethodSort),
291 // We passed through an item scope. Disallow upvars.
294 // We're in a constant item. Can't refer to dynamic stuff.
298 // Methods can be required or provided. RequiredMethod methods only occur in traits.
301 ProvidedMethod(NodeId)
304 enum UseLexicalScopeFlag {
309 enum ModulePrefixResult {
311 PrefixFound(Rc<Module>, uint)
314 #[deriving(Clone, Eq, PartialEq)]
315 pub enum TraitItemKind {
316 NonstaticMethodTraitItemKind,
317 StaticMethodTraitItemKind,
322 pub fn from_explicit_self_category(explicit_self_category:
323 ExplicitSelfCategory)
325 if explicit_self_category == StaticExplicitSelfCategory {
326 StaticMethodTraitItemKind
328 NonstaticMethodTraitItemKind
333 #[deriving(PartialEq)]
334 enum NameSearchType {
335 /// We're doing a name search in order to resolve a `use` directive.
338 /// We're doing a name search in order to resolve a path type, a path
339 /// expression, or a path pattern.
343 enum BareIdentifierPatternResolution {
344 FoundStructOrEnumVariant(Def, LastPrivate),
345 FoundConst(Def, LastPrivate),
346 BareIdentifierPatternUnresolved
349 // Specifies how duplicates should be handled when adding a child item if
350 // another item exists with the same name in some namespace.
351 #[deriving(PartialEq)]
352 enum DuplicateCheckingMode {
353 ForbidDuplicateModules,
354 ForbidDuplicateTypesAndModules,
355 ForbidDuplicateValues,
356 ForbidDuplicateTypesAndValues,
362 bindings: RefCell<HashMap<Name, DefLike>>,
367 fn new(kind: RibKind) -> Rib {
369 bindings: RefCell::new(HashMap::new()),
375 /// One import directive.
376 struct ImportDirective {
377 module_path: Vec<Ident>,
378 subclass: ImportDirectiveSubclass,
381 is_public: bool, // see note in ImportResolution about how to use this
385 impl ImportDirective {
386 fn new(module_path: Vec<Ident> ,
387 subclass: ImportDirectiveSubclass,
394 module_path: module_path,
398 is_public: is_public,
399 shadowable: shadowable,
404 /// The item that an import resolves to.
407 target_module: Rc<Module>,
408 bindings: Rc<NameBindings>,
413 fn new(target_module: Rc<Module>,
414 bindings: Rc<NameBindings>,
418 target_module: target_module,
420 shadowable: shadowable,
425 /// An ImportResolution represents a particular `use` directive.
426 struct ImportResolution {
427 /// Whether this resolution came from a `use` or a `pub use`. Note that this
428 /// should *not* be used whenever resolution is being performed, this is
429 /// only looked at for glob imports statements currently. Privacy testing
430 /// occurs during a later phase of compilation.
433 // The number of outstanding references to this name. When this reaches
434 // zero, outside modules can count on the targets being correct. Before
435 // then, all bets are off; future imports could override this name.
436 outstanding_references: uint,
438 /// The value that this `use` directive names, if there is one.
439 value_target: Option<Target>,
440 /// The source node of the `use` directive leading to the value target
444 /// The type that this `use` directive names, if there is one.
445 type_target: Option<Target>,
446 /// The source node of the `use` directive leading to the type target
451 impl ImportResolution {
452 fn new(id: NodeId, is_public: bool) -> ImportResolution {
456 outstanding_references: 0,
459 is_public: is_public,
463 fn target_for_namespace(&self, namespace: Namespace)
466 TypeNS => self.type_target.clone(),
467 ValueNS => self.value_target.clone(),
471 fn id(&self, namespace: Namespace) -> NodeId {
473 TypeNS => self.type_id,
474 ValueNS => self.value_id,
479 /// The link from a module up to its nearest parent node.
483 ModuleParentLink(Weak<Module>, Ident),
484 BlockParentLink(Weak<Module>, NodeId)
487 /// The type of module this is.
488 #[deriving(PartialEq)]
497 /// One node in the tree of modules.
499 parent_link: ParentLink,
500 def_id: Cell<Option<DefId>>,
501 kind: Cell<ModuleKind>,
504 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
505 imports: RefCell<Vec<ImportDirective>>,
507 // The external module children of this node that were declared with
509 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
511 // The anonymous children of this node. Anonymous children are pseudo-
512 // modules that are implicitly created around items contained within
515 // For example, if we have this:
523 // There will be an anonymous module created around `g` with the ID of the
524 // entry block for `f`.
525 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
527 // The status of resolving each import in this module.
528 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
530 // The number of unresolved globs that this module exports.
531 glob_count: Cell<uint>,
533 // The index of the import we're resolving.
534 resolved_import_count: Cell<uint>,
536 // Whether this module is populated. If not populated, any attempt to
537 // access the children must be preceded with a
538 // `populate_module_if_necessary` call.
539 populated: Cell<bool>,
543 fn new(parent_link: ParentLink,
544 def_id: Option<DefId>,
550 parent_link: parent_link,
551 def_id: Cell::new(def_id),
552 kind: Cell::new(kind),
553 is_public: is_public,
554 children: RefCell::new(HashMap::new()),
555 imports: RefCell::new(Vec::new()),
556 external_module_children: RefCell::new(HashMap::new()),
557 anonymous_children: RefCell::new(NodeMap::new()),
558 import_resolutions: RefCell::new(HashMap::new()),
559 glob_count: Cell::new(0),
560 resolved_import_count: Cell::new(0),
561 populated: Cell::new(!external),
565 fn all_imports_resolved(&self) -> bool {
566 self.imports.borrow().len() == self.resolved_import_count.get()
570 // Records a possibly-private type definition.
573 is_public: bool, // see note in ImportResolution about how to use this
574 module_def: Option<Rc<Module>>,
575 type_def: Option<Def>,
576 type_span: Option<Span>
579 // Records a possibly-private value definition.
582 is_public: bool, // see note in ImportResolution about how to use this
584 value_span: Option<Span>,
587 // Records the definitions (at most one for each namespace) that a name is
589 struct NameBindings {
590 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
591 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
594 /// Ways in which a trait can be referenced
595 enum TraitReferenceType {
596 TraitImplementation, // impl SomeTrait for T { ... }
597 TraitDerivation, // trait T : SomeTrait { ... }
598 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
602 fn new() -> NameBindings {
604 type_def: RefCell::new(None),
605 value_def: RefCell::new(None),
609 /// Creates a new module in this set of name bindings.
610 fn define_module(&self,
611 parent_link: ParentLink,
612 def_id: Option<DefId>,
617 // Merges the module with the existing type def or creates a new one.
618 let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
620 let type_def = self.type_def.borrow().clone();
623 *self.type_def.borrow_mut() = Some(TypeNsDef {
624 is_public: is_public,
625 module_def: Some(module_),
631 *self.type_def.borrow_mut() = Some(TypeNsDef {
632 is_public: is_public,
633 module_def: Some(module_),
635 type_def: type_def.type_def
641 /// Sets the kind of the module, creating a new one if necessary.
642 fn set_module_kind(&self,
643 parent_link: ParentLink,
644 def_id: Option<DefId>,
649 let type_def = self.type_def.borrow().clone();
652 let module = Module::new(parent_link, def_id, kind,
653 external, is_public);
654 *self.type_def.borrow_mut() = Some(TypeNsDef {
655 is_public: is_public,
656 module_def: Some(Rc::new(module)),
662 match type_def.module_def {
664 let module = Module::new(parent_link,
669 *self.type_def.borrow_mut() = Some(TypeNsDef {
670 is_public: is_public,
671 module_def: Some(Rc::new(module)),
672 type_def: type_def.type_def,
676 Some(module_def) => module_def.kind.set(kind),
682 /// Records a type definition.
683 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
684 // Merges the type with the existing type def or creates a new one.
685 let type_def = self.type_def.borrow().clone();
688 *self.type_def.borrow_mut() = Some(TypeNsDef {
692 is_public: is_public,
696 *self.type_def.borrow_mut() = Some(TypeNsDef {
699 module_def: type_def.module_def,
700 is_public: is_public,
706 /// Records a value definition.
707 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
708 *self.value_def.borrow_mut() = Some(ValueNsDef {
710 value_span: Some(sp),
711 is_public: is_public,
715 /// Returns the module node if applicable.
716 fn get_module_if_available(&self) -> Option<Rc<Module>> {
717 match *self.type_def.borrow() {
718 Some(ref type_def) => type_def.module_def.clone(),
724 * Returns the module node. Fails if this node does not have a module
727 fn get_module(&self) -> Rc<Module> {
728 match self.get_module_if_available() {
730 fail!("get_module called on a node with no module \
733 Some(module_def) => module_def
737 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
739 TypeNS => return self.type_def.borrow().is_some(),
740 ValueNS => return self.value_def.borrow().is_some()
744 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
746 TypeNS => match *self.type_def.borrow() {
747 Some(ref def) => def.is_public, None => false
749 ValueNS => match *self.value_def.borrow() {
750 Some(ref def) => def.is_public, None => false
755 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
758 match *self.type_def.borrow() {
760 Some(ref type_def) => {
761 match type_def.type_def {
762 Some(type_def) => Some(type_def),
764 match type_def.module_def {
765 Some(ref module) => {
766 match module.def_id.get() {
767 Some(did) => Some(DefMod(did)),
779 match *self.value_def.borrow() {
781 Some(value_def) => Some(value_def.def)
787 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
788 if self.defined_in_namespace(namespace) {
791 match *self.type_def.borrow() {
793 Some(ref type_def) => type_def.type_span
797 match *self.value_def.borrow() {
799 Some(ref value_def) => value_def.value_span
809 /// Interns the names of the primitive types.
810 struct PrimitiveTypeTable {
811 primitive_types: HashMap<Name, PrimTy>,
814 impl PrimitiveTypeTable {
815 fn new() -> PrimitiveTypeTable {
816 let mut table = PrimitiveTypeTable {
817 primitive_types: HashMap::new()
820 table.intern("bool", TyBool);
821 table.intern("char", TyChar);
822 table.intern("f32", TyFloat(TyF32));
823 table.intern("f64", TyFloat(TyF64));
824 table.intern("int", TyInt(TyI));
825 table.intern("i8", TyInt(TyI8));
826 table.intern("i16", TyInt(TyI16));
827 table.intern("i32", TyInt(TyI32));
828 table.intern("i64", TyInt(TyI64));
829 table.intern("str", TyStr);
830 table.intern("uint", TyUint(TyU));
831 table.intern("u8", TyUint(TyU8));
832 table.intern("u16", TyUint(TyU16));
833 table.intern("u32", TyUint(TyU32));
834 table.intern("u64", TyUint(TyU64));
839 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
840 self.primitive_types.insert(token::intern(string), primitive_type);
845 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
848 ModuleError | TypeError => "type or module",
849 ValueError => "value",
853 /// The main resolver class.
854 struct Resolver<'a> {
855 session: &'a Session,
857 graph_root: NameBindings,
859 trait_item_map: RefCell<FnvHashMap<(Name, DefId), TraitItemKind>>,
861 structs: FnvHashMap<DefId, Vec<Name>>,
863 // The number of imports that are currently unresolved.
864 unresolved_imports: uint,
866 // The module that represents the current item scope.
867 current_module: Rc<Module>,
869 // The current set of local scopes, for values.
870 // FIXME #4948: Reuse ribs to avoid allocation.
871 value_ribs: RefCell<Vec<Rib>>,
873 // The current set of local scopes, for types.
874 type_ribs: RefCell<Vec<Rib>>,
876 // The current set of local scopes, for labels.
877 label_ribs: RefCell<Vec<Rib>>,
879 // The trait that the current context can refer to.
880 current_trait_ref: Option<(DefId, TraitRef)>,
882 // The current self type if inside an impl (used for better errors).
883 current_self_type: Option<Ty>,
885 // The ident for the keyword "self".
887 // The ident for the non-keyword "Self".
888 type_self_name: Name,
890 // The idents for the primitive types.
891 primitive_type_table: PrimitiveTypeTable,
894 freevars: RefCell<FreevarMap>,
895 freevars_seen: RefCell<NodeMap<NodeSet>>,
896 capture_mode_map: RefCell<CaptureModeMap>,
897 export_map2: ExportMap2,
899 external_exports: ExternalExports,
900 last_private: LastPrivateMap,
902 // Whether or not to print error messages. Can be set to true
903 // when getting additional info for error message suggestions,
904 // so as to avoid printing duplicate errors
907 used_imports: HashSet<(NodeId, Namespace)>,
908 used_crates: HashSet<CrateNum>,
911 struct BuildReducedGraphVisitor<'a, 'b:'a> {
912 resolver: &'a mut Resolver<'b>,
913 parent: ReducedGraphParent
916 impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
918 fn visit_item(&mut self, item: &Item) {
919 let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
920 let old_parent = replace(&mut self.parent, p);
921 visit::walk_item(self, item);
922 self.parent = old_parent;
925 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
926 let parent = self.parent.clone();
927 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
930 let mut v = BuildReducedGraphVisitor {
932 parent: parent.clone()
934 visit::walk_foreign_item(&mut v, foreign_item);
938 fn visit_view_item(&mut self, view_item: &ViewItem) {
939 self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
942 fn visit_block(&mut self, block: &Block) {
943 let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
944 let old_parent = replace(&mut self.parent, np);
945 visit::walk_block(self, block);
946 self.parent = old_parent;
951 struct UnusedImportCheckVisitor<'a, 'b:'a> {
952 resolver: &'a mut Resolver<'b>
955 impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
956 fn visit_view_item(&mut self, vi: &ViewItem) {
957 self.resolver.check_for_item_unused_imports(vi);
958 visit::walk_view_item(self, vi);
962 impl<'a> Resolver<'a> {
963 fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
964 let graph_root = NameBindings::new();
966 graph_root.define_module(NoParentLink,
967 Some(DefId { krate: 0, node: 0 }),
973 let current_module = graph_root.get_module();
978 // The outermost module has def ID 0; this is not reflected in the
981 graph_root: graph_root,
983 trait_item_map: RefCell::new(FnvHashMap::new()),
984 structs: FnvHashMap::new(),
986 unresolved_imports: 0,
988 current_module: current_module,
989 value_ribs: RefCell::new(Vec::new()),
990 type_ribs: RefCell::new(Vec::new()),
991 label_ribs: RefCell::new(Vec::new()),
993 current_trait_ref: None,
994 current_self_type: None,
996 self_name: special_names::self_,
997 type_self_name: special_names::type_self,
999 primitive_type_table: PrimitiveTypeTable::new(),
1001 def_map: RefCell::new(NodeMap::new()),
1002 freevars: RefCell::new(NodeMap::new()),
1003 freevars_seen: RefCell::new(NodeMap::new()),
1004 capture_mode_map: RefCell::new(NodeMap::new()),
1005 export_map2: RefCell::new(NodeMap::new()),
1006 trait_map: NodeMap::new(),
1007 used_imports: HashSet::new(),
1008 used_crates: HashSet::new(),
1009 external_exports: DefIdSet::new(),
1010 last_private: NodeMap::new(),
1015 /// The main name resolution procedure.
1016 fn resolve(&mut self, krate: &ast::Crate) {
1017 self.build_reduced_graph(krate);
1018 self.session.abort_if_errors();
1020 self.resolve_imports();
1021 self.session.abort_if_errors();
1023 self.record_exports();
1024 self.session.abort_if_errors();
1026 self.resolve_crate(krate);
1027 self.session.abort_if_errors();
1029 self.check_for_unused_imports(krate);
1033 // Reduced graph building
1035 // Here we build the "reduced graph": the graph of the module tree without
1036 // any imports resolved.
1039 /// Constructs the reduced graph for the entire crate.
1040 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
1041 let parent = ModuleReducedGraphParent(self.graph_root.get_module());
1042 let mut visitor = BuildReducedGraphVisitor {
1046 visit::walk_crate(&mut visitor, krate);
1050 * Adds a new child item to the module definition of the parent node and
1051 * returns its corresponding name bindings as well as the current parent.
1052 * Or, if we're inside a block, creates (or reuses) an anonymous module
1053 * corresponding to the innermost block ID and returns the name bindings
1054 * as well as the newly-created parent.
1056 * If this node does not have a module definition and we are not inside
1061 reduced_graph_parent: ReducedGraphParent,
1062 duplicate_checking_mode: DuplicateCheckingMode,
1063 // For printing errors
1065 -> Rc<NameBindings> {
1066 // If this is the immediate descendant of a module, then we add the
1067 // child name directly. Otherwise, we create or reuse an anonymous
1068 // module and add the child to that.
1070 let module_ = reduced_graph_parent.module();
1072 self.check_for_conflicts_between_external_crates_and_items(&*module_,
1076 // Add or reuse the child.
1077 let child = module_.children.borrow().find_copy(&name.name);
1080 let child = Rc::new(NameBindings::new());
1081 module_.children.borrow_mut().insert(name.name, child.clone());
1085 // Enforce the duplicate checking mode:
1087 // * If we're requesting duplicate module checking, check that
1088 // there isn't a module in the module with the same name.
1090 // * If we're requesting duplicate type checking, check that
1091 // there isn't a type in the module with the same name.
1093 // * If we're requesting duplicate value checking, check that
1094 // there isn't a value in the module with the same name.
1096 // * If we're requesting duplicate type checking and duplicate
1097 // value checking, check that there isn't a duplicate type
1098 // and a duplicate value with the same name.
1100 // * If no duplicate checking was requested at all, do
1103 let mut duplicate_type = NoError;
1104 let ns = match duplicate_checking_mode {
1105 ForbidDuplicateModules => {
1106 if child.get_module_if_available().is_some() {
1107 duplicate_type = ModuleError;
1111 ForbidDuplicateTypesAndModules => {
1112 match child.def_for_namespace(TypeNS) {
1114 Some(_) if child.get_module_if_available()
1115 .map(|m| m.kind.get()) ==
1116 Some(ImplModuleKind) => {}
1117 Some(_) => duplicate_type = TypeError
1121 ForbidDuplicateValues => {
1122 if child.defined_in_namespace(ValueNS) {
1123 duplicate_type = ValueError;
1127 ForbidDuplicateTypesAndValues => {
1129 match child.def_for_namespace(TypeNS) {
1130 Some(DefMod(_)) | None => {}
1133 duplicate_type = TypeError;
1136 if child.defined_in_namespace(ValueNS) {
1137 duplicate_type = ValueError;
1142 OverwriteDuplicates => None
1144 if duplicate_type != NoError {
1145 // Return an error here by looking up the namespace that
1146 // had the duplicate.
1147 let ns = ns.unwrap();
1148 self.resolve_error(sp,
1149 format!("duplicate definition of {} `{}`",
1150 namespace_error_to_string(duplicate_type),
1151 token::get_ident(name)).as_slice());
1153 let r = child.span_for_namespace(ns);
1154 for sp in r.iter() {
1155 self.session.span_note(*sp,
1156 format!("first definition of {} `{}` here",
1157 namespace_error_to_string(duplicate_type),
1158 token::get_ident(name)).as_slice());
1167 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1168 // If the block has view items, we need an anonymous module.
1169 if block.view_items.len() > 0 {
1173 // Check each statement.
1174 for statement in block.stmts.iter() {
1175 match statement.node {
1176 StmtDecl(ref declaration, _) => {
1177 match declaration.node {
1192 // If we found neither view items nor items, we don't need to create
1193 // an anonymous module.
1198 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1201 ModuleReducedGraphParent(module_) => {
1202 return ModuleParentLink(module_.downgrade(), name);
1207 /// Constructs the reduced graph for one item.
1208 fn build_reduced_graph_for_item(&mut self,
1210 parent: ReducedGraphParent)
1211 -> ReducedGraphParent
1213 let ident = item.ident;
1215 let is_public = item.vis == ast::Public;
1220 self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp);
1222 let parent_link = self.get_parent_link(parent, ident);
1223 let def_id = DefId { krate: 0, node: item.id };
1224 name_bindings.define_module(parent_link,
1228 item.vis == ast::Public,
1231 ModuleReducedGraphParent(name_bindings.get_module())
1234 ItemForeignMod(..) => parent,
1236 // These items live in the value namespace.
1237 ItemStatic(_, m, _) => {
1239 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1240 let mutbl = m == ast::MutMutable;
1242 name_bindings.define_value
1243 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1246 ItemFn(_, fn_style, _, _, _) => {
1248 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1250 let def = DefFn(local_def(item.id), fn_style);
1251 name_bindings.define_value(def, sp, is_public);
1255 // These items live in the type namespace.
1258 self.add_child(ident,
1260 ForbidDuplicateTypesAndModules,
1263 name_bindings.define_type
1264 (DefTy(local_def(item.id), false), sp, is_public);
1268 ItemEnum(ref enum_definition, _) => {
1270 self.add_child(ident,
1272 ForbidDuplicateTypesAndModules,
1275 name_bindings.define_type
1276 (DefTy(local_def(item.id), true), sp, is_public);
1278 for variant in (*enum_definition).variants.iter() {
1279 self.build_reduced_graph_for_variant(
1288 // These items live in both the type and value namespaces.
1289 ItemStruct(ref struct_def, _) => {
1290 // Adding to both Type and Value namespaces or just Type?
1291 let (forbid, ctor_id) = match struct_def.ctor_id {
1292 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1293 None => (ForbidDuplicateTypesAndModules, None)
1296 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
1298 // Define a name in the type namespace.
1299 name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public);
1301 // If this is a newtype or unit-like struct, define a name
1302 // in the value namespace as well
1303 ctor_id.while_some(|cid| {
1304 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1309 // Record the def ID and fields of this struct.
1310 let named_fields = struct_def.fields.iter().filter_map(|f| {
1312 NamedField(ident, _) => Some(ident.name),
1313 UnnamedField(_) => None
1316 self.structs.insert(local_def(item.id), named_fields);
1321 ItemImpl(_, None, ref ty, ref impl_items) => {
1322 // If this implements an anonymous trait, then add all the
1323 // methods within to a new module, if the type was defined
1324 // within this module.
1326 // Create the module and add all methods.
1328 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1329 let name = path.segments.last().unwrap().identifier;
1331 let parent_opt = parent.module().children.borrow()
1332 .find_copy(&name.name);
1333 let new_parent = match parent_opt {
1334 // It already exists
1335 Some(ref child) if child.get_module_if_available()
1337 child.get_module().kind.get() ==
1339 ModuleReducedGraphParent(child.get_module())
1341 // Create the module
1344 self.add_child(name,
1346 ForbidDuplicateModules,
1350 self.get_parent_link(parent.clone(), ident);
1351 let def_id = local_def(item.id);
1354 !name_bindings.defined_in_namespace(ns) ||
1355 name_bindings.defined_in_public_namespace(ns);
1357 name_bindings.define_module(parent_link,
1364 ModuleReducedGraphParent(
1365 name_bindings.get_module())
1369 // For each implementation item...
1370 for impl_item in impl_items.iter() {
1372 MethodImplItem(ref method) => {
1373 // Add the method to the module.
1374 let ident = method.pe_ident();
1375 let method_name_bindings =
1376 self.add_child(ident,
1378 ForbidDuplicateValues,
1380 let def = match method.pe_explicit_self()
1383 // Static methods become
1384 // `def_static_method`s.
1386 local_def(method.id),
1387 FromImpl(local_def(item.id)),
1388 method.pe_fn_style())
1391 // Non-static methods become
1393 DefMethod(local_def(method.id),
1399 method.pe_vis() == ast::Public;
1400 method_name_bindings.define_value(
1405 TypeImplItem(ref typedef) => {
1406 // Add the typedef to the module.
1407 let ident = typedef.ident;
1408 let typedef_name_bindings =
1412 ForbidDuplicateTypesAndModules,
1414 let def = DefAssociatedTy(local_def(
1416 let is_public = typedef.vis ==
1418 typedef_name_bindings.define_type(
1427 self.resolve_error(ty.span,
1428 "inherent implementations may \
1429 only be implemented in the same \
1430 module as the type they are \
1438 ItemImpl(_, Some(_), _, _) => parent,
1440 ItemTrait(_, _, _, ref methods) => {
1442 self.add_child(ident,
1444 ForbidDuplicateTypesAndModules,
1447 // Add all the methods within to a new module.
1448 let parent_link = self.get_parent_link(parent.clone(), ident);
1449 name_bindings.define_module(parent_link,
1450 Some(local_def(item.id)),
1453 item.vis == ast::Public,
1455 let module_parent = ModuleReducedGraphParent(name_bindings.
1458 let def_id = local_def(item.id);
1460 // Add the names of all the methods to the trait info.
1461 for method in methods.iter() {
1462 let (ident, kind) = match *method {
1463 ast::RequiredMethod(_) |
1464 ast::ProvidedMethod(_) => {
1466 ast_util::trait_item_to_ty_method(method);
1468 let ident = ty_m.ident;
1470 // Add it as a name in the trait module.
1471 let (def, static_flag) = match ty_m.explicit_self
1474 // Static methods become
1475 // `def_static_method`s.
1478 FromTrait(local_def(item.id)),
1480 StaticMethodTraitItemKind)
1483 // Non-static methods become
1485 (DefMethod(local_def(ty_m.id),
1486 Some(local_def(item.id))),
1487 NonstaticMethodTraitItemKind)
1491 let method_name_bindings =
1492 self.add_child(ident,
1493 module_parent.clone(),
1494 ForbidDuplicateTypesAndValues,
1496 method_name_bindings.define_value(def,
1500 (ident, static_flag)
1502 ast::TypeTraitItem(ref associated_type) => {
1503 let def = DefAssociatedTy(local_def(
1504 associated_type.id));
1507 self.add_child(associated_type.ident,
1508 module_parent.clone(),
1509 ForbidDuplicateTypesAndValues,
1510 associated_type.span);
1511 name_bindings.define_type(def,
1512 associated_type.span,
1515 (associated_type.ident, TypeTraitItemKind)
1521 .insert((ident.name, def_id), kind);
1524 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1527 ItemMac(..) => parent
1531 // Constructs the reduced graph for one variant. Variants exist in the
1532 // type and value namespaces.
1533 fn build_reduced_graph_for_variant(&mut self,
1536 parent: ReducedGraphParent,
1538 let ident = variant.node.name;
1539 let is_exported = match variant.node.kind {
1540 TupleVariantKind(_) => false,
1541 StructVariantKind(_) => {
1542 // Not adding fields for variants as they are not accessed with a self receiver
1543 self.structs.insert(local_def(variant.node.id), Vec::new());
1548 let child = self.add_child(ident, parent,
1549 ForbidDuplicateTypesAndValues,
1551 child.define_value(DefVariant(item_id,
1552 local_def(variant.node.id), is_exported),
1553 variant.span, is_public);
1554 child.define_type(DefVariant(item_id,
1555 local_def(variant.node.id), is_exported),
1556 variant.span, is_public);
1559 /// Constructs the reduced graph for one 'view item'. View items consist
1560 /// of imports and use directives.
1561 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1562 parent: ReducedGraphParent) {
1563 match view_item.node {
1564 ViewItemUse(ref view_path) => {
1565 // Extract and intern the module part of the path. For
1566 // globs and lists, the path is found directly in the AST;
1567 // for simple paths we have to munge the path a little.
1568 let module_path = match view_path.node {
1569 ViewPathSimple(_, ref full_path, _) => {
1572 .iter().map(|ident| ident.identifier)
1576 ViewPathGlob(ref module_ident_path, _) |
1577 ViewPathList(ref module_ident_path, _, _) => {
1578 module_ident_path.segments
1579 .iter().map(|ident| ident.identifier).collect()
1583 // Build up the import directives.
1584 let module_ = parent.module();
1585 let is_public = view_item.vis == ast::Public;
1590 attr.name() == token::get_ident(
1591 special_idents::prelude_import)
1594 match view_path.node {
1595 ViewPathSimple(binding, ref full_path, id) => {
1597 full_path.segments.last().unwrap().identifier;
1598 if token::get_ident(source_ident).get() == "mod" {
1599 self.resolve_error(view_path.span,
1600 "`mod` imports are only allowed within a { } list");
1603 let subclass = SingleImport(binding,
1605 self.build_import_directive(&*module_,
1613 ViewPathList(_, ref source_items, _) => {
1614 // Make sure there's at most one `mod` import in the list.
1615 let mod_spans = source_items.iter().filter_map(|item| match item.node {
1616 PathListMod { .. } => Some(item.span),
1618 }).collect::<Vec<Span>>();
1619 if mod_spans.len() > 1 {
1620 self.resolve_error(mod_spans[0],
1621 "`mod` import can only appear once in the list");
1622 for other_span in mod_spans.iter().skip(1) {
1623 self.session.span_note(*other_span,
1624 "another `mod` import appears here");
1628 for source_item in source_items.iter() {
1629 let (module_path, name) = match source_item.node {
1630 PathListIdent { name, .. } =>
1631 (module_path.clone(), name),
1632 PathListMod { .. } => {
1633 let name = match module_path.last() {
1634 Some(ident) => ident.clone(),
1636 self.resolve_error(source_item.span,
1637 "`mod` import can only appear in an import list \
1638 with a non-empty prefix");
1642 let module_path = module_path.as_slice().init();
1643 (Vec::from_slice(module_path), name)
1646 self.build_import_directive(
1649 SingleImport(name, name),
1651 source_item.node.id(),
1656 ViewPathGlob(_, id) => {
1657 self.build_import_directive(&*module_,
1668 ViewItemExternCrate(name, _, node_id) => {
1669 // n.b. we don't need to look at the path option here, because cstore already did
1670 for &crate_id in self.session.cstore
1671 .find_extern_mod_stmt_cnum(node_id).iter() {
1672 let def_id = DefId { krate: crate_id, node: 0 };
1673 self.external_exports.insert(def_id);
1675 ModuleParentLink(parent.module().downgrade(), name);
1676 let external_module = Rc::new(Module::new(parent_link,
1681 debug!("(build reduced graph for item) found extern `{}`",
1682 self.module_to_string(&*external_module));
1683 self.check_for_conflicts_between_external_crates(
1687 parent.module().external_module_children.borrow_mut()
1688 .insert(name.name, external_module.clone());
1689 self.build_reduced_graph_for_external_crate(external_module);
1695 /// Constructs the reduced graph for one foreign item.
1696 fn build_reduced_graph_for_foreign_item(&mut self,
1697 foreign_item: &ForeignItem,
1698 parent: ReducedGraphParent,
1699 f: |&mut Resolver|) {
1700 let name = foreign_item.ident;
1701 let is_public = foreign_item.vis == ast::Public;
1703 self.add_child(name, parent, ForbidDuplicateValues,
1706 match foreign_item.node {
1707 ForeignItemFn(_, ref generics) => {
1708 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1709 name_bindings.define_value(def, foreign_item.span, is_public);
1711 self.with_type_parameter_rib(
1712 HasTypeParameters(generics,
1718 ForeignItemStatic(_, m) => {
1719 let def = DefStatic(local_def(foreign_item.id), m);
1720 name_bindings.define_value(def, foreign_item.span, is_public);
1727 fn build_reduced_graph_for_block(&mut self,
1729 parent: ReducedGraphParent)
1730 -> ReducedGraphParent
1732 if self.block_needs_anonymous_module(block) {
1733 let block_id = block.id;
1735 debug!("(building reduced graph for block) creating a new \
1736 anonymous module for block {}",
1739 let parent_module = parent.module();
1740 let new_module = Rc::new(Module::new(
1741 BlockParentLink(parent_module.downgrade(), block_id),
1743 AnonymousModuleKind,
1746 parent_module.anonymous_children.borrow_mut()
1747 .insert(block_id, new_module.clone());
1748 ModuleReducedGraphParent(new_module)
1754 fn handle_external_def(&mut self,
1757 child_name_bindings: &NameBindings,
1760 new_parent: ReducedGraphParent) {
1761 debug!("(building reduced graph for \
1762 external crate) building external def, priv {:?}",
1764 let is_public = vis == ast::Public;
1765 let is_exported = is_public && match new_parent {
1766 ModuleReducedGraphParent(ref module) => {
1767 match module.def_id.get() {
1769 Some(did) => self.external_exports.contains(&did)
1774 self.external_exports.insert(def.def_id());
1777 let kind = match def {
1778 DefStruct(..) | DefTy(..) => ImplModuleKind,
1779 _ => NormalModuleKind
1783 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1784 DefTy(def_id, _) => {
1785 let type_def = child_name_bindings.type_def.borrow().clone();
1787 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1788 debug!("(building reduced graph for external crate) \
1789 already created module");
1790 module_def.def_id.set(Some(def_id));
1793 debug!("(building reduced graph for \
1794 external crate) building module \
1796 let parent_link = self.get_parent_link(new_parent.clone(), ident);
1798 child_name_bindings.define_module(parent_link,
1811 DefMod(_) | DefForeignMod(_) => {}
1812 DefVariant(enum_did, variant_id, is_struct) => {
1813 debug!("(building reduced graph for external crate) building \
1816 // If this variant is public, then it was publicly reexported,
1817 // otherwise we need to inherit the visibility of the enum
1819 let is_exported = is_public ||
1820 self.external_exports.contains(&enum_did);
1822 child_name_bindings.define_type(def, DUMMY_SP, is_exported);
1823 // Not adding fields for variants as they are not accessed with a self receiver
1824 self.structs.insert(variant_id, Vec::new());
1826 child_name_bindings.define_value(def, DUMMY_SP, is_exported);
1829 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1830 debug!("(building reduced graph for external \
1831 crate) building value (fn/static) {}", final_ident);
1832 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1834 DefTrait(def_id) => {
1835 debug!("(building reduced graph for external \
1836 crate) building type {}", final_ident);
1838 // If this is a trait, add all the trait item names to the trait
1841 let trait_item_def_ids =
1842 csearch::get_trait_item_def_ids(&self.session.cstore, def_id);
1843 for trait_item_def_id in trait_item_def_ids.iter() {
1844 let (trait_item_name, trait_item_kind) =
1845 csearch::get_trait_item_name_and_kind(
1846 &self.session.cstore,
1847 trait_item_def_id.def_id());
1849 debug!("(building reduced graph for external crate) ... \
1850 adding trait item '{}'",
1851 token::get_ident(trait_item_name));
1855 .insert((trait_item_name.name, def_id),
1859 self.external_exports
1860 .insert(trait_item_def_id.def_id());
1864 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1866 // Define a module if necessary.
1867 let parent_link = self.get_parent_link(new_parent, ident);
1868 child_name_bindings.set_module_kind(parent_link,
1875 DefTy(..) | DefAssociatedTy(..) => {
1876 debug!("(building reduced graph for external \
1877 crate) building type {}", final_ident);
1879 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1881 DefStruct(def_id) => {
1882 debug!("(building reduced graph for external \
1883 crate) building type and value for {}",
1885 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1886 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
1888 }).collect::<Vec<_>>();
1890 if fields.len() == 0 {
1891 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1894 // Record the def ID and fields of this struct.
1895 self.structs.insert(def_id, fields);
1898 debug!("(building reduced graph for external crate) \
1899 ignoring {:?}", def);
1900 // Ignored; handled elsewhere.
1902 DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
1903 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1904 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1905 fail!("didn't expect `{:?}`", def);
1910 /// Builds the reduced graph for a single item in an external crate.
1911 fn build_reduced_graph_for_external_crate_def(&mut self,
1915 visibility: Visibility) {
1918 // Add the new child item, if necessary.
1920 DefForeignMod(def_id) => {
1921 // Foreign modules have no names. Recur and populate
1923 csearch::each_child_of_item(&self.session.cstore,
1928 self.build_reduced_graph_for_external_crate_def(
1936 let child_name_bindings =
1937 self.add_child(ident,
1938 ModuleReducedGraphParent(root.clone()),
1939 OverwriteDuplicates,
1942 self.handle_external_def(def,
1944 &*child_name_bindings,
1945 token::get_ident(ident).get(),
1947 ModuleReducedGraphParent(root));
1952 // We only process static methods of impls here.
1953 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1955 Some(final_ident) => {
1956 let static_methods_opt =
1957 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1958 match static_methods_opt {
1959 Some(ref static_methods) if
1960 static_methods.len() >= 1 => {
1961 debug!("(building reduced graph for \
1962 external crate) processing \
1963 static methods for type name {}",
1964 token::get_ident(final_ident));
1966 let child_name_bindings =
1969 ModuleReducedGraphParent(root.clone()),
1970 OverwriteDuplicates,
1973 // Process the static methods. First,
1974 // create the module.
1976 let type_def = child_name_bindings.type_def.borrow().clone();
1979 module_def: Some(module_def),
1982 // We already have a module. This
1984 type_module = module_def;
1986 // Mark it as an impl module if
1988 type_module.kind.set(ImplModuleKind);
1992 self.get_parent_link(ModuleReducedGraphParent(root),
1994 child_name_bindings.define_module(
2002 child_name_bindings.
2007 // Add each static method to the module.
2009 ModuleReducedGraphParent(type_module);
2010 for static_method_info in
2011 static_methods.iter() {
2012 let ident = static_method_info.ident;
2013 debug!("(building reduced graph for \
2014 external crate) creating \
2015 static method '{}'",
2016 token::get_ident(ident));
2018 let method_name_bindings =
2019 self.add_child(ident,
2021 OverwriteDuplicates,
2024 static_method_info.def_id,
2025 static_method_info.fn_style);
2027 method_name_bindings.define_value(
2029 visibility == ast::Public);
2033 // Otherwise, do nothing.
2034 Some(_) | None => {}
2040 debug!("(building reduced graph for external crate) \
2046 /// Builds the reduced graph rooted at the given external module.
2047 fn populate_external_module(&mut self, module: Rc<Module>) {
2048 debug!("(populating external module) attempting to populate {}",
2049 self.module_to_string(&*module));
2051 let def_id = match module.def_id.get() {
2053 debug!("(populating external module) ... no def ID!");
2056 Some(def_id) => def_id,
2059 csearch::each_child_of_item(&self.session.cstore,
2061 |def_like, child_ident, visibility| {
2062 debug!("(populating external module) ... found ident: {}",
2063 token::get_ident(child_ident));
2064 self.build_reduced_graph_for_external_crate_def(module.clone(),
2069 module.populated.set(true)
2072 /// Ensures that the reduced graph rooted at the given external module
2073 /// is built, building it if it is not.
2074 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
2075 if !module.populated.get() {
2076 self.populate_external_module(module.clone())
2078 assert!(module.populated.get())
2081 /// Builds the reduced graph rooted at the 'use' directive for an external
2083 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
2084 csearch::each_top_level_item_of_crate(&self.session.cstore,
2089 |def_like, ident, visibility| {
2090 self.build_reduced_graph_for_external_crate_def(root.clone(),
2097 /// Creates and adds an import directive to the given module.
2098 fn build_import_directive(&mut self,
2100 module_path: Vec<Ident> ,
2101 subclass: ImportDirectiveSubclass,
2106 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
2112 self.unresolved_imports += 1;
2113 // Bump the reference count on the name. Or, if this is a glob, set
2114 // the appropriate flag.
2117 SingleImport(target, _) => {
2118 debug!("(building import directive) building import \
2120 self.idents_to_string(module_.imports.borrow().last().unwrap()
2121 .module_path.as_slice()),
2122 token::get_ident(target));
2124 let mut import_resolutions = module_.import_resolutions
2126 match import_resolutions.find_mut(&target.name) {
2127 Some(resolution) => {
2128 debug!("(building import directive) bumping \
2130 resolution.outstanding_references += 1;
2132 // the source of this name is different now
2133 resolution.type_id = id;
2134 resolution.value_id = id;
2135 resolution.is_public = is_public;
2140 debug!("(building import directive) creating new");
2141 let mut resolution = ImportResolution::new(id, is_public);
2142 resolution.outstanding_references = 1;
2143 import_resolutions.insert(target.name, resolution);
2146 // Set the glob flag. This tells us that we don't know the
2147 // module's exports ahead of time.
2149 module_.glob_count.set(module_.glob_count.get() + 1);
2154 // Import resolution
2156 // This is a fixed-point algorithm. We resolve imports until our efforts
2157 // are stymied by an unresolved import; then we bail out of the current
2158 // module and continue. We terminate successfully once no more imports
2159 // remain or unsuccessfully when no forward progress in resolving imports
2162 /// Resolves all imports for the crate. This method performs the fixed-
2163 /// point iteration.
2164 fn resolve_imports(&mut self) {
2166 let mut prev_unresolved_imports = 0;
2168 debug!("(resolving imports) iteration {}, {} imports left",
2169 i, self.unresolved_imports);
2171 let module_root = self.graph_root.get_module();
2172 self.resolve_imports_for_module_subtree(module_root.clone());
2174 if self.unresolved_imports == 0 {
2175 debug!("(resolving imports) success");
2179 if self.unresolved_imports == prev_unresolved_imports {
2180 self.report_unresolved_imports(module_root);
2185 prev_unresolved_imports = self.unresolved_imports;
2189 /// Attempts to resolve imports for the given module and all of its
2191 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2192 debug!("(resolving imports for module subtree) resolving {}",
2193 self.module_to_string(&*module_));
2194 let orig_module = replace(&mut self.current_module, module_.clone());
2195 self.resolve_imports_for_module(module_.clone());
2196 self.current_module = orig_module;
2198 self.populate_module_if_necessary(&module_);
2199 for (_, child_node) in module_.children.borrow().iter() {
2200 match child_node.get_module_if_available() {
2204 Some(child_module) => {
2205 self.resolve_imports_for_module_subtree(child_module);
2210 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2211 self.resolve_imports_for_module_subtree(child_module.clone());
2215 /// Attempts to resolve imports for the given module only.
2216 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2217 if module.all_imports_resolved() {
2218 debug!("(resolving imports for module) all imports resolved for \
2220 self.module_to_string(&*module));
2224 let imports = module.imports.borrow();
2225 let import_count = imports.len();
2226 while module.resolved_import_count.get() < import_count {
2227 let import_index = module.resolved_import_count.get();
2228 let import_directive = imports.get(import_index);
2229 match self.resolve_import_for_module(module.clone(),
2232 let (span, help) = match err {
2233 Some((span, msg)) => (span, format!(". {}", msg)),
2234 None => (import_directive.span, String::new())
2236 let msg = format!("unresolved import `{}`{}",
2237 self.import_path_to_string(
2238 import_directive.module_path
2240 import_directive.subclass),
2242 self.resolve_error(span, msg.as_slice());
2244 Indeterminate => break, // Bail out. We'll come around next time.
2245 Success(()) => () // Good. Continue.
2248 module.resolved_import_count
2249 .set(module.resolved_import_count.get() + 1);
2253 fn idents_to_string(&self, idents: &[Ident]) -> String {
2254 let mut first = true;
2255 let mut result = String::new();
2256 for ident in idents.iter() {
2260 result.push_str("::")
2262 result.push_str(token::get_ident(*ident).get());
2267 fn path_idents_to_string(&self, path: &Path) -> String {
2268 let identifiers: Vec<ast::Ident> = path.segments
2270 .map(|seg| seg.identifier)
2272 self.idents_to_string(identifiers.as_slice())
2275 fn import_directive_subclass_to_string(&mut self,
2276 subclass: ImportDirectiveSubclass)
2279 SingleImport(_, source) => {
2280 token::get_ident(source).get().to_string()
2282 GlobImport => "*".to_string()
2286 fn import_path_to_string(&mut self,
2288 subclass: ImportDirectiveSubclass)
2290 if idents.is_empty() {
2291 self.import_directive_subclass_to_string(subclass)
2294 self.idents_to_string(idents),
2295 self.import_directive_subclass_to_string(
2296 subclass))).to_string()
2300 /// Attempts to resolve the given import. The return value indicates
2301 /// failure if we're certain the name does not exist, indeterminate if we
2302 /// don't know whether the name exists at the moment due to other
2303 /// currently-unresolved imports, or success if we know the name exists.
2304 /// If successful, the resolved bindings are written into the module.
2305 fn resolve_import_for_module(&mut self,
2306 module_: Rc<Module>,
2307 import_directive: &ImportDirective)
2308 -> ResolveResult<()> {
2309 let mut resolution_result = Failed(None);
2310 let module_path = &import_directive.module_path;
2312 debug!("(resolving import for module) resolving import `{}::...` in \
2314 self.idents_to_string(module_path.as_slice()),
2315 self.module_to_string(&*module_));
2317 // First, resolve the module path for the directive, if necessary.
2318 let container = if module_path.len() == 0 {
2319 // Use the crate root.
2320 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2322 match self.resolve_module_path(module_.clone(),
2323 module_path.as_slice(),
2324 DontUseLexicalScope,
2325 import_directive.span,
2328 resolution_result = Failed(err);
2332 resolution_result = Indeterminate;
2335 Success(container) => Some(container),
2341 Some((containing_module, lp)) => {
2342 // We found the module that the target is contained
2343 // within. Attempt to resolve the import within it.
2345 match import_directive.subclass {
2346 SingleImport(target, source) => {
2348 self.resolve_single_import(&*module_,
2357 self.resolve_glob_import(&*module_,
2366 // Decrement the count of unresolved imports.
2367 match resolution_result {
2369 assert!(self.unresolved_imports >= 1);
2370 self.unresolved_imports -= 1;
2373 // Nothing to do here; just return the error.
2377 // Decrement the count of unresolved globs if necessary. But only if
2378 // the resolution result is indeterminate -- otherwise we'll stop
2379 // processing imports here. (See the loop in
2380 // resolve_imports_for_module.)
2382 if !resolution_result.indeterminate() {
2383 match import_directive.subclass {
2385 assert!(module_.glob_count.get() >= 1);
2386 module_.glob_count.set(module_.glob_count.get() - 1);
2388 SingleImport(..) => {
2394 return resolution_result;
2397 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2399 type_def: RefCell::new(Some(TypeNsDef {
2401 module_def: Some(module),
2405 value_def: RefCell::new(None),
2409 fn resolve_single_import(&mut self,
2411 containing_module: Rc<Module>,
2414 directive: &ImportDirective,
2416 -> ResolveResult<()> {
2417 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2418 `{}` id {}, last private {:?}",
2419 token::get_ident(target),
2420 self.module_to_string(&*containing_module),
2421 token::get_ident(source),
2422 self.module_to_string(module_),
2428 LastImport {..} => {
2430 .span_bug(directive.span,
2431 "not expecting Import here, must be LastMod")
2435 // We need to resolve both namespaces for this to succeed.
2438 let mut value_result = UnknownResult;
2439 let mut type_result = UnknownResult;
2441 // Search for direct children of the containing module.
2442 self.populate_module_if_necessary(&containing_module);
2444 match containing_module.children.borrow().find(&source.name) {
2448 Some(ref child_name_bindings) => {
2449 if child_name_bindings.defined_in_namespace(ValueNS) {
2450 debug!("(resolving single import) found value binding");
2451 value_result = BoundResult(containing_module.clone(),
2452 (*child_name_bindings).clone());
2454 if child_name_bindings.defined_in_namespace(TypeNS) {
2455 debug!("(resolving single import) found type binding");
2456 type_result = BoundResult(containing_module.clone(),
2457 (*child_name_bindings).clone());
2462 // Unless we managed to find a result in both namespaces (unlikely),
2463 // search imports as well.
2464 let mut value_used_reexport = false;
2465 let mut type_used_reexport = false;
2466 match (value_result.clone(), type_result.clone()) {
2467 (BoundResult(..), BoundResult(..)) => {} // Continue.
2469 // If there is an unresolved glob at this point in the
2470 // containing module, bail out. We don't know enough to be
2471 // able to resolve this import.
2473 if containing_module.glob_count.get() > 0 {
2474 debug!("(resolving single import) unresolved glob; \
2476 return Indeterminate;
2479 // Now search the exported imports within the containing module.
2480 match containing_module.import_resolutions.borrow().find(&source.name) {
2482 debug!("(resolving single import) no import");
2483 // The containing module definitely doesn't have an
2484 // exported import with the name in question. We can
2485 // therefore accurately report that the names are
2488 if value_result.is_unknown() {
2489 value_result = UnboundResult;
2491 if type_result.is_unknown() {
2492 type_result = UnboundResult;
2495 Some(import_resolution)
2496 if import_resolution.outstanding_references == 0 => {
2498 fn get_binding(this: &mut Resolver,
2499 import_resolution: &ImportResolution,
2500 namespace: Namespace)
2501 -> NamespaceResult {
2503 // Import resolutions must be declared with "pub"
2504 // in order to be exported.
2505 if !import_resolution.is_public {
2506 return UnboundResult;
2509 match import_resolution.
2510 target_for_namespace(namespace) {
2512 return UnboundResult;
2519 debug!("(resolving single import) found \
2520 import in ns {:?}", namespace);
2521 let id = import_resolution.id(namespace);
2522 // track used imports and extern crates as well
2523 this.used_imports.insert((id, namespace));
2524 match target_module.def_id.get() {
2525 Some(DefId{krate: kid, ..}) => {
2526 this.used_crates.insert(kid);
2530 return BoundResult(target_module, bindings);
2535 // The name is an import which has been fully
2536 // resolved. We can, therefore, just follow it.
2537 if value_result.is_unknown() {
2538 value_result = get_binding(self, import_resolution,
2540 value_used_reexport = import_resolution.is_public;
2542 if type_result.is_unknown() {
2543 type_result = get_binding(self, import_resolution,
2545 type_used_reexport = import_resolution.is_public;
2550 // The import is unresolved. Bail out.
2551 debug!("(resolving single import) unresolved import; \
2553 return Indeterminate;
2559 // If we didn't find a result in the type namespace, search the
2560 // external modules.
2561 let mut value_used_public = false;
2562 let mut type_used_public = false;
2564 BoundResult(..) => {}
2566 match containing_module.external_module_children.borrow_mut()
2567 .find_copy(&source.name) {
2568 None => {} // Continue.
2570 debug!("(resolving single import) found external \
2572 // track the module as used.
2573 match module.def_id.get() {
2574 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
2578 Rc::new(Resolver::create_name_bindings_from_module(
2580 type_result = BoundResult(containing_module.clone(),
2582 type_used_public = true;
2588 // We've successfully resolved the import. Write the results in.
2589 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2590 let import_resolution = import_resolutions.get_mut(&target.name);
2592 match value_result {
2593 BoundResult(ref target_module, ref name_bindings) => {
2594 debug!("(resolving single import) found value target");
2595 self.check_for_conflicting_import(
2596 &import_resolution.value_target,
2601 import_resolution.value_target =
2602 Some(Target::new(target_module.clone(),
2603 name_bindings.clone(),
2604 directive.shadowable));
2605 import_resolution.value_id = directive.id;
2606 import_resolution.is_public = directive.is_public;
2607 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2609 UnboundResult => { /* Continue. */ }
2611 fail!("value result should be known at this point");
2615 BoundResult(ref target_module, ref name_bindings) => {
2616 debug!("(resolving single import) found type target: {:?}",
2617 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2618 self.check_for_conflicting_import(
2619 &import_resolution.type_target,
2624 import_resolution.type_target =
2625 Some(Target::new(target_module.clone(),
2626 name_bindings.clone(),
2627 directive.shadowable));
2628 import_resolution.type_id = directive.id;
2629 import_resolution.is_public = directive.is_public;
2630 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2632 UnboundResult => { /* Continue. */ }
2634 fail!("type result should be known at this point");
2638 self.check_for_conflicts_between_imports_and_items(
2644 if value_result.is_unbound() && type_result.is_unbound() {
2645 let msg = format!("There is no `{}` in `{}`",
2646 token::get_ident(source),
2647 self.module_to_string(&*containing_module));
2648 return Failed(Some((directive.span, msg)));
2650 let value_used_public = value_used_reexport || value_used_public;
2651 let type_used_public = type_used_reexport || type_used_public;
2653 assert!(import_resolution.outstanding_references >= 1);
2654 import_resolution.outstanding_references -= 1;
2656 // record what this import resolves to for later uses in documentation,
2657 // this may resolve to either a value or a type, but for documentation
2658 // purposes it's good enough to just favor one over the other.
2659 let value_private = match import_resolution.value_target {
2660 Some(ref target) => {
2661 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2662 self.def_map.borrow_mut().insert(directive.id, def);
2663 let did = def.def_id();
2664 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2666 // AllPublic here and below is a dummy value, it should never be used because
2667 // _exists is false.
2670 let type_private = match import_resolution.type_target {
2671 Some(ref target) => {
2672 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2673 self.def_map.borrow_mut().insert(directive.id, def);
2674 let did = def.def_id();
2675 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2680 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2682 type_priv: type_private,
2685 debug!("(resolving single import) successfully resolved import");
2689 // Resolves a glob import. Note that this function cannot fail; it either
2690 // succeeds or bails out (as importing * from an empty module or a module
2691 // that exports nothing is valid).
2692 fn resolve_glob_import(&mut self,
2694 containing_module: Rc<Module>,
2695 import_directive: &ImportDirective,
2697 -> ResolveResult<()> {
2698 let id = import_directive.id;
2699 let is_public = import_directive.is_public;
2701 // This function works in a highly imperative manner; it eagerly adds
2702 // everything it can to the list of import resolutions of the module
2704 debug!("(resolving glob import) resolving glob import {}", id);
2706 // We must bail out if the node has unresolved imports of any kind
2707 // (including globs).
2708 if !(*containing_module).all_imports_resolved() {
2709 debug!("(resolving glob import) target module has unresolved \
2710 imports; bailing out");
2711 return Indeterminate;
2714 assert_eq!(containing_module.glob_count.get(), 0);
2716 // Add all resolved imports from the containing module.
2717 let import_resolutions = containing_module.import_resolutions
2719 for (ident, target_import_resolution) in import_resolutions.iter() {
2720 debug!("(resolving glob import) writing module resolution \
2722 target_import_resolution.type_target.is_none(),
2723 self.module_to_string(module_));
2725 if !target_import_resolution.is_public {
2726 debug!("(resolving glob import) nevermind, just kidding");
2730 // Here we merge two import resolutions.
2731 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2732 match import_resolutions.find_mut(ident) {
2733 Some(dest_import_resolution) => {
2734 // Merge the two import resolutions at a finer-grained
2737 match target_import_resolution.value_target {
2741 Some(ref value_target) => {
2742 dest_import_resolution.value_target =
2743 Some(value_target.clone());
2746 match target_import_resolution.type_target {
2750 Some(ref type_target) => {
2751 dest_import_resolution.type_target =
2752 Some(type_target.clone());
2755 dest_import_resolution.is_public = is_public;
2761 // Simple: just copy the old import resolution.
2762 let mut new_import_resolution = ImportResolution::new(id, is_public);
2763 new_import_resolution.value_target =
2764 target_import_resolution.value_target.clone();
2765 new_import_resolution.type_target =
2766 target_import_resolution.type_target.clone();
2768 import_resolutions.insert(*ident, new_import_resolution);
2771 // Add all children from the containing module.
2772 self.populate_module_if_necessary(&containing_module);
2774 for (&name, name_bindings) in containing_module.children
2776 self.merge_import_resolution(module_,
2777 containing_module.clone(),
2780 name_bindings.clone());
2784 // Add external module children from the containing module.
2785 for (&name, module) in containing_module.external_module_children
2788 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2789 self.merge_import_resolution(module_,
2790 containing_module.clone(),
2796 // Record the destination of this import
2797 match containing_module.def_id.get() {
2799 self.def_map.borrow_mut().insert(id, DefMod(did));
2800 self.last_private.insert(id, lp);
2805 debug!("(resolving glob import) successfully resolved import");
2809 fn merge_import_resolution(&mut self,
2811 containing_module: Rc<Module>,
2812 import_directive: &ImportDirective,
2814 name_bindings: Rc<NameBindings>) {
2815 let id = import_directive.id;
2816 let is_public = import_directive.is_public;
2818 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2819 let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
2820 // Create a new import resolution from this child.
2821 ImportResolution::new(id, is_public)
2824 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2826 token::get_name(name).get().to_string(),
2827 self.module_to_string(&*containing_module),
2828 self.module_to_string(module_));
2830 // Merge the child item into the import resolution.
2831 if name_bindings.defined_in_public_namespace(ValueNS) {
2832 debug!("(resolving glob import) ... for value target");
2833 dest_import_resolution.value_target =
2834 Some(Target::new(containing_module.clone(),
2835 name_bindings.clone(),
2836 import_directive.shadowable));
2837 dest_import_resolution.value_id = id;
2839 if name_bindings.defined_in_public_namespace(TypeNS) {
2840 debug!("(resolving glob import) ... for type target");
2841 dest_import_resolution.type_target =
2842 Some(Target::new(containing_module,
2843 name_bindings.clone(),
2844 import_directive.shadowable));
2845 dest_import_resolution.type_id = id;
2847 dest_import_resolution.is_public = is_public;
2849 self.check_for_conflicts_between_imports_and_items(
2851 dest_import_resolution,
2852 import_directive.span,
2856 /// Checks that imported names and items don't have the same name.
2857 fn check_for_conflicting_import(&mut self,
2858 target: &Option<Target>,
2861 namespace: Namespace) {
2862 if self.session.features.borrow().import_shadowing {
2867 Some(ref target) if !target.shadowable => {
2868 let msg = format!("a {} named `{}` has already been imported \
2874 token::get_name(name).get());
2875 self.session.span_err(import_span, msg.as_slice());
2877 Some(_) | None => {}
2881 /// Checks that imported names and items don't have the same name.
2882 fn check_for_conflicts_between_imports_and_items(&mut self,
2885 &mut ImportResolution,
2888 if self.session.features.borrow().import_shadowing {
2892 // First, check for conflicts between imports and `extern crate`s.
2893 if module.external_module_children
2895 .contains_key(&name) {
2896 match import_resolution.type_target {
2897 Some(ref target) if !target.shadowable => {
2898 let msg = format!("import `{}` conflicts with imported \
2899 crate in this module",
2900 token::get_name(name).get());
2901 self.session.span_err(import_span, msg.as_slice());
2903 Some(_) | None => {}
2907 // Check for item conflicts.
2908 let children = module.children.borrow();
2909 let name_bindings = match children.find(&name) {
2911 // There can't be any conflicts.
2914 Some(ref name_bindings) => (*name_bindings).clone(),
2917 match import_resolution.value_target {
2918 Some(ref target) if !target.shadowable => {
2919 match *name_bindings.value_def.borrow() {
2921 Some(ref value) => {
2922 let msg = format!("import `{}` conflicts with value \
2924 token::get_name(name).get());
2925 self.session.span_err(import_span, msg.as_slice());
2926 match value.value_span {
2931 "note conflicting value here");
2937 Some(_) | None => {}
2940 match import_resolution.type_target {
2941 Some(ref target) if !target.shadowable => {
2942 match *name_bindings.type_def.borrow() {
2945 let msg = format!("import `{}` conflicts with type in \
2947 token::get_name(name).get());
2948 self.session.span_err(import_span, msg.as_slice());
2949 match ty.type_span {
2954 "note conflicting type here")
2960 Some(_) | None => {}
2964 /// Checks that the names of external crates don't collide with other
2965 /// external crates.
2966 fn check_for_conflicts_between_external_crates(&self,
2970 if self.session.features.borrow().import_shadowing {
2974 if module.external_module_children.borrow().contains_key(&name) {
2977 format!("an external crate named `{}` has already \
2978 been imported into this module",
2979 token::get_name(name).get()).as_slice());
2983 /// Checks that the names of items don't collide with external crates.
2984 fn check_for_conflicts_between_external_crates_and_items(&self,
2988 if self.session.features.borrow().import_shadowing {
2992 if module.external_module_children.borrow().contains_key(&name) {
2995 format!("the name `{}` conflicts with an external \
2996 crate that has been imported into this \
2998 token::get_name(name).get()).as_slice());
3002 /// Resolves the given module path from the given root `module_`.
3003 fn resolve_module_path_from_root(&mut self,
3004 module_: Rc<Module>,
3005 module_path: &[Ident],
3008 name_search_type: NameSearchType,
3010 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3011 fn search_parent_externals(needle: Name, module: &Rc<Module>)
3012 -> Option<Rc<Module>> {
3013 module.external_module_children.borrow()
3015 .map(|_| module.clone())
3017 match module.parent_link.clone() {
3018 ModuleParentLink(parent, _) => {
3019 search_parent_externals(needle,
3020 &parent.upgrade().unwrap())
3027 let mut search_module = module_;
3028 let mut index = index;
3029 let module_path_len = module_path.len();
3030 let mut closest_private = lp;
3032 // Resolve the module part of the path. This does not involve looking
3033 // upward though scope chains; we simply resolve names directly in
3034 // modules as we go.
3035 while index < module_path_len {
3036 let name = module_path[index];
3037 match self.resolve_name_in_module(search_module.clone(),
3043 let segment_name = token::get_ident(name);
3044 let module_name = self.module_to_string(&*search_module);
3045 let mut span = span;
3046 let msg = if "???" == module_name.as_slice() {
3047 span.hi = span.lo + Pos::from_uint(segment_name.get().len());
3049 match search_parent_externals(name.name,
3050 &self.current_module) {
3052 let path_str = self.idents_to_string(module_path);
3053 let target_mod_str = self.module_to_string(&*module);
3054 let current_mod_str =
3055 self.module_to_string(&*self.current_module);
3057 let prefix = if target_mod_str == current_mod_str {
3058 "self::".to_string()
3060 format!("{}::", target_mod_str)
3063 format!("Did you mean `{}{}`?", prefix, path_str)
3065 None => format!("Maybe a missing `extern crate {}`?",
3069 format!("Could not find `{}` in `{}`.",
3074 return Failed(Some((span, msg)));
3076 Failed(err) => return Failed(err),
3078 debug!("(resolving module path for import) module \
3079 resolution is indeterminate: {}",
3080 token::get_ident(name));
3081 return Indeterminate;
3083 Success((target, used_proxy)) => {
3084 // Check to see whether there are type bindings, and, if
3085 // so, whether there is a module within.
3086 match *target.bindings.type_def.borrow() {
3087 Some(ref type_def) => {
3088 match type_def.module_def {
3090 let msg = format!("Not a module `{}`",
3091 token::get_ident(name));
3093 return Failed(Some((span, msg)));
3095 Some(ref module_def) => {
3096 // If we're doing the search for an
3097 // import, do not allow traits and impls
3099 match (name_search_type,
3100 module_def.kind.get()) {
3101 (ImportSearch, TraitModuleKind) |
3102 (ImportSearch, ImplModuleKind) => {
3104 "Cannot import from a trait or \
3105 type implementation".to_string();
3106 return Failed(Some((span, msg)));
3109 search_module = module_def.clone();
3111 // track extern crates for unused_extern_crate lint
3112 match module_def.def_id.get() {
3114 self.used_crates.insert(did.krate);
3119 // Keep track of the closest
3120 // private module used when
3121 // resolving this import chain.
3123 !search_module.is_public {
3124 match search_module.def_id
3128 LastMod(DependsOn(did));
3139 // There are no type bindings at all.
3140 let msg = format!("Not a module `{}`",
3141 token::get_ident(name));
3142 return Failed(Some((span, msg)));
3151 return Success((search_module, closest_private));
3154 /// Attempts to resolve the module part of an import directive or path
3155 /// rooted at the given module.
3157 /// On success, returns the resolved module, and the closest *private*
3158 /// module found to the destination when resolving this path.
3159 fn resolve_module_path(&mut self,
3160 module_: Rc<Module>,
3161 module_path: &[Ident],
3162 use_lexical_scope: UseLexicalScopeFlag,
3164 name_search_type: NameSearchType)
3165 -> ResolveResult<(Rc<Module>, LastPrivate)> {
3166 let module_path_len = module_path.len();
3167 assert!(module_path_len > 0);
3169 debug!("(resolving module path for import) processing `{}` rooted at \
3171 self.idents_to_string(module_path),
3172 self.module_to_string(&*module_));
3174 // Resolve the module prefix, if any.
3175 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
3181 match module_prefix_result {
3183 let mpath = self.idents_to_string(module_path);
3184 let mpath = mpath.as_slice();
3185 match mpath.rfind(':') {
3187 let msg = format!("Could not find `{}` in `{}`",
3188 // idx +- 1 to account for the
3189 // colons on either side
3190 mpath.slice_from(idx + 1),
3191 mpath.slice_to(idx - 1));
3192 return Failed(Some((span, msg)));
3194 None => return Failed(None),
3197 Failed(err) => return Failed(err),
3199 debug!("(resolving module path for import) indeterminate; \
3201 return Indeterminate;
3203 Success(NoPrefixFound) => {
3204 // There was no prefix, so we're considering the first element
3205 // of the path. How we handle this depends on whether we were
3206 // instructed to use lexical scope or not.
3207 match use_lexical_scope {
3208 DontUseLexicalScope => {
3209 // This is a crate-relative path. We will start the
3210 // resolution process at index zero.
3211 search_module = self.graph_root.get_module();
3213 last_private = LastMod(AllPublic);
3215 UseLexicalScope => {
3216 // This is not a crate-relative path. We resolve the
3217 // first component of the path in the current lexical
3218 // scope and then proceed to resolve below that.
3219 match self.resolve_module_in_lexical_scope(
3222 Failed(err) => return Failed(err),
3224 debug!("(resolving module path for import) \
3225 indeterminate; bailing");
3226 return Indeterminate;
3228 Success(containing_module) => {
3229 search_module = containing_module;
3231 last_private = LastMod(AllPublic);
3237 Success(PrefixFound(ref containing_module, index)) => {
3238 search_module = containing_module.clone();
3239 start_index = index;
3240 last_private = LastMod(DependsOn(containing_module.def_id
3246 self.resolve_module_path_from_root(search_module,
3254 /// Invariant: This must only be called during main resolution, not during
3255 /// import resolution.
3256 fn resolve_item_in_lexical_scope(&mut self,
3257 module_: Rc<Module>,
3259 namespace: Namespace)
3260 -> ResolveResult<(Target, bool)> {
3261 debug!("(resolving item in lexical scope) resolving `{}` in \
3262 namespace {:?} in `{}`",
3263 token::get_ident(name),
3265 self.module_to_string(&*module_));
3267 // The current module node is handled specially. First, check for
3268 // its immediate children.
3269 self.populate_module_if_necessary(&module_);
3271 match module_.children.borrow().find(&name.name) {
3273 if name_bindings.defined_in_namespace(namespace) => {
3274 debug!("top name bindings succeeded");
3275 return Success((Target::new(module_.clone(),
3276 name_bindings.clone(),
3280 Some(_) | None => { /* Not found; continue. */ }
3283 // Now check for its import directives. We don't have to have resolved
3284 // all its imports in the usual way; this is because chains of
3285 // adjacent import statements are processed as though they mutated the
3287 match module_.import_resolutions.borrow().find(&name.name) {
3289 // Not found; continue.
3291 Some(import_resolution) => {
3292 match (*import_resolution).target_for_namespace(namespace) {
3294 // Not found; continue.
3295 debug!("(resolving item in lexical scope) found \
3296 import resolution, but not in namespace {:?}",
3300 debug!("(resolving item in lexical scope) using \
3301 import resolution");
3302 // track used imports and extern crates as well
3303 self.used_imports.insert((import_resolution.id(namespace), namespace));
3304 match target.target_module.def_id.get() {
3305 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
3308 return Success((target, false));
3314 // Search for external modules.
3315 if namespace == TypeNS {
3316 match module_.external_module_children.borrow().find_copy(&name.name) {
3320 Rc::new(Resolver::create_name_bindings_from_module(module));
3321 debug!("lower name bindings succeeded");
3322 return Success((Target::new(module_,
3330 // Finally, proceed up the scope chain looking for parent modules.
3331 let mut search_module = module_;
3333 // Go to the next parent.
3334 match search_module.parent_link.clone() {
3336 // No more parents. This module was unresolved.
3337 debug!("(resolving item in lexical scope) unresolved \
3339 return Failed(None);
3341 ModuleParentLink(parent_module_node, _) => {
3342 match search_module.kind.get() {
3343 NormalModuleKind => {
3344 // We stop the search here.
3345 debug!("(resolving item in lexical \
3346 scope) unresolved module: not \
3347 searching through module \
3349 return Failed(None);
3354 AnonymousModuleKind => {
3355 search_module = parent_module_node.upgrade().unwrap();
3359 BlockParentLink(ref parent_module_node, _) => {
3360 search_module = parent_module_node.upgrade().unwrap();
3364 // Resolve the name in the parent module.
3365 match self.resolve_name_in_module(search_module.clone(),
3370 Failed(Some((span, msg))) =>
3371 self.resolve_error(span, format!("failed to resolve. {}",
3373 Failed(None) => (), // Continue up the search chain.
3375 // We couldn't see through the higher scope because of an
3376 // unresolved import higher up. Bail.
3378 debug!("(resolving item in lexical scope) indeterminate \
3379 higher scope; bailing");
3380 return Indeterminate;
3382 Success((target, used_reexport)) => {
3383 // We found the module.
3384 debug!("(resolving item in lexical scope) found name \
3386 return Success((target, used_reexport));
3392 /// Resolves a module name in the current lexical scope.
3393 fn resolve_module_in_lexical_scope(&mut self,
3394 module_: Rc<Module>,
3396 -> ResolveResult<Rc<Module>> {
3397 // If this module is an anonymous module, resolve the item in the
3398 // lexical scope. Otherwise, resolve the item from the crate root.
3399 let resolve_result = self.resolve_item_in_lexical_scope(
3400 module_, name, TypeNS);
3401 match resolve_result {
3402 Success((target, _)) => {
3403 let bindings = &*target.bindings;
3404 match *bindings.type_def.borrow() {
3405 Some(ref type_def) => {
3406 match type_def.module_def {
3408 debug!("!!! (resolving module in lexical \
3409 scope) module wasn't actually a \
3411 return Failed(None);
3413 Some(ref module_def) => {
3414 return Success(module_def.clone());
3419 debug!("!!! (resolving module in lexical scope) module
3420 wasn't actually a module!");
3421 return Failed(None);
3426 debug!("(resolving module in lexical scope) indeterminate; \
3428 return Indeterminate;
3431 debug!("(resolving module in lexical scope) failed to resolve");
3437 /// Returns the nearest normal module parent of the given module.
3438 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3439 -> Option<Rc<Module>> {
3440 let mut module_ = module_;
3442 match module_.parent_link.clone() {
3443 NoParentLink => return None,
3444 ModuleParentLink(new_module, _) |
3445 BlockParentLink(new_module, _) => {
3446 let new_module = new_module.upgrade().unwrap();
3447 match new_module.kind.get() {
3448 NormalModuleKind => return Some(new_module),
3452 AnonymousModuleKind => module_ = new_module,
3459 /// Returns the nearest normal module parent of the given module, or the
3460 /// module itself if it is a normal module.
3461 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3463 match module_.kind.get() {
3464 NormalModuleKind => return module_,
3468 AnonymousModuleKind => {
3469 match self.get_nearest_normal_module_parent(module_.clone()) {
3471 Some(new_module) => new_module
3477 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3478 /// (b) some chain of `super::`.
3479 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3480 fn resolve_module_prefix(&mut self,
3481 module_: Rc<Module>,
3482 module_path: &[Ident])
3483 -> ResolveResult<ModulePrefixResult> {
3484 // Start at the current module if we see `self` or `super`, or at the
3485 // top of the crate otherwise.
3486 let mut containing_module;
3488 let first_module_path_string = token::get_ident(module_path[0]);
3489 if "self" == first_module_path_string.get() {
3491 self.get_nearest_normal_module_parent_or_self(module_);
3493 } else if "super" == first_module_path_string.get() {
3495 self.get_nearest_normal_module_parent_or_self(module_);
3496 i = 0; // We'll handle `super` below.
3498 return Success(NoPrefixFound);
3501 // Now loop through all the `super`s we find.
3502 while i < module_path.len() {
3503 let string = token::get_ident(module_path[i]);
3504 if "super" != string.get() {
3507 debug!("(resolving module prefix) resolving `super` at {}",
3508 self.module_to_string(&*containing_module));
3509 match self.get_nearest_normal_module_parent(containing_module) {
3510 None => return Failed(None),
3511 Some(new_module) => {
3512 containing_module = new_module;
3518 debug!("(resolving module prefix) finished resolving prefix at {}",
3519 self.module_to_string(&*containing_module));
3521 return Success(PrefixFound(containing_module, i));
3524 /// Attempts to resolve the supplied name in the given module for the
3525 /// given namespace. If successful, returns the target corresponding to
3528 /// The boolean returned on success is an indicator of whether this lookup
3529 /// passed through a public re-export proxy.
3530 fn resolve_name_in_module(&mut self,
3531 module_: Rc<Module>,
3533 namespace: Namespace,
3534 name_search_type: NameSearchType,
3535 allow_private_imports: bool)
3536 -> ResolveResult<(Target, bool)> {
3537 debug!("(resolving name in module) resolving `{}` in `{}`",
3538 token::get_name(name).get(),
3539 self.module_to_string(&*module_));
3541 // First, check the direct children of the module.
3542 self.populate_module_if_necessary(&module_);
3544 match module_.children.borrow().find(&name) {
3546 if name_bindings.defined_in_namespace(namespace) => {
3547 debug!("(resolving name in module) found node as child");
3548 return Success((Target::new(module_.clone(),
3549 name_bindings.clone(),
3558 // Next, check the module's imports if necessary.
3560 // If this is a search of all imports, we should be done with glob
3561 // resolution at this point.
3562 if name_search_type == PathSearch {
3563 assert_eq!(module_.glob_count.get(), 0);
3566 // Check the list of resolved imports.
3567 match module_.import_resolutions.borrow().find(&name) {
3568 Some(import_resolution) if allow_private_imports ||
3569 import_resolution.is_public => {
3571 if import_resolution.is_public &&
3572 import_resolution.outstanding_references != 0 {
3573 debug!("(resolving name in module) import \
3574 unresolved; bailing out");
3575 return Indeterminate;
3577 match import_resolution.target_for_namespace(namespace) {
3579 debug!("(resolving name in module) name found, \
3580 but not in namespace {:?}",
3584 debug!("(resolving name in module) resolved to \
3586 // track used imports and extern crates as well
3587 self.used_imports.insert((import_resolution.id(namespace), namespace));
3588 match target.target_module.def_id.get() {
3589 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
3592 return Success((target, true));
3596 Some(..) | None => {} // Continue.
3599 // Finally, search through external children.
3600 if namespace == TypeNS {
3601 match module_.external_module_children.borrow().find_copy(&name) {
3605 Rc::new(Resolver::create_name_bindings_from_module(module));
3606 return Success((Target::new(module_,
3614 // We're out of luck.
3615 debug!("(resolving name in module) failed to resolve `{}`",
3616 token::get_name(name).get());
3617 return Failed(None);
3620 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3621 let index = module_.resolved_import_count.get();
3622 let imports = module_.imports.borrow();
3623 let import_count = imports.len();
3624 if index != import_count {
3625 let sn = self.session
3627 .span_to_snippet(imports.get(index).span)
3629 if sn.as_slice().contains("::") {
3630 self.resolve_error(imports.get(index).span,
3631 "unresolved import");
3633 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3634 sn.as_slice().slice(0, sn.len()));
3635 self.resolve_error(imports.get(index).span, err.as_slice());
3639 // Descend into children and anonymous children.
3640 self.populate_module_if_necessary(&module_);
3642 for (_, child_node) in module_.children.borrow().iter() {
3643 match child_node.get_module_if_available() {
3647 Some(child_module) => {
3648 self.report_unresolved_imports(child_module);
3653 for (_, module_) in module_.anonymous_children.borrow().iter() {
3654 self.report_unresolved_imports(module_.clone());
3660 // This pass simply determines what all "export" keywords refer to and
3661 // writes the results into the export map.
3663 // FIXME #4953 This pass will be removed once exports change to per-item.
3664 // Then this operation can simply be performed as part of item (or import)
3667 fn record_exports(&mut self) {
3668 let root_module = self.graph_root.get_module();
3669 self.record_exports_for_module_subtree(root_module);
3672 fn record_exports_for_module_subtree(&mut self,
3673 module_: Rc<Module>) {
3674 // If this isn't a local krate, then bail out. We don't need to record
3675 // exports for nonlocal crates.
3677 match module_.def_id.get() {
3678 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3680 debug!("(recording exports for module subtree) recording \
3681 exports for local module `{}`",
3682 self.module_to_string(&*module_));
3685 // Record exports for the root module.
3686 debug!("(recording exports for module subtree) recording \
3687 exports for root module `{}`",
3688 self.module_to_string(&*module_));
3692 debug!("(recording exports for module subtree) not recording \
3694 self.module_to_string(&*module_));
3699 self.record_exports_for_module(&*module_);
3700 self.populate_module_if_necessary(&module_);
3702 for (_, child_name_bindings) in module_.children.borrow().iter() {
3703 match child_name_bindings.get_module_if_available() {
3707 Some(child_module) => {
3708 self.record_exports_for_module_subtree(child_module);
3713 for (_, child_module) in module_.anonymous_children.borrow().iter() {
3714 self.record_exports_for_module_subtree(child_module.clone());
3718 fn record_exports_for_module(&mut self, module_: &Module) {
3719 let mut exports2 = Vec::new();
3721 self.add_exports_for_module(&mut exports2, module_);
3722 match module_.def_id.get() {
3724 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3725 debug!("(computing exports) writing exports for {} (some)",
3732 fn add_exports_of_namebindings(&mut self,
3733 exports2: &mut Vec<Export2> ,
3735 namebindings: &NameBindings,
3737 match namebindings.def_for_namespace(ns) {
3739 let name = token::get_name(name);
3740 debug!("(computing exports) YES: export '{}' => {:?}",
3742 exports2.push(Export2 {
3743 name: name.get().to_string(),
3748 debug!("(computing exports) NO: {:?}", d_opt);
3753 fn add_exports_for_module(&mut self,
3754 exports2: &mut Vec<Export2> ,
3756 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3757 if !importresolution.is_public {
3760 let xs = [TypeNS, ValueNS];
3761 for &ns in xs.iter() {
3762 match importresolution.target_for_namespace(ns) {
3764 debug!("(computing exports) maybe export '{}'",
3765 token::get_name(*name));
3766 self.add_exports_of_namebindings(exports2,
3779 // We maintain a list of value ribs and type ribs.
3781 // Simultaneously, we keep track of the current position in the module
3782 // graph in the `current_module` pointer. When we go to resolve a name in
3783 // the value or type namespaces, we first look through all the ribs and
3784 // then query the module graph. When we resolve a name in the module
3785 // namespace, we can skip all the ribs (since nested modules are not
3786 // allowed within blocks in Rust) and jump straight to the current module
3789 // Named implementations are handled separately. When we find a method
3790 // call, we consult the module node to find all of the implementations in
3791 // scope. This information is lazily cached in the module node. We then
3792 // generate a fake "implementation scope" containing all the
3793 // implementations thus found, for compatibility with old resolve pass.
3795 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3796 let orig_module = self.current_module.clone();
3798 // Move down in the graph.
3804 self.populate_module_if_necessary(&orig_module);
3806 match orig_module.children.borrow().find(&name.name) {
3808 debug!("!!! (with scope) didn't find `{}` in `{}`",
3809 token::get_ident(name),
3810 self.module_to_string(&*orig_module));
3812 Some(name_bindings) => {
3813 match (*name_bindings).get_module_if_available() {
3815 debug!("!!! (with scope) didn't find module \
3817 token::get_ident(name),
3818 self.module_to_string(&*orig_module));
3821 self.current_module = module_;
3831 self.current_module = orig_module;
3834 /// Wraps the given definition in the appropriate number of `DefUpvar`
3840 -> Option<DefLike> {
3842 DlDef(d @ DefUpvar(..)) => {
3843 self.session.span_bug(span,
3844 format!("unexpected {} in bindings", d).as_slice())
3846 DlDef(d @ DefLocal(_)) => {
3847 let node_id = d.def_id().node;
3849 let mut last_proc_body_id = ast::DUMMY_NODE_ID;
3850 for rib in ribs.iter() {
3853 // Nothing to do. Continue.
3855 ClosureRibKind(function_id, maybe_proc_body) => {
3857 if maybe_proc_body != ast::DUMMY_NODE_ID {
3858 last_proc_body_id = maybe_proc_body;
3860 def = DefUpvar(node_id, function_id, last_proc_body_id);
3862 let mut seen = self.freevars_seen.borrow_mut();
3863 let seen = seen.find_or_insert(function_id, NodeSet::new());
3864 if seen.contains(&node_id) {
3867 self.freevars.borrow_mut().find_or_insert(function_id, vec![])
3868 .push(Freevar { def: prev_def, span: span });
3869 seen.insert(node_id);
3871 MethodRibKind(item_id, _) => {
3872 // If the def is a ty param, and came from the parent
3875 DefTyParam(_, did, _) if {
3876 self.def_map.borrow().find_copy(&did.node)
3877 == Some(DefTyParamBinder(item_id))
3879 DefSelfTy(did) if did == item_id => {} // ok
3881 // This was an attempt to access an upvar inside a
3882 // named function item. This is not allowed, so we
3887 "can't capture dynamic environment in a fn item; \
3888 use the || { ... } closure form instead");
3895 // This was an attempt to access an upvar inside a
3896 // named function item. This is not allowed, so we
3901 "can't capture dynamic environment in a fn item; \
3902 use the || { ... } closure form instead");
3906 ConstantItemRibKind => {
3907 // Still doesn't deal with upvars
3908 self.resolve_error(span,
3909 "attempt to use a non-constant \
3910 value in a constant");
3917 DlDef(def @ DefTyParam(..)) |
3918 DlDef(def @ DefSelfTy(..)) => {
3919 for rib in ribs.iter() {
3921 NormalRibKind | ClosureRibKind(..) => {
3922 // Nothing to do. Continue.
3924 MethodRibKind(item_id, _) => {
3925 // If the def is a ty param, and came from the parent
3928 DefTyParam(_, did, _) if {
3929 self.def_map.borrow().find_copy(&did.node)
3930 == Some(DefTyParamBinder(item_id))
3932 DefSelfTy(did) if did == item_id => {} // ok
3935 // This was an attempt to use a type parameter outside
3938 self.resolve_error(span,
3939 "can't use type parameters from \
3940 outer function; try using a local \
3941 type parameter instead");
3948 // This was an attempt to use a type parameter outside
3951 self.resolve_error(span,
3952 "can't use type parameters from \
3953 outer function; try using a local \
3954 type parameter instead");
3958 ConstantItemRibKind => {
3960 self.resolve_error(span,
3961 "cannot use an outer type \
3962 parameter in this context");
3973 fn search_ribs(&self,
3977 -> Option<DefLike> {
3978 // FIXME #4950: Try caching?
3980 for (i, rib) in ribs.iter().enumerate().rev() {
3981 match rib.bindings.borrow().find_copy(&name) {
3983 return self.upvarify(ribs.slice_from(i + 1), def_like, span);
3994 fn resolve_crate(&mut self, krate: &ast::Crate) {
3995 debug!("(resolving crate) starting");
3997 visit::walk_crate(self, krate);
4000 fn resolve_item(&mut self, item: &Item) {
4001 debug!("(resolving item) resolving {}",
4002 token::get_ident(item.ident));
4006 // enum item: resolve all the variants' discrs,
4007 // then resolve the ty params
4008 ItemEnum(ref enum_def, ref generics) => {
4009 for variant in (*enum_def).variants.iter() {
4010 for dis_expr in variant.node.disr_expr.iter() {
4011 // resolve the discriminator expr
4013 self.with_constant_rib(|this| {
4014 this.resolve_expr(&**dis_expr);
4019 // n.b. the discr expr gets visited twice.
4020 // but maybe it's okay since the first time will signal an
4021 // error if there is one? -- tjc
4022 self.with_type_parameter_rib(HasTypeParameters(generics,
4027 this.resolve_type_parameters(&generics.ty_params);
4028 this.resolve_where_clause(&generics.where_clause);
4029 visit::walk_item(this, item);
4033 ItemTy(_, ref generics) => {
4034 self.with_type_parameter_rib(HasTypeParameters(generics,
4039 this.resolve_type_parameters(&generics.ty_params);
4040 visit::walk_item(this, item);
4044 ItemImpl(ref generics,
4045 ref implemented_traits,
4047 ref impl_items) => {
4048 self.resolve_implementation(item.id,
4052 impl_items.as_slice());
4055 ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
4056 // Create a new rib for the self type.
4057 let self_type_rib = Rib::new(ItemRibKind);
4059 // plain insert (no renaming, types are not currently hygienic....)
4060 let name = self.type_self_name;
4061 self_type_rib.bindings.borrow_mut()
4062 .insert(name, DlDef(DefSelfTy(item.id)));
4063 self.type_ribs.borrow_mut().push(self_type_rib);
4065 // Create a new rib for the trait-wide type parameters.
4066 self.with_type_parameter_rib(HasTypeParameters(generics,
4071 this.resolve_type_parameters(&generics.ty_params);
4072 this.resolve_where_clause(&generics.where_clause);
4074 this.resolve_type_parameter_bounds(item.id, bounds,
4078 &Some(ast::TraitTyParamBound(ref tpb)) => {
4079 this.resolve_trait_reference(item.id, tpb, TraitDerivation);
4084 for method in (*methods).iter() {
4085 // Create a new rib for the method-specific type
4088 // FIXME #4951: Do we need a node ID here?
4091 ast::RequiredMethod(ref ty_m) => {
4092 this.with_type_parameter_rib
4093 (HasTypeParameters(&ty_m.generics,
4096 MethodRibKind(item.id, RequiredMethod)),
4099 // Resolve the method-specific type
4101 this.resolve_type_parameters(
4102 &ty_m.generics.ty_params);
4103 this.resolve_where_clause(&ty_m.generics
4106 for argument in ty_m.decl.inputs.iter() {
4107 this.resolve_type(&*argument.ty);
4110 match ty_m.explicit_self.node {
4111 SelfExplicit(ref typ, _) => {
4112 this.resolve_type(&**typ)
4117 this.resolve_type(&*ty_m.decl.output);
4120 ast::ProvidedMethod(ref m) => {
4121 this.resolve_method(MethodRibKind(item.id,
4122 ProvidedMethod(m.id)),
4125 ast::TypeTraitItem(_) => {
4126 visit::walk_trait_item(this, method);
4132 self.type_ribs.borrow_mut().pop();
4135 ItemStruct(ref struct_def, ref generics) => {
4136 self.resolve_struct(item.id,
4138 &struct_def.super_struct,
4139 struct_def.fields.as_slice());
4142 ItemMod(ref module_) => {
4143 self.with_scope(Some(item.ident), |this| {
4144 this.resolve_module(module_, item.span, item.ident,
4149 ItemForeignMod(ref foreign_module) => {
4150 self.with_scope(Some(item.ident), |this| {
4151 for foreign_item in foreign_module.items.iter() {
4152 match foreign_item.node {
4153 ForeignItemFn(_, ref generics) => {
4154 this.with_type_parameter_rib(
4156 generics, FnSpace, foreign_item.id,
4158 |this| visit::walk_foreign_item(this,
4161 ForeignItemStatic(..) => {
4162 visit::walk_foreign_item(this,
4170 ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
4171 self.resolve_function(ItemRibKind,
4182 self.with_constant_rib(|this| {
4183 visit::walk_item(this, item);
4188 // do nothing, these are just around to be encoded
4193 fn with_type_parameter_rib(&mut self,
4194 type_parameters: TypeParameters,
4195 f: |&mut Resolver|) {
4196 match type_parameters {
4197 HasTypeParameters(generics, space, node_id,
4200 let function_type_rib = Rib::new(rib_kind);
4202 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
4203 let ident = type_parameter.ident;
4204 debug!("with_type_parameter_rib: {} {}", node_id,
4206 let def_like = DlDef(DefTyParam(space,
4207 local_def(type_parameter.id),
4209 // Associate this type parameter with
4210 // the item that bound it
4211 self.record_def(type_parameter.id,
4212 (DefTyParamBinder(node_id), LastMod(AllPublic)));
4213 // plain insert (no renaming)
4214 function_type_rib.bindings.borrow_mut()
4215 .insert(ident.name, def_like);
4217 self.type_ribs.borrow_mut().push(function_type_rib);
4220 NoTypeParameters => {
4227 match type_parameters {
4228 HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
4229 NoTypeParameters => { }
4233 fn with_label_rib(&mut self, f: |&mut Resolver|) {
4234 self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4236 self.label_ribs.borrow_mut().pop();
4239 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
4240 self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4241 self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
4243 self.type_ribs.borrow_mut().pop();
4244 self.value_ribs.borrow_mut().pop();
4247 fn resolve_function(&mut self,
4249 optional_declaration: Option<&FnDecl>,
4250 type_parameters: TypeParameters,
4252 // Create a value rib for the function.
4253 let function_value_rib = Rib::new(rib_kind);
4254 self.value_ribs.borrow_mut().push(function_value_rib);
4256 // Create a label rib for the function.
4257 let function_label_rib = Rib::new(rib_kind);
4258 self.label_ribs.borrow_mut().push(function_label_rib);
4260 // If this function has type parameters, add them now.
4261 self.with_type_parameter_rib(type_parameters, |this| {
4262 // Resolve the type parameters.
4263 match type_parameters {
4264 NoTypeParameters => {
4267 HasTypeParameters(ref generics, _, _, _) => {
4268 this.resolve_type_parameters(&generics.ty_params);
4269 this.resolve_where_clause(&generics.where_clause);
4273 // Add each argument to the rib.
4274 match optional_declaration {
4278 Some(declaration) => {
4279 for argument in declaration.inputs.iter() {
4280 let mut bindings_list = HashMap::new();
4281 this.resolve_pattern(&*argument.pat,
4282 ArgumentIrrefutableMode,
4283 &mut bindings_list);
4285 this.resolve_type(&*argument.ty);
4287 debug!("(resolving function) recorded argument");
4290 this.resolve_type(&*declaration.output);
4294 // Resolve the function body.
4295 this.resolve_block(&*block);
4297 debug!("(resolving function) leaving function");
4300 self.label_ribs.borrow_mut().pop();
4301 self.value_ribs.borrow_mut().pop();
4304 fn resolve_type_parameters(&mut self,
4305 type_parameters: &OwnedSlice<TyParam>) {
4306 for type_parameter in type_parameters.iter() {
4307 for bound in type_parameter.bounds.iter() {
4308 self.resolve_type_parameter_bound(type_parameter.id, bound,
4309 TraitBoundingTypeParameter);
4311 match &type_parameter.unbound {
4312 &Some(ref unbound) =>
4313 self.resolve_type_parameter_bound(
4314 type_parameter.id, unbound, TraitBoundingTypeParameter),
4317 match type_parameter.default {
4318 Some(ref ty) => self.resolve_type(&**ty),
4324 fn resolve_type_parameter_bounds(&mut self,
4326 type_parameter_bounds: &OwnedSlice<TyParamBound>,
4327 reference_type: TraitReferenceType) {
4328 for type_parameter_bound in type_parameter_bounds.iter() {
4329 self.resolve_type_parameter_bound(id, type_parameter_bound,
4334 fn resolve_type_parameter_bound(&mut self,
4336 type_parameter_bound: &TyParamBound,
4337 reference_type: TraitReferenceType) {
4338 match *type_parameter_bound {
4339 TraitTyParamBound(ref tref) => {
4340 self.resolve_trait_reference(id, tref, reference_type)
4342 UnboxedFnTyParamBound(ref unboxed_function) => {
4343 match self.resolve_path(unboxed_function.ref_id,
4344 &unboxed_function.path,
4348 let path_str = self.path_idents_to_string(
4349 &unboxed_function.path);
4350 self.resolve_error(unboxed_function.path.span,
4351 format!("unresolved trait `{}`",
4352 path_str).as_slice())
4356 (DefTrait(_), _) => {
4357 self.record_def(unboxed_function.ref_id, def);
4361 format!("`{}` is not a trait",
4362 self.path_idents_to_string(
4363 &unboxed_function.path));
4364 self.resolve_error(unboxed_function.path.span,
4371 for argument in unboxed_function.decl.inputs.iter() {
4372 self.resolve_type(&*argument.ty);
4375 self.resolve_type(&*unboxed_function.decl.output);
4377 RegionTyParamBound(..) => {}
4381 fn resolve_trait_reference(&mut self,
4383 trait_reference: &TraitRef,
4384 reference_type: TraitReferenceType) {
4385 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
4387 let path_str = self.path_idents_to_string(&trait_reference.path);
4388 let usage_str = match reference_type {
4389 TraitBoundingTypeParameter => "bound type parameter with",
4390 TraitImplementation => "implement",
4391 TraitDerivation => "derive",
4394 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
4395 self.resolve_error(trait_reference.path.span, msg.as_slice());
4399 (DefTrait(_), _) => {
4400 debug!("(resolving trait) found trait def: {:?}", def);
4401 self.record_def(trait_reference.ref_id, def);
4404 self.resolve_error(trait_reference.path.span,
4405 format!("`{}` is not a trait",
4406 self.path_idents_to_string(
4407 &trait_reference.path)));
4409 // If it's a typedef, give a note
4412 self.session.span_note(
4413 trait_reference.path.span,
4414 format!("`type` aliases cannot \
4415 be used for traits")
4427 fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
4428 for predicate in where_clause.predicates.iter() {
4429 match self.resolve_identifier(predicate.ident,
4433 Some((def @ DefTyParam(_, _, _), last_private)) => {
4434 self.record_def(predicate.id, (def, last_private));
4439 format!("undeclared type parameter `{}`",
4441 predicate.ident)).as_slice());
4445 for bound in predicate.bounds.iter() {
4446 self.resolve_type_parameter_bound(predicate.id, bound,
4447 TraitBoundingTypeParameter);
4452 fn resolve_struct(&mut self,
4454 generics: &Generics,
4455 super_struct: &Option<P<Ty>>,
4456 fields: &[StructField]) {
4457 // If applicable, create a rib for the type parameters.
4458 self.with_type_parameter_rib(HasTypeParameters(generics,
4463 // Resolve the type parameters.
4464 this.resolve_type_parameters(&generics.ty_params);
4465 this.resolve_where_clause(&generics.where_clause);
4467 // Resolve the super struct.
4468 match *super_struct {
4469 Some(ref t) => match t.node {
4470 TyPath(ref path, None, path_id) => {
4471 match this.resolve_path(id, path, TypeNS, true) {
4472 Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
4473 let def = DefStruct(def_id);
4474 debug!("(resolving struct) resolved `{}` to type {:?}",
4475 token::get_ident(path.segments
4479 debug!("(resolving struct) writing resolution for `{}` (id {})",
4480 this.path_idents_to_string(path),
4482 this.record_def(path_id, (def, lp));
4484 Some((DefStruct(_), _)) => {
4485 span_err!(this.session, t.span, E0154,
4486 "super-struct is defined in a different crate");
4489 span_err!(this.session, t.span, E0155,
4490 "super-struct is not a struct type");
4493 span_err!(this.session, t.span, E0156,
4494 "super-struct could not be resolved");
4498 _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4504 for field in fields.iter() {
4505 this.resolve_type(&*field.node.ty);
4510 // Does this really need to take a RibKind or is it always going
4511 // to be NormalRibKind?
4512 fn resolve_method(&mut self,
4514 method: &ast::Method) {
4515 let method_generics = method.pe_generics();
4516 let type_parameters = HasTypeParameters(method_generics,
4521 match method.pe_explicit_self().node {
4522 SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
4526 self.resolve_function(rib_kind,
4527 Some(method.pe_fn_decl()),
4532 fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4533 // Handle nested impls (inside fn bodies)
4534 let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4535 let result = f(self);
4536 self.current_self_type = previous_value;
4540 fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4541 opt_trait_ref: &Option<TraitRef>,
4542 f: |&mut Resolver| -> T) -> T {
4543 let new_val = match *opt_trait_ref {
4544 Some(ref trait_ref) => {
4545 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4547 match self.def_map.borrow().find(&trait_ref.ref_id) {
4549 let did = def.def_id();
4550 Some((did, trait_ref.clone()))
4557 let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4558 let result = f(self);
4559 self.current_trait_ref = original_trait_ref;
4563 fn resolve_implementation(&mut self,
4565 generics: &Generics,
4566 opt_trait_reference: &Option<TraitRef>,
4568 impl_items: &[ImplItem]) {
4569 // If applicable, create a rib for the type parameters.
4570 self.with_type_parameter_rib(HasTypeParameters(generics,
4575 // Resolve the type parameters.
4576 this.resolve_type_parameters(&generics.ty_params);
4577 this.resolve_where_clause(&generics.where_clause);
4579 // Resolve the trait reference, if necessary.
4580 this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4581 // Resolve the self type.
4582 this.resolve_type(self_type);
4584 this.with_current_self_type(self_type, |this| {
4585 for impl_item in impl_items.iter() {
4587 MethodImplItem(ref method) => {
4588 // If this is a trait impl, ensure the method
4590 this.check_trait_item(method.pe_ident(),
4593 // We also need a new scope for the method-
4594 // specific type parameters.
4595 this.resolve_method(
4597 ProvidedMethod(method.id)),
4600 TypeImplItem(ref typedef) => {
4601 // If this is a trait impl, ensure the method
4603 this.check_trait_item(typedef.ident,
4606 this.resolve_type(&*typedef.typ);
4615 fn check_trait_item(&self, ident: Ident, span: Span) {
4616 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4617 for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4618 let method_name = ident.name;
4620 if self.trait_item_map.borrow().find(&(method_name, did)).is_none() {
4621 let path_str = self.path_idents_to_string(&trait_ref.path);
4622 self.resolve_error(span,
4623 format!("method `{}` is not a member of trait `{}`",
4624 token::get_name(method_name),
4625 path_str).as_slice());
4630 fn resolve_module(&mut self, module: &Mod, _span: Span,
4631 _name: Ident, id: NodeId) {
4632 // Write the implementations in scope into the module metadata.
4633 debug!("(resolving module) resolving module ID {}", id);
4634 visit::walk_mod(self, module);
4637 fn resolve_local(&mut self, local: &Local) {
4638 // Resolve the type.
4639 self.resolve_type(&*local.ty);
4641 // Resolve the initializer, if necessary.
4646 Some(ref initializer) => {
4647 self.resolve_expr(&**initializer);
4651 // Resolve the pattern.
4652 let mut bindings_list = HashMap::new();
4653 self.resolve_pattern(&*local.pat,
4654 LocalIrrefutableMode,
4655 &mut bindings_list);
4658 // build a map from pattern identifiers to binding-info's.
4659 // this is done hygienically. This could arise for a macro
4660 // that expands into an or-pattern where one 'x' was from the
4661 // user and one 'x' came from the macro.
4662 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4663 let mut result = HashMap::new();
4664 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4665 let name = mtwt::resolve(path1.node);
4667 binding_info {span: sp,
4668 binding_mode: binding_mode});
4673 // check that all of the arms in an or-pattern have exactly the
4674 // same set of bindings, with the same binding modes for each.
4675 fn check_consistent_bindings(&mut self, arm: &Arm) {
4676 if arm.pats.len() == 0 {
4679 let map_0 = self.binding_mode_map(&**arm.pats.get(0));
4680 for (i, p) in arm.pats.iter().enumerate() {
4681 let map_i = self.binding_mode_map(&**p);
4683 for (&key, &binding_0) in map_0.iter() {
4684 match map_i.find(&key) {
4688 format!("variable `{}` from pattern #1 is \
4689 not bound in pattern #{}",
4690 token::get_name(key),
4693 Some(binding_i) => {
4694 if binding_0.binding_mode != binding_i.binding_mode {
4697 format!("variable `{}` is bound with different \
4698 mode in pattern #{} than in pattern #1",
4699 token::get_name(key),
4706 for (&key, &binding) in map_i.iter() {
4707 if !map_0.contains_key(&key) {
4710 format!("variable `{}` from pattern {}{} is \
4711 not bound in pattern {}1",
4712 token::get_name(key),
4713 "#", i + 1, "#").as_slice());
4719 fn resolve_arm(&mut self, arm: &Arm) {
4720 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4722 let mut bindings_list = HashMap::new();
4723 for pattern in arm.pats.iter() {
4724 self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4727 // This has to happen *after* we determine which
4728 // pat_idents are variants
4729 self.check_consistent_bindings(arm);
4731 visit::walk_expr_opt(self, &arm.guard);
4732 self.resolve_expr(&*arm.body);
4734 self.value_ribs.borrow_mut().pop();
4737 fn resolve_block(&mut self, block: &Block) {
4738 debug!("(resolving block) entering block");
4739 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4741 // Move down in the graph, if there's an anonymous module rooted here.
4742 let orig_module = self.current_module.clone();
4743 match orig_module.anonymous_children.borrow().find(&block.id) {
4744 None => { /* Nothing to do. */ }
4745 Some(anonymous_module) => {
4746 debug!("(resolving block) found anonymous module, moving \
4748 self.current_module = anonymous_module.clone();
4752 // Descend into the block.
4753 visit::walk_block(self, block);
4756 self.current_module = orig_module;
4758 self.value_ribs.borrow_mut().pop();
4759 debug!("(resolving block) leaving block");
4762 fn resolve_type(&mut self, ty: &Ty) {
4764 // Like path expressions, the interpretation of path types depends
4765 // on whether the path has multiple elements in it or not.
4767 TyPath(ref path, ref bounds, path_id) => {
4768 // This is a path in the type namespace. Walk through scopes
4770 let mut result_def = None;
4772 // First, check to see whether the name is a primitive type.
4773 if path.segments.len() == 1 {
4774 let id = path.segments.last().unwrap().identifier;
4776 match self.primitive_type_table
4780 Some(&primitive_type) => {
4782 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4786 .any(|s| !s.lifetimes.is_empty()) {
4787 span_err!(self.session, path.span, E0157,
4788 "lifetime parameters are not allowed on this type");
4789 } else if path.segments
4791 .any(|s| s.types.len() > 0) {
4792 span_err!(self.session, path.span, E0153,
4793 "type parameters are not allowed on this type");
4804 match self.resolve_path(ty.id, path, TypeNS, true) {
4806 debug!("(resolving type) resolved `{}` to \
4808 token::get_ident(path.segments
4812 result_def = Some(def);
4819 Some(_) => {} // Continue.
4824 // Write the result into the def map.
4825 debug!("(resolving type) writing resolution for `{}` \
4827 self.path_idents_to_string(path),
4829 self.record_def(path_id, def);
4832 let msg = format!("use of undeclared type name `{}`",
4833 self.path_idents_to_string(path));
4834 self.resolve_error(ty.span, msg.as_slice());
4838 bounds.as_ref().map(|bound_vec| {
4839 self.resolve_type_parameter_bounds(ty.id, bound_vec,
4840 TraitBoundingTypeParameter);
4844 TyQPath(ref qpath) => {
4845 self.resolve_type(&*qpath.for_type);
4847 let current_module = self.current_module.clone();
4848 let module_path_idents: Vec<_> =
4852 .map(|ps| ps.identifier)
4854 match self.resolve_module_path(
4856 module_path_idents.as_slice(),
4858 qpath.trait_name.span,
4860 Success((ref module, _)) if module.kind.get() ==
4861 TraitModuleKind => {
4862 match self.resolve_definition_of_name_in_module(
4864 qpath.item_name.name,
4866 ChildNameDefinition(def, lp) |
4867 ImportNameDefinition(def, lp) => {
4869 DefAssociatedTy(trait_type_id) => {
4870 let def = DefAssociatedTy(
4872 self.record_def(ty.id, (def, lp));
4877 "not an associated type");
4881 NoNameDefinition => {
4882 self.resolve_error(ty.span,
4883 "unresolved associated \
4888 Success(..) => self.resolve_error(ty.span, "not a trait"),
4890 self.session.span_bug(ty.span,
4891 "indeterminate result when \
4892 resolving associated type")
4895 let (span, help) = match error {
4896 Some((span, msg)) => (span, format!("; {}", msg)),
4897 None => (ty.span, String::new()),
4899 self.resolve_error(span,
4900 format!("unresolved trait: {}",
4906 TyClosure(ref c) | TyProc(ref c) => {
4907 self.resolve_type_parameter_bounds(
4910 TraitBoundingTypeParameter);
4911 visit::walk_ty(self, ty);
4915 // Just resolve embedded types.
4916 visit::walk_ty(self, ty);
4921 fn resolve_pattern(&mut self,
4923 mode: PatternBindingMode,
4924 // Maps idents to the node ID for the (outermost)
4925 // pattern that binds them
4926 bindings_list: &mut HashMap<Name,NodeId>) {
4927 let pat_id = pattern.id;
4928 walk_pat(pattern, |pattern| {
4929 match pattern.node {
4930 PatIdent(binding_mode, ref path1, _) => {
4932 // The meaning of pat_ident with no type parameters
4933 // depends on whether an enum variant or unit-like struct
4934 // with that name is in scope. The probing lookup has to
4935 // be careful not to emit spurious errors. Only matching
4936 // patterns (match) can match nullary variants or
4937 // unit-like structs. For binding patterns (let), matching
4938 // such a value is simply disallowed (since it's rarely
4941 let ident = path1.node;
4942 let renamed = mtwt::resolve(ident);
4944 match self.resolve_bare_identifier_pattern(ident, pattern.span) {
4945 FoundStructOrEnumVariant(ref def, lp)
4946 if mode == RefutableMode => {
4947 debug!("(resolving pattern) resolving `{}` to \
4948 struct or enum variant",
4949 token::get_name(renamed));
4951 self.enforce_default_binding_mode(
4955 self.record_def(pattern.id, (def.clone(), lp));
4957 FoundStructOrEnumVariant(..) => {
4960 format!("declaration of `{}` shadows an enum \
4961 variant or unit-like struct in \
4963 token::get_name(renamed)).as_slice());
4965 FoundConst(ref def, lp) if mode == RefutableMode => {
4966 debug!("(resolving pattern) resolving `{}` to \
4968 token::get_name(renamed));
4970 self.enforce_default_binding_mode(
4974 self.record_def(pattern.id, (def.clone(), lp));
4977 self.resolve_error(pattern.span,
4978 "only irrefutable patterns \
4981 BareIdentifierPatternUnresolved => {
4982 debug!("(resolving pattern) binding `{}`",
4983 token::get_name(renamed));
4985 let def = DefLocal(pattern.id);
4987 // Record the definition so that later passes
4988 // will be able to distinguish variants from
4989 // locals in patterns.
4991 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4993 // Add the binding to the local ribs, if it
4994 // doesn't already exist in the bindings list. (We
4995 // must not add it if it's in the bindings list
4996 // because that breaks the assumptions later
4997 // passes make about or-patterns.)
4999 if !bindings_list.contains_key(&renamed) {
5000 let this = &mut *self;
5001 let value_ribs = this.value_ribs.borrow();
5002 let length = value_ribs.len();
5003 let last_rib = value_ribs.get(
5005 last_rib.bindings.borrow_mut()
5006 .insert(renamed, DlDef(def));
5007 bindings_list.insert(renamed, pat_id);
5008 } else if bindings_list.find(&renamed) ==
5010 // Then this is a duplicate variable in the
5011 // same disjunction, which is an error.
5012 self.resolve_error(pattern.span,
5013 format!("identifier `{}` is bound \
5014 more than once in the same \
5016 token::get_ident(ident)).as_slice());
5018 // Else, not bound in the same pattern: do
5024 PatEnum(ref path, _) => {
5025 // This must be an enum variant, struct or const.
5026 match self.resolve_path(pat_id, path, ValueNS, false) {
5027 Some(def @ (DefFn(..), _)) |
5028 Some(def @ (DefVariant(..), _)) |
5029 Some(def @ (DefStruct(..), _)) |
5030 Some(def @ (DefStatic(..), _)) => {
5031 self.record_def(pattern.id, def);
5034 self.resolve_error(path.span,
5035 format!("`{}` is not an enum variant, struct or const",
5040 .identifier)).as_slice());
5043 self.resolve_error(path.span,
5044 format!("unresolved enum variant, struct or const `{}`",
5049 .identifier)).as_slice());
5053 // Check the types in the path pattern.
5054 for ty in path.segments
5056 .flat_map(|s| s.types.iter()) {
5057 self.resolve_type(&**ty);
5061 PatLit(ref expr) => {
5062 self.resolve_expr(&**expr);
5065 PatRange(ref first_expr, ref last_expr) => {
5066 self.resolve_expr(&**first_expr);
5067 self.resolve_expr(&**last_expr);
5070 PatStruct(ref path, _, _) => {
5071 match self.resolve_path(pat_id, path, TypeNS, false) {
5072 Some(definition) => {
5073 self.record_def(pattern.id, definition);
5076 debug!("(resolving pattern) didn't find struct \
5077 def: {:?}", result);
5078 let msg = format!("`{}` does not name a structure",
5079 self.path_idents_to_string(path));
5080 self.resolve_error(path.span, msg.as_slice());
5093 fn resolve_bare_identifier_pattern(&mut self, name: Ident, span: Span)
5094 -> BareIdentifierPatternResolution {
5095 let module = self.current_module.clone();
5096 match self.resolve_item_in_lexical_scope(module,
5099 Success((target, _)) => {
5100 debug!("(resolve bare identifier pattern) succeeded in \
5101 finding {} at {:?}",
5102 token::get_ident(name),
5103 target.bindings.value_def.borrow());
5104 match *target.bindings.value_def.borrow() {
5106 fail!("resolved name in the value namespace to a \
5107 set of name bindings with no def?!");
5110 // For the two success cases, this lookup can be
5111 // considered as not having a private component because
5112 // the lookup happened only within the current module.
5114 def @ DefVariant(..) | def @ DefStruct(..) => {
5115 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
5117 def @ DefStatic(_, false) => {
5118 return FoundConst(def, LastMod(AllPublic));
5120 DefStatic(_, true) => {
5121 self.resolve_error(span,
5122 "mutable static variables cannot be referenced in a pattern");
5123 return BareIdentifierPatternUnresolved;
5126 return BareIdentifierPatternUnresolved;
5134 fail!("unexpected indeterminate result");
5138 Some((span, msg)) => {
5139 self.resolve_error(span, format!("failed to resolve: {}",
5145 debug!("(resolve bare identifier pattern) failed to find {}",
5146 token::get_ident(name));
5147 return BareIdentifierPatternUnresolved;
5152 /// If `check_ribs` is true, checks the local definitions first; i.e.
5153 /// doesn't skip straight to the containing module.
5154 fn resolve_path(&mut self,
5157 namespace: Namespace,
5158 check_ribs: bool) -> Option<(Def, LastPrivate)> {
5159 // First, resolve the types.
5160 for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
5161 self.resolve_type(&**ty);
5165 return self.resolve_crate_relative_path(path, namespace);
5168 let unqualified_def =
5169 self.resolve_identifier(path.segments
5176 if path.segments.len() > 1 {
5177 let def = self.resolve_module_relative_path(path, namespace);
5178 match (def, unqualified_def) {
5179 (Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
5181 .add_lint(lint::builtin::UNNECESSARY_QUALIFICATION,
5184 "unnecessary qualification".to_string());
5192 return unqualified_def;
5195 // resolve a single identifier (used as a varref)
5196 fn resolve_identifier(&mut self,
5198 namespace: Namespace,
5201 -> Option<(Def, LastPrivate)> {
5203 match self.resolve_identifier_in_local_ribs(identifier,
5207 return Some((def, LastMod(AllPublic)));
5215 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
5219 // FIXME #4952: Merge me with resolve_name_in_module?
5220 fn resolve_definition_of_name_in_module(&mut self,
5221 containing_module: Rc<Module>,
5223 namespace: Namespace)
5225 // First, search children.
5226 self.populate_module_if_necessary(&containing_module);
5228 match containing_module.children.borrow().find(&name) {
5229 Some(child_name_bindings) => {
5230 match child_name_bindings.def_for_namespace(namespace) {
5232 // Found it. Stop the search here.
5233 let p = child_name_bindings.defined_in_public_namespace(
5235 let lp = if p {LastMod(AllPublic)} else {
5236 LastMod(DependsOn(def.def_id()))
5238 return ChildNameDefinition(def, lp);
5246 // Next, search import resolutions.
5247 match containing_module.import_resolutions.borrow().find(&name) {
5248 Some(import_resolution) if import_resolution.is_public => {
5249 match (*import_resolution).target_for_namespace(namespace) {
5251 match target.bindings.def_for_namespace(namespace) {
5254 let id = import_resolution.id(namespace);
5255 // track imports and extern crates as well
5256 self.used_imports.insert((id, namespace));
5257 match target.target_module.def_id.get() {
5258 Some(DefId{krate: kid, ..}) => {
5259 self.used_crates.insert(kid);
5263 return ImportNameDefinition(def, LastMod(AllPublic));
5266 // This can happen with external impls, due to
5267 // the imperfect way we read the metadata.
5274 Some(..) | None => {} // Continue.
5277 // Finally, search through external children.
5278 if namespace == TypeNS {
5279 match containing_module.external_module_children.borrow()
5283 match module.def_id.get() {
5284 None => {} // Continue.
5286 // track used crates
5287 self.used_crates.insert(def_id.krate);
5288 let lp = if module.is_public {LastMod(AllPublic)} else {
5289 LastMod(DependsOn(def_id))
5291 return ChildNameDefinition(DefMod(def_id), lp);
5298 return NoNameDefinition;
5301 // resolve a "module-relative" path, e.g. a::b::c
5302 fn resolve_module_relative_path(&mut self,
5304 namespace: Namespace)
5305 -> Option<(Def, LastPrivate)> {
5306 let module_path_idents = path.segments.init().iter()
5307 .map(|ps| ps.identifier)
5308 .collect::<Vec<_>>();
5310 let containing_module;
5312 let module = self.current_module.clone();
5313 match self.resolve_module_path(module,
5314 module_path_idents.as_slice(),
5319 let (span, msg) = match err {
5320 Some((span, msg)) => (span, msg),
5322 let msg = format!("Use of undeclared module `{}`",
5323 self.idents_to_string(
5324 module_path_idents.as_slice()));
5329 self.resolve_error(span, format!("failed to resolve. {}",
5333 Indeterminate => fail!("indeterminate unexpected"),
5334 Success((resulting_module, resulting_last_private)) => {
5335 containing_module = resulting_module;
5336 last_private = resulting_last_private;
5340 let ident = path.segments.last().unwrap().identifier;
5341 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
5344 NoNameDefinition => {
5345 // We failed to resolve the name. Report an error.
5348 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5349 (def, last_private.or(lp))
5352 match containing_module.kind.get() {
5353 TraitModuleKind | ImplModuleKind => {
5354 match containing_module.def_id.get() {
5356 match self.trait_item_map.borrow().find(&(ident.name, def_id)) {
5357 Some(&StaticMethodTraitItemKind) => (),
5358 Some(&TypeTraitItemKind) => (),
5360 Some(&NonstaticMethodTraitItemKind) => {
5361 debug!("containing module was a trait or impl \
5362 and name was a method -> not resolved");
5372 match containing_module.def_id.get() {
5373 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
5379 /// Invariant: This must be called only during main resolution, not during
5380 /// import resolution.
5381 fn resolve_crate_relative_path(&mut self,
5383 namespace: Namespace)
5384 -> Option<(Def, LastPrivate)> {
5385 let module_path_idents = path.segments.init().iter()
5386 .map(|ps| ps.identifier)
5387 .collect::<Vec<_>>();
5389 let root_module = self.graph_root.get_module();
5391 let containing_module;
5393 match self.resolve_module_path_from_root(root_module,
5394 module_path_idents.as_slice(),
5398 LastMod(AllPublic)) {
5400 let (span, msg) = match err {
5401 Some((span, msg)) => (span, msg),
5403 let msg = format!("Use of undeclared module `::{}`",
5404 self.idents_to_string(
5405 module_path_idents.as_slice()));
5410 self.resolve_error(span, format!("failed to resolve. {}",
5416 fail!("indeterminate unexpected");
5419 Success((resulting_module, resulting_last_private)) => {
5420 containing_module = resulting_module;
5421 last_private = resulting_last_private;
5425 let name = path.segments.last().unwrap().identifier.name;
5426 match self.resolve_definition_of_name_in_module(containing_module,
5429 NoNameDefinition => {
5430 // We failed to resolve the name. Report an error.
5433 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
5434 return Some((def, last_private.or(lp)));
5439 fn resolve_identifier_in_local_ribs(&mut self,
5441 namespace: Namespace,
5444 // Check the local set of ribs.
5445 let search_result = match namespace {
5447 let renamed = mtwt::resolve(ident);
5448 self.search_ribs(self.value_ribs.borrow().as_slice(),
5452 let name = ident.name;
5453 self.search_ribs(self.type_ribs.borrow().as_slice(), name, span)
5457 match search_result {
5458 Some(DlDef(def)) => {
5459 debug!("(resolving path in local ribs) resolved `{}` to \
5461 token::get_ident(ident),
5465 Some(DlField) | Some(DlImpl(_)) | None => {
5471 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
5473 namespace: Namespace)
5474 -> Option<(Def, LastPrivate)> {
5476 let module = self.current_module.clone();
5477 match self.resolve_item_in_lexical_scope(module,
5480 Success((target, _)) => {
5481 match (*target.bindings).def_for_namespace(namespace) {
5483 // This can happen if we were looking for a type and
5484 // found a module instead. Modules don't have defs.
5485 debug!("(resolving item path by identifier in lexical \
5486 scope) failed to resolve {} after success...",
5487 token::get_ident(ident));
5491 debug!("(resolving item path in lexical scope) \
5492 resolved `{}` to item",
5493 token::get_ident(ident));
5494 // This lookup is "all public" because it only searched
5495 // for one identifier in the current module (couldn't
5496 // have passed through reexports or anything like that.
5497 return Some((def, LastMod(AllPublic)));
5502 fail!("unexpected indeterminate result");
5506 Some((span, msg)) =>
5507 self.resolve_error(span, format!("failed to resolve. {}", msg)),
5511 debug!("(resolving item path by identifier in lexical scope) \
5512 failed to resolve {}", token::get_ident(ident));
5518 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
5519 self.emit_errors = false;
5521 self.emit_errors = true;
5525 fn resolve_error<T: Str>(&self, span: Span, s: T) {
5526 if self.emit_errors {
5527 self.session.span_err(span, s.as_slice());
5531 fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
5532 #[deriving(PartialEq)]
5533 enum FallbackChecks {
5538 fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
5539 -> Option<(Path, NodeId, FallbackChecks)> {
5541 TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
5542 TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5543 TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5544 // This doesn't handle the remaining `Ty` variants as they are not
5545 // that commonly the self_type, it might be interesting to provide
5546 // support for those in future.
5551 fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
5552 -> Option<Rc<Module>> {
5553 let root = this.current_module.clone();
5554 let last_name = ident_path.last().unwrap().name;
5556 if ident_path.len() == 1 {
5557 match this.primitive_type_table.primitive_types.find(&last_name) {
5560 match this.current_module.children.borrow().find(&last_name) {
5561 Some(child) => child.get_module_if_available(),
5567 match this.resolve_module_path(root,
5568 ident_path.as_slice(),
5572 Success((module, _)) => Some(module),
5578 let (path, node_id, allowed) = match self.current_self_type {
5579 Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5581 None => return NoSuggestion,
5583 None => return NoSuggestion,
5586 if allowed == Everything {
5587 // Look for a field with the same name in the current self_type.
5588 match self.def_map.borrow().find(&node_id) {
5589 Some(&DefTy(did, _))
5590 | Some(&DefStruct(did))
5591 | Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
5594 if fields.iter().any(|&field_name| name == field_name) {
5599 _ => {} // Self type didn't resolve properly
5603 let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
5605 // Look for a method in the current self type's impl module.
5606 match get_module(self, path.span, ident_path.as_slice()) {
5607 Some(module) => match module.children.borrow().find(&name) {
5609 let p_str = self.path_idents_to_string(&path);
5610 match binding.def_for_namespace(ValueNS) {
5611 Some(DefStaticMethod(_, provenance, _)) => {
5613 FromImpl(_) => return StaticMethod(p_str),
5614 FromTrait(_) => unreachable!()
5617 Some(DefMethod(_, None)) if allowed == Everything => return Method,
5618 Some(DefMethod(_, Some(_))) => return TraitItem,
5627 // Look for a method in the current trait.
5628 let trait_item_map = self.trait_item_map.borrow();
5629 match self.current_trait_ref {
5630 Some((did, ref trait_ref)) => {
5631 let path_str = self.path_idents_to_string(&trait_ref.path);
5633 match trait_item_map.find(&(name, did)) {
5634 Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
5635 Some(_) => return TraitItem,
5645 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5647 let this = &mut *self;
5649 let mut maybes: Vec<token::InternedString> = Vec::new();
5650 let mut values: Vec<uint> = Vec::new();
5652 let mut j = this.value_ribs.borrow().len();
5655 let value_ribs = this.value_ribs.borrow();
5656 let bindings = value_ribs.get(j).bindings.borrow();
5657 for (&k, _) in bindings.iter() {
5658 maybes.push(token::get_name(k));
5659 values.push(uint::MAX);
5663 let mut smallest = 0;
5664 for (i, other) in maybes.iter().enumerate() {
5665 *values.get_mut(i) = name.lev_distance(other.get());
5667 if *values.get(i) <= *values.get(smallest) {
5672 if values.len() > 0 &&
5673 *values.get(smallest) != uint::MAX &&
5674 *values.get(smallest) < name.len() + 2 &&
5675 *values.get(smallest) <= max_distance &&
5676 name != maybes.get(smallest).get() {
5678 Some(maybes.get(smallest).get().to_string())
5685 fn resolve_expr(&mut self, expr: &Expr) {
5686 // First, record candidate traits for this expression if it could
5687 // result in the invocation of a method call.
5689 self.record_candidate_traits_for_expr_if_necessary(expr);
5691 // Next, resolve the node.
5693 // The interpretation of paths depends on whether the path has
5694 // multiple elements in it or not.
5696 ExprPath(ref path) => {
5697 // This is a local path in the value namespace. Walk through
5698 // scopes looking for it.
5700 match self.resolve_path(expr.id, path, ValueNS, true) {
5702 // Write the result into the def map.
5703 debug!("(resolving expr) resolved `{}`",
5704 self.path_idents_to_string(path));
5706 // First-class methods are not supported yet; error
5709 (DefMethod(..), _) => {
5710 self.resolve_error(expr.span,
5711 "first-class methods \
5712 are not supported");
5713 self.session.span_note(expr.span,
5721 self.record_def(expr.id, def);
5724 let wrong_name = self.path_idents_to_string(path);
5725 // Be helpful if the name refers to a struct
5726 // (The pattern matching def_tys where the id is in self.structs
5727 // matches on regular structs while excluding tuple- and enum-like
5728 // structs, which wouldn't result in this error.)
5729 match self.with_no_errors(|this|
5730 this.resolve_path(expr.id, path, TypeNS, false)) {
5731 Some((DefTy(struct_id, _), _))
5732 if self.structs.contains_key(&struct_id) => {
5733 self.resolve_error(expr.span,
5734 format!("`{}` is a structure name, but \
5736 uses it like a function name",
5737 wrong_name).as_slice());
5739 self.session.span_note(expr.span,
5740 format!("Did you mean to write: \
5741 `{} {{ /* fields */ }}`?",
5742 wrong_name).as_slice());
5746 let mut method_scope = false;
5747 self.value_ribs.borrow().iter().rev().all(|rib| {
5748 let res = match *rib {
5749 Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5750 Rib { bindings: _, kind: ItemRibKind } => false,
5751 _ => return true, // Keep advancing
5755 false // Stop advancing
5758 if method_scope && token::get_name(self.self_name).get()
5759 == wrong_name.as_slice() {
5762 "`self` is not available \
5763 in a static method. Maybe a \
5764 `self` argument is missing?");
5766 let last_name = path.segments.last().unwrap().identifier.name;
5767 let mut msg = match self.find_fallback_in_self_type(last_name) {
5769 // limit search to 5 to reduce the number
5770 // of stupid suggestions
5771 self.find_best_match_for_name(wrong_name.as_slice(), 5)
5772 .map_or("".to_string(),
5773 |x| format!("`{}`", x))
5776 format!("`self.{}`", wrong_name),
5779 format!("to call `self.{}`", wrong_name),
5780 StaticTraitMethod(path_str)
5781 | StaticMethod(path_str) =>
5782 format!("to call `{}::{}`", path_str, wrong_name)
5786 msg = format!(" Did you mean {}?", msg)
5791 format!("unresolved name `{}`.{}",
5800 visit::walk_expr(self, expr);
5803 ExprFnBlock(_, ref fn_decl, ref block) => {
5804 // NOTE(stage0): After snapshot, change to:
5806 //self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
5807 self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByRef);
5808 self.resolve_function(ClosureRibKind(expr.id, ast::DUMMY_NODE_ID),
5809 Some(&**fn_decl), NoTypeParameters,
5812 ExprProc(ref fn_decl, ref block) => {
5813 self.capture_mode_map.borrow_mut().insert(expr.id, ast::CaptureByValue);
5814 self.resolve_function(ClosureRibKind(expr.id, block.id),
5815 Some(&**fn_decl), NoTypeParameters,
5818 ExprUnboxedFn(capture_clause, _, ref fn_decl, ref block) => {
5819 self.capture_mode_map.borrow_mut().insert(expr.id, capture_clause);
5820 self.resolve_function(ClosureRibKind(expr.id, block.id),
5821 Some(&**fn_decl), NoTypeParameters,
5825 ExprStruct(ref path, _, _) => {
5826 // Resolve the path to the structure it goes to. We don't
5827 // check to ensure that the path is actually a structure; that
5828 // is checked later during typeck.
5829 match self.resolve_path(expr.id, path, TypeNS, false) {
5830 Some(definition) => self.record_def(expr.id, definition),
5832 debug!("(resolving expression) didn't find struct \
5833 def: {:?}", result);
5834 let msg = format!("`{}` does not name a structure",
5835 self.path_idents_to_string(path));
5836 self.resolve_error(path.span, msg.as_slice());
5840 visit::walk_expr(self, expr);
5843 ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
5844 self.with_label_rib(|this| {
5845 let def_like = DlDef(DefLabel(expr.id));
5848 let label_ribs = this.label_ribs.borrow();
5849 let length = label_ribs.len();
5850 let rib = label_ribs.get(length - 1);
5851 let renamed = mtwt::resolve(label);
5852 rib.bindings.borrow_mut().insert(renamed, def_like);
5855 visit::walk_expr(this, expr);
5859 ExprForLoop(ref pattern, ref head, ref body, optional_label) => {
5860 self.resolve_expr(&**head);
5862 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
5864 self.resolve_pattern(&**pattern,
5865 LocalIrrefutableMode,
5866 &mut HashMap::new());
5868 match optional_label {
5873 .push(Rib::new(NormalRibKind));
5874 let def_like = DlDef(DefLabel(expr.id));
5877 let label_ribs = self.label_ribs.borrow();
5878 let length = label_ribs.len();
5879 let rib = label_ribs.get(length - 1);
5880 let renamed = mtwt::resolve(label);
5881 rib.bindings.borrow_mut().insert(renamed,
5887 self.resolve_block(&**body);
5889 if optional_label.is_some() {
5890 drop(self.label_ribs.borrow_mut().pop())
5893 self.value_ribs.borrow_mut().pop();
5896 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5897 let renamed = mtwt::resolve(label);
5898 match self.search_ribs(self.label_ribs.borrow().as_slice(),
5899 renamed, expr.span) {
5903 format!("use of undeclared label `{}`",
5904 token::get_ident(label)).as_slice())
5906 Some(DlDef(def @ DefLabel(_))) => {
5907 // Since this def is a label, it is never read.
5908 self.record_def(expr.id, (def, LastMod(AllPublic)))
5911 self.session.span_bug(expr.span,
5912 "label wasn't mapped to a \
5919 visit::walk_expr(self, expr);
5924 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5926 ExprField(_, ident, _) => {
5927 // FIXME(#6890): Even though you can't treat a method like a
5928 // field, we need to add any trait methods we find that match
5929 // the field name so that we can do some nice error reporting
5930 // later on in typeck.
5931 let traits = self.search_for_traits_containing_method(ident.node.name);
5932 self.trait_map.insert(expr.id, traits);
5934 ExprMethodCall(ident, _, _) => {
5935 debug!("(recording candidate traits for expr) recording \
5938 let traits = self.search_for_traits_containing_method(ident.node.name);
5939 self.trait_map.insert(expr.id, traits);
5947 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5948 debug!("(searching for traits containing method) looking for '{}'",
5949 token::get_name(name));
5951 fn add_trait_info(found_traits: &mut Vec<DefId>,
5952 trait_def_id: DefId,
5954 debug!("(adding trait info) found trait {}:{} for method '{}'",
5957 token::get_name(name));
5958 found_traits.push(trait_def_id);
5961 let mut found_traits = Vec::new();
5962 let mut search_module = self.current_module.clone();
5964 // Look for the current trait.
5965 match self.current_trait_ref {
5966 Some((trait_def_id, _)) => {
5967 let trait_item_map = self.trait_item_map.borrow();
5969 if trait_item_map.contains_key(&(name, trait_def_id)) {
5970 add_trait_info(&mut found_traits, trait_def_id, name);
5973 None => {} // Nothing to do.
5976 // Look for trait children.
5977 self.populate_module_if_necessary(&search_module);
5980 let trait_item_map = self.trait_item_map.borrow();
5981 for (_, child_names) in search_module.children.borrow().iter() {
5982 let def = match child_names.def_for_namespace(TypeNS) {
5986 let trait_def_id = match def {
5987 DefTrait(trait_def_id) => trait_def_id,
5990 if trait_item_map.contains_key(&(name, trait_def_id)) {
5991 add_trait_info(&mut found_traits, trait_def_id, name);
5996 // Look for imports.
5997 for (_, import) in search_module.import_resolutions.borrow().iter() {
5998 let target = match import.target_for_namespace(TypeNS) {
6000 Some(target) => target,
6002 let did = match target.bindings.def_for_namespace(TypeNS) {
6003 Some(DefTrait(trait_def_id)) => trait_def_id,
6004 Some(..) | None => continue,
6006 if self.trait_item_map.borrow().contains_key(&(name, did)) {
6007 add_trait_info(&mut found_traits, did, name);
6008 self.used_imports.insert((import.type_id, TypeNS));
6009 match target.target_module.def_id.get() {
6010 Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
6016 match search_module.parent_link.clone() {
6017 NoParentLink | ModuleParentLink(..) => break,
6018 BlockParentLink(parent_module, _) => {
6019 search_module = parent_module.upgrade().unwrap();
6027 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
6028 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
6030 assert!(match lp {LastImport{..} => false, _ => true},
6031 "Import should only be used for `use` directives");
6032 self.last_private.insert(node_id, lp);
6033 self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
6034 // Resolve appears to "resolve" the same ID multiple
6035 // times, so here is a sanity check it at least comes to
6036 // the same conclusion! - nmatsakis
6037 if def != *old_value {
6039 .bug(format!("node_id {:?} resolved first to {:?} and \
6048 fn enforce_default_binding_mode(&mut self,
6050 pat_binding_mode: BindingMode,
6052 match pat_binding_mode {
6053 BindByValue(_) => {}
6055 self.resolve_error(pat.span,
6056 format!("cannot use `ref` binding mode \
6064 // Unused import checking
6066 // Although this is mostly a lint pass, it lives in here because it depends on
6067 // resolve data structures and because it finalises the privacy information for
6068 // `use` directives.
6071 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
6072 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
6073 visit::walk_crate(&mut visitor, krate);
6076 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
6077 // Ignore is_public import statements because there's no way to be sure
6078 // whether they're used or not. Also ignore imports with a dummy span
6079 // because this means that they were generated in some fashion by the
6080 // compiler and we don't need to consider them.
6081 if vi.vis == Public { return }
6082 if vi.span == DUMMY_SP { return }
6085 ViewItemExternCrate(_, _, id) => {
6086 match self.session.cstore.find_extern_mod_stmt_cnum(id)
6088 Some(crate_num) => if !self.used_crates.contains(&crate_num) {
6089 self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATE,
6092 "unused extern crate".to_string());
6097 ViewItemUse(ref p) => {
6099 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
6101 ViewPathList(_, ref list, _) => {
6102 for i in list.iter() {
6103 self.finalize_import(i.node.id(), i.span);
6106 ViewPathGlob(_, id) => {
6107 if !self.used_imports.contains(&(id, TypeNS)) &&
6108 !self.used_imports.contains(&(id, ValueNS)) {
6110 .add_lint(lint::builtin::UNUSED_IMPORTS,
6113 "unused import".to_string());
6121 // We have information about whether `use` (import) directives are actually used now.
6122 // If an import is not used at all, we signal a lint error. If an import is only used
6123 // for a single namespace, we remove the other namespace from the recorded privacy
6124 // information. That means in privacy.rs, we will only check imports and namespaces
6125 // which are used. In particular, this means that if an import could name either a
6126 // public or private item, we will check the correct thing, dependent on how the import
6128 fn finalize_import(&mut self, id: NodeId, span: Span) {
6129 debug!("finalizing import uses for {}",
6130 self.session.codemap().span_to_snippet(span));
6132 if !self.used_imports.contains(&(id, TypeNS)) &&
6133 !self.used_imports.contains(&(id, ValueNS)) {
6134 self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
6137 "unused import".to_string());
6140 let (v_priv, t_priv) = match self.last_private.find(&id) {
6148 fail!("we should only have LastImport for `use` directives")
6153 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
6158 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
6164 match (v_priv, t_priv) {
6165 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
6166 // we might have two LastPrivates pointing at the same thing. There is no point
6167 // checking both, so lets not check the value one.
6168 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
6172 self.last_private.insert(id, LastImport{value_priv: v_priv,
6175 type_used: t_used});
6181 // Diagnostics are not particularly efficient, because they're rarely
6185 /// A somewhat inefficient routine to obtain the name of a module.
6186 fn module_to_string(&self, module: &Module) -> String {
6187 let mut idents = Vec::new();
6189 fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
6190 match module.parent_link {
6192 ModuleParentLink(ref module, name) => {
6194 collect_mod(idents, &*module.upgrade().unwrap());
6196 BlockParentLink(ref module, _) => {
6197 // danger, shouldn't be ident?
6198 idents.push(special_idents::opaque);
6199 collect_mod(idents, &*module.upgrade().unwrap());
6203 collect_mod(&mut idents, module);
6205 if idents.len() == 0 {
6206 return "???".to_string();
6208 self.idents_to_string(idents.into_iter().rev()
6209 .collect::<Vec<ast::Ident>>()
6213 #[allow(dead_code)] // useful for debugging
6214 fn dump_module(&mut self, module_: Rc<Module>) {
6215 debug!("Dump of module `{}`:", self.module_to_string(&*module_));
6217 debug!("Children:");
6218 self.populate_module_if_necessary(&module_);
6219 for (&name, _) in module_.children.borrow().iter() {
6220 debug!("* {}", token::get_name(name));
6223 debug!("Import resolutions:");
6224 let import_resolutions = module_.import_resolutions.borrow();
6225 for (&name, import_resolution) in import_resolutions.iter() {
6227 match import_resolution.target_for_namespace(ValueNS) {
6228 None => { value_repr = "".to_string(); }
6230 value_repr = " value:?".to_string();
6236 match import_resolution.target_for_namespace(TypeNS) {
6237 None => { type_repr = "".to_string(); }
6239 type_repr = " type:?".to_string();
6244 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
6249 pub struct CrateMap {
6250 pub def_map: DefMap,
6251 pub freevars: RefCell<FreevarMap>,
6252 pub capture_mode_map: RefCell<CaptureModeMap>,
6253 pub exp_map2: ExportMap2,
6254 pub trait_map: TraitMap,
6255 pub external_exports: ExternalExports,
6256 pub last_private_map: LastPrivateMap,
6259 /// Entry point to crate resolution.
6260 pub fn resolve_crate(session: &Session,
6264 let mut resolver = Resolver::new(session, krate.span);
6265 resolver.resolve(krate);
6267 def_map: resolver.def_map,
6268 freevars: resolver.freevars,
6269 capture_mode_map: resolver.capture_mode_map,
6270 exp_map2: resolver.export_map2,
6271 trait_map: resolver.trait_map,
6272 external_exports: resolver.external_exports,
6273 last_private_map: resolver.last_private,