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 util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
26 use syntax::ast_util::{local_def, PostExpansionMethod};
27 use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
28 use syntax::ext::mtwt;
29 use syntax::parse::token::special_names;
30 use syntax::parse::token::special_idents;
31 use syntax::parse::token;
32 use syntax::codemap::{Span, DUMMY_SP, Pos};
33 use syntax::owned_slice::OwnedSlice;
35 use syntax::visit::Visitor;
37 use std::collections::{HashMap, HashSet};
38 use std::cell::{Cell, RefCell};
39 use std::gc::{Gc, GC};
40 use std::mem::replace;
41 use std::rc::{Rc, Weak};
45 pub type DefMap = RefCell<NodeMap<Def>>;
49 binding_mode: BindingMode,
52 // Map from the name in a pattern to its binding mode.
53 type BindingMap = HashMap<Name,binding_info>;
55 // Trait method resolution
56 pub type TraitMap = NodeMap<Vec<DefId> >;
58 // This is the replacement export map. It maps a module to all of the exports
60 pub type ExportMap2 = RefCell<NodeMap<Vec<Export2> >>;
63 pub name: String, // The name of the target.
64 pub def_id: DefId, // The definition of the target.
67 // This set contains all exported definitions from external crates. The set does
68 // not contain any entries from local crates.
69 pub type ExternalExports = DefIdSet;
72 pub type LastPrivateMap = NodeMap<LastPrivate>;
74 pub enum LastPrivate {
76 // `use` directives (imports) can refer to two separate definitions in the
77 // type and value namespaces. We record here the last private node for each
78 // and whether the import is in fact used for each.
79 // If the Option<PrivateDep> fields are None, it means there is no definition
81 LastImport{pub value_priv: Option<PrivateDep>,
82 pub value_used: ImportUse,
83 pub type_priv: Option<PrivateDep>,
84 pub type_used: ImportUse},
92 // How an import is used.
93 #[deriving(PartialEq)]
95 Unused, // The import is not used.
96 Used, // The import is used.
100 fn or(self, other: LastPrivate) -> LastPrivate {
101 match (self, other) {
102 (me, LastMod(AllPublic)) => me,
108 #[deriving(PartialEq)]
109 enum PatternBindingMode {
111 LocalIrrefutableMode,
112 ArgumentIrrefutableMode,
115 #[deriving(PartialEq, Eq, Hash)]
121 #[deriving(PartialEq)]
122 enum NamespaceError {
129 /// A NamespaceResult represents the result of resolving an import in
130 /// a particular namespace. The result is either definitely-resolved,
131 /// definitely- unresolved, or unknown.
133 enum NamespaceResult {
134 /// Means that resolve hasn't gathered enough information yet to determine
135 /// whether the name is bound in this namespace. (That is, it hasn't
136 /// resolved all `use` directives yet.)
138 /// Means that resolve has determined that the name is definitely
139 /// not bound in the namespace.
141 /// Means that resolve has determined that the name is bound in the Module
142 /// argument, and specified by the NameBindings argument.
143 BoundResult(Rc<Module>, Rc<NameBindings>)
146 impl NamespaceResult {
147 fn is_unknown(&self) -> bool {
149 UnknownResult => true,
153 fn is_unbound(&self) -> bool {
155 UnboundResult => true,
161 enum NameDefinition {
162 NoNameDefinition, //< The name was unbound.
163 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
164 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
167 impl<'a> Visitor<()> for Resolver<'a> {
168 fn visit_item(&mut self, item: &Item, _: ()) {
169 self.resolve_item(item);
171 fn visit_arm(&mut self, arm: &Arm, _: ()) {
172 self.resolve_arm(arm);
174 fn visit_block(&mut self, block: &Block, _: ()) {
175 self.resolve_block(block);
177 fn visit_expr(&mut self, expr: &Expr, _: ()) {
178 self.resolve_expr(expr);
180 fn visit_local(&mut self, local: &Local, _: ()) {
181 self.resolve_local(local);
183 fn visit_ty(&mut self, ty: &Ty, _: ()) {
184 self.resolve_type(ty);
188 /// Contains data for specific types of import directives.
189 enum ImportDirectiveSubclass {
190 SingleImport(Ident /* target */, Ident /* source */),
194 /// The context that we thread through while building the reduced graph.
196 enum ReducedGraphParent {
197 ModuleReducedGraphParent(Rc<Module>)
200 impl ReducedGraphParent {
201 fn module(&self) -> Rc<Module> {
203 ModuleReducedGraphParent(ref m) => {
210 type ErrorMessage = Option<(Span, String)>;
212 enum ResolveResult<T> {
213 Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
214 Indeterminate, // Couldn't determine due to unresolved globs.
215 Success(T) // Successfully resolved the import.
218 impl<T> ResolveResult<T> {
219 fn indeterminate(&self) -> bool {
220 match *self { Indeterminate => true, _ => false }
224 enum FallbackSuggestion {
229 StaticMethod(String),
230 StaticTraitMethod(String),
233 enum TypeParameters<'a> {
239 // Identifies the things that these parameters
240 // were declared on (type, fn, etc)
243 // ID of the enclosing item.
246 // The kind of the rib used for type parameters.
250 // The rib kind controls the translation of argument or local definitions
251 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
254 // No translation needs to be applied.
257 // We passed through a function scope at the given node ID. Translate
258 // upvars as appropriate.
259 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
261 // We passed through an impl or trait and are now in one of its
262 // methods. Allow references to ty params that impl or trait
263 // binds. Disallow any other upvars (including other ty params that are
265 // parent; method itself
266 MethodRibKind(NodeId, MethodSort),
268 // We passed through an item scope. Disallow upvars.
271 // We're in a constant item. Can't refer to dynamic stuff.
275 // Methods can be required or provided. Required methods only occur in traits.
281 enum UseLexicalScopeFlag {
286 enum ModulePrefixResult {
288 PrefixFound(Rc<Module>, uint)
291 #[deriving(Clone, Eq, PartialEq)]
292 enum MethodIsStaticFlag {
297 impl MethodIsStaticFlag {
298 fn from_explicit_self_category(explicit_self_category:
299 ExplicitSelfCategory)
300 -> MethodIsStaticFlag {
301 if explicit_self_category == StaticExplicitSelfCategory {
309 #[deriving(PartialEq)]
310 enum NameSearchType {
311 /// We're doing a name search in order to resolve a `use` directive.
314 /// We're doing a name search in order to resolve a path type, a path
315 /// expression, or a path pattern.
319 enum BareIdentifierPatternResolution {
320 FoundStructOrEnumVariant(Def, LastPrivate),
321 FoundConst(Def, LastPrivate),
322 BareIdentifierPatternUnresolved
325 // Specifies how duplicates should be handled when adding a child item if
326 // another item exists with the same name in some namespace.
327 #[deriving(PartialEq)]
328 enum DuplicateCheckingMode {
329 ForbidDuplicateModules,
330 ForbidDuplicateTypesAndModules,
331 ForbidDuplicateValues,
332 ForbidDuplicateTypesAndValues,
338 bindings: RefCell<HashMap<Name, DefLike>>,
343 fn new(kind: RibKind) -> Rib {
345 bindings: RefCell::new(HashMap::new()),
351 /// One import directive.
352 struct ImportDirective {
353 module_path: Vec<Ident>,
354 subclass: ImportDirectiveSubclass,
357 is_public: bool, // see note in ImportResolution about how to use this
360 impl ImportDirective {
361 fn new(module_path: Vec<Ident> ,
362 subclass: ImportDirectiveSubclass,
368 module_path: module_path,
372 is_public: is_public,
377 /// The item that an import resolves to.
380 target_module: Rc<Module>,
381 bindings: Rc<NameBindings>,
385 fn new(target_module: Rc<Module>, bindings: Rc<NameBindings>) -> Target {
387 target_module: target_module,
393 /// An ImportResolution represents a particular `use` directive.
394 struct ImportResolution {
395 /// Whether this resolution came from a `use` or a `pub use`. Note that this
396 /// should *not* be used whenever resolution is being performed, this is
397 /// only looked at for glob imports statements currently. Privacy testing
398 /// occurs during a later phase of compilation.
401 // The number of outstanding references to this name. When this reaches
402 // zero, outside modules can count on the targets being correct. Before
403 // then, all bets are off; future imports could override this name.
404 outstanding_references: uint,
406 /// The value that this `use` directive names, if there is one.
407 value_target: Option<Target>,
408 /// The source node of the `use` directive leading to the value target
412 /// The type that this `use` directive names, if there is one.
413 type_target: Option<Target>,
414 /// The source node of the `use` directive leading to the type target
419 impl ImportResolution {
420 fn new(id: NodeId, is_public: bool) -> ImportResolution {
424 outstanding_references: 0,
427 is_public: is_public,
431 fn target_for_namespace(&self, namespace: Namespace)
434 TypeNS => self.type_target.clone(),
435 ValueNS => self.value_target.clone(),
439 fn id(&self, namespace: Namespace) -> NodeId {
441 TypeNS => self.type_id,
442 ValueNS => self.value_id,
447 /// The link from a module up to its nearest parent node.
451 ModuleParentLink(Weak<Module>, Ident),
452 BlockParentLink(Weak<Module>, NodeId)
455 /// The type of module this is.
456 #[deriving(PartialEq)]
465 /// One node in the tree of modules.
467 parent_link: ParentLink,
468 def_id: Cell<Option<DefId>>,
469 kind: Cell<ModuleKind>,
472 children: RefCell<HashMap<Name, Rc<NameBindings>>>,
473 imports: RefCell<Vec<ImportDirective>>,
475 // The external module children of this node that were declared with
477 external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
479 // The anonymous children of this node. Anonymous children are pseudo-
480 // modules that are implicitly created around items contained within
483 // For example, if we have this:
491 // There will be an anonymous module created around `g` with the ID of the
492 // entry block for `f`.
493 anonymous_children: RefCell<NodeMap<Rc<Module>>>,
495 // The status of resolving each import in this module.
496 import_resolutions: RefCell<HashMap<Name, ImportResolution>>,
498 // The number of unresolved globs that this module exports.
499 glob_count: Cell<uint>,
501 // The index of the import we're resolving.
502 resolved_import_count: Cell<uint>,
504 // Whether this module is populated. If not populated, any attempt to
505 // access the children must be preceded with a
506 // `populate_module_if_necessary` call.
507 populated: Cell<bool>,
511 fn new(parent_link: ParentLink,
512 def_id: Option<DefId>,
518 parent_link: parent_link,
519 def_id: Cell::new(def_id),
520 kind: Cell::new(kind),
521 is_public: is_public,
522 children: RefCell::new(HashMap::new()),
523 imports: RefCell::new(Vec::new()),
524 external_module_children: RefCell::new(HashMap::new()),
525 anonymous_children: RefCell::new(NodeMap::new()),
526 import_resolutions: RefCell::new(HashMap::new()),
527 glob_count: Cell::new(0),
528 resolved_import_count: Cell::new(0),
529 populated: Cell::new(!external),
533 fn all_imports_resolved(&self) -> bool {
534 self.imports.borrow().len() == self.resolved_import_count.get()
538 // Records a possibly-private type definition.
541 is_public: bool, // see note in ImportResolution about how to use this
542 module_def: Option<Rc<Module>>,
543 type_def: Option<Def>,
544 type_span: Option<Span>
547 // Records a possibly-private value definition.
550 is_public: bool, // see note in ImportResolution about how to use this
552 value_span: Option<Span>,
555 // Records the definitions (at most one for each namespace) that a name is
557 struct NameBindings {
558 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
559 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
562 /// Ways in which a trait can be referenced
563 enum TraitReferenceType {
564 TraitImplementation, // impl SomeTrait for T { ... }
565 TraitDerivation, // trait T : SomeTrait { ... }
566 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
570 fn new() -> NameBindings {
572 type_def: RefCell::new(None),
573 value_def: RefCell::new(None),
577 /// Creates a new module in this set of name bindings.
578 fn define_module(&self,
579 parent_link: ParentLink,
580 def_id: Option<DefId>,
585 // Merges the module with the existing type def or creates a new one.
586 let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
588 let type_def = self.type_def.borrow().clone();
591 *self.type_def.borrow_mut() = Some(TypeNsDef {
592 is_public: is_public,
593 module_def: Some(module_),
599 *self.type_def.borrow_mut() = Some(TypeNsDef {
600 is_public: is_public,
601 module_def: Some(module_),
603 type_def: type_def.type_def
609 /// Sets the kind of the module, creating a new one if necessary.
610 fn set_module_kind(&self,
611 parent_link: ParentLink,
612 def_id: Option<DefId>,
617 let type_def = self.type_def.borrow().clone();
620 let module = Module::new(parent_link, def_id, kind,
621 external, is_public);
622 *self.type_def.borrow_mut() = Some(TypeNsDef {
623 is_public: is_public,
624 module_def: Some(Rc::new(module)),
630 match type_def.module_def {
632 let module = Module::new(parent_link,
637 *self.type_def.borrow_mut() = Some(TypeNsDef {
638 is_public: is_public,
639 module_def: Some(Rc::new(module)),
640 type_def: type_def.type_def,
644 Some(module_def) => module_def.kind.set(kind),
650 /// Records a type definition.
651 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
652 // Merges the type with the existing type def or creates a new one.
653 let type_def = self.type_def.borrow().clone();
656 *self.type_def.borrow_mut() = Some(TypeNsDef {
660 is_public: is_public,
664 *self.type_def.borrow_mut() = Some(TypeNsDef {
667 module_def: type_def.module_def,
668 is_public: is_public,
674 /// Records a value definition.
675 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
676 *self.value_def.borrow_mut() = Some(ValueNsDef {
678 value_span: Some(sp),
679 is_public: is_public,
683 /// Returns the module node if applicable.
684 fn get_module_if_available(&self) -> Option<Rc<Module>> {
685 match *self.type_def.borrow() {
686 Some(ref type_def) => type_def.module_def.clone(),
692 * Returns the module node. Fails if this node does not have a module
695 fn get_module(&self) -> Rc<Module> {
696 match self.get_module_if_available() {
698 fail!("get_module called on a node with no module \
701 Some(module_def) => module_def
705 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
707 TypeNS => return self.type_def.borrow().is_some(),
708 ValueNS => return self.value_def.borrow().is_some()
712 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
714 TypeNS => match *self.type_def.borrow() {
715 Some(ref def) => def.is_public, None => false
717 ValueNS => match *self.value_def.borrow() {
718 Some(ref def) => def.is_public, None => false
723 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
726 match *self.type_def.borrow() {
728 Some(ref type_def) => {
729 match type_def.type_def {
730 Some(type_def) => Some(type_def),
732 match type_def.module_def {
733 Some(ref module) => {
734 match module.def_id.get() {
735 Some(did) => Some(DefMod(did)),
747 match *self.value_def.borrow() {
749 Some(value_def) => Some(value_def.def)
755 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
756 if self.defined_in_namespace(namespace) {
759 match *self.type_def.borrow() {
761 Some(ref type_def) => type_def.type_span
765 match *self.value_def.borrow() {
767 Some(ref value_def) => value_def.value_span
777 /// Interns the names of the primitive types.
778 struct PrimitiveTypeTable {
779 primitive_types: HashMap<Name, PrimTy>,
782 impl PrimitiveTypeTable {
783 fn new() -> PrimitiveTypeTable {
784 let mut table = PrimitiveTypeTable {
785 primitive_types: HashMap::new()
788 table.intern("bool", TyBool);
789 table.intern("char", TyChar);
790 table.intern("f32", TyFloat(TyF32));
791 table.intern("f64", TyFloat(TyF64));
792 table.intern("int", TyInt(TyI));
793 table.intern("i8", TyInt(TyI8));
794 table.intern("i16", TyInt(TyI16));
795 table.intern("i32", TyInt(TyI32));
796 table.intern("i64", TyInt(TyI64));
797 table.intern("str", TyStr);
798 table.intern("uint", TyUint(TyU));
799 table.intern("u8", TyUint(TyU8));
800 table.intern("u16", TyUint(TyU16));
801 table.intern("u32", TyUint(TyU32));
802 table.intern("u64", TyUint(TyU64));
807 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
808 self.primitive_types.insert(token::intern(string), primitive_type);
813 fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
816 ModuleError | TypeError => "type or module",
817 ValueError => "value",
821 /// The main resolver class.
822 struct Resolver<'a> {
823 session: &'a Session,
825 graph_root: NameBindings,
827 method_map: RefCell<FnvHashMap<(Name, DefId), MethodIsStaticFlag>>,
829 structs: FnvHashMap<DefId, Vec<Name>>,
831 // The number of imports that are currently unresolved.
832 unresolved_imports: uint,
834 // The module that represents the current item scope.
835 current_module: Rc<Module>,
837 // The current set of local scopes, for values.
838 // FIXME #4948: Reuse ribs to avoid allocation.
839 value_ribs: RefCell<Vec<Rib>>,
841 // The current set of local scopes, for types.
842 type_ribs: RefCell<Vec<Rib>>,
844 // The current set of local scopes, for labels.
845 label_ribs: RefCell<Vec<Rib>>,
847 // The trait that the current context can refer to.
848 current_trait_ref: Option<(DefId, TraitRef)>,
850 // The current self type if inside an impl (used for better errors).
851 current_self_type: Option<Ty>,
853 // The ident for the keyword "self".
855 // The ident for the non-keyword "Self".
856 type_self_name: Name,
858 // The idents for the primitive types.
859 primitive_type_table: PrimitiveTypeTable,
862 export_map2: ExportMap2,
864 external_exports: ExternalExports,
865 last_private: LastPrivateMap,
867 // Whether or not to print error messages. Can be set to true
868 // when getting additional info for error message suggestions,
869 // so as to avoid printing duplicate errors
872 used_imports: HashSet<(NodeId, Namespace)>,
875 struct BuildReducedGraphVisitor<'a, 'b> {
876 resolver: &'a mut Resolver<'b>,
879 impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
881 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
882 let p = self.resolver.build_reduced_graph_for_item(item, context);
883 visit::walk_item(self, item, p);
886 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
887 context: ReducedGraphParent) {
888 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
891 let mut v = BuildReducedGraphVisitor{ resolver: r };
892 visit::walk_foreign_item(&mut v, foreign_item, context.clone());
896 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
897 self.resolver.build_reduced_graph_for_view_item(view_item, context);
900 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
901 let np = self.resolver.build_reduced_graph_for_block(block, context);
902 visit::walk_block(self, block, np);
907 struct UnusedImportCheckVisitor<'a, 'b> { resolver: &'a mut Resolver<'b> }
909 impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
910 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
911 self.resolver.check_for_item_unused_imports(vi);
912 visit::walk_view_item(self, vi, ());
916 impl<'a> Resolver<'a> {
917 fn new(session: &'a Session, crate_span: Span) -> Resolver<'a> {
918 let graph_root = NameBindings::new();
920 graph_root.define_module(NoParentLink,
921 Some(DefId { krate: 0, node: 0 }),
927 let current_module = graph_root.get_module();
932 // The outermost module has def ID 0; this is not reflected in the
935 graph_root: graph_root,
937 method_map: RefCell::new(FnvHashMap::new()),
938 structs: FnvHashMap::new(),
940 unresolved_imports: 0,
942 current_module: current_module,
943 value_ribs: RefCell::new(Vec::new()),
944 type_ribs: RefCell::new(Vec::new()),
945 label_ribs: RefCell::new(Vec::new()),
947 current_trait_ref: None,
948 current_self_type: None,
950 self_name: special_names::self_,
951 type_self_name: special_names::type_self,
953 primitive_type_table: PrimitiveTypeTable::new(),
955 def_map: RefCell::new(NodeMap::new()),
956 export_map2: RefCell::new(NodeMap::new()),
957 trait_map: NodeMap::new(),
958 used_imports: HashSet::new(),
959 external_exports: DefIdSet::new(),
960 last_private: NodeMap::new(),
965 /// The main name resolution procedure.
966 fn resolve(&mut self, krate: &ast::Crate) {
967 self.build_reduced_graph(krate);
968 self.session.abort_if_errors();
970 self.resolve_imports();
971 self.session.abort_if_errors();
973 self.record_exports();
974 self.session.abort_if_errors();
976 self.resolve_crate(krate);
977 self.session.abort_if_errors();
979 self.check_for_unused_imports(krate);
983 // Reduced graph building
985 // Here we build the "reduced graph": the graph of the module tree without
986 // any imports resolved.
989 /// Constructs the reduced graph for the entire crate.
990 fn build_reduced_graph(&mut self, krate: &ast::Crate) {
992 ModuleReducedGraphParent(self.graph_root.get_module());
994 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
995 visit::walk_crate(&mut visitor, krate, initial_parent);
999 * Adds a new child item to the module definition of the parent node and
1000 * returns its corresponding name bindings as well as the current parent.
1001 * Or, if we're inside a block, creates (or reuses) an anonymous module
1002 * corresponding to the innermost block ID and returns the name bindings
1003 * as well as the newly-created parent.
1005 * If this node does not have a module definition and we are not inside
1010 reduced_graph_parent: ReducedGraphParent,
1011 duplicate_checking_mode: DuplicateCheckingMode,
1012 // For printing errors
1014 -> Rc<NameBindings> {
1015 // If this is the immediate descendant of a module, then we add the
1016 // child name directly. Otherwise, we create or reuse an anonymous
1017 // module and add the child to that.
1019 let module_ = reduced_graph_parent.module();
1021 // Add or reuse the child.
1022 let child = module_.children.borrow().find_copy(&name.name);
1025 let child = Rc::new(NameBindings::new());
1026 module_.children.borrow_mut().insert(name.name, child.clone());
1030 // Enforce the duplicate checking mode:
1032 // * If we're requesting duplicate module checking, check that
1033 // there isn't a module in the module with the same name.
1035 // * If we're requesting duplicate type checking, check that
1036 // there isn't a type in the module with the same name.
1038 // * If we're requesting duplicate value checking, check that
1039 // there isn't a value in the module with the same name.
1041 // * If we're requesting duplicate type checking and duplicate
1042 // value checking, check that there isn't a duplicate type
1043 // and a duplicate value with the same name.
1045 // * If no duplicate checking was requested at all, do
1048 let mut duplicate_type = NoError;
1049 let ns = match duplicate_checking_mode {
1050 ForbidDuplicateModules => {
1051 if child.get_module_if_available().is_some() {
1052 duplicate_type = ModuleError;
1056 ForbidDuplicateTypesAndModules => {
1057 match child.def_for_namespace(TypeNS) {
1059 Some(_) if child.get_module_if_available()
1060 .map(|m| m.kind.get()) ==
1061 Some(ImplModuleKind) => {}
1062 Some(_) => duplicate_type = TypeError
1066 ForbidDuplicateValues => {
1067 if child.defined_in_namespace(ValueNS) {
1068 duplicate_type = ValueError;
1072 ForbidDuplicateTypesAndValues => {
1074 match child.def_for_namespace(TypeNS) {
1075 Some(DefMod(_)) | None => {}
1078 duplicate_type = TypeError;
1081 if child.defined_in_namespace(ValueNS) {
1082 duplicate_type = ValueError;
1087 OverwriteDuplicates => None
1089 if duplicate_type != NoError {
1090 // Return an error here by looking up the namespace that
1091 // had the duplicate.
1092 let ns = ns.unwrap();
1093 self.resolve_error(sp,
1094 format!("duplicate definition of {} `{}`",
1095 namespace_error_to_string(duplicate_type),
1096 token::get_ident(name)).as_slice());
1098 let r = child.span_for_namespace(ns);
1099 for sp in r.iter() {
1100 self.session.span_note(*sp,
1101 format!("first definition of {} `{}` here",
1102 namespace_error_to_string(duplicate_type),
1103 token::get_ident(name)).as_slice());
1112 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1113 // If the block has view items, we need an anonymous module.
1114 if block.view_items.len() > 0 {
1118 // Check each statement.
1119 for statement in block.stmts.iter() {
1120 match statement.node {
1121 StmtDecl(declaration, _) => {
1122 match declaration.node {
1137 // If we found neither view items nor items, we don't need to create
1138 // an anonymous module.
1143 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1146 ModuleReducedGraphParent(module_) => {
1147 return ModuleParentLink(module_.downgrade(), name);
1152 /// Constructs the reduced graph for one item.
1153 fn build_reduced_graph_for_item(&mut self,
1155 parent: ReducedGraphParent)
1156 -> ReducedGraphParent
1158 let ident = item.ident;
1160 let is_public = item.vis == ast::Public;
1165 self.add_child(ident, parent.clone(), ForbidDuplicateModules, sp);
1167 let parent_link = self.get_parent_link(parent, ident);
1168 let def_id = DefId { krate: 0, node: item.id };
1169 name_bindings.define_module(parent_link,
1173 item.vis == ast::Public,
1176 ModuleReducedGraphParent(name_bindings.get_module())
1179 ItemForeignMod(..) => parent,
1181 // These items live in the value namespace.
1182 ItemStatic(_, m, _) => {
1184 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1185 let mutbl = m == ast::MutMutable;
1187 name_bindings.define_value
1188 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1191 ItemFn(_, fn_style, _, _, _) => {
1193 self.add_child(ident, parent.clone(), ForbidDuplicateValues, sp);
1195 let def = DefFn(local_def(item.id), fn_style);
1196 name_bindings.define_value(def, sp, is_public);
1200 // These items live in the type namespace.
1203 self.add_child(ident,
1205 ForbidDuplicateTypesAndModules,
1208 name_bindings.define_type
1209 (DefTy(local_def(item.id)), sp, is_public);
1213 ItemEnum(ref enum_definition, _) => {
1215 self.add_child(ident,
1217 ForbidDuplicateTypesAndModules,
1220 name_bindings.define_type
1221 (DefTy(local_def(item.id)), sp, is_public);
1223 for variant in (*enum_definition).variants.iter() {
1224 self.build_reduced_graph_for_variant(
1233 // These items live in both the type and value namespaces.
1234 ItemStruct(struct_def, _) => {
1235 // Adding to both Type and Value namespaces or just Type?
1236 let (forbid, ctor_id) = match struct_def.ctor_id {
1237 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1238 None => (ForbidDuplicateTypesAndModules, None)
1241 let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
1243 // Define a name in the type namespace.
1244 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1246 // If this is a newtype or unit-like struct, define a name
1247 // in the value namespace as well
1248 ctor_id.while_some(|cid| {
1249 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1254 // Record the def ID and fields of this struct.
1255 let named_fields = struct_def.fields.iter().filter_map(|f| {
1257 NamedField(ident, _) => Some(ident.name),
1258 UnnamedField(_) => None
1261 self.structs.insert(local_def(item.id), named_fields);
1266 ItemImpl(_, None, ty, ref methods) => {
1267 // If this implements an anonymous trait, then add all the
1268 // methods within to a new module, if the type was defined
1269 // within this module.
1271 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1272 // should modify anonymous traits to only be implementable in
1273 // the same module that declared the type.
1275 // Create the module and add all methods.
1277 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1278 let name = path.segments.last().unwrap().identifier;
1280 let parent_opt = parent.module().children.borrow()
1281 .find_copy(&name.name);
1282 let new_parent = match parent_opt {
1283 // It already exists
1284 Some(ref child) if child.get_module_if_available()
1286 child.get_module().kind.get() ==
1288 ModuleReducedGraphParent(child.get_module())
1290 // Create the module
1293 self.add_child(name,
1295 ForbidDuplicateModules,
1299 self.get_parent_link(parent.clone(), ident);
1300 let def_id = local_def(item.id);
1303 !name_bindings.defined_in_namespace(ns) ||
1304 name_bindings.defined_in_public_namespace(ns);
1306 name_bindings.define_module(parent_link,
1313 ModuleReducedGraphParent(
1314 name_bindings.get_module())
1318 // For each method...
1319 for method in methods.iter() {
1320 // Add the method to the module.
1321 let ident = method.pe_ident();
1322 let method_name_bindings =
1323 self.add_child(ident,
1325 ForbidDuplicateValues,
1327 let def = match method.pe_explicit_self().node {
1329 // Static methods become
1330 // `def_static_method`s.
1331 DefStaticMethod(local_def(method.id),
1334 method.pe_fn_style())
1337 // Non-static methods become
1339 DefMethod(local_def(method.id), None)
1343 let is_public = method.pe_vis() == ast::Public;
1344 method_name_bindings.define_value(def,
1355 ItemImpl(_, Some(_), _, _) => parent,
1357 ItemTrait(_, _, _, ref methods) => {
1359 self.add_child(ident,
1361 ForbidDuplicateTypesAndModules,
1364 // Add all the methods within to a new module.
1365 let parent_link = self.get_parent_link(parent.clone(), ident);
1366 name_bindings.define_module(parent_link,
1367 Some(local_def(item.id)),
1370 item.vis == ast::Public,
1372 let module_parent = ModuleReducedGraphParent(name_bindings.
1375 let def_id = local_def(item.id);
1377 // Add the names of all the methods to the trait info.
1378 for method in methods.iter() {
1379 let ty_m = trait_method_to_ty_method(method);
1381 let ident = ty_m.ident;
1383 // Add it as a name in the trait module.
1384 let (def, static_flag) = match ty_m.explicit_self.node {
1386 // Static methods become `def_static_method`s.
1387 (DefStaticMethod(local_def(ty_m.id),
1388 FromTrait(local_def(item.id)),
1393 // Non-static methods become `def_method`s.
1394 (DefMethod(local_def(ty_m.id),
1395 Some(local_def(item.id))),
1400 let method_name_bindings =
1401 self.add_child(ident,
1402 module_parent.clone(),
1403 ForbidDuplicateValues,
1405 method_name_bindings.define_value(def, ty_m.span, true);
1409 .insert((ident.name, def_id), static_flag);
1412 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1415 ItemMac(..) => parent
1419 // Constructs the reduced graph for one variant. Variants exist in the
1420 // type and/or value namespaces.
1421 fn build_reduced_graph_for_variant(&mut self,
1424 parent: ReducedGraphParent,
1426 let ident = variant.node.name;
1428 match variant.node.kind {
1429 TupleVariantKind(_) => {
1430 let child = self.add_child(ident, parent, ForbidDuplicateValues, variant.span);
1431 child.define_value(DefVariant(item_id,
1432 local_def(variant.node.id), false),
1433 variant.span, is_public);
1435 StructVariantKind(_) => {
1436 let child = self.add_child(ident, parent,
1437 ForbidDuplicateTypesAndValues,
1439 child.define_type(DefVariant(item_id,
1440 local_def(variant.node.id), true),
1441 variant.span, is_public);
1443 // Not adding fields for variants as they are not accessed with a self receiver
1444 self.structs.insert(local_def(variant.node.id), Vec::new());
1449 /// Constructs the reduced graph for one 'view item'. View items consist
1450 /// of imports and use directives.
1451 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1452 parent: ReducedGraphParent) {
1453 match view_item.node {
1454 ViewItemUse(ref view_path) => {
1455 // Extract and intern the module part of the path. For
1456 // globs and lists, the path is found directly in the AST;
1457 // for simple paths we have to munge the path a little.
1459 let mut module_path = Vec::new();
1460 match view_path.node {
1461 ViewPathSimple(_, ref full_path, _) => {
1462 let path_len = full_path.segments.len();
1463 assert!(path_len != 0);
1465 for (i, segment) in full_path.segments
1468 if i != path_len - 1 {
1469 module_path.push(segment.identifier)
1474 ViewPathGlob(ref module_ident_path, _) |
1475 ViewPathList(ref module_ident_path, _, _) => {
1476 for segment in module_ident_path.segments.iter() {
1477 module_path.push(segment.identifier)
1482 // Build up the import directives.
1483 let module_ = parent.module();
1484 let is_public = view_item.vis == ast::Public;
1485 match view_path.node {
1486 ViewPathSimple(binding, ref full_path, id) => {
1488 full_path.segments.last().unwrap().identifier;
1489 let subclass = SingleImport(binding,
1491 self.build_import_directive(&*module_,
1498 ViewPathList(_, ref source_idents, _) => {
1499 for source_ident in source_idents.iter() {
1500 let name = source_ident.node.name;
1501 self.build_import_directive(
1503 module_path.clone(),
1504 SingleImport(name, name),
1506 source_ident.node.id,
1510 ViewPathGlob(_, id) => {
1511 self.build_import_directive(&*module_,
1521 ViewItemExternCrate(name, _, node_id) => {
1522 // n.b. we don't need to look at the path option here, because cstore already did
1523 for &crate_id in self.session.cstore
1524 .find_extern_mod_stmt_cnum(node_id).iter() {
1525 let def_id = DefId { krate: crate_id, node: 0 };
1526 self.external_exports.insert(def_id);
1528 ModuleParentLink(parent.module().downgrade(), name);
1529 let external_module = Rc::new(Module::new(parent_link,
1534 debug!("(build reduced graph for item) found extern `{}`",
1535 self.module_to_string(&*external_module));
1536 parent.module().external_module_children.borrow_mut()
1537 .insert(name.name, external_module.clone());
1538 self.build_reduced_graph_for_external_crate(external_module);
1544 /// Constructs the reduced graph for one foreign item.
1545 fn build_reduced_graph_for_foreign_item(&mut self,
1546 foreign_item: &ForeignItem,
1547 parent: ReducedGraphParent,
1548 f: |&mut Resolver|) {
1549 let name = foreign_item.ident;
1550 let is_public = foreign_item.vis == ast::Public;
1552 self.add_child(name, parent, ForbidDuplicateValues,
1555 match foreign_item.node {
1556 ForeignItemFn(_, ref generics) => {
1557 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1558 name_bindings.define_value(def, foreign_item.span, is_public);
1560 self.with_type_parameter_rib(
1561 HasTypeParameters(generics,
1567 ForeignItemStatic(_, m) => {
1568 let def = DefStatic(local_def(foreign_item.id), m);
1569 name_bindings.define_value(def, foreign_item.span, is_public);
1576 fn build_reduced_graph_for_block(&mut self,
1578 parent: ReducedGraphParent)
1579 -> ReducedGraphParent
1581 if self.block_needs_anonymous_module(block) {
1582 let block_id = block.id;
1584 debug!("(building reduced graph for block) creating a new \
1585 anonymous module for block {}",
1588 let parent_module = parent.module();
1589 let new_module = Rc::new(Module::new(
1590 BlockParentLink(parent_module.downgrade(), block_id),
1592 AnonymousModuleKind,
1595 parent_module.anonymous_children.borrow_mut()
1596 .insert(block_id, new_module.clone());
1597 ModuleReducedGraphParent(new_module)
1603 fn handle_external_def(&mut self,
1606 child_name_bindings: &NameBindings,
1609 new_parent: ReducedGraphParent) {
1610 debug!("(building reduced graph for \
1611 external crate) building external def, priv {:?}",
1613 let is_public = vis == ast::Public;
1614 let is_exported = is_public && match new_parent {
1615 ModuleReducedGraphParent(ref module) => {
1616 match module.def_id.get() {
1618 Some(did) => self.external_exports.contains(&did)
1623 self.external_exports.insert(def.def_id());
1626 let kind = match def {
1627 DefStruct(..) | DefTy(..) => ImplModuleKind,
1628 _ => NormalModuleKind
1632 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1634 let type_def = child_name_bindings.type_def.borrow().clone();
1636 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1637 debug!("(building reduced graph for external crate) \
1638 already created module");
1639 module_def.def_id.set(Some(def_id));
1642 debug!("(building reduced graph for \
1643 external crate) building module \
1645 let parent_link = self.get_parent_link(new_parent.clone(), ident);
1647 child_name_bindings.define_module(parent_link,
1660 DefMod(_) | DefForeignMod(_) => {}
1661 DefVariant(enum_did, variant_id, is_struct) => {
1662 debug!("(building reduced graph for external crate) building \
1665 // If this variant is public, then it was publicly reexported,
1666 // otherwise we need to inherit the visibility of the enum
1668 let is_exported = is_public ||
1669 self.external_exports.contains(&enum_did);
1671 child_name_bindings.define_type(def, DUMMY_SP, is_exported);
1672 // Not adding fields for variants as they are not accessed with a self receiver
1673 self.structs.insert(variant_id, Vec::new());
1675 child_name_bindings.define_value(def, DUMMY_SP, is_exported);
1678 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1679 debug!("(building reduced graph for external \
1680 crate) building value (fn/static) {}", final_ident);
1681 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1683 DefTrait(def_id) => {
1684 debug!("(building reduced graph for external \
1685 crate) building type {}", final_ident);
1687 // If this is a trait, add all the method names
1688 // to the trait info.
1690 let method_def_ids =
1691 csearch::get_trait_method_def_ids(&self.session.cstore, def_id);
1692 for &method_def_id in method_def_ids.iter() {
1693 let (method_name, explicit_self) =
1694 csearch::get_method_name_and_explicit_self(&self.session.cstore,
1697 debug!("(building reduced graph for \
1698 external crate) ... adding \
1700 token::get_ident(method_name));
1704 .insert((method_name.name, def_id),
1705 MethodIsStaticFlag::from_explicit_self_category(
1709 self.external_exports.insert(method_def_id);
1713 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1715 // Define a module if necessary.
1716 let parent_link = self.get_parent_link(new_parent, ident);
1717 child_name_bindings.set_module_kind(parent_link,
1725 debug!("(building reduced graph for external \
1726 crate) building type {}", final_ident);
1728 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1730 DefStruct(def_id) => {
1731 debug!("(building reduced graph for external \
1732 crate) building type and value for {}",
1734 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1735 let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
1737 }).collect::<Vec<_>>();
1739 if fields.len() == 0 {
1740 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1743 // Record the def ID and fields of this struct.
1744 self.structs.insert(def_id, fields);
1747 debug!("(building reduced graph for external crate) \
1748 ignoring {:?}", def);
1749 // Ignored; handled elsewhere.
1751 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1752 DefTyParam(..) | DefBinding(..) |
1753 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1754 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1755 fail!("didn't expect `{:?}`", def);
1760 /// Builds the reduced graph for a single item in an external crate.
1761 fn build_reduced_graph_for_external_crate_def(&mut self,
1765 visibility: Visibility) {
1768 // Add the new child item, if necessary.
1770 DefForeignMod(def_id) => {
1771 // Foreign modules have no names. Recur and populate
1773 csearch::each_child_of_item(&self.session.cstore,
1778 self.build_reduced_graph_for_external_crate_def(
1786 let child_name_bindings =
1787 self.add_child(ident,
1788 ModuleReducedGraphParent(root.clone()),
1789 OverwriteDuplicates,
1792 self.handle_external_def(def,
1794 &*child_name_bindings,
1795 token::get_ident(ident).get(),
1797 ModuleReducedGraphParent(root));
1802 // We only process static methods of impls here.
1803 match csearch::get_type_name_if_impl(&self.session.cstore, def) {
1805 Some(final_ident) => {
1806 let static_methods_opt =
1807 csearch::get_static_methods_if_impl(&self.session.cstore, def);
1808 match static_methods_opt {
1809 Some(ref static_methods) if
1810 static_methods.len() >= 1 => {
1811 debug!("(building reduced graph for \
1812 external crate) processing \
1813 static methods for type name {}",
1814 token::get_ident(final_ident));
1816 let child_name_bindings =
1819 ModuleReducedGraphParent(root.clone()),
1820 OverwriteDuplicates,
1823 // Process the static methods. First,
1824 // create the module.
1826 let type_def = child_name_bindings.type_def.borrow().clone();
1829 module_def: Some(module_def),
1832 // We already have a module. This
1834 type_module = module_def;
1836 // Mark it as an impl module if
1838 type_module.kind.set(ImplModuleKind);
1842 self.get_parent_link(ModuleReducedGraphParent(root),
1844 child_name_bindings.define_module(
1852 child_name_bindings.
1857 // Add each static method to the module.
1859 ModuleReducedGraphParent(type_module);
1860 for static_method_info in
1861 static_methods.iter() {
1862 let ident = static_method_info.ident;
1863 debug!("(building reduced graph for \
1864 external crate) creating \
1865 static method '{}'",
1866 token::get_ident(ident));
1868 let method_name_bindings =
1869 self.add_child(ident,
1871 OverwriteDuplicates,
1874 static_method_info.def_id,
1875 static_method_info.fn_style);
1877 method_name_bindings.define_value(
1879 visibility == ast::Public);
1883 // Otherwise, do nothing.
1884 Some(_) | None => {}
1890 debug!("(building reduced graph for external crate) \
1896 /// Builds the reduced graph rooted at the given external module.
1897 fn populate_external_module(&mut self, module: Rc<Module>) {
1898 debug!("(populating external module) attempting to populate {}",
1899 self.module_to_string(&*module));
1901 let def_id = match module.def_id.get() {
1903 debug!("(populating external module) ... no def ID!");
1906 Some(def_id) => def_id,
1909 csearch::each_child_of_item(&self.session.cstore,
1911 |def_like, child_ident, visibility| {
1912 debug!("(populating external module) ... found ident: {}",
1913 token::get_ident(child_ident));
1914 self.build_reduced_graph_for_external_crate_def(module.clone(),
1919 module.populated.set(true)
1922 /// Ensures that the reduced graph rooted at the given external module
1923 /// is built, building it if it is not.
1924 fn populate_module_if_necessary(&mut self, module: &Rc<Module>) {
1925 if !module.populated.get() {
1926 self.populate_external_module(module.clone())
1928 assert!(module.populated.get())
1931 /// Builds the reduced graph rooted at the 'use' directive for an external
1933 fn build_reduced_graph_for_external_crate(&mut self, root: Rc<Module>) {
1934 csearch::each_top_level_item_of_crate(&self.session.cstore,
1939 |def_like, ident, visibility| {
1940 self.build_reduced_graph_for_external_crate_def(root.clone(),
1947 /// Creates and adds an import directive to the given module.
1948 fn build_import_directive(&mut self,
1950 module_path: Vec<Ident> ,
1951 subclass: ImportDirectiveSubclass,
1955 module_.imports.borrow_mut().push(ImportDirective::new(module_path,
1959 self.unresolved_imports += 1;
1960 // Bump the reference count on the name. Or, if this is a glob, set
1961 // the appropriate flag.
1964 SingleImport(target, _) => {
1965 debug!("(building import directive) building import \
1967 self.idents_to_string(module_.imports.borrow().last().unwrap()
1968 .module_path.as_slice()),
1969 token::get_ident(target));
1971 let mut import_resolutions = module_.import_resolutions
1973 match import_resolutions.find_mut(&target.name) {
1974 Some(resolution) => {
1975 debug!("(building import directive) bumping \
1977 resolution.outstanding_references += 1;
1979 // the source of this name is different now
1980 resolution.type_id = id;
1981 resolution.value_id = id;
1982 resolution.is_public = is_public;
1987 debug!("(building import directive) creating new");
1988 let mut resolution = ImportResolution::new(id, is_public);
1989 resolution.outstanding_references = 1;
1990 import_resolutions.insert(target.name, resolution);
1993 // Set the glob flag. This tells us that we don't know the
1994 // module's exports ahead of time.
1996 module_.glob_count.set(module_.glob_count.get() + 1);
2001 // Import resolution
2003 // This is a fixed-point algorithm. We resolve imports until our efforts
2004 // are stymied by an unresolved import; then we bail out of the current
2005 // module and continue. We terminate successfully once no more imports
2006 // remain or unsuccessfully when no forward progress in resolving imports
2009 /// Resolves all imports for the crate. This method performs the fixed-
2010 /// point iteration.
2011 fn resolve_imports(&mut self) {
2013 let mut prev_unresolved_imports = 0;
2015 debug!("(resolving imports) iteration {}, {} imports left",
2016 i, self.unresolved_imports);
2018 let module_root = self.graph_root.get_module();
2019 self.resolve_imports_for_module_subtree(module_root.clone());
2021 if self.unresolved_imports == 0 {
2022 debug!("(resolving imports) success");
2026 if self.unresolved_imports == prev_unresolved_imports {
2027 self.report_unresolved_imports(module_root);
2032 prev_unresolved_imports = self.unresolved_imports;
2036 /// Attempts to resolve imports for the given module and all of its
2038 fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
2039 debug!("(resolving imports for module subtree) resolving {}",
2040 self.module_to_string(&*module_));
2041 let orig_module = replace(&mut self.current_module, module_.clone());
2042 self.resolve_imports_for_module(module_.clone());
2043 self.current_module = orig_module;
2045 self.populate_module_if_necessary(&module_);
2046 for (_, child_node) in module_.children.borrow().iter() {
2047 match child_node.get_module_if_available() {
2051 Some(child_module) => {
2052 self.resolve_imports_for_module_subtree(child_module);
2057 for (_, child_module) in module_.anonymous_children.borrow().iter() {
2058 self.resolve_imports_for_module_subtree(child_module.clone());
2062 /// Attempts to resolve imports for the given module only.
2063 fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
2064 if module.all_imports_resolved() {
2065 debug!("(resolving imports for module) all imports resolved for \
2067 self.module_to_string(&*module));
2071 let imports = module.imports.borrow();
2072 let import_count = imports.len();
2073 while module.resolved_import_count.get() < import_count {
2074 let import_index = module.resolved_import_count.get();
2075 let import_directive = imports.get(import_index);
2076 match self.resolve_import_for_module(module.clone(),
2079 let (span, help) = match err {
2080 Some((span, msg)) => (span, format!(". {}", msg)),
2081 None => (import_directive.span, String::new())
2083 let msg = format!("unresolved import `{}`{}",
2084 self.import_path_to_string(
2085 import_directive.module_path
2087 import_directive.subclass),
2089 self.resolve_error(span, msg.as_slice());
2091 Indeterminate => break, // Bail out. We'll come around next time.
2092 Success(()) => () // Good. Continue.
2095 module.resolved_import_count
2096 .set(module.resolved_import_count.get() + 1);
2100 fn idents_to_string(&self, idents: &[Ident]) -> String {
2101 let mut first = true;
2102 let mut result = String::new();
2103 for ident in idents.iter() {
2107 result.push_str("::")
2109 result.push_str(token::get_ident(*ident).get());
2114 fn path_idents_to_string(&self, path: &Path) -> String {
2115 let identifiers: Vec<ast::Ident> = path.segments
2117 .map(|seg| seg.identifier)
2119 self.idents_to_string(identifiers.as_slice())
2122 fn import_directive_subclass_to_string(&mut self,
2123 subclass: ImportDirectiveSubclass)
2126 SingleImport(_, source) => {
2127 token::get_ident(source).get().to_string()
2129 GlobImport => "*".to_string()
2133 fn import_path_to_string(&mut self,
2135 subclass: ImportDirectiveSubclass)
2137 if idents.is_empty() {
2138 self.import_directive_subclass_to_string(subclass)
2141 self.idents_to_string(idents),
2142 self.import_directive_subclass_to_string(
2143 subclass))).to_string()
2147 /// Attempts to resolve the given import. The return value indicates
2148 /// failure if we're certain the name does not exist, indeterminate if we
2149 /// don't know whether the name exists at the moment due to other
2150 /// currently-unresolved imports, or success if we know the name exists.
2151 /// If successful, the resolved bindings are written into the module.
2152 fn resolve_import_for_module(&mut self,
2153 module_: Rc<Module>,
2154 import_directive: &ImportDirective)
2155 -> ResolveResult<()> {
2156 let mut resolution_result = Failed(None);
2157 let module_path = &import_directive.module_path;
2159 debug!("(resolving import for module) resolving import `{}::...` in \
2161 self.idents_to_string(module_path.as_slice()),
2162 self.module_to_string(&*module_));
2164 // First, resolve the module path for the directive, if necessary.
2165 let container = if module_path.len() == 0 {
2166 // Use the crate root.
2167 Some((self.graph_root.get_module(), LastMod(AllPublic)))
2169 match self.resolve_module_path(module_.clone(),
2170 module_path.as_slice(),
2171 DontUseLexicalScope,
2172 import_directive.span,
2175 resolution_result = Failed(err);
2179 resolution_result = Indeterminate;
2182 Success(container) => Some(container),
2188 Some((containing_module, lp)) => {
2189 // We found the module that the target is contained
2190 // within. Attempt to resolve the import within it.
2192 match import_directive.subclass {
2193 SingleImport(target, source) => {
2195 self.resolve_single_import(&*module_,
2204 self.resolve_glob_import(&*module_,
2206 import_directive.id,
2207 import_directive.is_public,
2214 // Decrement the count of unresolved imports.
2215 match resolution_result {
2217 assert!(self.unresolved_imports >= 1);
2218 self.unresolved_imports -= 1;
2221 // Nothing to do here; just return the error.
2225 // Decrement the count of unresolved globs if necessary. But only if
2226 // the resolution result is indeterminate -- otherwise we'll stop
2227 // processing imports here. (See the loop in
2228 // resolve_imports_for_module.)
2230 if !resolution_result.indeterminate() {
2231 match import_directive.subclass {
2233 assert!(module_.glob_count.get() >= 1);
2234 module_.glob_count.set(module_.glob_count.get() - 1);
2236 SingleImport(..) => {
2242 return resolution_result;
2245 fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
2247 type_def: RefCell::new(Some(TypeNsDef {
2249 module_def: Some(module),
2253 value_def: RefCell::new(None),
2257 fn resolve_single_import(&mut self,
2259 containing_module: Rc<Module>,
2262 directive: &ImportDirective,
2264 -> ResolveResult<()> {
2265 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2266 `{}` id {}, last private {:?}",
2267 token::get_ident(target),
2268 self.module_to_string(&*containing_module),
2269 token::get_ident(source),
2270 self.module_to_string(module_),
2276 LastImport {..} => {
2278 .span_bug(directive.span,
2279 "not expecting Import here, must be LastMod")
2283 // We need to resolve both namespaces for this to succeed.
2286 let mut value_result = UnknownResult;
2287 let mut type_result = UnknownResult;
2289 // Search for direct children of the containing module.
2290 self.populate_module_if_necessary(&containing_module);
2292 match containing_module.children.borrow().find(&source.name) {
2296 Some(ref child_name_bindings) => {
2297 if child_name_bindings.defined_in_namespace(ValueNS) {
2298 debug!("(resolving single import) found value binding");
2299 value_result = BoundResult(containing_module.clone(),
2300 (*child_name_bindings).clone());
2302 if child_name_bindings.defined_in_namespace(TypeNS) {
2303 debug!("(resolving single import) found type binding");
2304 type_result = BoundResult(containing_module.clone(),
2305 (*child_name_bindings).clone());
2310 // Unless we managed to find a result in both namespaces (unlikely),
2311 // search imports as well.
2312 let mut value_used_reexport = false;
2313 let mut type_used_reexport = false;
2314 match (value_result.clone(), type_result.clone()) {
2315 (BoundResult(..), BoundResult(..)) => {} // Continue.
2317 // If there is an unresolved glob at this point in the
2318 // containing module, bail out. We don't know enough to be
2319 // able to resolve this import.
2321 if containing_module.glob_count.get() > 0 {
2322 debug!("(resolving single import) unresolved glob; \
2324 return Indeterminate;
2327 // Now search the exported imports within the containing module.
2328 match containing_module.import_resolutions.borrow().find(&source.name) {
2330 debug!("(resolving single import) no import");
2331 // The containing module definitely doesn't have an
2332 // exported import with the name in question. We can
2333 // therefore accurately report that the names are
2336 if value_result.is_unknown() {
2337 value_result = UnboundResult;
2339 if type_result.is_unknown() {
2340 type_result = UnboundResult;
2343 Some(import_resolution)
2344 if import_resolution.outstanding_references == 0 => {
2346 fn get_binding(this: &mut Resolver,
2347 import_resolution: &ImportResolution,
2348 namespace: Namespace)
2349 -> NamespaceResult {
2351 // Import resolutions must be declared with "pub"
2352 // in order to be exported.
2353 if !import_resolution.is_public {
2354 return UnboundResult;
2357 match import_resolution.
2358 target_for_namespace(namespace) {
2360 return UnboundResult;
2362 Some(Target {target_module, bindings}) => {
2363 debug!("(resolving single import) found \
2364 import in ns {:?}", namespace);
2365 let id = import_resolution.id(namespace);
2366 this.used_imports.insert((id, namespace));
2367 return BoundResult(target_module, bindings);
2372 // The name is an import which has been fully
2373 // resolved. We can, therefore, just follow it.
2374 if value_result.is_unknown() {
2375 value_result = get_binding(self, import_resolution,
2377 value_used_reexport = import_resolution.is_public;
2379 if type_result.is_unknown() {
2380 type_result = get_binding(self, import_resolution,
2382 type_used_reexport = import_resolution.is_public;
2387 // The import is unresolved. Bail out.
2388 debug!("(resolving single import) unresolved import; \
2390 return Indeterminate;
2396 // If we didn't find a result in the type namespace, search the
2397 // external modules.
2398 let mut value_used_public = false;
2399 let mut type_used_public = false;
2401 BoundResult(..) => {}
2403 match containing_module.external_module_children.borrow_mut()
2404 .find_copy(&source.name) {
2405 None => {} // Continue.
2407 debug!("(resolving single import) found external \
2410 Rc::new(Resolver::create_name_bindings_from_module(
2412 type_result = BoundResult(containing_module.clone(),
2414 type_used_public = true;
2420 // We've successfully resolved the import. Write the results in.
2421 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2422 let import_resolution = import_resolutions.get_mut(&target.name);
2424 match value_result {
2425 BoundResult(ref target_module, ref name_bindings) => {
2426 debug!("(resolving single import) found value target");
2427 import_resolution.value_target = Some(Target::new(target_module.clone(),
2428 name_bindings.clone()));
2429 import_resolution.value_id = directive.id;
2430 import_resolution.is_public = directive.is_public;
2431 value_used_public = name_bindings.defined_in_public_namespace(ValueNS);
2433 UnboundResult => { /* Continue. */ }
2435 fail!("value result should be known at this point");
2439 BoundResult(ref target_module, ref name_bindings) => {
2440 debug!("(resolving single import) found type target: {:?}",
2441 { name_bindings.type_def.borrow().clone().unwrap().type_def });
2442 import_resolution.type_target =
2443 Some(Target::new(target_module.clone(), name_bindings.clone()));
2444 import_resolution.type_id = directive.id;
2445 import_resolution.is_public = directive.is_public;
2446 type_used_public = name_bindings.defined_in_public_namespace(TypeNS);
2448 UnboundResult => { /* Continue. */ }
2450 fail!("type result should be known at this point");
2454 if value_result.is_unbound() && type_result.is_unbound() {
2455 let msg = format!("There is no `{}` in `{}`",
2456 token::get_ident(source),
2457 self.module_to_string(&*containing_module));
2458 return Failed(Some((directive.span, msg)));
2460 let value_used_public = value_used_reexport || value_used_public;
2461 let type_used_public = type_used_reexport || type_used_public;
2463 assert!(import_resolution.outstanding_references >= 1);
2464 import_resolution.outstanding_references -= 1;
2466 // record what this import resolves to for later uses in documentation,
2467 // this may resolve to either a value or a type, but for documentation
2468 // purposes it's good enough to just favor one over the other.
2469 let value_private = match import_resolution.value_target {
2470 Some(ref target) => {
2471 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2472 self.def_map.borrow_mut().insert(directive.id, def);
2473 let did = def.def_id();
2474 if value_used_public {Some(lp)} else {Some(DependsOn(did))}
2476 // AllPublic here and below is a dummy value, it should never be used because
2477 // _exists is false.
2480 let type_private = match import_resolution.type_target {
2481 Some(ref target) => {
2482 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2483 self.def_map.borrow_mut().insert(directive.id, def);
2484 let did = def.def_id();
2485 if type_used_public {Some(lp)} else {Some(DependsOn(did))}
2490 self.last_private.insert(directive.id, LastImport{value_priv: value_private,
2492 type_priv: type_private,
2495 debug!("(resolving single import) successfully resolved import");
2499 // Resolves a glob import. Note that this function cannot fail; it either
2500 // succeeds or bails out (as importing * from an empty module or a module
2501 // that exports nothing is valid).
2502 fn resolve_glob_import(&mut self,
2504 containing_module: Rc<Module>,
2508 -> ResolveResult<()> {
2509 // This function works in a highly imperative manner; it eagerly adds
2510 // everything it can to the list of import resolutions of the module
2512 debug!("(resolving glob import) resolving glob import {}", id);
2514 // We must bail out if the node has unresolved imports of any kind
2515 // (including globs).
2516 if !(*containing_module).all_imports_resolved() {
2517 debug!("(resolving glob import) target module has unresolved \
2518 imports; bailing out");
2519 return Indeterminate;
2522 assert_eq!(containing_module.glob_count.get(), 0);
2524 // Add all resolved imports from the containing module.
2525 let import_resolutions = containing_module.import_resolutions
2527 for (ident, target_import_resolution) in import_resolutions.iter() {
2528 debug!("(resolving glob import) writing module resolution \
2530 target_import_resolution.type_target.is_none(),
2531 self.module_to_string(module_));
2533 if !target_import_resolution.is_public {
2534 debug!("(resolving glob import) nevermind, just kidding");
2538 // Here we merge two import resolutions.
2539 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2540 match import_resolutions.find_mut(ident) {
2541 Some(dest_import_resolution) => {
2542 // Merge the two import resolutions at a finer-grained
2545 match target_import_resolution.value_target {
2549 Some(ref value_target) => {
2550 dest_import_resolution.value_target =
2551 Some(value_target.clone());
2554 match target_import_resolution.type_target {
2558 Some(ref type_target) => {
2559 dest_import_resolution.type_target =
2560 Some(type_target.clone());
2563 dest_import_resolution.is_public = is_public;
2569 // Simple: just copy the old import resolution.
2570 let mut new_import_resolution = ImportResolution::new(id, is_public);
2571 new_import_resolution.value_target =
2572 target_import_resolution.value_target.clone();
2573 new_import_resolution.type_target =
2574 target_import_resolution.type_target.clone();
2576 import_resolutions.insert(*ident, new_import_resolution);
2579 // Add all children from the containing module.
2580 self.populate_module_if_necessary(&containing_module);
2582 for (&name, name_bindings) in containing_module.children
2584 self.merge_import_resolution(module_, containing_module.clone(),
2586 name, name_bindings.clone());
2589 // Add external module children from the containing module.
2590 for (&name, module) in containing_module.external_module_children
2593 Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
2594 self.merge_import_resolution(module_, containing_module.clone(),
2596 name, name_bindings);
2599 // Record the destination of this import
2600 match containing_module.def_id.get() {
2602 self.def_map.borrow_mut().insert(id, DefMod(did));
2603 self.last_private.insert(id, lp);
2608 debug!("(resolving glob import) successfully resolved import");
2612 fn merge_import_resolution(&mut self,
2614 containing_module: Rc<Module>,
2618 name_bindings: Rc<NameBindings>) {
2619 let mut import_resolutions = module_.import_resolutions.borrow_mut();
2620 let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| {
2621 // Create a new import resolution from this child.
2622 ImportResolution::new(id, is_public)
2625 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2627 token::get_name(name).get().to_string(),
2628 self.module_to_string(&*containing_module),
2629 self.module_to_string(module_));
2631 // Merge the child item into the import resolution.
2632 if name_bindings.defined_in_public_namespace(ValueNS) {
2633 debug!("(resolving glob import) ... for value target");
2634 dest_import_resolution.value_target =
2635 Some(Target::new(containing_module.clone(), name_bindings.clone()));
2636 dest_import_resolution.value_id = id;
2638 if name_bindings.defined_in_public_namespace(TypeNS) {
2639 debug!("(resolving glob import) ... for type target");
2640 dest_import_resolution.type_target =
2641 Some(Target::new(containing_module, name_bindings.clone()));
2642 dest_import_resolution.type_id = id;
2644 dest_import_resolution.is_public = is_public;
2647 /// Resolves the given module path from the given root `module_`.
2648 fn resolve_module_path_from_root(&mut self,
2649 module_: Rc<Module>,
2650 module_path: &[Ident],
2653 name_search_type: NameSearchType,
2655 -> ResolveResult<(Rc<Module>, LastPrivate)> {
2656 fn search_parent_externals(needle: Name, module: &Rc<Module>)
2657 -> Option<Rc<Module>> {
2658 module.external_module_children.borrow()
2660 .map(|_| module.clone())
2662 match module.parent_link.clone() {
2663 ModuleParentLink(parent, _) => {
2664 search_parent_externals(needle,
2665 &parent.upgrade().unwrap())
2672 let mut search_module = module_;
2673 let mut index = index;
2674 let module_path_len = module_path.len();
2675 let mut closest_private = lp;
2677 // Resolve the module part of the path. This does not involve looking
2678 // upward though scope chains; we simply resolve names directly in
2679 // modules as we go.
2680 while index < module_path_len {
2681 let name = module_path[index];
2682 match self.resolve_name_in_module(search_module.clone(),
2688 let segment_name = token::get_ident(name);
2689 let module_name = self.module_to_string(&*search_module);
2690 let mut span = span;
2691 let msg = if "???" == module_name.as_slice() {
2692 span.hi = span.lo + Pos::from_uint(segment_name.get().len());
2694 match search_parent_externals(name.name,
2695 &self.current_module) {
2697 let path_str = self.idents_to_string(module_path);
2698 let target_mod_str = self.module_to_string(&*module);
2699 let current_mod_str =
2700 self.module_to_string(&*self.current_module);
2702 let prefix = if target_mod_str == current_mod_str {
2703 "self::".to_string()
2705 format!("{}::", target_mod_str)
2708 format!("Did you mean `{}{}`?", prefix, path_str)
2710 None => format!("Maybe a missing `extern crate {}`?",
2714 format!("Could not find `{}` in `{}`.",
2719 return Failed(Some((span, msg)));
2721 Failed(err) => return Failed(err),
2723 debug!("(resolving module path for import) module \
2724 resolution is indeterminate: {}",
2725 token::get_ident(name));
2726 return Indeterminate;
2728 Success((target, used_proxy)) => {
2729 // Check to see whether there are type bindings, and, if
2730 // so, whether there is a module within.
2731 match *target.bindings.type_def.borrow() {
2732 Some(ref type_def) => {
2733 match type_def.module_def {
2735 let msg = format!("Not a module `{}`",
2736 token::get_ident(name));
2738 return Failed(Some((span, msg)));
2740 Some(ref module_def) => {
2741 // If we're doing the search for an
2742 // import, do not allow traits and impls
2744 match (name_search_type,
2745 module_def.kind.get()) {
2746 (ImportSearch, TraitModuleKind) |
2747 (ImportSearch, ImplModuleKind) => {
2749 "Cannot import from a trait or \
2750 type implementation".to_string();
2751 return Failed(Some((span, msg)));
2754 search_module = module_def.clone();
2756 // Keep track of the closest
2757 // private module used when
2758 // resolving this import chain.
2760 !search_module.is_public {
2761 match search_module.def_id
2765 LastMod(DependsOn(did));
2776 // There are no type bindings at all.
2777 let msg = format!("Not a module `{}`",
2778 token::get_ident(name));
2779 return Failed(Some((span, msg)));
2788 return Success((search_module, closest_private));
2791 /// Attempts to resolve the module part of an import directive or path
2792 /// rooted at the given module.
2794 /// On success, returns the resolved module, and the closest *private*
2795 /// module found to the destination when resolving this path.
2796 fn resolve_module_path(&mut self,
2797 module_: Rc<Module>,
2798 module_path: &[Ident],
2799 use_lexical_scope: UseLexicalScopeFlag,
2801 name_search_type: NameSearchType)
2802 -> ResolveResult<(Rc<Module>, LastPrivate)> {
2803 let module_path_len = module_path.len();
2804 assert!(module_path_len > 0);
2806 debug!("(resolving module path for import) processing `{}` rooted at \
2808 self.idents_to_string(module_path),
2809 self.module_to_string(&*module_));
2811 // Resolve the module prefix, if any.
2812 let module_prefix_result = self.resolve_module_prefix(module_.clone(),
2818 match module_prefix_result {
2820 let mpath = self.idents_to_string(module_path);
2821 let mpath = mpath.as_slice();
2822 match mpath.rfind(':') {
2824 let msg = format!("Could not find `{}` in `{}`",
2825 // idx +- 1 to account for the
2826 // colons on either side
2827 mpath.slice_from(idx + 1),
2828 mpath.slice_to(idx - 1));
2829 return Failed(Some((span, msg)));
2831 None => return Failed(None),
2834 Failed(err) => return Failed(err),
2836 debug!("(resolving module path for import) indeterminate; \
2838 return Indeterminate;
2840 Success(NoPrefixFound) => {
2841 // There was no prefix, so we're considering the first element
2842 // of the path. How we handle this depends on whether we were
2843 // instructed to use lexical scope or not.
2844 match use_lexical_scope {
2845 DontUseLexicalScope => {
2846 // This is a crate-relative path. We will start the
2847 // resolution process at index zero.
2848 search_module = self.graph_root.get_module();
2850 last_private = LastMod(AllPublic);
2852 UseLexicalScope => {
2853 // This is not a crate-relative path. We resolve the
2854 // first component of the path in the current lexical
2855 // scope and then proceed to resolve below that.
2856 match self.resolve_module_in_lexical_scope(
2859 Failed(err) => return Failed(err),
2861 debug!("(resolving module path for import) \
2862 indeterminate; bailing");
2863 return Indeterminate;
2865 Success(containing_module) => {
2866 search_module = containing_module;
2868 last_private = LastMod(AllPublic);
2874 Success(PrefixFound(ref containing_module, index)) => {
2875 search_module = containing_module.clone();
2876 start_index = index;
2877 last_private = LastMod(DependsOn(containing_module.def_id
2883 self.resolve_module_path_from_root(search_module,
2891 /// Invariant: This must only be called during main resolution, not during
2892 /// import resolution.
2893 fn resolve_item_in_lexical_scope(&mut self,
2894 module_: Rc<Module>,
2896 namespace: Namespace)
2897 -> ResolveResult<(Target, bool)> {
2898 debug!("(resolving item in lexical scope) resolving `{}` in \
2899 namespace {:?} in `{}`",
2900 token::get_ident(name),
2902 self.module_to_string(&*module_));
2904 // The current module node is handled specially. First, check for
2905 // its immediate children.
2906 self.populate_module_if_necessary(&module_);
2908 match module_.children.borrow().find(&name.name) {
2910 if name_bindings.defined_in_namespace(namespace) => {
2911 debug!("top name bindings succeeded");
2912 return Success((Target::new(module_.clone(), name_bindings.clone()),
2915 Some(_) | None => { /* Not found; continue. */ }
2918 // Now check for its import directives. We don't have to have resolved
2919 // all its imports in the usual way; this is because chains of
2920 // adjacent import statements are processed as though they mutated the
2922 match module_.import_resolutions.borrow().find(&name.name) {
2924 // Not found; continue.
2926 Some(import_resolution) => {
2927 match (*import_resolution).target_for_namespace(namespace) {
2929 // Not found; continue.
2930 debug!("(resolving item in lexical scope) found \
2931 import resolution, but not in namespace {:?}",
2935 debug!("(resolving item in lexical scope) using \
2936 import resolution");
2937 self.used_imports.insert((import_resolution.id(namespace), namespace));
2938 return Success((target, false));
2944 // Search for external modules.
2945 if namespace == TypeNS {
2946 match module_.external_module_children.borrow().find_copy(&name.name) {
2950 Rc::new(Resolver::create_name_bindings_from_module(module));
2951 debug!("lower name bindings succeeded");
2952 return Success((Target::new(module_, name_bindings), false));
2957 // Finally, proceed up the scope chain looking for parent modules.
2958 let mut search_module = module_;
2960 // Go to the next parent.
2961 match search_module.parent_link.clone() {
2963 // No more parents. This module was unresolved.
2964 debug!("(resolving item in lexical scope) unresolved \
2966 return Failed(None);
2968 ModuleParentLink(parent_module_node, _) => {
2969 match search_module.kind.get() {
2970 NormalModuleKind => {
2971 // We stop the search here.
2972 debug!("(resolving item in lexical \
2973 scope) unresolved module: not \
2974 searching through module \
2976 return Failed(None);
2981 AnonymousModuleKind => {
2982 search_module = parent_module_node.upgrade().unwrap();
2986 BlockParentLink(ref parent_module_node, _) => {
2987 search_module = parent_module_node.upgrade().unwrap();
2991 // Resolve the name in the parent module.
2992 match self.resolve_name_in_module(search_module.clone(),
2997 Failed(Some((span, msg))) =>
2998 self.resolve_error(span, format!("failed to resolve. {}",
3000 Failed(None) => (), // Continue up the search chain.
3002 // We couldn't see through the higher scope because of an
3003 // unresolved import higher up. Bail.
3005 debug!("(resolving item in lexical scope) indeterminate \
3006 higher scope; bailing");
3007 return Indeterminate;
3009 Success((target, used_reexport)) => {
3010 // We found the module.
3011 debug!("(resolving item in lexical scope) found name \
3013 return Success((target, used_reexport));
3019 /// Resolves a module name in the current lexical scope.
3020 fn resolve_module_in_lexical_scope(&mut self,
3021 module_: Rc<Module>,
3023 -> ResolveResult<Rc<Module>> {
3024 // If this module is an anonymous module, resolve the item in the
3025 // lexical scope. Otherwise, resolve the item from the crate root.
3026 let resolve_result = self.resolve_item_in_lexical_scope(
3027 module_, name, TypeNS);
3028 match resolve_result {
3029 Success((target, _)) => {
3030 let bindings = &*target.bindings;
3031 match *bindings.type_def.borrow() {
3032 Some(ref type_def) => {
3033 match type_def.module_def {
3035 debug!("!!! (resolving module in lexical \
3036 scope) module wasn't actually a \
3038 return Failed(None);
3040 Some(ref module_def) => {
3041 return Success(module_def.clone());
3046 debug!("!!! (resolving module in lexical scope) module
3047 wasn't actually a module!");
3048 return Failed(None);
3053 debug!("(resolving module in lexical scope) indeterminate; \
3055 return Indeterminate;
3058 debug!("(resolving module in lexical scope) failed to resolve");
3064 /// Returns the nearest normal module parent of the given module.
3065 fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>)
3066 -> Option<Rc<Module>> {
3067 let mut module_ = module_;
3069 match module_.parent_link.clone() {
3070 NoParentLink => return None,
3071 ModuleParentLink(new_module, _) |
3072 BlockParentLink(new_module, _) => {
3073 let new_module = new_module.upgrade().unwrap();
3074 match new_module.kind.get() {
3075 NormalModuleKind => return Some(new_module),
3079 AnonymousModuleKind => module_ = new_module,
3086 /// Returns the nearest normal module parent of the given module, or the
3087 /// module itself if it is a normal module.
3088 fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>)
3090 match module_.kind.get() {
3091 NormalModuleKind => return module_,
3095 AnonymousModuleKind => {
3096 match self.get_nearest_normal_module_parent(module_.clone()) {
3098 Some(new_module) => new_module
3104 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3105 /// (b) some chain of `super::`.
3106 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3107 fn resolve_module_prefix(&mut self,
3108 module_: Rc<Module>,
3109 module_path: &[Ident])
3110 -> ResolveResult<ModulePrefixResult> {
3111 // Start at the current module if we see `self` or `super`, or at the
3112 // top of the crate otherwise.
3113 let mut containing_module;
3115 let first_module_path_string = token::get_ident(module_path[0]);
3116 if "self" == first_module_path_string.get() {
3118 self.get_nearest_normal_module_parent_or_self(module_);
3120 } else if "super" == first_module_path_string.get() {
3122 self.get_nearest_normal_module_parent_or_self(module_);
3123 i = 0; // We'll handle `super` below.
3125 return Success(NoPrefixFound);
3128 // Now loop through all the `super`s we find.
3129 while i < module_path.len() {
3130 let string = token::get_ident(module_path[i]);
3131 if "super" != string.get() {
3134 debug!("(resolving module prefix) resolving `super` at {}",
3135 self.module_to_string(&*containing_module));
3136 match self.get_nearest_normal_module_parent(containing_module) {
3137 None => return Failed(None),
3138 Some(new_module) => {
3139 containing_module = new_module;
3145 debug!("(resolving module prefix) finished resolving prefix at {}",
3146 self.module_to_string(&*containing_module));
3148 return Success(PrefixFound(containing_module, i));
3151 /// Attempts to resolve the supplied name in the given module for the
3152 /// given namespace. If successful, returns the target corresponding to
3155 /// The boolean returned on success is an indicator of whether this lookup
3156 /// passed through a public re-export proxy.
3157 fn resolve_name_in_module(&mut self,
3158 module_: Rc<Module>,
3160 namespace: Namespace,
3161 name_search_type: NameSearchType,
3162 allow_private_imports: bool)
3163 -> ResolveResult<(Target, bool)> {
3164 debug!("(resolving name in module) resolving `{}` in `{}`",
3165 token::get_name(name).get(),
3166 self.module_to_string(&*module_));
3168 // First, check the direct children of the module.
3169 self.populate_module_if_necessary(&module_);
3171 match module_.children.borrow().find(&name) {
3173 if name_bindings.defined_in_namespace(namespace) => {
3174 debug!("(resolving name in module) found node as child");
3175 return Success((Target::new(module_.clone(), name_bindings.clone()),
3183 // Next, check the module's imports if necessary.
3185 // If this is a search of all imports, we should be done with glob
3186 // resolution at this point.
3187 if name_search_type == PathSearch {
3188 assert_eq!(module_.glob_count.get(), 0);
3191 // Check the list of resolved imports.
3192 match module_.import_resolutions.borrow().find(&name) {
3193 Some(import_resolution) if allow_private_imports ||
3194 import_resolution.is_public => {
3196 if import_resolution.is_public &&
3197 import_resolution.outstanding_references != 0 {
3198 debug!("(resolving name in module) import \
3199 unresolved; bailing out");
3200 return Indeterminate;
3202 match import_resolution.target_for_namespace(namespace) {
3204 debug!("(resolving name in module) name found, \
3205 but not in namespace {:?}",
3209 debug!("(resolving name in module) resolved to \
3211 self.used_imports.insert((import_resolution.id(namespace), namespace));
3212 return Success((target, true));
3216 Some(..) | None => {} // Continue.
3219 // Finally, search through external children.
3220 if namespace == TypeNS {
3221 match module_.external_module_children.borrow().find_copy(&name) {
3225 Rc::new(Resolver::create_name_bindings_from_module(module));
3226 return Success((Target::new(module_, name_bindings), false));
3231 // We're out of luck.
3232 debug!("(resolving name in module) failed to resolve `{}`",
3233 token::get_name(name).get());
3234 return Failed(None);
3237 fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
3238 let index = module_.resolved_import_count.get();
3239 let imports = module_.imports.borrow();
3240 let import_count = imports.len();
3241 if index != import_count {
3242 let sn = self.session
3244 .span_to_snippet(imports.get(index).span)
3246 if sn.as_slice().contains("::") {
3247 self.resolve_error(imports.get(index).span,
3248 "unresolved import");
3250 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3251 sn.as_slice().slice(0, sn.len()));
3252 self.resolve_error(imports.get(index).span, err.as_slice());
3256 // Descend into children and anonymous children.
3257 self.populate_module_if_necessary(&module_);
3259 for (_, child_node) in module_.children.borrow().iter() {
3260 match child_node.get_module_if_available() {
3264 Some(child_module) => {
3265 self.report_unresolved_imports(child_module);
3270 for (_, module_) in module_.anonymous_children.borrow().iter() {
3271 self.report_unresolved_imports(module_.clone());
3277 // This pass simply determines what all "export" keywords refer to and
3278 // writes the results into the export map.
3280 // FIXME #4953 This pass will be removed once exports change to per-item.
3281 // Then this operation can simply be performed as part of item (or import)
3284 fn record_exports(&mut self) {
3285 let root_module = self.graph_root.get_module();
3286 self.record_exports_for_module_subtree(root_module);
3289 fn record_exports_for_module_subtree(&mut self,
3290 module_: Rc<Module>) {
3291 // If this isn't a local krate, then bail out. We don't need to record
3292 // exports for nonlocal crates.
3294 match module_.def_id.get() {
3295 Some(def_id) if def_id.krate == LOCAL_CRATE => {
3297 debug!("(recording exports for module subtree) recording \
3298 exports for local module `{}`",
3299 self.module_to_string(&*module_));
3302 // Record exports for the root module.
3303 debug!("(recording exports for module subtree) recording \
3304 exports for root module `{}`",
3305 self.module_to_string(&*module_));
3309 debug!("(recording exports for module subtree) not recording \
3311 self.module_to_string(&*module_));
3316 self.record_exports_for_module(&*module_);
3317 self.populate_module_if_necessary(&module_);
3319 for (_, child_name_bindings) in module_.children.borrow().iter() {
3320 match child_name_bindings.get_module_if_available() {
3324 Some(child_module) => {
3325 self.record_exports_for_module_subtree(child_module);
3330 for (_, child_module) in module_.anonymous_children.borrow().iter() {
3331 self.record_exports_for_module_subtree(child_module.clone());
3335 fn record_exports_for_module(&mut self, module_: &Module) {
3336 let mut exports2 = Vec::new();
3338 self.add_exports_for_module(&mut exports2, module_);
3339 match module_.def_id.get() {
3341 self.export_map2.borrow_mut().insert(def_id.node, exports2);
3342 debug!("(computing exports) writing exports for {} (some)",
3349 fn add_exports_of_namebindings(&mut self,
3350 exports2: &mut Vec<Export2> ,
3352 namebindings: &NameBindings,
3354 match namebindings.def_for_namespace(ns) {
3356 let name = token::get_name(name);
3357 debug!("(computing exports) YES: export '{}' => {:?}",
3359 exports2.push(Export2 {
3360 name: name.get().to_string(),
3365 debug!("(computing exports) NO: {:?}", d_opt);
3370 fn add_exports_for_module(&mut self,
3371 exports2: &mut Vec<Export2> ,
3373 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
3374 if !importresolution.is_public {
3377 let xs = [TypeNS, ValueNS];
3378 for &ns in xs.iter() {
3379 match importresolution.target_for_namespace(ns) {
3381 debug!("(computing exports) maybe export '{}'",
3382 token::get_name(*name));
3383 self.add_exports_of_namebindings(exports2,
3396 // We maintain a list of value ribs and type ribs.
3398 // Simultaneously, we keep track of the current position in the module
3399 // graph in the `current_module` pointer. When we go to resolve a name in
3400 // the value or type namespaces, we first look through all the ribs and
3401 // then query the module graph. When we resolve a name in the module
3402 // namespace, we can skip all the ribs (since nested modules are not
3403 // allowed within blocks in Rust) and jump straight to the current module
3406 // Named implementations are handled separately. When we find a method
3407 // call, we consult the module node to find all of the implementations in
3408 // scope. This information is lazily cached in the module node. We then
3409 // generate a fake "implementation scope" containing all the
3410 // implementations thus found, for compatibility with old resolve pass.
3412 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3413 let orig_module = self.current_module.clone();
3415 // Move down in the graph.
3421 self.populate_module_if_necessary(&orig_module);
3423 match orig_module.children.borrow().find(&name.name) {
3425 debug!("!!! (with scope) didn't find `{}` in `{}`",
3426 token::get_ident(name),
3427 self.module_to_string(&*orig_module));
3429 Some(name_bindings) => {
3430 match (*name_bindings).get_module_if_available() {
3432 debug!("!!! (with scope) didn't find module \
3434 token::get_ident(name),
3435 self.module_to_string(&*orig_module));
3438 self.current_module = module_;
3448 self.current_module = orig_module;
3451 /// Wraps the given definition in the appropriate number of `def_upvar`
3458 -> Option<DefLike> {
3463 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3464 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3466 is_ty_param = false;
3468 DlDef(d @ DefTyParam(..)) |
3469 DlDef(d @ DefSelfTy(..)) => {
3474 return Some(def_like);
3478 let mut rib_index = rib_index + 1;
3479 while rib_index < ribs.len() {
3480 match ribs[rib_index].kind {
3482 // Nothing to do. Continue.
3484 FunctionRibKind(function_id, body_id) => {
3486 def = DefUpvar(def.def_id().node,
3492 MethodRibKind(item_id, _) => {
3493 // If the def is a ty param, and came from the parent
3496 DefTyParam(_, did, _) if {
3497 self.def_map.borrow().find(&did.node).map(|x| *x)
3498 == Some(DefTyParamBinder(item_id))
3511 // This was an attempt to access an upvar inside a
3512 // named function item. This is not allowed, so we
3517 "can't capture dynamic environment in a fn item; \
3518 use the || { ... } closure form instead");
3520 // This was an attempt to use a type parameter outside
3523 self.resolve_error(span,
3524 "can't use type parameters from \
3525 outer function; try using a local \
3526 type parameter instead");
3535 // This was an attempt to access an upvar inside a
3536 // named function item. This is not allowed, so we
3541 "can't capture dynamic environment in a fn item; \
3542 use the || { ... } closure form instead");
3544 // This was an attempt to use a type parameter outside
3547 self.resolve_error(span,
3548 "can't use type parameters from \
3549 outer function; try using a local \
3550 type parameter instead");
3555 ConstantItemRibKind => {
3558 self.resolve_error(span,
3559 "cannot use an outer type \
3560 parameter in this context");
3562 // Still doesn't deal with upvars
3563 self.resolve_error(span,
3564 "attempt to use a non-constant \
3565 value in a constant");
3574 return Some(DlDef(def));
3577 fn search_ribs(&self,
3581 -> Option<DefLike> {
3582 // FIXME #4950: This should not use a while loop.
3583 // FIXME #4950: Try caching?
3585 let mut i = ribs.len();
3588 let binding_opt = ribs[i].bindings.borrow().find_copy(&name);
3591 return self.upvarify(ribs, i, def_like, span);
3602 fn resolve_crate(&mut self, krate: &ast::Crate) {
3603 debug!("(resolving crate) starting");
3605 visit::walk_crate(self, krate, ());
3608 fn resolve_item(&mut self, item: &Item) {
3609 debug!("(resolving item) resolving {}",
3610 token::get_ident(item.ident));
3614 // enum item: resolve all the variants' discrs,
3615 // then resolve the ty params
3616 ItemEnum(ref enum_def, ref generics) => {
3617 for variant in (*enum_def).variants.iter() {
3618 for dis_expr in variant.node.disr_expr.iter() {
3619 // resolve the discriminator expr
3621 self.with_constant_rib(|this| {
3622 this.resolve_expr(&**dis_expr);
3627 // n.b. the discr expr gets visited twice.
3628 // but maybe it's okay since the first time will signal an
3629 // error if there is one? -- tjc
3630 self.with_type_parameter_rib(HasTypeParameters(generics,
3635 this.resolve_type_parameters(&generics.ty_params);
3636 visit::walk_item(this, item, ());
3640 ItemTy(_, ref generics) => {
3641 self.with_type_parameter_rib(HasTypeParameters(generics,
3646 visit::walk_item(this, item, ());
3650 ItemImpl(ref generics,
3651 ref implemented_traits,
3654 self.resolve_implementation(item.id,
3658 methods.as_slice());
3661 ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
3662 // Create a new rib for the self type.
3663 let self_type_rib = Rib::new(ItemRibKind);
3665 // plain insert (no renaming, types are not currently hygienic....)
3666 let name = self.type_self_name;
3667 self_type_rib.bindings.borrow_mut()
3668 .insert(name, DlDef(DefSelfTy(item.id)));
3669 self.type_ribs.borrow_mut().push(self_type_rib);
3671 // Create a new rib for the trait-wide type parameters.
3672 self.with_type_parameter_rib(HasTypeParameters(generics,
3677 this.resolve_type_parameters(&generics.ty_params);
3679 // Resolve derived traits.
3680 for trt in traits.iter() {
3681 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3684 &Some(ast::TraitTyParamBound(ref tpb)) => {
3685 this.resolve_trait_reference(item.id, tpb, TraitDerivation);
3690 for method in (*methods).iter() {
3691 // Create a new rib for the method-specific type
3694 // FIXME #4951: Do we need a node ID here?
3697 ast::Required(ref ty_m) => {
3698 this.with_type_parameter_rib
3699 (HasTypeParameters(&ty_m.generics,
3702 MethodRibKind(item.id, Required)),
3705 // Resolve the method-specific type
3707 this.resolve_type_parameters(
3708 &ty_m.generics.ty_params);
3710 for argument in ty_m.decl.inputs.iter() {
3711 this.resolve_type(&*argument.ty);
3714 match ty_m.explicit_self.node {
3715 SelfExplicit(ref typ, _) => {
3716 this.resolve_type(&**typ)
3721 this.resolve_type(&*ty_m.decl.output);
3724 ast::Provided(ref m) => {
3725 this.resolve_method(MethodRibKind(item.id,
3733 self.type_ribs.borrow_mut().pop();
3736 ItemStruct(ref struct_def, ref generics) => {
3737 self.resolve_struct(item.id,
3739 struct_def.super_struct,
3740 struct_def.fields.as_slice());
3743 ItemMod(ref module_) => {
3744 self.with_scope(Some(item.ident), |this| {
3745 this.resolve_module(module_, item.span, item.ident,
3750 ItemForeignMod(ref foreign_module) => {
3751 self.with_scope(Some(item.ident), |this| {
3752 for foreign_item in foreign_module.items.iter() {
3753 match foreign_item.node {
3754 ForeignItemFn(_, ref generics) => {
3755 this.with_type_parameter_rib(
3757 generics, FnSpace, foreign_item.id,
3759 |this| visit::walk_foreign_item(this,
3763 ForeignItemStatic(..) => {
3764 visit::walk_foreign_item(this,
3773 ItemFn(fn_decl, _, _, ref generics, block) => {
3774 self.resolve_function(ItemRibKind,
3785 self.with_constant_rib(|this| {
3786 visit::walk_item(this, item, ());
3791 // do nothing, these are just around to be encoded
3796 fn with_type_parameter_rib(&mut self,
3797 type_parameters: TypeParameters,
3798 f: |&mut Resolver|) {
3799 match type_parameters {
3800 HasTypeParameters(generics, space, node_id,
3803 let function_type_rib = Rib::new(rib_kind);
3805 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3806 let ident = type_parameter.ident;
3807 debug!("with_type_parameter_rib: {} {}", node_id,
3809 let def_like = DlDef(DefTyParam(space,
3810 local_def(type_parameter.id),
3812 // Associate this type parameter with
3813 // the item that bound it
3814 self.record_def(type_parameter.id,
3815 (DefTyParamBinder(node_id), LastMod(AllPublic)));
3816 // plain insert (no renaming)
3817 function_type_rib.bindings.borrow_mut()
3818 .insert(ident.name, def_like);
3820 self.type_ribs.borrow_mut().push(function_type_rib);
3823 NoTypeParameters => {
3830 match type_parameters {
3831 HasTypeParameters(..) => { self.type_ribs.borrow_mut().pop(); }
3832 NoTypeParameters => { }
3836 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3837 self.label_ribs.borrow_mut().push(Rib::new(NormalRibKind));
3839 self.label_ribs.borrow_mut().pop();
3842 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3843 self.value_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
3844 self.type_ribs.borrow_mut().push(Rib::new(ConstantItemRibKind));
3846 self.type_ribs.borrow_mut().pop();
3847 self.value_ribs.borrow_mut().pop();
3850 fn resolve_function(&mut self,
3852 optional_declaration: Option<P<FnDecl>>,
3853 type_parameters: TypeParameters,
3855 // Create a value rib for the function.
3856 let function_value_rib = Rib::new(rib_kind);
3857 self.value_ribs.borrow_mut().push(function_value_rib);
3859 // Create a label rib for the function.
3860 let function_label_rib = Rib::new(rib_kind);
3861 self.label_ribs.borrow_mut().push(function_label_rib);
3863 // If this function has type parameters, add them now.
3864 self.with_type_parameter_rib(type_parameters, |this| {
3865 // Resolve the type parameters.
3866 match type_parameters {
3867 NoTypeParameters => {
3870 HasTypeParameters(ref generics, _, _, _) => {
3871 this.resolve_type_parameters(&generics.ty_params);
3875 // Add each argument to the rib.
3876 match optional_declaration {
3880 Some(declaration) => {
3881 for argument in declaration.inputs.iter() {
3882 let mut bindings_list = HashMap::new();
3883 this.resolve_pattern(&*argument.pat,
3884 ArgumentIrrefutableMode,
3885 &mut bindings_list);
3887 this.resolve_type(&*argument.ty);
3889 debug!("(resolving function) recorded argument");
3892 this.resolve_type(&*declaration.output);
3896 // Resolve the function body.
3897 this.resolve_block(&*block);
3899 debug!("(resolving function) leaving function");
3902 self.label_ribs.borrow_mut().pop();
3903 self.value_ribs.borrow_mut().pop();
3906 fn resolve_type_parameters(&mut self,
3907 type_parameters: &OwnedSlice<TyParam>) {
3908 for type_parameter in type_parameters.iter() {
3909 for bound in type_parameter.bounds.iter() {
3910 self.resolve_type_parameter_bound(type_parameter.id, bound);
3912 match &type_parameter.unbound {
3913 &Some(ref unbound) => self.resolve_type_parameter_bound(type_parameter.id, unbound),
3916 match type_parameter.default {
3917 Some(ref ty) => self.resolve_type(&**ty),
3923 fn resolve_type_parameter_bound(&mut self,
3925 type_parameter_bound: &TyParamBound) {
3926 match *type_parameter_bound {
3927 TraitTyParamBound(ref tref) => {
3928 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3930 UnboxedFnTyParamBound(ref unboxed_function) => {
3931 for argument in unboxed_function.decl.inputs.iter() {
3932 self.resolve_type(&*argument.ty);
3935 self.resolve_type(&*unboxed_function.decl.output);
3937 StaticRegionTyParamBound | OtherRegionTyParamBound(_) => {}
3941 fn resolve_trait_reference(&mut self,
3943 trait_reference: &TraitRef,
3944 reference_type: TraitReferenceType) {
3945 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3947 let path_str = self.path_idents_to_string(&trait_reference.path);
3948 let usage_str = match reference_type {
3949 TraitBoundingTypeParameter => "bound type parameter with",
3950 TraitImplementation => "implement",
3951 TraitDerivation => "derive"
3954 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
3955 self.resolve_error(trait_reference.path.span, msg.as_slice());
3959 (DefTrait(_), _) => {
3960 debug!("(resolving trait) found trait def: {:?}", def);
3961 self.record_def(trait_reference.ref_id, def);
3964 self.resolve_error(trait_reference.path.span,
3965 format!("`{}` is not a trait",
3966 self.path_idents_to_string(
3967 &trait_reference.path)));
3969 // If it's a typedef, give a note
3972 self.session.span_note(
3973 trait_reference.path.span,
3974 format!("`type` aliases cannot \
3975 be used for traits")
3987 fn resolve_struct(&mut self,
3989 generics: &Generics,
3990 super_struct: Option<P<Ty>>,
3991 fields: &[StructField]) {
3992 // If applicable, create a rib for the type parameters.
3993 self.with_type_parameter_rib(HasTypeParameters(generics,
3998 // Resolve the type parameters.
3999 this.resolve_type_parameters(&generics.ty_params);
4001 // Resolve the super struct.
4002 match super_struct {
4003 Some(t) => match t.node {
4004 TyPath(ref path, None, path_id) => {
4005 match this.resolve_path(id, path, TypeNS, true) {
4006 Some((DefTy(def_id), lp)) if this.structs.contains_key(&def_id) => {
4007 let def = DefStruct(def_id);
4008 debug!("(resolving struct) resolved `{}` to type {:?}",
4009 token::get_ident(path.segments
4013 debug!("(resolving struct) writing resolution for `{}` (id {})",
4014 this.path_idents_to_string(path),
4016 this.record_def(path_id, (def, lp));
4018 Some((DefStruct(_), _)) => {
4019 this.session.span_err(t.span,
4020 "super-struct is defined \
4021 in a different crate")
4023 Some(_) => this.session.span_err(t.span,
4024 "super-struct is not a struct type"),
4025 None => this.session.span_err(t.span,
4026 "super-struct could not be resolved"),
4029 _ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4035 for field in fields.iter() {
4036 this.resolve_type(&*field.node.ty);
4041 // Does this really need to take a RibKind or is it always going
4042 // to be NormalRibKind?
4043 fn resolve_method(&mut self,
4046 let method_generics = method.pe_generics();
4047 let type_parameters = HasTypeParameters(method_generics,
4052 match method.pe_explicit_self().node {
4053 SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
4057 self.resolve_function(rib_kind,
4058 Some(method.pe_fn_decl()),
4063 fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
4064 // Handle nested impls (inside fn bodies)
4065 let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
4066 let result = f(self);
4067 self.current_self_type = previous_value;
4071 fn with_optional_trait_ref<T>(&mut self, id: NodeId,
4072 opt_trait_ref: &Option<TraitRef>,
4073 f: |&mut Resolver| -> T) -> T {
4074 let new_val = match *opt_trait_ref {
4075 Some(ref trait_ref) => {
4076 self.resolve_trait_reference(id, trait_ref, TraitImplementation);
4078 match self.def_map.borrow().find(&trait_ref.ref_id) {
4080 let did = def.def_id();
4081 Some((did, trait_ref.clone()))
4088 let original_trait_ref = replace(&mut self.current_trait_ref, new_val);
4089 let result = f(self);
4090 self.current_trait_ref = original_trait_ref;
4094 fn resolve_implementation(&mut self,
4096 generics: &Generics,
4097 opt_trait_reference: &Option<TraitRef>,
4099 methods: &[Gc<Method>]) {
4100 // If applicable, create a rib for the type parameters.
4101 self.with_type_parameter_rib(HasTypeParameters(generics,
4106 // Resolve the type parameters.
4107 this.resolve_type_parameters(&generics.ty_params);
4109 // Resolve the trait reference, if necessary.
4110 this.with_optional_trait_ref(id, opt_trait_reference, |this| {
4111 // Resolve the self type.
4112 this.resolve_type(self_type);
4114 this.with_current_self_type(self_type, |this| {
4115 for method in methods.iter() {
4116 // If this is a trait impl, ensure the method exists in trait
4117 this.check_trait_method(&**method);
4119 // We also need a new scope for the method-specific type parameters.
4120 this.resolve_method(MethodRibKind(id, Provided(method.id)),
4128 fn check_trait_method(&self, method: &Method) {
4129 // If there is a TraitRef in scope for an impl, then the method must be in the trait.
4130 for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4131 let method_name = method.pe_ident().name;
4133 if self.method_map.borrow().find(&(method_name, did)).is_none() {
4134 let path_str = self.path_idents_to_string(&trait_ref.path);
4135 self.resolve_error(method.span,
4136 format!("method `{}` is not a member of trait `{}`",
4137 token::get_name(method_name),
4138 path_str).as_slice());
4143 fn resolve_module(&mut self, module: &Mod, _span: Span,
4144 _name: Ident, id: NodeId) {
4145 // Write the implementations in scope into the module metadata.
4146 debug!("(resolving module) resolving module ID {}", id);
4147 visit::walk_mod(self, module, ());
4150 fn resolve_local(&mut self, local: &Local) {
4151 // Resolve the type.
4152 self.resolve_type(&*local.ty);
4154 // Resolve the initializer, if necessary.
4159 Some(ref initializer) => {
4160 self.resolve_expr(&**initializer);
4164 // Resolve the pattern.
4165 let mut bindings_list = HashMap::new();
4166 self.resolve_pattern(&*local.pat,
4167 LocalIrrefutableMode,
4168 &mut bindings_list);
4171 // build a map from pattern identifiers to binding-info's.
4172 // this is done hygienically. This could arise for a macro
4173 // that expands into an or-pattern where one 'x' was from the
4174 // user and one 'x' came from the macro.
4175 fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
4176 let mut result = HashMap::new();
4177 pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| {
4178 let name = mtwt::resolve(path1.node);
4180 binding_info {span: sp,
4181 binding_mode: binding_mode});
4186 // check that all of the arms in an or-pattern have exactly the
4187 // same set of bindings, with the same binding modes for each.
4188 fn check_consistent_bindings(&mut self, arm: &Arm) {
4189 if arm.pats.len() == 0 {
4192 let map_0 = self.binding_mode_map(&**arm.pats.get(0));
4193 for (i, p) in arm.pats.iter().enumerate() {
4194 let map_i = self.binding_mode_map(&**p);
4196 for (&key, &binding_0) in map_0.iter() {
4197 match map_i.find(&key) {
4201 format!("variable `{}` from pattern #1 is \
4202 not bound in pattern #{}",
4203 token::get_name(key),
4206 Some(binding_i) => {
4207 if binding_0.binding_mode != binding_i.binding_mode {
4210 format!("variable `{}` is bound with different \
4211 mode in pattern #{} than in pattern #1",
4212 token::get_name(key),
4219 for (&key, &binding) in map_i.iter() {
4220 if !map_0.contains_key(&key) {
4223 format!("variable `{}` from pattern {}{} is \
4224 not bound in pattern {}1",
4225 token::get_name(key),
4226 "#", i + 1, "#").as_slice());
4232 fn resolve_arm(&mut self, arm: &Arm) {
4233 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4235 let mut bindings_list = HashMap::new();
4236 for pattern in arm.pats.iter() {
4237 self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
4240 // This has to happen *after* we determine which
4241 // pat_idents are variants
4242 self.check_consistent_bindings(arm);
4244 visit::walk_expr_opt(self, arm.guard, ());
4245 self.resolve_expr(&*arm.body);
4247 self.value_ribs.borrow_mut().pop();
4250 fn resolve_block(&mut self, block: &Block) {
4251 debug!("(resolving block) entering block");
4252 self.value_ribs.borrow_mut().push(Rib::new(NormalRibKind));
4254 // Move down in the graph, if there's an anonymous module rooted here.
4255 let orig_module = self.current_module.clone();
4256 match orig_module.anonymous_children.borrow().find(&block.id) {
4257 None => { /* Nothing to do. */ }
4258 Some(anonymous_module) => {
4259 debug!("(resolving block) found anonymous module, moving \
4261 self.current_module = anonymous_module.clone();
4265 // Descend into the block.
4266 visit::walk_block(self, block, ());
4269 self.current_module = orig_module;
4271 self.value_ribs.borrow_mut().pop();
4272 debug!("(resolving block) leaving block");
4275 fn resolve_type(&mut self, ty: &Ty) {
4277 // Like path expressions, the interpretation of path types depends
4278 // on whether the path has multiple elements in it or not.
4280 TyPath(ref path, ref bounds, path_id) => {
4281 // This is a path in the type namespace. Walk through scopes
4283 let mut result_def = None;
4285 // First, check to see whether the name is a primitive type.
4286 if path.segments.len() == 1 {
4287 let id = path.segments.last().unwrap().identifier;
4289 match self.primitive_type_table
4293 Some(&primitive_type) => {
4295 Some((DefPrimTy(primitive_type), LastMod(AllPublic)));
4299 .any(|s| !s.lifetimes.is_empty()) {
4300 self.session.span_err(path.span,
4301 "lifetime parameters \
4302 are not allowed on \
4304 } else if path.segments
4306 .any(|s| s.types.len() > 0) {
4307 self.session.span_err(path.span,
4308 "type parameters are \
4309 not allowed on this \
4321 match self.resolve_path(ty.id, path, TypeNS, true) {
4323 debug!("(resolving type) resolved `{}` to \
4325 token::get_ident(path.segments
4329 result_def = Some(def);
4336 Some(_) => {} // Continue.
4341 // Write the result into the def map.
4342 debug!("(resolving type) writing resolution for `{}` \
4344 self.path_idents_to_string(path),
4346 self.record_def(path_id, def);
4349 let msg = format!("use of undeclared type name `{}`",
4350 self.path_idents_to_string(path));
4351 self.resolve_error(ty.span, msg.as_slice());
4355 bounds.as_ref().map(|bound_vec| {
4356 for bound in bound_vec.iter() {
4357 self.resolve_type_parameter_bound(ty.id, bound);
4362 TyClosure(c, _) | TyProc(c) => {
4363 c.bounds.as_ref().map(|bounds| {
4364 for bound in bounds.iter() {
4365 self.resolve_type_parameter_bound(ty.id, bound);
4368 visit::walk_ty(self, ty, ());
4372 // Just resolve embedded types.
4373 visit::walk_ty(self, ty, ());
4378 fn resolve_pattern(&mut self,
4380 mode: PatternBindingMode,
4381 // Maps idents to the node ID for the (outermost)
4382 // pattern that binds them
4383 bindings_list: &mut HashMap<Name,NodeId>) {
4384 let pat_id = pattern.id;
4385 walk_pat(pattern, |pattern| {
4386 match pattern.node {
4387 PatIdent(binding_mode, ref path1, _) => {
4389 // The meaning of pat_ident with no type parameters
4390 // depends on whether an enum variant or unit-like struct
4391 // with that name is in scope. The probing lookup has to
4392 // be careful not to emit spurious errors. Only matching
4393 // patterns (match) can match nullary variants or
4394 // unit-like structs. For binding patterns (let), matching
4395 // such a value is simply disallowed (since it's rarely
4398 let ident = path1.node;
4399 let renamed = mtwt::resolve(ident);
4401 match self.resolve_bare_identifier_pattern(ident, pattern.span) {
4402 FoundStructOrEnumVariant(def, lp)
4403 if mode == RefutableMode => {
4404 debug!("(resolving pattern) resolving `{}` to \
4405 struct or enum variant",
4406 token::get_name(renamed));
4408 self.enforce_default_binding_mode(
4412 self.record_def(pattern.id, (def, lp));
4414 FoundStructOrEnumVariant(..) => {
4417 format!("declaration of `{}` shadows an enum \
4418 variant or unit-like struct in \
4420 token::get_name(renamed)).as_slice());
4422 FoundConst(def, lp) if mode == RefutableMode => {
4423 debug!("(resolving pattern) resolving `{}` to \
4425 token::get_name(renamed));
4427 self.enforce_default_binding_mode(
4431 self.record_def(pattern.id, (def, lp));
4434 self.resolve_error(pattern.span,
4435 "only irrefutable patterns \
4438 BareIdentifierPatternUnresolved => {
4439 debug!("(resolving pattern) binding `{}`",
4440 token::get_name(renamed));
4442 let def = match mode {
4444 // For pattern arms, we must use
4445 // `def_binding` definitions.
4447 DefBinding(pattern.id, binding_mode)
4449 LocalIrrefutableMode => {
4450 // But for locals, we use `def_local`.
4451 DefLocal(pattern.id, binding_mode)
4453 ArgumentIrrefutableMode => {
4454 // And for function arguments, `def_arg`.
4455 DefArg(pattern.id, binding_mode)
4459 // Record the definition so that later passes
4460 // will be able to distinguish variants from
4461 // locals in patterns.
4463 self.record_def(pattern.id, (def, LastMod(AllPublic)));
4465 // Add the binding to the local ribs, if it
4466 // doesn't already exist in the bindings list. (We
4467 // must not add it if it's in the bindings list
4468 // because that breaks the assumptions later
4469 // passes make about or-patterns.)
4471 if !bindings_list.contains_key(&renamed) {
4472 let this = &mut *self;
4473 let value_ribs = this.value_ribs.borrow();
4474 let length = value_ribs.len();
4475 let last_rib = value_ribs.get(
4477 last_rib.bindings.borrow_mut()
4478 .insert(renamed, DlDef(def));
4479 bindings_list.insert(renamed, pat_id);
4480 } else if bindings_list.find(&renamed) ==
4482 // Then this is a duplicate variable in the
4483 // same disjunction, which is an error.
4484 self.resolve_error(pattern.span,
4485 format!("identifier `{}` is bound \
4486 more than once in the same \
4488 token::get_ident(ident)).as_slice());
4490 // Else, not bound in the same pattern: do
4496 PatEnum(ref path, _) => {
4497 // This must be an enum variant, struct or const.
4498 match self.resolve_path(pat_id, path, ValueNS, false) {
4499 Some(def @ (DefFn(..), _)) |
4500 Some(def @ (DefVariant(..), _)) |
4501 Some(def @ (DefStruct(..), _)) |
4502 Some(def @ (DefStatic(..), _)) => {
4503 self.record_def(pattern.id, def);
4506 self.resolve_error(path.span,
4507 format!("`{}` is not an enum variant, struct or const",
4512 .identifier)).as_slice());
4515 self.resolve_error(path.span,
4516 format!("unresolved enum variant, struct or const `{}`",
4521 .identifier)).as_slice());
4525 // Check the types in the path pattern.
4526 for ty in path.segments
4528 .flat_map(|s| s.types.iter()) {
4529 self.resolve_type(&**ty);
4533 PatLit(ref expr) => {
4534 self.resolve_expr(&**expr);
4537 PatRange(ref first_expr, ref last_expr) => {
4538 self.resolve_expr(&**first_expr);
4539 self.resolve_expr(&**last_expr);
4542 PatStruct(ref path, _, _) => {
4543 match self.resolve_path(pat_id, path, TypeNS, false) {
4544 Some(definition) => {
4545 self.record_def(pattern.id, definition);
4548 debug!("(resolving pattern) didn't find struct \
4549 def: {:?}", result);
4550 let msg = format!("`{}` does not name a structure",
4551 self.path_idents_to_string(path));
4552 self.resolve_error(path.span, msg.as_slice());
4565 fn resolve_bare_identifier_pattern(&mut self, name: Ident, span: Span)
4566 -> BareIdentifierPatternResolution {
4567 let module = self.current_module.clone();
4568 match self.resolve_item_in_lexical_scope(module,
4571 Success((target, _)) => {
4572 debug!("(resolve bare identifier pattern) succeeded in \
4573 finding {} at {:?}",
4574 token::get_ident(name),
4575 target.bindings.value_def.borrow());
4576 match *target.bindings.value_def.borrow() {
4578 fail!("resolved name in the value namespace to a \
4579 set of name bindings with no def?!");
4582 // For the two success cases, this lookup can be
4583 // considered as not having a private component because
4584 // the lookup happened only within the current module.
4586 def @ DefVariant(..) | def @ DefStruct(..) => {
4587 return FoundStructOrEnumVariant(def, LastMod(AllPublic));
4589 def @ DefStatic(_, false) => {
4590 return FoundConst(def, LastMod(AllPublic));
4592 DefStatic(_, true) => {
4593 self.resolve_error(span,
4594 "mutable static variables cannot be referenced in a pattern");
4595 return BareIdentifierPatternUnresolved;
4598 return BareIdentifierPatternUnresolved;
4606 fail!("unexpected indeterminate result");
4610 Some((span, msg)) => {
4611 self.resolve_error(span, format!("failed to resolve: {}",
4617 debug!("(resolve bare identifier pattern) failed to find {}",
4618 token::get_ident(name));
4619 return BareIdentifierPatternUnresolved;
4624 /// If `check_ribs` is true, checks the local definitions first; i.e.
4625 /// doesn't skip straight to the containing module.
4626 fn resolve_path(&mut self,
4629 namespace: Namespace,
4630 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4631 // First, resolve the types.
4632 for ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4633 self.resolve_type(&**ty);
4637 return self.resolve_crate_relative_path(path, namespace);
4640 let unqualified_def =
4641 self.resolve_identifier(path.segments
4648 if path.segments.len() > 1 {
4649 let def = self.resolve_module_relative_path(path, namespace);
4650 match (def, unqualified_def) {
4651 (Some((d, _)), Some((ud, _))) if d == ud => {
4653 .add_lint(lint::builtin::UNNECESSARY_QUALIFICATION,
4656 "unnecessary qualification".to_string());
4664 return unqualified_def;
4667 // resolve a single identifier (used as a varref)
4668 fn resolve_identifier(&mut self,
4670 namespace: Namespace,
4673 -> Option<(Def, LastPrivate)> {
4675 match self.resolve_identifier_in_local_ribs(identifier,
4679 return Some((def, LastMod(AllPublic)));
4687 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4691 // FIXME #4952: Merge me with resolve_name_in_module?
4692 fn resolve_definition_of_name_in_module(&mut self,
4693 containing_module: Rc<Module>,
4695 namespace: Namespace)
4697 // First, search children.
4698 self.populate_module_if_necessary(&containing_module);
4700 match containing_module.children.borrow().find(&name) {
4701 Some(child_name_bindings) => {
4702 match child_name_bindings.def_for_namespace(namespace) {
4704 // Found it. Stop the search here.
4705 let p = child_name_bindings.defined_in_public_namespace(
4707 let lp = if p {LastMod(AllPublic)} else {
4708 LastMod(DependsOn(def.def_id()))
4710 return ChildNameDefinition(def, lp);
4718 // Next, search import resolutions.
4719 match containing_module.import_resolutions.borrow().find(&name) {
4720 Some(import_resolution) if import_resolution.is_public => {
4721 match (*import_resolution).target_for_namespace(namespace) {
4723 match target.bindings.def_for_namespace(namespace) {
4726 let id = import_resolution.id(namespace);
4727 self.used_imports.insert((id, namespace));
4728 return ImportNameDefinition(def, LastMod(AllPublic));
4731 // This can happen with external impls, due to
4732 // the imperfect way we read the metadata.
4739 Some(..) | None => {} // Continue.
4742 // Finally, search through external children.
4743 if namespace == TypeNS {
4744 match containing_module.external_module_children.borrow()
4748 match module.def_id.get() {
4749 None => {} // Continue.
4751 let lp = if module.is_public {LastMod(AllPublic)} else {
4752 LastMod(DependsOn(def_id))
4754 return ChildNameDefinition(DefMod(def_id), lp);
4761 return NoNameDefinition;
4764 // resolve a "module-relative" path, e.g. a::b::c
4765 fn resolve_module_relative_path(&mut self,
4767 namespace: Namespace)
4768 -> Option<(Def, LastPrivate)> {
4769 let module_path_idents = path.segments.init().iter()
4770 .map(|ps| ps.identifier)
4771 .collect::<Vec<_>>();
4773 let containing_module;
4775 let module = self.current_module.clone();
4776 match self.resolve_module_path(module,
4777 module_path_idents.as_slice(),
4782 let (span, msg) = match err {
4783 Some((span, msg)) => (span, msg),
4785 let msg = format!("Use of undeclared module `{}`",
4786 self.idents_to_string(
4787 module_path_idents.as_slice()));
4792 self.resolve_error(span, format!("failed to resolve. {}",
4796 Indeterminate => fail!("indeterminate unexpected"),
4797 Success((resulting_module, resulting_last_private)) => {
4798 containing_module = resulting_module;
4799 last_private = resulting_last_private;
4803 let ident = path.segments.last().unwrap().identifier;
4804 let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
4807 NoNameDefinition => {
4808 // We failed to resolve the name. Report an error.
4811 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4812 (def, last_private.or(lp))
4815 match containing_module.kind.get() {
4816 TraitModuleKind | ImplModuleKind => {
4817 match containing_module.def_id.get() {
4819 match self.method_map.borrow().find(&(ident.name, def_id)) {
4820 Some(&MethodIsStatic) => (),
4823 debug!("containing module was a trait or impl \
4824 and name was a method -> not resolved");
4837 /// Invariant: This must be called only during main resolution, not during
4838 /// import resolution.
4839 fn resolve_crate_relative_path(&mut self,
4841 namespace: Namespace)
4842 -> Option<(Def, LastPrivate)> {
4843 let module_path_idents = path.segments.init().iter()
4844 .map(|ps| ps.identifier)
4845 .collect::<Vec<_>>();
4847 let root_module = self.graph_root.get_module();
4849 let containing_module;
4851 match self.resolve_module_path_from_root(root_module,
4852 module_path_idents.as_slice(),
4856 LastMod(AllPublic)) {
4858 let (span, msg) = match err {
4859 Some((span, msg)) => (span, msg),
4861 let msg = format!("Use of undeclared module `::{}`",
4862 self.idents_to_string(
4863 module_path_idents.as_slice()));
4868 self.resolve_error(span, format!("failed to resolve. {}",
4874 fail!("indeterminate unexpected");
4877 Success((resulting_module, resulting_last_private)) => {
4878 containing_module = resulting_module;
4879 last_private = resulting_last_private;
4883 let name = path.segments.last().unwrap().identifier.name;
4884 match self.resolve_definition_of_name_in_module(containing_module,
4887 NoNameDefinition => {
4888 // We failed to resolve the name. Report an error.
4891 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4892 return Some((def, last_private.or(lp)));
4897 fn resolve_identifier_in_local_ribs(&mut self,
4899 namespace: Namespace,
4902 // Check the local set of ribs.
4903 let search_result = match namespace {
4905 let renamed = mtwt::resolve(ident);
4906 self.search_ribs(self.value_ribs.borrow().as_slice(),
4910 let name = ident.name;
4911 self.search_ribs(self.type_ribs.borrow().as_slice(), name, span)
4915 match search_result {
4916 Some(DlDef(def)) => {
4917 debug!("(resolving path in local ribs) resolved `{}` to \
4919 token::get_ident(ident),
4923 Some(DlField) | Some(DlImpl(_)) | None => {
4929 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
4931 namespace: Namespace)
4932 -> Option<(Def, LastPrivate)> {
4934 let module = self.current_module.clone();
4935 match self.resolve_item_in_lexical_scope(module,
4938 Success((target, _)) => {
4939 match (*target.bindings).def_for_namespace(namespace) {
4941 // This can happen if we were looking for a type and
4942 // found a module instead. Modules don't have defs.
4943 debug!("(resolving item path by identifier in lexical \
4944 scope) failed to resolve {} after success...",
4945 token::get_ident(ident));
4949 debug!("(resolving item path in lexical scope) \
4950 resolved `{}` to item",
4951 token::get_ident(ident));
4952 // This lookup is "all public" because it only searched
4953 // for one identifier in the current module (couldn't
4954 // have passed through reexports or anything like that.
4955 return Some((def, LastMod(AllPublic)));
4960 fail!("unexpected indeterminate result");
4964 Some((span, msg)) =>
4965 self.resolve_error(span, format!("failed to resolve. {}", msg)),
4969 debug!("(resolving item path by identifier in lexical scope) \
4970 failed to resolve {}", token::get_ident(ident));
4976 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
4977 self.emit_errors = false;
4979 self.emit_errors = true;
4983 fn resolve_error<T: Str>(&self, span: Span, s: T) {
4984 if self.emit_errors {
4985 self.session.span_err(span, s.as_slice());
4989 fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
4990 #[deriving(PartialEq)]
4991 enum FallbackChecks {
4996 fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
4997 -> Option<(Path, NodeId, FallbackChecks)> {
4999 TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
5000 TyPtr(mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
5001 TyRptr(_, mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
5002 // This doesn't handle the remaining `Ty` variants as they are not
5003 // that commonly the self_type, it might be interesting to provide
5004 // support for those in future.
5009 fn get_module(this: &mut Resolver, span: Span, ident_path: &[ast::Ident])
5010 -> Option<Rc<Module>> {
5011 let root = this.current_module.clone();
5012 let last_name = ident_path.last().unwrap().name;
5014 if ident_path.len() == 1 {
5015 match this.primitive_type_table.primitive_types.find(&last_name) {
5018 match this.current_module.children.borrow().find(&last_name) {
5019 Some(child) => child.get_module_if_available(),
5025 match this.resolve_module_path(root,
5026 ident_path.as_slice(),
5030 Success((module, _)) => Some(module),
5036 let (path, node_id, allowed) = match self.current_self_type {
5037 Some(ref ty) => match extract_path_and_node_id(ty, Everything) {
5039 None => return NoSuggestion,
5041 None => return NoSuggestion,
5044 if allowed == Everything {
5045 // Look for a field with the same name in the current self_type.
5046 match self.def_map.borrow().find(&node_id) {
5048 | Some(&DefStruct(did))
5049 | Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
5052 if fields.iter().any(|&field_name| name == field_name) {
5057 _ => {} // Self type didn't resolve properly
5061 let ident_path = path.segments.iter().map(|seg| seg.identifier).collect::<Vec<_>>();
5063 // Look for a method in the current self type's impl module.
5064 match get_module(self, path.span, ident_path.as_slice()) {
5065 Some(module) => match module.children.borrow().find(&name) {
5067 let p_str = self.path_idents_to_string(&path);
5068 match binding.def_for_namespace(ValueNS) {
5069 Some(DefStaticMethod(_, provenance, _)) => {
5071 FromImpl(_) => return StaticMethod(p_str),
5072 FromTrait(_) => unreachable!()
5075 Some(DefMethod(_, None)) if allowed == Everything => return Method,
5076 Some(DefMethod(_, Some(_))) => return TraitMethod,
5085 // Look for a method in the current trait.
5086 let method_map = self.method_map.borrow();
5087 match self.current_trait_ref {
5088 Some((did, ref trait_ref)) => {
5089 let path_str = self.path_idents_to_string(&trait_ref.path);
5091 match method_map.find(&(name, did)) {
5092 Some(&MethodIsStatic) => return StaticTraitMethod(path_str),
5093 Some(_) => return TraitMethod,
5103 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5105 let this = &mut *self;
5107 let mut maybes: Vec<token::InternedString> = Vec::new();
5108 let mut values: Vec<uint> = Vec::new();
5110 let mut j = this.value_ribs.borrow().len();
5113 let value_ribs = this.value_ribs.borrow();
5114 let bindings = value_ribs.get(j).bindings.borrow();
5115 for (&k, _) in bindings.iter() {
5116 maybes.push(token::get_name(k));
5117 values.push(uint::MAX);
5121 let mut smallest = 0;
5122 for (i, other) in maybes.iter().enumerate() {
5123 *values.get_mut(i) = name.lev_distance(other.get());
5125 if *values.get(i) <= *values.get(smallest) {
5130 if values.len() > 0 &&
5131 *values.get(smallest) != uint::MAX &&
5132 *values.get(smallest) < name.len() + 2 &&
5133 *values.get(smallest) <= max_distance &&
5134 name != maybes.get(smallest).get() {
5136 Some(maybes.get(smallest).get().to_string())
5143 fn resolve_expr(&mut self, expr: &Expr) {
5144 // First, record candidate traits for this expression if it could
5145 // result in the invocation of a method call.
5147 self.record_candidate_traits_for_expr_if_necessary(expr);
5149 // Next, resolve the node.
5151 // The interpretation of paths depends on whether the path has
5152 // multiple elements in it or not.
5154 ExprPath(ref path) => {
5155 // This is a local path in the value namespace. Walk through
5156 // scopes looking for it.
5158 match self.resolve_path(expr.id, path, ValueNS, true) {
5160 // Write the result into the def map.
5161 debug!("(resolving expr) resolved `{}`",
5162 self.path_idents_to_string(path));
5164 // First-class methods are not supported yet; error
5167 (DefMethod(..), _) => {
5168 self.resolve_error(expr.span,
5169 "first-class methods \
5170 are not supported");
5171 self.session.span_note(expr.span,
5179 self.record_def(expr.id, def);
5182 let wrong_name = self.path_idents_to_string(path);
5183 // Be helpful if the name refers to a struct
5184 // (The pattern matching def_tys where the id is in self.structs
5185 // matches on regular structs while excluding tuple- and enum-like
5186 // structs, which wouldn't result in this error.)
5187 match self.with_no_errors(|this|
5188 this.resolve_path(expr.id, path, TypeNS, false)) {
5189 Some((DefTy(struct_id), _))
5190 if self.structs.contains_key(&struct_id) => {
5191 self.resolve_error(expr.span,
5192 format!("`{}` is a structure name, but \
5194 uses it like a function name",
5195 wrong_name).as_slice());
5197 self.session.span_note(expr.span,
5198 format!("Did you mean to write: \
5199 `{} {{ /* fields */ }}`?",
5200 wrong_name).as_slice());
5204 let mut method_scope = false;
5205 self.value_ribs.borrow().iter().rev().all(|rib| {
5206 let res = match *rib {
5207 Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
5208 Rib { bindings: _, kind: ItemRibKind } => false,
5209 _ => return true, // Keep advancing
5213 false // Stop advancing
5216 if method_scope && token::get_name(self.self_name).get()
5217 == wrong_name.as_slice() {
5220 "`self` is not available \
5221 in a static method. Maybe a \
5222 `self` argument is missing?");
5224 let last_name = path.segments.last().unwrap().identifier.name;
5225 let mut msg = match self.find_fallback_in_self_type(last_name) {
5227 // limit search to 5 to reduce the number
5228 // of stupid suggestions
5229 self.find_best_match_for_name(wrong_name.as_slice(), 5)
5230 .map_or("".to_string(),
5231 |x| format!("`{}`", x))
5234 format!("`self.{}`", wrong_name),
5237 format!("to call `self.{}`", wrong_name),
5238 StaticTraitMethod(path_str)
5239 | StaticMethod(path_str) =>
5240 format!("to call `{}::{}`", path_str, wrong_name)
5244 msg = format!(" Did you mean {}?", msg)
5249 format!("unresolved name `{}`.{}",
5258 visit::walk_expr(self, expr, ());
5261 ExprFnBlock(fn_decl, block) |
5262 ExprProc(fn_decl, block) |
5263 ExprUnboxedFn(fn_decl, block) => {
5264 self.resolve_function(FunctionRibKind(expr.id, block.id),
5265 Some(fn_decl), NoTypeParameters,
5269 ExprStruct(ref path, _, _) => {
5270 // Resolve the path to the structure it goes to. We don't
5271 // check to ensure that the path is actually a structure; that
5272 // is checked later during typeck.
5273 match self.resolve_path(expr.id, path, TypeNS, false) {
5274 Some(definition) => self.record_def(expr.id, definition),
5276 debug!("(resolving expression) didn't find struct \
5277 def: {:?}", result);
5278 let msg = format!("`{}` does not name a structure",
5279 self.path_idents_to_string(path));
5280 self.resolve_error(path.span, msg.as_slice());
5284 visit::walk_expr(self, expr, ());
5287 ExprLoop(_, Some(label)) => {
5288 self.with_label_rib(|this| {
5289 let def_like = DlDef(DefLabel(expr.id));
5292 let label_ribs = this.label_ribs.borrow();
5293 let length = label_ribs.len();
5294 let rib = label_ribs.get(length - 1);
5295 let renamed = mtwt::resolve(label);
5296 rib.bindings.borrow_mut().insert(renamed, def_like);
5299 visit::walk_expr(this, expr, ());
5303 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5305 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5306 let renamed = mtwt::resolve(label);
5307 match self.search_ribs(self.label_ribs.borrow().as_slice(),
5308 renamed, expr.span) {
5312 format!("use of undeclared label `{}`",
5313 token::get_ident(label)).as_slice())
5315 Some(DlDef(def @ DefLabel(_))) => {
5316 // Since this def is a label, it is never read.
5317 self.record_def(expr.id, (def, LastMod(AllPublic)))
5320 self.session.span_bug(expr.span,
5321 "label wasn't mapped to a \
5328 visit::walk_expr(self, expr, ());
5333 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5335 ExprField(_, ident, _) => {
5336 // FIXME(#6890): Even though you can't treat a method like a
5337 // field, we need to add any trait methods we find that match
5338 // the field name so that we can do some nice error reporting
5339 // later on in typeck.
5340 let traits = self.search_for_traits_containing_method(ident.node.name);
5341 self.trait_map.insert(expr.id, traits);
5343 ExprMethodCall(ident, _, _) => {
5344 debug!("(recording candidate traits for expr) recording \
5347 let traits = self.search_for_traits_containing_method(ident.node.name);
5348 self.trait_map.insert(expr.id, traits);
5356 fn search_for_traits_containing_method(&mut self, name: Name) -> Vec<DefId> {
5357 debug!("(searching for traits containing method) looking for '{}'",
5358 token::get_name(name));
5360 fn add_trait_info(found_traits: &mut Vec<DefId>,
5361 trait_def_id: DefId,
5363 debug!("(adding trait info) found trait {}:{} for method '{}'",
5366 token::get_name(name));
5367 found_traits.push(trait_def_id);
5370 let mut found_traits = Vec::new();
5371 let mut search_module = self.current_module.clone();
5373 // Look for the current trait.
5374 match self.current_trait_ref {
5375 Some((trait_def_id, _)) => {
5376 let method_map = self.method_map.borrow();
5378 if method_map.contains_key(&(name, trait_def_id)) {
5379 add_trait_info(&mut found_traits, trait_def_id, name);
5382 None => {} // Nothing to do.
5385 // Look for trait children.
5386 self.populate_module_if_necessary(&search_module);
5389 let method_map = self.method_map.borrow();
5390 for (_, child_names) in search_module.children.borrow().iter() {
5391 let def = match child_names.def_for_namespace(TypeNS) {
5395 let trait_def_id = match def {
5396 DefTrait(trait_def_id) => trait_def_id,
5399 if method_map.contains_key(&(name, trait_def_id)) {
5400 add_trait_info(&mut found_traits, trait_def_id, name);
5405 // Look for imports.
5406 for (_, import) in search_module.import_resolutions.borrow().iter() {
5407 let target = match import.target_for_namespace(TypeNS) {
5409 Some(target) => target,
5411 let did = match target.bindings.def_for_namespace(TypeNS) {
5412 Some(DefTrait(trait_def_id)) => trait_def_id,
5413 Some(..) | None => continue,
5415 if self.method_map.borrow().contains_key(&(name, did)) {
5416 add_trait_info(&mut found_traits, did, name);
5417 self.used_imports.insert((import.type_id, TypeNS));
5421 match search_module.parent_link.clone() {
5422 NoParentLink | ModuleParentLink(..) => break,
5423 BlockParentLink(parent_module, _) => {
5424 search_module = parent_module.upgrade().unwrap();
5432 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5433 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5435 assert!(match lp {LastImport{..} => false, _ => true},
5436 "Import should only be used for `use` directives");
5437 self.last_private.insert(node_id, lp);
5438 self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| {
5439 // Resolve appears to "resolve" the same ID multiple
5440 // times, so here is a sanity check it at least comes to
5441 // the same conclusion! - nmatsakis
5442 if def != *old_value {
5444 .bug(format!("node_id {:?} resolved first to {:?} and \
5453 fn enforce_default_binding_mode(&mut self,
5455 pat_binding_mode: BindingMode,
5457 match pat_binding_mode {
5458 BindByValue(_) => {}
5460 self.resolve_error(pat.span,
5461 format!("cannot use `ref` binding mode \
5469 // Unused import checking
5471 // Although this is mostly a lint pass, it lives in here because it depends on
5472 // resolve data structures and because it finalises the privacy information for
5473 // `use` directives.
5476 fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
5477 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5478 visit::walk_crate(&mut visitor, krate, ());
5481 fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {
5482 // Ignore is_public import statements because there's no way to be sure
5483 // whether they're used or not. Also ignore imports with a dummy span
5484 // because this means that they were generated in some fashion by the
5485 // compiler and we don't need to consider them.
5486 if vi.vis == Public { return }
5487 if vi.span == DUMMY_SP { return }
5490 ViewItemExternCrate(..) => {} // ignore
5491 ViewItemUse(ref p) => {
5493 ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
5494 ViewPathList(_, ref list, _) => {
5495 for i in list.iter() {
5496 self.finalize_import(i.node.id, i.span);
5499 ViewPathGlob(_, id) => {
5500 if !self.used_imports.contains(&(id, TypeNS)) &&
5501 !self.used_imports.contains(&(id, ValueNS)) {
5503 .add_lint(lint::builtin::UNUSED_IMPORTS,
5506 "unused import".to_string());
5514 // We have information about whether `use` (import) directives are actually used now.
5515 // If an import is not used at all, we signal a lint error. If an import is only used
5516 // for a single namespace, we remove the other namespace from the recorded privacy
5517 // information. That means in privacy.rs, we will only check imports and namespaces
5518 // which are used. In particular, this means that if an import could name either a
5519 // public or private item, we will check the correct thing, dependent on how the import
5521 fn finalize_import(&mut self, id: NodeId, span: Span) {
5522 debug!("finalizing import uses for {}",
5523 self.session.codemap().span_to_snippet(span));
5525 if !self.used_imports.contains(&(id, TypeNS)) &&
5526 !self.used_imports.contains(&(id, ValueNS)) {
5527 self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
5530 "unused import".to_string());
5533 let (v_priv, t_priv) = match self.last_private.find(&id) {
5541 fail!("we should only have LastImport for `use` directives")
5546 let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
5551 let t_used = if self.used_imports.contains(&(id, TypeNS)) {
5557 match (v_priv, t_priv) {
5558 // Since some items may be both in the value _and_ type namespaces (e.g., structs)
5559 // we might have two LastPrivates pointing at the same thing. There is no point
5560 // checking both, so lets not check the value one.
5561 (Some(DependsOn(def_v)), Some(DependsOn(def_t))) if def_v == def_t => v_used = Unused,
5565 self.last_private.insert(id, LastImport{value_priv: v_priv,
5568 type_used: t_used});
5574 // Diagnostics are not particularly efficient, because they're rarely
5578 /// A somewhat inefficient routine to obtain the name of a module.
5579 fn module_to_string(&self, module: &Module) -> String {
5580 let mut idents = Vec::new();
5582 fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
5583 match module.parent_link {
5585 ModuleParentLink(ref module, name) => {
5587 collect_mod(idents, &*module.upgrade().unwrap());
5589 BlockParentLink(ref module, _) => {
5590 // danger, shouldn't be ident?
5591 idents.push(special_idents::opaque);
5592 collect_mod(idents, &*module.upgrade().unwrap());
5596 collect_mod(&mut idents, module);
5598 if idents.len() == 0 {
5599 return "???".to_string();
5601 self.idents_to_string(idents.move_iter().rev()
5602 .collect::<Vec<ast::Ident>>()
5606 #[allow(dead_code)] // useful for debugging
5607 fn dump_module(&mut self, module_: Rc<Module>) {
5608 debug!("Dump of module `{}`:", self.module_to_string(&*module_));
5610 debug!("Children:");
5611 self.populate_module_if_necessary(&module_);
5612 for (&name, _) in module_.children.borrow().iter() {
5613 debug!("* {}", token::get_name(name));
5616 debug!("Import resolutions:");
5617 let import_resolutions = module_.import_resolutions.borrow();
5618 for (&name, import_resolution) in import_resolutions.iter() {
5620 match import_resolution.target_for_namespace(ValueNS) {
5621 None => { value_repr = "".to_string(); }
5623 value_repr = " value:?".to_string();
5629 match import_resolution.target_for_namespace(TypeNS) {
5630 None => { type_repr = "".to_string(); }
5632 type_repr = " type:?".to_string();
5637 debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
5642 pub struct CrateMap {
5643 pub def_map: DefMap,
5644 pub exp_map2: ExportMap2,
5645 pub trait_map: TraitMap,
5646 pub external_exports: ExternalExports,
5647 pub last_private_map: LastPrivateMap,
5650 /// Entry point to crate resolution.
5651 pub fn resolve_crate(session: &Session,
5655 let mut resolver = Resolver::new(session, krate.span);
5656 resolver.resolve(krate);
5657 let Resolver { def_map, export_map2, trait_map, last_private,
5658 external_exports, .. } = resolver;
5661 exp_map2: export_map2,
5662 trait_map: trait_map,
5663 external_exports: external_exports,
5664 last_private_map: last_private,