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.
12 use driver::session::Session;
13 use metadata::csearch;
14 use metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
15 use middle::lang_items::LanguageItems;
16 use middle::lint::{UnnecessaryQualification, UnusedImports};
17 use middle::pat_util::pat_bindings;
21 use syntax::ast_util::{def_id_of_def, local_def, mtwt_resolve};
22 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
23 use syntax::parse::token;
24 use syntax::parse::token::{IdentInterner, interner_get};
25 use syntax::parse::token::special_idents;
26 use syntax::print::pprust::path_to_str;
27 use syntax::codemap::{Span, DUMMY_SP, Pos};
28 use syntax::opt_vec::OptVec;
30 use syntax::visit::Visitor;
32 use std::cell::{Cell, RefCell};
34 use std::hashmap::{HashMap, HashSet};
38 pub type DefMap = @RefCell<HashMap<NodeId,Def>>;
42 binding_mode: BindingMode,
45 // Map from the name in a pattern to its binding mode.
46 type BindingMap = HashMap<Name,binding_info>;
48 // Trait method resolution
49 pub type TraitMap = HashMap<NodeId,@RefCell<~[DefId]>>;
51 // This is the replacement export map. It maps a module to all of the exports
53 pub type ExportMap2 = @RefCell<HashMap<NodeId, ~[Export2]>>;
56 name: @str, // The name of the target.
57 def_id: DefId, // The definition of the target.
60 // This set contains all exported definitions from external crates. The set does
61 // not contain any entries from local crates.
62 pub type ExternalExports = HashSet<DefId>;
65 pub type LastPrivateMap = HashMap<NodeId, LastPrivate>;
67 pub enum LastPrivate {
73 fn or(self, other: LastPrivate) -> LastPrivate {
75 (me, AllPublic) => me,
82 enum PatternBindingMode {
85 ArgumentIrrefutableMode,
102 /// A NamespaceResult represents the result of resolving an import in
103 /// a particular namespace. The result is either definitely-resolved,
104 /// definitely- unresolved, or unknown.
105 enum NamespaceResult {
106 /// Means that resolve hasn't gathered enough information yet to determine
107 /// whether the name is bound in this namespace. (That is, it hasn't
108 /// resolved all `use` directives yet.)
110 /// Means that resolve has determined that the name is definitely
111 /// not bound in the namespace.
113 /// Means that resolve has determined that the name is bound in the Module
114 /// argument, and specified by the NameBindings argument.
115 BoundResult(@Module, @NameBindings)
118 impl NamespaceResult {
119 fn is_unknown(&self) -> bool {
121 UnknownResult => true,
127 enum NameDefinition {
128 NoNameDefinition, //< The name was unbound.
129 ChildNameDefinition(Def, LastPrivate), //< The name identifies an immediate child.
130 ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
133 impl Visitor<()> for Resolver {
134 fn visit_item(&mut self, item: &Item, _: ()) {
135 self.resolve_item(item);
137 fn visit_arm(&mut self, arm: &Arm, _: ()) {
138 self.resolve_arm(arm);
140 fn visit_block(&mut self, block: &Block, _: ()) {
141 self.resolve_block(block);
143 fn visit_expr(&mut self, expr: &Expr, _: ()) {
144 self.resolve_expr(expr);
146 fn visit_local(&mut self, local: &Local, _: ()) {
147 self.resolve_local(local);
149 fn visit_ty(&mut self, ty: &Ty, _: ()) {
150 self.resolve_type(ty);
154 /// Contains data for specific types of import directives.
155 enum ImportDirectiveSubclass {
156 SingleImport(Ident /* target */, Ident /* source */),
160 /// The context that we thread through while building the reduced graph.
162 enum ReducedGraphParent {
163 ModuleReducedGraphParent(@Module)
166 impl ReducedGraphParent {
167 fn module(&self) -> @Module {
169 ModuleReducedGraphParent(m) => {
176 enum ResolveResult<T> {
177 Failed, // Failed to resolve the name.
178 Indeterminate, // Couldn't determine due to unresolved globs.
179 Success(T) // Successfully resolved the import.
182 impl<T> ResolveResult<T> {
183 fn indeterminate(&self) -> bool {
184 match *self { Indeterminate => true, _ => false }
188 enum TypeParameters<'a> {
189 NoTypeParameters, //< No type parameters.
190 HasTypeParameters(&'a Generics, //< Type parameters.
191 NodeId, //< ID of the enclosing item
193 // The index to start numbering the type parameters at.
194 // This is zero if this is the outermost set of type
195 // parameters, or equal to the number of outer type
196 // parameters. For example, if we have:
199 // fn method<U>() { ... }
202 // The index at the method site will be 1, because the
203 // outer T had index 0.
206 // The kind of the rib used for type parameters.
210 // The rib kind controls the translation of argument or local definitions
211 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
214 // No translation needs to be applied.
217 // We passed through a function scope at the given node ID. Translate
218 // upvars as appropriate.
219 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
221 // We passed through an impl or trait and are now in one of its
222 // methods. Allow references to ty params that impl or trait
223 // binds. Disallow any other upvars (including other ty params that are
225 // parent; method itself
226 MethodRibKind(NodeId, MethodSort),
228 // We passed through a function *item* scope. Disallow upvars.
229 OpaqueFunctionRibKind,
231 // We're in a constant item. Can't refer to dynamic stuff.
235 // Methods can be required or provided. Required methods only occur in traits.
241 enum UseLexicalScopeFlag {
246 enum SearchThroughModulesFlag {
247 DontSearchThroughModules,
251 enum ModulePrefixResult {
253 PrefixFound(@Module, uint)
257 enum NameSearchType {
258 /// We're doing a name search in order to resolve a `use` directive.
261 /// We're doing a name search in order to resolve a path type, a path
262 /// expression, or a path pattern.
266 enum BareIdentifierPatternResolution {
267 FoundStructOrEnumVariant(Def, LastPrivate),
268 FoundConst(Def, LastPrivate),
269 BareIdentifierPatternUnresolved
272 // Specifies how duplicates should be handled when adding a child item if
273 // another item exists with the same name in some namespace.
275 enum DuplicateCheckingMode {
276 ForbidDuplicateModules,
277 ForbidDuplicateTypes,
278 ForbidDuplicateValues,
279 ForbidDuplicateTypesAndValues,
285 bindings: RefCell<HashMap<Name, DefLike>>,
290 fn new(kind: RibKind) -> Rib {
292 bindings: RefCell::new(HashMap::new()),
298 /// One import directive.
299 struct ImportDirective {
300 module_path: ~[Ident],
301 subclass: @ImportDirectiveSubclass,
304 is_public: bool, // see note in ImportResolution about how to use this
307 impl ImportDirective {
308 fn new(module_path: ~[Ident],
309 subclass: @ImportDirectiveSubclass,
315 module_path: module_path,
319 is_public: is_public,
324 /// The item that an import resolves to.
327 target_module: @Module,
328 bindings: @NameBindings,
332 fn new(target_module: @Module, bindings: @NameBindings) -> Target {
334 target_module: target_module,
340 /// An ImportResolution represents a particular `use` directive.
341 struct ImportResolution {
342 /// Whether this resolution came from a `use` or a `pub use`. Note that this
343 /// should *not* be used whenever resolution is being performed, this is
344 /// only looked at for glob imports statements currently. Privacy testing
345 /// occurs during a later phase of compilation.
346 is_public: Cell<bool>,
348 // The number of outstanding references to this name. When this reaches
349 // zero, outside modules can count on the targets being correct. Before
350 // then, all bets are off; future imports could override this name.
351 outstanding_references: Cell<uint>,
353 /// The value that this `use` directive names, if there is one.
354 value_target: RefCell<Option<Target>>,
355 /// The source node of the `use` directive leading to the value target
357 value_id: Cell<NodeId>,
359 /// The type that this `use` directive names, if there is one.
360 type_target: RefCell<Option<Target>>,
361 /// The source node of the `use` directive leading to the type target
363 type_id: Cell<NodeId>,
366 impl ImportResolution {
367 fn new(id: NodeId, is_public: bool) -> ImportResolution {
369 type_id: Cell::new(id),
370 value_id: Cell::new(id),
371 outstanding_references: Cell::new(0),
372 value_target: RefCell::new(None),
373 type_target: RefCell::new(None),
374 is_public: Cell::new(is_public),
378 fn target_for_namespace(&self, namespace: Namespace)
381 TypeNS => return self.type_target.get(),
382 ValueNS => return self.value_target.get(),
386 fn id(&self, namespace: Namespace) -> NodeId {
388 TypeNS => self.type_id.get(),
389 ValueNS => self.value_id.get(),
394 /// The link from a module up to its nearest parent node.
397 ModuleParentLink(@Module, Ident),
398 BlockParentLink(@Module, NodeId)
401 /// The type of module this is.
411 /// One node in the tree of modules.
413 parent_link: ParentLink,
414 def_id: Cell<Option<DefId>>,
415 kind: Cell<ModuleKind>,
418 children: RefCell<HashMap<Name, @NameBindings>>,
419 imports: RefCell<~[@ImportDirective]>,
421 // The external module children of this node that were declared with
423 external_module_children: RefCell<HashMap<Name, @Module>>,
425 // The anonymous children of this node. Anonymous children are pseudo-
426 // modules that are implicitly created around items contained within
429 // For example, if we have this:
437 // There will be an anonymous module created around `g` with the ID of the
438 // entry block for `f`.
439 anonymous_children: RefCell<HashMap<NodeId,@Module>>,
441 // The status of resolving each import in this module.
442 import_resolutions: RefCell<HashMap<Name, @ImportResolution>>,
444 // The number of unresolved globs that this module exports.
445 glob_count: Cell<uint>,
447 // The index of the import we're resolving.
448 resolved_import_count: Cell<uint>,
450 // Whether this module is populated. If not populated, any attempt to
451 // access the children must be preceded with a
452 // `populate_module_if_necessary` call.
453 populated: Cell<bool>,
457 fn new(parent_link: ParentLink,
458 def_id: Option<DefId>,
464 parent_link: parent_link,
465 def_id: Cell::new(def_id),
466 kind: Cell::new(kind),
467 is_public: is_public,
468 children: RefCell::new(HashMap::new()),
469 imports: RefCell::new(~[]),
470 external_module_children: RefCell::new(HashMap::new()),
471 anonymous_children: RefCell::new(HashMap::new()),
472 import_resolutions: RefCell::new(HashMap::new()),
473 glob_count: Cell::new(0),
474 resolved_import_count: Cell::new(0),
475 populated: Cell::new(!external),
479 fn all_imports_resolved(&self) -> bool {
480 let mut imports = self.imports.borrow_mut();
481 return imports.get().len() == self.resolved_import_count.get();
485 // Records a possibly-private type definition.
488 is_public: bool, // see note in ImportResolution about how to use this
489 module_def: Option<@Module>,
490 type_def: Option<Def>,
491 type_span: Option<Span>
494 // Records a possibly-private value definition.
497 is_public: bool, // see note in ImportResolution about how to use this
499 value_span: Option<Span>,
502 // Records the definitions (at most one for each namespace) that a name is
504 struct NameBindings {
505 type_def: RefCell<Option<TypeNsDef>>, //< Meaning in type namespace.
506 value_def: RefCell<Option<ValueNsDef>>, //< Meaning in value namespace.
509 /// Ways in which a trait can be referenced
510 enum TraitReferenceType {
511 TraitImplementation, // impl SomeTrait for T { ... }
512 TraitDerivation, // trait T : SomeTrait { ... }
513 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
517 /// Creates a new module in this set of name bindings.
518 fn define_module(&self,
519 parent_link: ParentLink,
520 def_id: Option<DefId>,
525 // Merges the module with the existing type def or creates a new one.
526 let module_ = @Module::new(parent_link, def_id, kind, external,
528 match self.type_def.get() {
530 self.type_def.set(Some(TypeNsDef {
531 is_public: is_public,
532 module_def: Some(module_),
538 self.type_def.set(Some(TypeNsDef {
539 is_public: is_public,
540 module_def: Some(module_),
542 type_def: type_def.type_def
548 /// Sets the kind of the module, creating a new one if necessary.
549 fn set_module_kind(&self,
550 parent_link: ParentLink,
551 def_id: Option<DefId>,
556 match self.type_def.get() {
558 let module = @Module::new(parent_link, def_id, kind,
559 external, is_public);
560 self.type_def.set(Some(TypeNsDef {
561 is_public: is_public,
562 module_def: Some(module),
568 match type_def.module_def {
570 let module = @Module::new(parent_link,
575 self.type_def.set(Some(TypeNsDef {
576 is_public: is_public,
577 module_def: Some(module),
578 type_def: type_def.type_def,
582 Some(module_def) => module_def.kind.set(kind),
588 /// Records a type definition.
589 fn define_type(&self, def: Def, sp: Span, is_public: bool) {
590 // Merges the type with the existing type def or creates a new one.
591 match self.type_def.get() {
593 self.type_def.set(Some(TypeNsDef {
597 is_public: is_public,
601 self.type_def.set(Some(TypeNsDef {
604 module_def: type_def.module_def,
605 is_public: is_public,
611 /// Records a value definition.
612 fn define_value(&self, def: Def, sp: Span, is_public: bool) {
613 self.value_def.set(Some(ValueNsDef {
615 value_span: Some(sp),
616 is_public: is_public,
620 /// Returns the module node if applicable.
621 fn get_module_if_available(&self) -> Option<@Module> {
622 let type_def = self.type_def.borrow();
623 match *type_def.get() {
624 Some(ref type_def) => (*type_def).module_def,
630 * Returns the module node. Fails if this node does not have a module
633 fn get_module(&self) -> @Module {
634 match self.get_module_if_available() {
636 fail!("get_module called on a node with no module \
639 Some(module_def) => module_def
643 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
645 TypeNS => return self.type_def.get().is_some(),
646 ValueNS => return self.value_def.get().is_some()
650 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
652 TypeNS => match self.type_def.get() {
653 Some(def) => def.is_public, None => false
655 ValueNS => match self.value_def.get() {
656 Some(def) => def.is_public, None => false
661 fn def_for_namespace(&self, namespace: Namespace) -> Option<Def> {
664 match self.type_def.get() {
667 match type_def.type_def {
668 Some(type_def) => Some(type_def),
670 match type_def.module_def {
672 match module.def_id.get() {
673 Some(did) => Some(DefMod(did)),
685 match self.value_def.get() {
687 Some(value_def) => Some(value_def.def)
693 fn span_for_namespace(&self, namespace: Namespace) -> Option<Span> {
694 if self.defined_in_namespace(namespace) {
697 match self.type_def.get() {
699 Some(type_def) => type_def.type_span
703 match self.value_def.get() {
705 Some(value_def) => value_def.value_span
715 fn NameBindings() -> NameBindings {
717 type_def: RefCell::new(None),
718 value_def: RefCell::new(None),
722 /// Interns the names of the primitive types.
723 struct PrimitiveTypeTable {
724 primitive_types: HashMap<Name, PrimTy>,
727 impl PrimitiveTypeTable {
728 fn intern(&mut self, string: &str, primitive_type: PrimTy) {
729 self.primitive_types.insert(token::intern(string), primitive_type);
733 fn PrimitiveTypeTable() -> PrimitiveTypeTable {
734 let mut table = PrimitiveTypeTable {
735 primitive_types: HashMap::new()
738 table.intern("bool", TyBool);
739 table.intern("char", TyChar);
740 table.intern("f32", TyFloat(TyF32));
741 table.intern("f64", TyFloat(TyF64));
742 table.intern("int", TyInt(TyI));
743 table.intern("i8", TyInt(TyI8));
744 table.intern("i16", TyInt(TyI16));
745 table.intern("i32", TyInt(TyI32));
746 table.intern("i64", TyInt(TyI64));
747 table.intern("str", TyStr);
748 table.intern("uint", TyUint(TyU));
749 table.intern("u8", TyUint(TyU8));
750 table.intern("u16", TyUint(TyU16));
751 table.intern("u32", TyUint(TyU32));
752 table.intern("u64", TyUint(TyU64));
758 fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
761 ModuleError => "module",
763 ValueError => "value",
767 fn Resolver(session: Session,
768 lang_items: @LanguageItems,
769 crate_span: Span) -> Resolver {
770 let graph_root = @NameBindings();
772 graph_root.define_module(NoParentLink,
773 Some(DefId { crate: 0, node: 0 }),
779 let current_module = graph_root.get_module();
781 let this = Resolver {
783 lang_items: lang_items,
785 // The outermost module has def ID 0; this is not reflected in the
788 graph_root: graph_root,
790 method_map: @RefCell::new(HashMap::new()),
791 structs: HashSet::new(),
793 unresolved_imports: 0,
795 current_module: current_module,
796 value_ribs: @RefCell::new(~[]),
797 type_ribs: @RefCell::new(~[]),
798 label_ribs: @RefCell::new(~[]),
800 current_trait_refs: None,
802 self_ident: special_idents::self_,
803 type_self_ident: special_idents::type_self,
805 primitive_type_table: @PrimitiveTypeTable(),
807 namespaces: ~[ TypeNS, ValueNS ],
809 def_map: @RefCell::new(HashMap::new()),
810 export_map2: @RefCell::new(HashMap::new()),
811 trait_map: HashMap::new(),
812 used_imports: HashSet::new(),
813 external_exports: HashSet::new(),
814 last_private: HashMap::new(),
823 /// The main resolver class.
826 lang_items: @LanguageItems,
828 intr: @IdentInterner,
830 graph_root: @NameBindings,
832 method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
833 structs: HashSet<DefId>,
835 // The number of imports that are currently unresolved.
836 unresolved_imports: uint,
838 // The module that represents the current item scope.
839 current_module: @Module,
841 // The current set of local scopes, for values.
842 // FIXME #4948: Reuse ribs to avoid allocation.
843 value_ribs: @RefCell<~[@Rib]>,
845 // The current set of local scopes, for types.
846 type_ribs: @RefCell<~[@Rib]>,
848 // The current set of local scopes, for labels.
849 label_ribs: @RefCell<~[@Rib]>,
851 // The trait that the current context can refer to.
852 current_trait_refs: Option<~[DefId]>,
854 // The ident for the keyword "self".
856 // The ident for the non-keyword "Self".
857 type_self_ident: Ident,
859 // The idents for the primitive types.
860 primitive_type_table: @PrimitiveTypeTable,
862 // The four namespaces.
863 namespaces: ~[Namespace],
866 export_map2: ExportMap2,
868 external_exports: ExternalExports,
869 last_private: LastPrivateMap,
871 // Whether or not to print error messages. Can be set to true
872 // when getting additional info for error message suggestions,
873 // so as to avoid printing duplicate errors
876 used_imports: HashSet<NodeId>,
879 struct BuildReducedGraphVisitor<'a> {
880 resolver: &'a mut Resolver,
883 impl<'a> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a> {
885 fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
886 let p = self.resolver.build_reduced_graph_for_item(item, context);
887 visit::walk_item(self, item, p);
890 fn visit_foreign_item(&mut self, foreign_item: &ForeignItem,
891 context: ReducedGraphParent) {
892 self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
895 let mut v = BuildReducedGraphVisitor{ resolver: r };
896 visit::walk_foreign_item(&mut v, foreign_item, c);
900 fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
901 self.resolver.build_reduced_graph_for_view_item(view_item, context);
904 fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
905 let np = self.resolver.build_reduced_graph_for_block(block, context);
906 visit::walk_block(self, block, np);
911 struct UnusedImportCheckVisitor<'a> { resolver: &'a Resolver }
913 impl<'a> Visitor<()> for UnusedImportCheckVisitor<'a> {
914 fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
915 self.resolver.check_for_item_unused_imports(vi);
916 visit::walk_view_item(self, vi, ());
921 /// The main name resolution procedure.
922 fn resolve(&mut self, crate: &ast::Crate) {
923 self.build_reduced_graph(crate);
924 self.session.abort_if_errors();
926 self.resolve_imports();
927 self.session.abort_if_errors();
929 self.record_exports();
930 self.session.abort_if_errors();
932 self.resolve_crate(crate);
933 self.session.abort_if_errors();
935 self.check_for_unused_imports(crate);
939 // Reduced graph building
941 // Here we build the "reduced graph": the graph of the module tree without
942 // any imports resolved.
945 /// Constructs the reduced graph for the entire crate.
946 fn build_reduced_graph(&mut self, crate: &ast::Crate) {
948 ModuleReducedGraphParent(self.graph_root.get_module());
950 let mut visitor = BuildReducedGraphVisitor { resolver: self, };
951 visit::walk_crate(&mut visitor, crate, initial_parent);
954 /// Returns the current module tracked by the reduced graph parent.
955 fn get_module_from_parent(&mut self,
956 reduced_graph_parent: ReducedGraphParent)
958 match reduced_graph_parent {
959 ModuleReducedGraphParent(module_) => {
966 * Adds a new child item to the module definition of the parent node and
967 * returns its corresponding name bindings as well as the current parent.
968 * Or, if we're inside a block, creates (or reuses) an anonymous module
969 * corresponding to the innermost block ID and returns the name bindings
970 * as well as the newly-created parent.
972 * If this node does not have a module definition and we are not inside
975 fn add_child(&mut self,
977 reduced_graph_parent: ReducedGraphParent,
978 duplicate_checking_mode: DuplicateCheckingMode,
979 // For printing errors
981 -> (@NameBindings, ReducedGraphParent) {
982 // If this is the immediate descendant of a module, then we add the
983 // child name directly. Otherwise, we create or reuse an anonymous
984 // module and add the child to that.
987 match reduced_graph_parent {
988 ModuleReducedGraphParent(parent_module) => {
989 module_ = parent_module;
993 // Add or reuse the child.
994 let new_parent = ModuleReducedGraphParent(module_);
996 let children = module_.children.borrow();
997 children.get().find_copy(&name.name)
1001 let child = @NameBindings();
1002 let mut children = module_.children.borrow_mut();
1003 children.get().insert(name.name, child);
1004 return (child, new_parent);
1007 // Enforce the duplicate checking mode:
1009 // * If we're requesting duplicate module checking, check that
1010 // there isn't a module in the module with the same name.
1012 // * If we're requesting duplicate type checking, check that
1013 // there isn't a type in the module with the same name.
1015 // * If we're requesting duplicate value checking, check that
1016 // there isn't a value in the module with the same name.
1018 // * If we're requesting duplicate type checking and duplicate
1019 // value checking, check that there isn't a duplicate type
1020 // and a duplicate value with the same name.
1022 // * If no duplicate checking was requested at all, do
1025 let mut duplicate_type = NoError;
1026 let ns = match duplicate_checking_mode {
1027 ForbidDuplicateModules => {
1028 if child.get_module_if_available().is_some() {
1029 duplicate_type = ModuleError;
1033 ForbidDuplicateTypes => {
1034 match child.def_for_namespace(TypeNS) {
1035 Some(DefMod(_)) | None => {}
1036 Some(_) => duplicate_type = TypeError
1040 ForbidDuplicateValues => {
1041 if child.defined_in_namespace(ValueNS) {
1042 duplicate_type = ValueError;
1046 ForbidDuplicateTypesAndValues => {
1048 match child.def_for_namespace(TypeNS) {
1049 Some(DefMod(_)) | None => {}
1052 duplicate_type = TypeError;
1055 if child.defined_in_namespace(ValueNS) {
1056 duplicate_type = ValueError;
1061 OverwriteDuplicates => None
1063 if duplicate_type != NoError {
1064 // Return an error here by looking up the namespace that
1065 // had the duplicate.
1066 let ns = ns.unwrap();
1067 self.resolve_error(sp,
1068 format!("duplicate definition of {} `{}`",
1069 namespace_error_to_str(duplicate_type),
1070 self.session.str_of(name)));
1072 let r = child.span_for_namespace(ns);
1073 for sp in r.iter() {
1074 self.session.span_note(*sp,
1075 format!("first definition of {} `{}` here",
1076 namespace_error_to_str(duplicate_type),
1077 self.session.str_of(name)));
1081 return (child, new_parent);
1086 fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
1087 // If the block has view items, we need an anonymous module.
1088 if block.view_items.len() > 0 {
1092 // Check each statement.
1093 for statement in block.stmts.iter() {
1094 match statement.node {
1095 StmtDecl(declaration, _) => {
1096 match declaration.node {
1111 // If we found neither view items nor items, we don't need to create
1112 // an anonymous module.
1117 fn get_parent_link(&mut self, parent: ReducedGraphParent, name: Ident)
1120 ModuleReducedGraphParent(module_) => {
1121 return ModuleParentLink(module_, name);
1126 /// Constructs the reduced graph for one item.
1127 fn build_reduced_graph_for_item(&mut self,
1129 parent: ReducedGraphParent)
1130 -> ReducedGraphParent
1132 let ident = item.ident;
1134 let is_public = item.vis == ast::Public;
1138 let (name_bindings, new_parent) =
1139 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1141 let parent_link = self.get_parent_link(new_parent, ident);
1142 let def_id = DefId { crate: 0, node: item.id };
1143 name_bindings.define_module(parent_link,
1147 item.vis == ast::Public,
1150 ModuleReducedGraphParent(name_bindings.get_module())
1153 ItemForeignMod(..) => parent,
1155 // These items live in the value namespace.
1156 ItemStatic(_, m, _) => {
1157 let (name_bindings, _) =
1158 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1159 let mutbl = m == ast::MutMutable;
1161 name_bindings.define_value
1162 (DefStatic(local_def(item.id), mutbl), sp, is_public);
1165 ItemFn(_, purity, _, _, _) => {
1166 let (name_bindings, new_parent) =
1167 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1169 let def = DefFn(local_def(item.id), purity);
1170 name_bindings.define_value(def, sp, is_public);
1174 // These items live in the type namespace.
1176 let (name_bindings, _) =
1177 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1179 name_bindings.define_type
1180 (DefTy(local_def(item.id)), sp, is_public);
1184 ItemEnum(ref enum_definition, _) => {
1185 let (name_bindings, new_parent) =
1186 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1188 name_bindings.define_type
1189 (DefTy(local_def(item.id)), sp, is_public);
1191 for &variant in (*enum_definition).variants.iter() {
1192 self.build_reduced_graph_for_variant(
1201 // These items live in both the type and value namespaces.
1202 ItemStruct(struct_def, _) => {
1203 // Adding to both Type and Value namespaces or just Type?
1204 let (forbid, ctor_id) = match struct_def.ctor_id {
1205 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1206 None => (ForbidDuplicateTypes, None)
1209 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1211 // Define a name in the type namespace.
1212 name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
1214 // If this is a newtype or unit-like struct, define a name
1215 // in the value namespace as well
1216 ctor_id.while_some(|cid| {
1217 name_bindings.define_value(DefStruct(local_def(cid)), sp,
1222 // Record the def ID of this struct.
1223 self.structs.insert(local_def(item.id));
1228 ItemImpl(_, None, ty, ref methods) => {
1229 // If this implements an anonymous trait, then add all the
1230 // methods within to a new module, if the type was defined
1231 // within this module.
1233 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1234 // should modify anonymous traits to only be implementable in
1235 // the same module that declared the type.
1237 // Create the module and add all methods.
1239 TyPath(ref path, _, _) if path.segments.len() == 1 => {
1240 let name = path_to_ident(path);
1242 let existing_parent_opt = {
1243 let children = parent.module().children.borrow();
1244 children.get().find_copy(&name.name)
1246 let new_parent = match existing_parent_opt {
1247 // It already exists
1248 Some(child) if child.get_module_if_available()
1250 child.get_module().kind.get() ==
1252 ModuleReducedGraphParent(child.get_module())
1254 // Create the module
1256 let (name_bindings, new_parent) =
1257 self.add_child(name,
1259 ForbidDuplicateModules,
1263 self.get_parent_link(new_parent, ident);
1264 let def_id = local_def(item.id);
1267 !name_bindings.defined_in_namespace(ns) ||
1268 name_bindings.defined_in_public_namespace(ns);
1270 name_bindings.define_module(parent_link,
1277 ModuleReducedGraphParent(
1278 name_bindings.get_module())
1282 // For each method...
1283 for method in methods.iter() {
1284 // Add the method to the module.
1285 let ident = method.ident;
1286 let (method_name_bindings, _) =
1287 self.add_child(ident,
1289 ForbidDuplicateValues,
1291 let def = match method.explicit_self.node {
1293 // Static methods become
1294 // `def_static_method`s.
1295 DefStaticMethod(local_def(method.id),
1301 // Non-static methods become
1303 DefMethod(local_def(method.id), None)
1307 let is_public = method.vis == ast::Public;
1308 method_name_bindings.define_value(def,
1319 ItemImpl(_, Some(_), _, _) => parent,
1321 ItemTrait(_, _, ref methods) => {
1322 let (name_bindings, new_parent) =
1323 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1325 // Add all the methods within to a new module.
1326 let parent_link = self.get_parent_link(parent, ident);
1327 name_bindings.define_module(parent_link,
1328 Some(local_def(item.id)),
1331 item.vis == ast::Public,
1333 let module_parent = ModuleReducedGraphParent(name_bindings.
1336 // Add the names of all the methods to the trait info.
1337 let mut method_names = HashMap::new();
1338 for method in methods.iter() {
1339 let ty_m = trait_method_to_ty_method(method);
1341 let ident = ty_m.ident;
1343 // Add it as a name in the trait module.
1344 let def = match ty_m.explicit_self.node {
1346 // Static methods become `def_static_method`s.
1347 DefStaticMethod(local_def(ty_m.id),
1348 FromTrait(local_def(item.id)),
1352 // Non-static methods become `def_method`s.
1353 DefMethod(local_def(ty_m.id),
1354 Some(local_def(item.id)))
1358 let (method_name_bindings, _) =
1359 self.add_child(ident,
1361 ForbidDuplicateValues,
1363 method_name_bindings.define_value(def, ty_m.span, true);
1365 // Add it to the trait info if not static.
1366 match ty_m.explicit_self.node {
1369 method_names.insert(ident.name, ());
1374 let def_id = local_def(item.id);
1375 for (name, _) in method_names.iter() {
1376 let mut method_map = self.method_map.borrow_mut();
1377 if !method_map.get().contains_key(name) {
1378 method_map.get().insert(*name, HashSet::new());
1380 match method_map.get().find_mut(name) {
1381 Some(s) => { s.insert(def_id); },
1382 _ => fail!("Can't happen"),
1386 name_bindings.define_type(DefTrait(def_id), sp, is_public);
1389 ItemMac(..) => parent
1393 // Constructs the reduced graph for one variant. Variants exist in the
1394 // type and/or value namespaces.
1395 fn build_reduced_graph_for_variant(&mut self,
1398 parent: ReducedGraphParent,
1399 parent_public: bool) {
1400 let ident = variant.node.name;
1401 // FIXME: this is unfortunate to have to do this privacy calculation
1402 // here. This should be living in middle::privacy, but it's
1403 // necessary to keep around in some form becaues of glob imports...
1404 let is_public = parent_public && variant.node.vis != ast::Private;
1406 match variant.node.kind {
1407 TupleVariantKind(_) => {
1408 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1410 child.define_value(DefVariant(item_id,
1411 local_def(variant.node.id), false),
1412 variant.span, is_public);
1414 StructVariantKind(_) => {
1415 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1417 child.define_type(DefVariant(item_id,
1418 local_def(variant.node.id), true),
1419 variant.span, is_public);
1420 self.structs.insert(local_def(variant.node.id));
1425 /// Constructs the reduced graph for one 'view item'. View items consist
1426 /// of imports and use directives.
1427 fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem,
1428 parent: ReducedGraphParent) {
1429 match view_item.node {
1430 ViewItemUse(ref view_paths) => {
1431 for view_path in view_paths.iter() {
1432 // Extract and intern the module part of the path. For
1433 // globs and lists, the path is found directly in the AST;
1434 // for simple paths we have to munge the path a little.
1436 let mut module_path = ~[];
1437 match view_path.node {
1438 ViewPathSimple(_, ref full_path, _) => {
1439 let path_len = full_path.segments.len();
1440 assert!(path_len != 0);
1442 for (i, segment) in full_path.segments
1445 if i != path_len - 1 {
1446 module_path.push(segment.identifier)
1451 ViewPathGlob(ref module_ident_path, _) |
1452 ViewPathList(ref module_ident_path, _, _) => {
1453 for segment in module_ident_path.segments.iter() {
1454 module_path.push(segment.identifier)
1459 // Build up the import directives.
1460 let module_ = self.get_module_from_parent(parent);
1461 let is_public = view_item.vis == ast::Public;
1462 match view_path.node {
1463 ViewPathSimple(binding, ref full_path, id) => {
1465 full_path.segments.last().unwrap().identifier;
1466 let subclass = @SingleImport(binding,
1468 self.build_import_directive(module_,
1475 ViewPathList(_, ref source_idents, _) => {
1476 for source_ident in source_idents.iter() {
1477 let name = source_ident.node.name;
1478 let subclass = @SingleImport(name, name);
1479 self.build_import_directive(
1481 module_path.clone(),
1484 source_ident.node.id,
1488 ViewPathGlob(_, id) => {
1489 self.build_import_directive(module_,
1500 ViewItemExternMod(name, _, node_id) => {
1501 // n.b. we don't need to look at the path option here, because cstore already did
1502 match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
1504 let def_id = DefId { crate: crate_id, node: 0 };
1505 self.external_exports.insert(def_id);
1506 let parent_link = ModuleParentLink
1507 (self.get_module_from_parent(parent), name);
1508 let external_module = @Module::new(parent_link,
1515 let mut external_module_children =
1516 parent.module().external_module_children.borrow_mut();
1517 external_module_children.get().insert(
1522 self.build_reduced_graph_for_external_crate(
1525 None => {} // Ignore.
1531 /// Constructs the reduced graph for one foreign item.
1532 fn build_reduced_graph_for_foreign_item(&mut self,
1533 foreign_item: &ForeignItem,
1534 parent: ReducedGraphParent,
1536 ReducedGraphParent|) {
1537 let name = foreign_item.ident;
1538 let is_public = foreign_item.vis == ast::Public;
1539 let (name_bindings, new_parent) =
1540 self.add_child(name, parent, ForbidDuplicateValues,
1543 match foreign_item.node {
1544 ForeignItemFn(_, ref generics) => {
1545 let def = DefFn(local_def(foreign_item.id), UnsafeFn);
1546 name_bindings.define_value(def, foreign_item.span, is_public);
1548 self.with_type_parameter_rib(
1549 HasTypeParameters(generics,
1553 |this| f(this, new_parent));
1555 ForeignItemStatic(_, m) => {
1556 let def = DefStatic(local_def(foreign_item.id), m);
1557 name_bindings.define_value(def, foreign_item.span, is_public);
1564 fn build_reduced_graph_for_block(&mut self,
1566 parent: ReducedGraphParent)
1567 -> ReducedGraphParent
1569 if self.block_needs_anonymous_module(block) {
1570 let block_id = block.id;
1572 debug!("(building reduced graph for block) creating a new \
1573 anonymous module for block {}",
1576 let parent_module = self.get_module_from_parent(parent);
1577 let new_module = @Module::new(
1578 BlockParentLink(parent_module, block_id),
1580 AnonymousModuleKind,
1584 let mut anonymous_children = parent_module.anonymous_children
1586 anonymous_children.get().insert(block_id, new_module);
1587 ModuleReducedGraphParent(new_module)
1594 fn handle_external_def(&mut self,
1597 child_name_bindings: @NameBindings,
1600 new_parent: ReducedGraphParent) {
1601 debug!("(building reduced graph for \
1602 external crate) building external def, priv {:?}",
1604 let is_public = vis == ast::Public;
1605 let is_exported = is_public && match new_parent {
1606 ModuleReducedGraphParent(module) => {
1607 match module.def_id.get() {
1609 Some(did) => self.external_exports.contains(&did)
1614 self.external_exports.insert(def_id_of_def(def));
1617 DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
1619 match child_name_bindings.type_def.get() {
1620 Some(TypeNsDef { module_def: Some(module_def), .. }) => {
1621 debug!("(building reduced graph for external crate) \
1622 already created module");
1623 module_def.def_id.set(Some(def_id));
1626 debug!("(building reduced graph for \
1627 external crate) building module \
1629 let parent_link = self.get_parent_link(new_parent, ident);
1631 child_name_bindings.define_module(parent_link,
1644 DefMod(_) | DefForeignMod(_) => {}
1645 DefVariant(_, variant_id, is_struct) => {
1646 debug!("(building reduced graph for external crate) building \
1649 // We assume the parent is visible, or else we wouldn't have seen
1650 // it. Also variants are public-by-default if the parent was also
1652 let is_public = vis != ast::Private;
1654 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1655 self.structs.insert(variant_id);
1657 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1660 DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
1661 debug!("(building reduced graph for external \
1662 crate) building value (fn/static) {}", final_ident);
1663 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1665 DefTrait(def_id) => {
1666 debug!("(building reduced graph for external \
1667 crate) building type {}", final_ident);
1669 // If this is a trait, add all the method names
1670 // to the trait info.
1672 let method_def_ids =
1673 csearch::get_trait_method_def_ids(self.session.cstore, def_id);
1674 let mut interned_method_names = HashSet::new();
1675 for &method_def_id in method_def_ids.iter() {
1676 let (method_name, explicit_self) =
1677 csearch::get_method_name_and_explicit_self(self.session.cstore,
1680 debug!("(building reduced graph for \
1681 external crate) ... adding \
1683 self.session.str_of(method_name));
1685 // Add it to the trait info if not static.
1686 if explicit_self != SelfStatic {
1687 interned_method_names.insert(method_name.name);
1690 self.external_exports.insert(method_def_id);
1693 for name in interned_method_names.iter() {
1694 let mut method_map = self.method_map.borrow_mut();
1695 if !method_map.get().contains_key(name) {
1696 method_map.get().insert(*name, HashSet::new());
1698 match method_map.get().find_mut(name) {
1699 Some(s) => { s.insert(def_id); },
1700 _ => fail!("Can't happen"),
1704 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1706 // Define a module if necessary.
1707 let parent_link = self.get_parent_link(new_parent, ident);
1708 child_name_bindings.set_module_kind(parent_link,
1716 debug!("(building reduced graph for external \
1717 crate) building type {}", final_ident);
1719 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1721 DefStruct(def_id) => {
1722 debug!("(building reduced graph for external \
1723 crate) building type and value for {}",
1725 child_name_bindings.define_type(def, DUMMY_SP, is_public);
1726 if csearch::get_struct_fields(self.session.cstore, def_id).len() == 0 {
1727 child_name_bindings.define_value(def, DUMMY_SP, is_public);
1729 self.structs.insert(def_id);
1732 debug!("(building reduced graph for external crate) \
1733 ignoring {:?}", def);
1734 // Ignored; handled elsewhere.
1736 DefArg(..) | DefLocal(..) | DefPrimTy(..) |
1737 DefTyParam(..) | DefBinding(..) |
1738 DefUse(..) | DefUpvar(..) | DefRegion(..) |
1739 DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
1740 fail!("didn't expect `{:?}`", def);
1745 /// Builds the reduced graph for a single item in an external crate.
1746 fn build_reduced_graph_for_external_crate_def(&mut self,
1750 visibility: Visibility) {
1753 // Add the new child item, if necessary.
1755 DefForeignMod(def_id) => {
1756 // Foreign modules have no names. Recur and populate
1758 csearch::each_child_of_item(self.session.cstore,
1763 self.build_reduced_graph_for_external_crate_def(
1771 let (child_name_bindings, new_parent) =
1772 self.add_child(ident,
1773 ModuleReducedGraphParent(root),
1774 OverwriteDuplicates,
1777 self.handle_external_def(def,
1779 child_name_bindings,
1780 self.session.str_of(ident),
1787 // We only process static methods of impls here.
1788 match csearch::get_type_name_if_impl(self.session.cstore, def) {
1790 Some(final_ident) => {
1791 let static_methods_opt =
1792 csearch::get_static_methods_if_impl(self.session.cstore, def);
1793 match static_methods_opt {
1794 Some(ref static_methods) if
1795 static_methods.len() >= 1 => {
1796 debug!("(building reduced graph for \
1797 external crate) processing \
1798 static methods for type name {}",
1799 self.session.str_of(
1802 let (child_name_bindings, new_parent) =
1805 ModuleReducedGraphParent(root),
1806 OverwriteDuplicates,
1809 // Process the static methods. First,
1810 // create the module.
1812 match child_name_bindings.type_def.get() {
1814 module_def: Some(module_def),
1817 // We already have a module. This
1819 type_module = module_def;
1821 // Mark it as an impl module if
1823 type_module.kind.set(ImplModuleKind);
1827 self.get_parent_link(new_parent,
1829 child_name_bindings.define_module(
1837 child_name_bindings.
1842 // Add each static method to the module.
1844 ModuleReducedGraphParent(type_module);
1845 for static_method_info in
1846 static_methods.iter() {
1847 let ident = static_method_info.ident;
1848 debug!("(building reduced graph for \
1849 external crate) creating \
1850 static method '{}'",
1851 self.session.str_of(ident));
1853 let (method_name_bindings, _) =
1854 self.add_child(ident,
1856 OverwriteDuplicates,
1859 static_method_info.def_id,
1860 static_method_info.purity);
1862 method_name_bindings.define_value(
1864 visibility == ast::Public);
1868 // Otherwise, do nothing.
1869 Some(_) | None => {}
1875 debug!("(building reduced graph for external crate) \
1881 /// Builds the reduced graph rooted at the given external module.
1882 fn populate_external_module(&mut self, module: @Module) {
1883 debug!("(populating external module) attempting to populate {}",
1884 self.module_to_str(module));
1886 let def_id = match module.def_id.get() {
1888 debug!("(populating external module) ... no def ID!");
1891 Some(def_id) => def_id,
1894 csearch::each_child_of_item(self.session.cstore,
1896 |def_like, child_ident, visibility| {
1897 debug!("(populating external module) ... found ident: {}",
1898 token::ident_to_str(&child_ident));
1899 self.build_reduced_graph_for_external_crate_def(module,
1904 module.populated.set(true)
1907 /// Ensures that the reduced graph rooted at the given external module
1908 /// is built, building it if it is not.
1909 fn populate_module_if_necessary(&mut self, module: @Module) {
1910 if !module.populated.get() {
1911 self.populate_external_module(module)
1913 assert!(module.populated.get())
1916 /// Builds the reduced graph rooted at the 'use' directive for an external
1918 fn build_reduced_graph_for_external_crate(&mut self,
1920 csearch::each_top_level_item_of_crate(self.session.cstore,
1925 |def_like, ident, visibility| {
1926 self.build_reduced_graph_for_external_crate_def(root,
1933 /// Creates and adds an import directive to the given module.
1934 fn build_import_directive(&mut self,
1936 module_path: ~[Ident],
1937 subclass: @ImportDirectiveSubclass,
1941 let directive = @ImportDirective::new(module_path,
1946 let mut imports = module_.imports.borrow_mut();
1947 imports.get().push(directive);
1950 // Bump the reference count on the name. Or, if this is a glob, set
1951 // the appropriate flag.
1954 SingleImport(target, _) => {
1955 debug!("(building import directive) building import \
1957 self.idents_to_str(directive.module_path),
1958 self.session.str_of(target));
1960 let mut import_resolutions = module_.import_resolutions
1962 match import_resolutions.get().find(&target.name) {
1963 Some(&resolution) => {
1964 debug!("(building import directive) bumping \
1966 resolution.outstanding_references.set(
1967 resolution.outstanding_references.get() + 1);
1969 // the source of this name is different now
1970 resolution.type_id.set(id);
1971 resolution.value_id.set(id);
1974 debug!("(building import directive) creating new");
1975 let resolution = @ImportResolution::new(id, is_public);
1976 resolution.outstanding_references.set(1);
1977 import_resolutions.get().insert(target.name,
1983 // Set the glob flag. This tells us that we don't know the
1984 // module's exports ahead of time.
1986 module_.glob_count.set(module_.glob_count.get() + 1);
1990 self.unresolved_imports += 1;
1993 // Import resolution
1995 // This is a fixed-point algorithm. We resolve imports until our efforts
1996 // are stymied by an unresolved import; then we bail out of the current
1997 // module and continue. We terminate successfully once no more imports
1998 // remain or unsuccessfully when no forward progress in resolving imports
2001 /// Resolves all imports for the crate. This method performs the fixed-
2002 /// point iteration.
2003 fn resolve_imports(&mut self) {
2005 let mut prev_unresolved_imports = 0;
2007 debug!("(resolving imports) iteration {}, {} imports left",
2008 i, self.unresolved_imports);
2010 let module_root = self.graph_root.get_module();
2011 self.resolve_imports_for_module_subtree(module_root);
2013 if self.unresolved_imports == 0 {
2014 debug!("(resolving imports) success");
2018 if self.unresolved_imports == prev_unresolved_imports {
2019 self.report_unresolved_imports(module_root);
2024 prev_unresolved_imports = self.unresolved_imports;
2028 /// Attempts to resolve imports for the given module and all of its
2030 fn resolve_imports_for_module_subtree(&mut self,
2032 debug!("(resolving imports for module subtree) resolving {}",
2033 self.module_to_str(module_));
2034 self.resolve_imports_for_module(module_);
2036 self.populate_module_if_necessary(module_);
2038 let children = module_.children.borrow();
2039 for (_, &child_node) in children.get().iter() {
2040 match child_node.get_module_if_available() {
2044 Some(child_module) => {
2045 self.resolve_imports_for_module_subtree(child_module);
2051 let anonymous_children = module_.anonymous_children.borrow();
2052 for (_, &child_module) in anonymous_children.get().iter() {
2053 self.resolve_imports_for_module_subtree(child_module);
2057 /// Attempts to resolve imports for the given module only.
2058 fn resolve_imports_for_module(&mut self, module: @Module) {
2059 if module.all_imports_resolved() {
2060 debug!("(resolving imports for module) all imports resolved for \
2062 self.module_to_str(module));
2066 let mut imports = module.imports.borrow_mut();
2067 let import_count = imports.get().len();
2068 while module.resolved_import_count.get() < import_count {
2069 let import_index = module.resolved_import_count.get();
2070 let import_directive = imports.get()[import_index];
2071 match self.resolve_import_for_module(module, import_directive) {
2073 // We presumably emitted an error. Continue.
2074 let msg = format!("failed to resolve import `{}`",
2075 self.import_path_to_str(
2076 import_directive.module_path,
2077 *import_directive.subclass));
2078 self.resolve_error(import_directive.span, msg);
2081 // Bail out. We'll come around next time.
2089 module.resolved_import_count
2090 .set(module.resolved_import_count.get() + 1);
2094 fn idents_to_str(&mut self, idents: &[Ident]) -> ~str {
2095 let mut first = true;
2096 let mut result = ~"";
2097 for ident in idents.iter() {
2101 result.push_str("::")
2103 result.push_str(self.session.str_of(*ident));
2108 fn path_idents_to_str(&mut self, path: &Path) -> ~str {
2109 let identifiers: ~[ast::Ident] = path.segments
2111 .map(|seg| seg.identifier)
2113 self.idents_to_str(identifiers)
2116 fn import_directive_subclass_to_str(&mut self,
2117 subclass: ImportDirectiveSubclass)
2120 SingleImport(_target, source) => self.session.str_of(source),
2125 fn import_path_to_str(&mut self,
2127 subclass: ImportDirectiveSubclass)
2129 if idents.is_empty() {
2130 self.import_directive_subclass_to_str(subclass)
2133 self.idents_to_str(idents),
2134 self.import_directive_subclass_to_str(subclass))).to_managed()
2138 /// Attempts to resolve the given import. The return value indicates
2139 /// failure if we're certain the name does not exist, indeterminate if we
2140 /// don't know whether the name exists at the moment due to other
2141 /// currently-unresolved imports, or success if we know the name exists.
2142 /// If successful, the resolved bindings are written into the module.
2143 fn resolve_import_for_module(&mut self,
2145 import_directive: @ImportDirective)
2146 -> ResolveResult<()> {
2147 let mut resolution_result = Failed;
2148 let module_path = &import_directive.module_path;
2150 debug!("(resolving import for module) resolving import `{}::...` in \
2152 self.idents_to_str(*module_path),
2153 self.module_to_str(module_));
2155 // First, resolve the module path for the directive, if necessary.
2156 let container = if module_path.len() == 0 {
2157 // Use the crate root.
2158 Some((self.graph_root.get_module(), AllPublic))
2160 match self.resolve_module_path(module_,
2162 DontUseLexicalScope,
2163 import_directive.span,
2168 resolution_result = Indeterminate;
2171 Success(container) => Some(container),
2177 Some((containing_module, lp)) => {
2178 // We found the module that the target is contained
2179 // within. Attempt to resolve the import within it.
2181 match *import_directive.subclass {
2182 SingleImport(target, source) => {
2184 self.resolve_single_import(module_,
2193 self.resolve_glob_import(module_,
2195 import_directive.id,
2196 import_directive.is_public,
2203 // Decrement the count of unresolved imports.
2204 match resolution_result {
2206 assert!(self.unresolved_imports >= 1);
2207 self.unresolved_imports -= 1;
2210 // Nothing to do here; just return the error.
2214 // Decrement the count of unresolved globs if necessary. But only if
2215 // the resolution result is indeterminate -- otherwise we'll stop
2216 // processing imports here. (See the loop in
2217 // resolve_imports_for_module.)
2219 if !resolution_result.indeterminate() {
2220 match *import_directive.subclass {
2222 assert!(module_.glob_count.get() >= 1);
2223 module_.glob_count.set(module_.glob_count.get() - 1);
2225 SingleImport(..) => {
2231 return resolution_result;
2234 fn create_name_bindings_from_module(module: @Module) -> NameBindings {
2236 type_def: RefCell::new(Some(TypeNsDef {
2238 module_def: Some(module),
2242 value_def: RefCell::new(None),
2246 fn resolve_single_import(&mut self,
2248 containing_module: @Module,
2251 directive: &ImportDirective,
2253 -> ResolveResult<()> {
2254 debug!("(resolving single import) resolving `{}` = `{}::{}` from \
2255 `{}` id {}, last private {:?}",
2256 self.session.str_of(target),
2257 self.module_to_str(containing_module),
2258 self.session.str_of(source),
2259 self.module_to_str(module_),
2263 // We need to resolve both namespaces for this to succeed.
2266 let mut value_result = UnknownResult;
2267 let mut type_result = UnknownResult;
2269 // Search for direct children of the containing module.
2270 self.populate_module_if_necessary(containing_module);
2273 let children = containing_module.children.borrow();
2274 match children.get().find(&source.name) {
2278 Some(child_name_bindings) => {
2279 if child_name_bindings.defined_in_namespace(ValueNS) {
2280 value_result = BoundResult(containing_module,
2281 *child_name_bindings);
2283 if child_name_bindings.defined_in_namespace(TypeNS) {
2284 type_result = BoundResult(containing_module,
2285 *child_name_bindings);
2291 // Unless we managed to find a result in both namespaces (unlikely),
2292 // search imports as well.
2293 let mut used_reexport = false;
2294 match (value_result, type_result) {
2295 (BoundResult(..), BoundResult(..)) => {} // Continue.
2297 // If there is an unresolved glob at this point in the
2298 // containing module, bail out. We don't know enough to be
2299 // able to resolve this import.
2301 if containing_module.glob_count.get() > 0 {
2302 debug!("(resolving single import) unresolved glob; \
2304 return Indeterminate;
2307 // Now search the exported imports within the containing
2310 let import_resolutions = containing_module.import_resolutions
2312 match import_resolutions.get().find(&source.name) {
2314 // The containing module definitely doesn't have an
2315 // exported import with the name in question. We can
2316 // therefore accurately report that the names are
2319 if value_result.is_unknown() {
2320 value_result = UnboundResult;
2322 if type_result.is_unknown() {
2323 type_result = UnboundResult;
2326 Some(import_resolution)
2327 if import_resolution.outstanding_references.get()
2330 fn get_binding(this: &mut Resolver,
2331 import_resolution: @ImportResolution,
2332 namespace: Namespace)
2333 -> NamespaceResult {
2335 // Import resolutions must be declared with "pub"
2336 // in order to be exported.
2337 if !import_resolution.is_public.get() {
2338 return UnboundResult;
2341 match (*import_resolution).
2342 target_for_namespace(namespace) {
2344 return UnboundResult;
2347 let id = import_resolution.id(namespace);
2348 this.used_imports.insert(id);
2349 return BoundResult(target.target_module,
2355 // The name is an import which has been fully
2356 // resolved. We can, therefore, just follow it.
2357 if value_result.is_unknown() {
2358 value_result = get_binding(self, *import_resolution,
2360 used_reexport = import_resolution.is_public.get();
2362 if type_result.is_unknown() {
2363 type_result = get_binding(self, *import_resolution,
2365 used_reexport = import_resolution.is_public.get();
2370 // The import is unresolved. Bail out.
2371 debug!("(resolving single import) unresolved import; \
2373 return Indeterminate;
2379 // If we didn't find a result in the type namespace, search the
2380 // external modules.
2381 let mut used_public = false;
2383 BoundResult(..) => {}
2386 let mut external_module_children =
2387 containing_module.external_module_children
2389 external_module_children.get().find_copy(&source.name)
2392 None => {} // Continue.
2395 @Resolver::create_name_bindings_from_module(
2397 type_result = BoundResult(containing_module,
2405 // We've successfully resolved the import. Write the results in.
2406 let import_resolution = {
2407 let import_resolutions = module_.import_resolutions.borrow();
2408 assert!(import_resolutions.get().contains_key(&target.name));
2409 import_resolutions.get().get_copy(&target.name)
2412 match value_result {
2413 BoundResult(target_module, name_bindings) => {
2414 debug!("(resolving single import) found value target");
2415 import_resolution.value_target.set(
2416 Some(Target::new(target_module, name_bindings)));
2417 import_resolution.value_id.set(directive.id);
2418 used_public = name_bindings.defined_in_public_namespace(ValueNS);
2420 UnboundResult => { /* Continue. */ }
2422 fail!("value result should be known at this point");
2426 BoundResult(target_module, name_bindings) => {
2427 debug!("(resolving single import) found type target: {:?}",
2428 {name_bindings.type_def.get().unwrap().type_def});
2429 import_resolution.type_target.set(
2430 Some(Target::new(target_module, name_bindings)));
2431 import_resolution.type_id.set(directive.id);
2432 used_public = name_bindings.defined_in_public_namespace(TypeNS);
2434 UnboundResult => { /* Continue. */ }
2436 fail!("type result should be known at this point");
2440 if import_resolution.value_target.get().is_none() &&
2441 import_resolution.type_target.get().is_none() {
2442 let msg = format!("unresolved import: there is no \
2444 self.session.str_of(source),
2445 self.module_to_str(containing_module));
2446 self.resolve_error(directive.span, msg);
2449 let used_public = used_reexport || used_public;
2451 assert!(import_resolution.outstanding_references.get() >= 1);
2452 import_resolution.outstanding_references.set(
2453 import_resolution.outstanding_references.get() - 1);
2455 // record what this import resolves to for later uses in documentation,
2456 // this may resolve to either a value or a type, but for documentation
2457 // purposes it's good enough to just favor one over the other.
2458 match import_resolution.value_target.get() {
2460 let def = target.bindings.def_for_namespace(ValueNS).unwrap();
2461 let mut def_map = self.def_map.borrow_mut();
2462 def_map.get().insert(directive.id, def);
2463 let did = def_id_of_def(def);
2464 self.last_private.insert(directive.id,
2465 if used_public {lp} else {DependsOn(did)});
2469 match import_resolution.type_target.get() {
2471 let def = target.bindings.def_for_namespace(TypeNS).unwrap();
2472 let mut def_map = self.def_map.borrow_mut();
2473 def_map.get().insert(directive.id, def);
2474 let did = def_id_of_def(def);
2475 self.last_private.insert(directive.id,
2476 if used_public {lp} else {DependsOn(did)});
2481 debug!("(resolving single import) successfully resolved import");
2485 // Resolves a glob import. Note that this function cannot fail; it either
2486 // succeeds or bails out (as importing * from an empty module or a module
2487 // that exports nothing is valid).
2488 fn resolve_glob_import(&mut self,
2490 containing_module: @Module,
2494 -> ResolveResult<()> {
2495 // This function works in a highly imperative manner; it eagerly adds
2496 // everything it can to the list of import resolutions of the module
2498 debug!("(resolving glob import) resolving glob import {}", id);
2500 // We must bail out if the node has unresolved imports of any kind
2501 // (including globs).
2502 if !(*containing_module).all_imports_resolved() {
2503 debug!("(resolving glob import) target module has unresolved \
2504 imports; bailing out");
2505 return Indeterminate;
2508 assert_eq!(containing_module.glob_count.get(), 0);
2510 // Add all resolved imports from the containing module.
2511 let import_resolutions = containing_module.import_resolutions
2513 for (ident, target_import_resolution) in import_resolutions.get()
2515 debug!("(resolving glob import) writing module resolution \
2517 target_import_resolution.type_target.get().is_none(),
2518 self.module_to_str(module_));
2520 if !target_import_resolution.is_public.get() {
2521 debug!("(resolving glob import) nevermind, just kidding");
2525 // Here we merge two import resolutions.
2526 let mut import_resolutions = module_.import_resolutions
2528 match import_resolutions.get().find(ident) {
2530 // Simple: just copy the old import resolution.
2531 let new_import_resolution =
2532 @ImportResolution::new(id, is_public);
2533 new_import_resolution.value_target.set(
2534 target_import_resolution.value_target.get());
2535 new_import_resolution.type_target.set(
2536 target_import_resolution.type_target.get());
2538 import_resolutions.get().insert
2539 (*ident, new_import_resolution);
2541 Some(&dest_import_resolution) => {
2542 // Merge the two import resolutions at a finer-grained
2545 match target_import_resolution.value_target.get() {
2549 Some(value_target) => {
2550 dest_import_resolution.value_target.set(
2551 Some(value_target));
2554 match target_import_resolution.type_target.get() {
2558 Some(type_target) => {
2559 dest_import_resolution.type_target.set(
2563 dest_import_resolution.is_public.set(is_public);
2568 let merge_import_resolution = |name, name_bindings: @NameBindings| {
2569 let dest_import_resolution;
2570 let mut import_resolutions = module_.import_resolutions
2572 match import_resolutions.get().find(&name) {
2574 // Create a new import resolution from this child.
2575 dest_import_resolution =
2576 @ImportResolution::new(id, is_public);
2577 import_resolutions.get().insert(name,
2578 dest_import_resolution);
2580 Some(&existing_import_resolution) => {
2581 dest_import_resolution = existing_import_resolution;
2585 debug!("(resolving glob import) writing resolution `{}` in `{}` \
2588 self.module_to_str(containing_module),
2589 self.module_to_str(module_));
2591 // Merge the child item into the import resolution.
2592 if name_bindings.defined_in_public_namespace(ValueNS) {
2593 debug!("(resolving glob import) ... for value target");
2594 dest_import_resolution.value_target.set(
2595 Some(Target::new(containing_module, name_bindings)));
2596 dest_import_resolution.value_id.set(id);
2598 if name_bindings.defined_in_public_namespace(TypeNS) {
2599 debug!("(resolving glob import) ... for type target");
2600 dest_import_resolution.type_target.set(
2601 Some(Target::new(containing_module, name_bindings)));
2602 dest_import_resolution.type_id.set(id);
2604 dest_import_resolution.is_public.set(is_public);
2607 // Add all children from the containing module.
2608 self.populate_module_if_necessary(containing_module);
2611 let children = containing_module.children.borrow();
2612 for (&name, name_bindings) in children.get().iter() {
2613 merge_import_resolution(name, *name_bindings);
2617 // Add external module children from the containing module.
2619 let external_module_children =
2620 containing_module.external_module_children.borrow();
2621 for (&name, module) in external_module_children.get().iter() {
2623 @Resolver::create_name_bindings_from_module(*module);
2624 merge_import_resolution(name, name_bindings);
2628 // Record the destination of this import
2629 match containing_module.def_id.get() {
2631 let mut def_map = self.def_map.borrow_mut();
2632 def_map.get().insert(id, DefMod(did));
2633 self.last_private.insert(id, lp);
2638 debug!("(resolving glob import) successfully resolved import");
2642 /// Resolves the given module path from the given root `module_`.
2643 fn resolve_module_path_from_root(&mut self,
2645 module_path: &[Ident],
2648 name_search_type: NameSearchType,
2650 -> ResolveResult<(@Module, LastPrivate)> {
2651 let mut search_module = module_;
2652 let mut index = index;
2653 let module_path_len = module_path.len();
2654 let mut closest_private = lp;
2656 // Resolve the module part of the path. This does not involve looking
2657 // upward though scope chains; we simply resolve names directly in
2658 // modules as we go.
2659 while index < module_path_len {
2660 let name = module_path[index];
2661 match self.resolve_name_in_module(search_module,
2666 let segment_name = self.session.str_of(name);
2667 let module_name = self.module_to_str(search_module);
2668 if "???" == module_name {
2671 hi: span.lo + Pos::from_uint(segment_name.len()),
2672 expn_info: span.expn_info,
2674 self.resolve_error(span,
2675 format!("unresolved import. maybe \
2676 a missing `extern mod \
2681 self.resolve_error(span, format!("unresolved import: could not find `{}` in \
2682 `{}`.", segment_name, module_name));
2686 debug!("(resolving module path for import) module \
2687 resolution is indeterminate: {}",
2688 self.session.str_of(name));
2689 return Indeterminate;
2691 Success((target, used_proxy)) => {
2692 // Check to see whether there are type bindings, and, if
2693 // so, whether there is a module within.
2694 match target.bindings.type_def.get() {
2696 match type_def.module_def {
2699 self.resolve_error(span,
2707 Some(module_def) => {
2708 // If we're doing the search for an
2709 // import, do not allow traits and impls
2711 match (name_search_type,
2712 module_def.kind.get()) {
2713 (ImportSearch, TraitModuleKind) |
2714 (ImportSearch, ImplModuleKind) => {
2717 "cannot import from a trait \
2718 or type implementation");
2722 search_module = module_def;
2724 // Keep track of the closest
2725 // private module used when
2726 // resolving this import chain.
2728 !search_module.is_public {
2729 match search_module.def_id
2744 // There are no type bindings at all.
2745 self.resolve_error(span,
2746 format!("not a module `{}`",
2747 self.session.str_of(
2758 return Success((search_module, closest_private));
2761 /// Attempts to resolve the module part of an import directive or path
2762 /// rooted at the given module.
2764 /// On success, returns the resolved module, and the closest *private*
2765 /// module found to the destination when resolving this path.
2766 fn resolve_module_path(&mut self,
2768 module_path: &[Ident],
2769 use_lexical_scope: UseLexicalScopeFlag,
2771 name_search_type: NameSearchType)
2772 -> ResolveResult<(@Module, LastPrivate)> {
2773 let module_path_len = module_path.len();
2774 assert!(module_path_len > 0);
2776 debug!("(resolving module path for import) processing `{}` rooted at \
2778 self.idents_to_str(module_path),
2779 self.module_to_str(module_));
2781 // Resolve the module prefix, if any.
2782 let module_prefix_result = self.resolve_module_prefix(module_,
2788 match module_prefix_result {
2790 let mpath = self.idents_to_str(module_path);
2791 match mpath.rfind(':') {
2793 self.resolve_error(span, format!("unresolved import: could not find `{}` \
2795 // idx +- 1 to account for the colons
2797 mpath.slice_from(idx + 1),
2798 mpath.slice_to(idx - 1)));
2805 debug!("(resolving module path for import) indeterminate; \
2807 return Indeterminate;
2809 Success(NoPrefixFound) => {
2810 // There was no prefix, so we're considering the first element
2811 // of the path. How we handle this depends on whether we were
2812 // instructed to use lexical scope or not.
2813 match use_lexical_scope {
2814 DontUseLexicalScope => {
2815 // This is a crate-relative path. We will start the
2816 // resolution process at index zero.
2817 search_module = self.graph_root.get_module();
2819 last_private = AllPublic;
2821 UseLexicalScope => {
2822 // This is not a crate-relative path. We resolve the
2823 // first component of the path in the current lexical
2824 // scope and then proceed to resolve below that.
2825 let result = self.resolve_module_in_lexical_scope(
2830 self.resolve_error(span, "unresolved name");
2834 debug!("(resolving module path for import) \
2835 indeterminate; bailing");
2836 return Indeterminate;
2838 Success(containing_module) => {
2839 search_module = containing_module;
2841 last_private = AllPublic;
2847 Success(PrefixFound(containing_module, index)) => {
2848 search_module = containing_module;
2849 start_index = index;
2850 last_private = DependsOn(containing_module.def_id
2856 self.resolve_module_path_from_root(search_module,
2864 /// Invariant: This must only be called during main resolution, not during
2865 /// import resolution.
2866 fn resolve_item_in_lexical_scope(&mut self,
2869 namespace: Namespace,
2870 search_through_modules:
2871 SearchThroughModulesFlag)
2872 -> ResolveResult<(Target, bool)> {
2873 debug!("(resolving item in lexical scope) resolving `{}` in \
2874 namespace {:?} in `{}`",
2875 self.session.str_of(name),
2877 self.module_to_str(module_));
2879 // The current module node is handled specially. First, check for
2880 // its immediate children.
2881 self.populate_module_if_necessary(module_);
2884 let children = module_.children.borrow();
2885 match children.get().find(&name.name) {
2887 if name_bindings.defined_in_namespace(namespace) => {
2888 debug!("top name bindings succeeded");
2889 return Success((Target::new(module_, *name_bindings),
2892 Some(_) | None => { /* Not found; continue. */ }
2896 // Now check for its import directives. We don't have to have resolved
2897 // all its imports in the usual way; this is because chains of
2898 // adjacent import statements are processed as though they mutated the
2900 let import_resolutions = module_.import_resolutions.borrow();
2901 match import_resolutions.get().find(&name.name) {
2903 // Not found; continue.
2905 Some(import_resolution) => {
2906 match (*import_resolution).target_for_namespace(namespace) {
2908 // Not found; continue.
2909 debug!("(resolving item in lexical scope) found \
2910 import resolution, but not in namespace {:?}",
2914 debug!("(resolving item in lexical scope) using \
2915 import resolution");
2916 self.used_imports.insert(import_resolution.id(namespace));
2917 return Success((target, false));
2923 // Search for external modules.
2924 if namespace == TypeNS {
2926 let external_module_children =
2927 module_.external_module_children.borrow();
2928 external_module_children.get().find_copy(&name.name)
2934 @Resolver::create_name_bindings_from_module(module);
2935 debug!("lower name bindings succeeded");
2936 return Success((Target::new(module_, name_bindings), false));
2941 // Finally, proceed up the scope chain looking for parent modules.
2942 let mut search_module = module_;
2944 // Go to the next parent.
2945 match search_module.parent_link {
2947 // No more parents. This module was unresolved.
2948 debug!("(resolving item in lexical scope) unresolved \
2952 ModuleParentLink(parent_module_node, _) => {
2953 match search_through_modules {
2954 DontSearchThroughModules => {
2955 match search_module.kind.get() {
2956 NormalModuleKind => {
2957 // We stop the search here.
2958 debug!("(resolving item in lexical \
2959 scope) unresolved module: not \
2960 searching through module \
2967 AnonymousModuleKind => {
2968 search_module = parent_module_node;
2972 SearchThroughModules => {
2973 search_module = parent_module_node;
2977 BlockParentLink(parent_module_node, _) => {
2978 search_module = parent_module_node;
2982 // Resolve the name in the parent module.
2983 match self.resolve_name_in_module(search_module,
2988 // Continue up the search chain.
2991 // We couldn't see through the higher scope because of an
2992 // unresolved import higher up. Bail.
2994 debug!("(resolving item in lexical scope) indeterminate \
2995 higher scope; bailing");
2996 return Indeterminate;
2998 Success((target, used_reexport)) => {
2999 // We found the module.
3000 debug!("(resolving item in lexical scope) found name \
3002 return Success((target, used_reexport));
3008 /// Resolves a module name in the current lexical scope.
3009 fn resolve_module_in_lexical_scope(&mut self,
3012 -> ResolveResult<@Module> {
3013 // If this module is an anonymous module, resolve the item in the
3014 // lexical scope. Otherwise, resolve the item from the crate root.
3015 let resolve_result = self.resolve_item_in_lexical_scope(
3016 module_, name, TypeNS, DontSearchThroughModules);
3017 match resolve_result {
3018 Success((target, _)) => {
3019 let bindings = &*target.bindings;
3020 match bindings.type_def.get() {
3022 match type_def.module_def {
3024 error!("!!! (resolving module in lexical \
3025 scope) module wasn't actually a \
3029 Some(module_def) => {
3030 return Success(module_def);
3035 error!("!!! (resolving module in lexical scope) module
3036 wasn't actually a module!");
3042 debug!("(resolving module in lexical scope) indeterminate; \
3044 return Indeterminate;
3047 debug!("(resolving module in lexical scope) failed to \
3054 /// Returns the nearest normal module parent of the given module.
3055 fn get_nearest_normal_module_parent(&mut self, module_: @Module)
3056 -> Option<@Module> {
3057 let mut module_ = module_;
3059 match module_.parent_link {
3060 NoParentLink => return None,
3061 ModuleParentLink(new_module, _) |
3062 BlockParentLink(new_module, _) => {
3063 match new_module.kind.get() {
3064 NormalModuleKind => return Some(new_module),
3068 AnonymousModuleKind => module_ = new_module,
3075 /// Returns the nearest normal module parent of the given module, or the
3076 /// module itself if it is a normal module.
3077 fn get_nearest_normal_module_parent_or_self(&mut self, module_: @Module)
3079 match module_.kind.get() {
3080 NormalModuleKind => return module_,
3084 AnonymousModuleKind => {
3085 match self.get_nearest_normal_module_parent(module_) {
3087 Some(new_module) => new_module
3093 /// Resolves a "module prefix". A module prefix is one or both of (a) `self::`;
3094 /// (b) some chain of `super::`.
3095 /// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
3096 fn resolve_module_prefix(&mut self,
3098 module_path: &[Ident])
3099 -> ResolveResult<ModulePrefixResult> {
3100 // Start at the current module if we see `self` or `super`, or at the
3101 // top of the crate otherwise.
3102 let mut containing_module;
3104 if "self" == token::ident_to_str(&module_path[0]) {
3106 self.get_nearest_normal_module_parent_or_self(module_);
3108 } else if "super" == token::ident_to_str(&module_path[0]) {
3110 self.get_nearest_normal_module_parent_or_self(module_);
3111 i = 0; // We'll handle `super` below.
3113 return Success(NoPrefixFound);
3116 // Now loop through all the `super`s we find.
3117 while i < module_path.len() &&
3118 "super" == token::ident_to_str(&module_path[i]) {
3119 debug!("(resolving module prefix) resolving `super` at {}",
3120 self.module_to_str(containing_module));
3121 match self.get_nearest_normal_module_parent(containing_module) {
3122 None => return Failed,
3123 Some(new_module) => {
3124 containing_module = new_module;
3130 debug!("(resolving module prefix) finished resolving prefix at {}",
3131 self.module_to_str(containing_module));
3133 return Success(PrefixFound(containing_module, i));
3136 /// Attempts to resolve the supplied name in the given module for the
3137 /// given namespace. If successful, returns the target corresponding to
3140 /// The boolean returned on success is an indicator of whether this lookup
3141 /// passed through a public re-export proxy.
3142 fn resolve_name_in_module(&mut self,
3145 namespace: Namespace,
3146 name_search_type: NameSearchType)
3147 -> ResolveResult<(Target, bool)> {
3148 debug!("(resolving name in module) resolving `{}` in `{}`",
3149 self.session.str_of(name),
3150 self.module_to_str(module_));
3152 // First, check the direct children of the module.
3153 self.populate_module_if_necessary(module_);
3156 let children = module_.children.borrow();
3157 match children.get().find(&name.name) {
3159 if name_bindings.defined_in_namespace(namespace) => {
3160 debug!("(resolving name in module) found node as child");
3161 return Success((Target::new(module_, *name_bindings),
3170 // Next, check the module's imports if necessary.
3172 // If this is a search of all imports, we should be done with glob
3173 // resolution at this point.
3174 if name_search_type == PathSearch {
3175 assert_eq!(module_.glob_count.get(), 0);
3178 // Check the list of resolved imports.
3179 let import_resolutions = module_.import_resolutions.borrow();
3180 match import_resolutions.get().find(&name.name) {
3181 Some(import_resolution) => {
3182 if import_resolution.is_public.get() &&
3183 import_resolution.outstanding_references.get() != 0 {
3184 debug!("(resolving name in module) import \
3185 unresolved; bailing out");
3186 return Indeterminate;
3188 match import_resolution.target_for_namespace(namespace) {
3190 debug!("(resolving name in module) name found, \
3191 but not in namespace {:?}",
3195 debug!("(resolving name in module) resolved to \
3197 self.used_imports.insert(import_resolution.id(namespace));
3198 return Success((target, true));
3202 None => {} // Continue.
3205 // Finally, search through external children.
3206 if namespace == TypeNS {
3208 let external_module_children =
3209 module_.external_module_children.borrow();
3210 external_module_children.get().find_copy(&name.name)
3216 @Resolver::create_name_bindings_from_module(module);
3217 return Success((Target::new(module_, name_bindings), false));
3222 // We're out of luck.
3223 debug!("(resolving name in module) failed to resolve `{}`",
3224 self.session.str_of(name));
3228 fn report_unresolved_imports(&mut self, module_: @Module) {
3229 let index = module_.resolved_import_count.get();
3230 let mut imports = module_.imports.borrow_mut();
3231 let import_count = imports.get().len();
3232 if index != import_count {
3233 let sn = self.session
3235 .span_to_snippet(imports.get()[index].span)
3237 if sn.contains("::") {
3238 self.resolve_error(imports.get()[index].span,
3239 "unresolved import");
3241 let err = format!("unresolved import (maybe you meant `{}::*`?)",
3242 sn.slice(0, sn.len()));
3243 self.resolve_error(imports.get()[index].span, err);
3247 // Descend into children and anonymous children.
3248 self.populate_module_if_necessary(module_);
3251 let children = module_.children.borrow();
3252 for (_, &child_node) in children.get().iter() {
3253 match child_node.get_module_if_available() {
3257 Some(child_module) => {
3258 self.report_unresolved_imports(child_module);
3264 let anonymous_children = module_.anonymous_children.borrow();
3265 for (_, &module_) in anonymous_children.get().iter() {
3266 self.report_unresolved_imports(module_);
3272 // This pass simply determines what all "export" keywords refer to and
3273 // writes the results into the export map.
3275 // FIXME #4953 This pass will be removed once exports change to per-item.
3276 // Then this operation can simply be performed as part of item (or import)
3279 fn record_exports(&mut self) {
3280 let root_module = self.graph_root.get_module();
3281 self.record_exports_for_module_subtree(root_module);
3284 fn record_exports_for_module_subtree(&mut self,
3286 // If this isn't a local crate, then bail out. We don't need to record
3287 // exports for nonlocal crates.
3289 match module_.def_id.get() {
3290 Some(def_id) if def_id.crate == LOCAL_CRATE => {
3292 debug!("(recording exports for module subtree) recording \
3293 exports for local module `{}`",
3294 self.module_to_str(module_));
3297 // Record exports for the root module.
3298 debug!("(recording exports for module subtree) recording \
3299 exports for root module `{}`",
3300 self.module_to_str(module_));
3304 debug!("(recording exports for module subtree) not recording \
3306 self.module_to_str(module_));
3311 self.record_exports_for_module(module_);
3312 self.populate_module_if_necessary(module_);
3315 let children = module_.children.borrow();
3316 for (_, &child_name_bindings) in children.get().iter() {
3317 match child_name_bindings.get_module_if_available() {
3321 Some(child_module) => {
3322 self.record_exports_for_module_subtree(child_module);
3328 let anonymous_children = module_.anonymous_children.borrow();
3329 for (_, &child_module) in anonymous_children.get().iter() {
3330 self.record_exports_for_module_subtree(child_module);
3334 fn record_exports_for_module(&mut self, module_: @Module) {
3335 let mut exports2 = ~[];
3337 self.add_exports_for_module(&mut exports2, module_);
3338 match module_.def_id.get() {
3340 let mut export_map2 = self.export_map2.borrow_mut();
3341 export_map2.get().insert(def_id.node, exports2);
3342 debug!("(computing exports) writing exports for {} (some)",
3349 fn add_exports_of_namebindings(&mut self,
3350 exports2: &mut ~[Export2],
3352 namebindings: @NameBindings,
3354 match namebindings.def_for_namespace(ns) {
3356 debug!("(computing exports) YES: export '{}' => {:?}",
3359 exports2.push(Export2 {
3360 name: interner_get(name),
3361 def_id: def_id_of_def(d)
3365 debug!("(computing exports) NO: {:?}", d_opt);
3370 fn add_exports_for_module(&mut self,
3371 exports2: &mut ~[Export2],
3373 let import_resolutions = module_.import_resolutions.borrow();
3374 for (name, importresolution) in import_resolutions.get().iter() {
3375 if !importresolution.is_public.get() {
3378 let xs = [TypeNS, ValueNS];
3379 for &ns in xs.iter() {
3380 match importresolution.target_for_namespace(ns) {
3382 debug!("(computing exports) maybe export '{}'",
3383 interner_get(*name));
3384 self.add_exports_of_namebindings(exports2,
3397 // We maintain a list of value ribs and type ribs.
3399 // Simultaneously, we keep track of the current position in the module
3400 // graph in the `current_module` pointer. When we go to resolve a name in
3401 // the value or type namespaces, we first look through all the ribs and
3402 // then query the module graph. When we resolve a name in the module
3403 // namespace, we can skip all the ribs (since nested modules are not
3404 // allowed within blocks in Rust) and jump straight to the current module
3407 // Named implementations are handled separately. When we find a method
3408 // call, we consult the module node to find all of the implementations in
3409 // scope. This information is lazily cached in the module node. We then
3410 // generate a fake "implementation scope" containing all the
3411 // implementations thus found, for compatibility with old resolve pass.
3413 fn with_scope(&mut self, name: Option<Ident>, f: |&mut Resolver|) {
3414 let orig_module = self.current_module;
3416 // Move down in the graph.
3422 self.populate_module_if_necessary(orig_module);
3424 let children = orig_module.children.borrow();
3425 match children.get().find(&name.name) {
3427 debug!("!!! (with scope) didn't find `{}` in `{}`",
3428 self.session.str_of(name),
3429 self.module_to_str(orig_module));
3431 Some(name_bindings) => {
3432 match (*name_bindings).get_module_if_available() {
3434 debug!("!!! (with scope) didn't find module \
3436 self.session.str_of(name),
3437 self.module_to_str(orig_module));
3440 self.current_module = module_;
3450 self.current_module = orig_module;
3453 /// Wraps the given definition in the appropriate number of `def_upvar`
3455 fn upvarify(&mut self,
3460 -> Option<DefLike> {
3465 DlDef(d @ DefLocal(..)) | DlDef(d @ DefUpvar(..)) |
3466 DlDef(d @ DefArg(..)) | DlDef(d @ DefBinding(..)) => {
3468 is_ty_param = false;
3470 DlDef(d @ DefTyParam(..)) => {
3475 return Some(def_like);
3479 let mut rib_index = rib_index + 1;
3480 while rib_index < ribs.len() {
3481 match ribs[rib_index].kind {
3483 // Nothing to do. Continue.
3485 FunctionRibKind(function_id, body_id) => {
3487 def = DefUpvar(def_id_of_def(def).node,
3493 MethodRibKind(item_id, _) => {
3494 // If the def is a ty param, and came from the parent
3497 DefTyParam(did, _) if {
3498 let def_map = self.def_map.borrow();
3499 def_map.get().find(&did.node).map(|x| *x)
3500 == Some(DefTyParamBinder(item_id))
3506 // This was an attempt to access an upvar inside a
3507 // named function item. This is not allowed, so we
3512 "can't capture dynamic environment in a fn item; \
3513 use the || { ... } closure form instead");
3515 // This was an attempt to use a type parameter outside
3518 self.resolve_error(span,
3519 "attempt to use a type \
3520 argument out of scope");
3527 OpaqueFunctionRibKind => {
3529 // This was an attempt to access an upvar inside a
3530 // named function item. This is not allowed, so we
3535 "can't capture dynamic environment in a fn item; \
3536 use the || { ... } closure form instead");
3538 // This was an attempt to use a type parameter outside
3541 self.resolve_error(span,
3542 "attempt to use a type \
3543 argument out of scope");
3548 ConstantItemRibKind => {
3551 self.resolve_error(span,
3552 "cannot use an outer type \
3553 parameter in this context");
3555 // Still doesn't deal with upvars
3556 self.resolve_error(span,
3557 "attempt to use a non-constant \
3558 value in a constant");
3567 return Some(DlDef(def));
3570 fn search_ribs(&mut self,
3574 -> Option<DefLike> {
3575 // FIXME #4950: This should not use a while loop.
3576 // FIXME #4950: Try caching?
3578 let mut i = ribs.len();
3582 let bindings = ribs[i].bindings.borrow();
3583 bindings.get().find_copy(&name)
3587 return self.upvarify(ribs, i, def_like, span);
3598 fn resolve_crate(&mut self, crate: &ast::Crate) {
3599 debug!("(resolving crate) starting");
3601 visit::walk_crate(self, crate, ());
3604 fn resolve_item(&mut self, item: &Item) {
3605 debug!("(resolving item) resolving {}",
3606 self.session.str_of(item.ident));
3610 // enum item: resolve all the variants' discrs,
3611 // then resolve the ty params
3612 ItemEnum(ref enum_def, ref generics) => {
3613 for variant in (*enum_def).variants.iter() {
3614 for dis_expr in variant.node.disr_expr.iter() {
3615 // resolve the discriminator expr
3617 self.with_constant_rib(|this| {
3618 this.resolve_expr(*dis_expr);
3623 // n.b. the discr expr gets visted twice.
3624 // but maybe it's okay since the first time will signal an
3625 // error if there is one? -- tjc
3626 self.with_type_parameter_rib(HasTypeParameters(generics,
3631 visit::walk_item(this, item, ());
3635 ItemTy(_, ref generics) => {
3636 self.with_type_parameter_rib(HasTypeParameters(generics,
3641 visit::walk_item(this, item, ());
3645 ItemImpl(ref generics,
3646 ref implemented_traits,
3649 self.resolve_implementation(item.id,
3656 ItemTrait(ref generics, ref traits, ref methods) => {
3657 // Create a new rib for the self type.
3658 let self_type_rib = @Rib::new(NormalRibKind);
3660 let mut type_ribs = self.type_ribs.borrow_mut();
3661 type_ribs.get().push(self_type_rib);
3663 // plain insert (no renaming)
3664 let name = self.type_self_ident.name;
3666 let mut bindings = self_type_rib.bindings.borrow_mut();
3667 bindings.get().insert(name, DlDef(DefSelfTy(item.id)));
3670 // Create a new rib for the trait-wide type parameters.
3671 self.with_type_parameter_rib(HasTypeParameters(generics,
3676 this.resolve_type_parameters(&generics.ty_params);
3678 // Resolve derived traits.
3679 for trt in traits.iter() {
3680 this.resolve_trait_reference(item.id, trt, TraitDerivation);
3683 for method in (*methods).iter() {
3684 // Create a new rib for the method-specific type
3687 // FIXME #4951: Do we need a node ID here?
3690 ast::Required(ref ty_m) => {
3691 this.with_type_parameter_rib
3692 (HasTypeParameters(&ty_m.generics,
3694 generics.ty_params.len(),
3695 MethodRibKind(item.id, Required)),
3698 // Resolve the method-specific type
3700 this.resolve_type_parameters(
3701 &ty_m.generics.ty_params);
3703 for argument in ty_m.decl.inputs.iter() {
3704 this.resolve_type(argument.ty);
3707 this.resolve_type(ty_m.decl.output);
3710 ast::Provided(m) => {
3711 this.resolve_method(MethodRibKind(item.id,
3714 generics.ty_params.len())
3720 let mut type_ribs = self.type_ribs.borrow_mut();
3721 type_ribs.get().pop();
3724 ItemStruct(ref struct_def, ref generics) => {
3725 self.resolve_struct(item.id,
3730 ItemMod(ref module_) => {
3731 self.with_scope(Some(item.ident), |this| {
3732 this.resolve_module(module_, item.span, item.ident,
3737 ItemForeignMod(ref foreign_module) => {
3738 self.with_scope(Some(item.ident), |this| {
3739 for foreign_item in foreign_module.items.iter() {
3740 match foreign_item.node {
3741 ForeignItemFn(_, ref generics) => {
3742 this.with_type_parameter_rib(
3744 generics, foreign_item.id, 0,
3746 |this| visit::walk_foreign_item(this,
3750 ForeignItemStatic(..) => {
3751 visit::walk_foreign_item(this,
3760 ItemFn(fn_decl, _, _, ref generics, block) => {
3761 self.resolve_function(OpaqueFunctionRibKind,
3767 OpaqueFunctionRibKind),
3772 self.with_constant_rib(|this| {
3773 visit::walk_item(this, item, ());
3778 // do nothing, these are just around to be encoded
3783 fn with_type_parameter_rib(&mut self,
3784 type_parameters: TypeParameters,
3785 f: |&mut Resolver|) {
3786 match type_parameters {
3787 HasTypeParameters(generics, node_id, initial_index,
3790 let function_type_rib = @Rib::new(rib_kind);
3792 let mut type_ribs = self.type_ribs.borrow_mut();
3793 type_ribs.get().push(function_type_rib);
3796 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3797 let ident = type_parameter.ident;
3798 debug!("with_type_parameter_rib: {} {}", node_id,
3800 let def_like = DlDef(DefTyParam
3801 (local_def(type_parameter.id),
3802 index + initial_index));
3803 // Associate this type parameter with
3804 // the item that bound it
3805 self.record_def(type_parameter.id,
3806 (DefTyParamBinder(node_id), AllPublic));
3807 // plain insert (no renaming)
3808 let mut bindings = function_type_rib.bindings
3810 bindings.get().insert(ident.name, def_like);
3814 NoTypeParameters => {
3821 match type_parameters {
3822 HasTypeParameters(..) => {
3823 let mut type_ribs = self.type_ribs.borrow_mut();
3824 type_ribs.get().pop();
3827 NoTypeParameters => {
3833 fn with_label_rib(&mut self, f: |&mut Resolver|) {
3835 let mut label_ribs = self.label_ribs.borrow_mut();
3836 label_ribs.get().push(@Rib::new(NormalRibKind));
3842 let mut label_ribs = self.label_ribs.borrow_mut();
3843 label_ribs.get().pop();
3847 fn with_constant_rib(&mut self, f: |&mut Resolver|) {
3849 let mut value_ribs = self.value_ribs.borrow_mut();
3850 let mut type_ribs = self.type_ribs.borrow_mut();
3851 value_ribs.get().push(@Rib::new(ConstantItemRibKind));
3852 type_ribs.get().push(@Rib::new(ConstantItemRibKind));
3856 let mut value_ribs = self.value_ribs.borrow_mut();
3857 let mut type_ribs = self.type_ribs.borrow_mut();
3858 type_ribs.get().pop();
3859 value_ribs.get().pop();
3863 fn resolve_function(&mut self,
3865 optional_declaration: Option<P<FnDecl>>,
3866 type_parameters: TypeParameters,
3868 // Create a value rib for the function.
3869 let function_value_rib = @Rib::new(rib_kind);
3871 let mut value_ribs = self.value_ribs.borrow_mut();
3872 value_ribs.get().push(function_value_rib);
3875 // Create a label rib for the function.
3877 let mut label_ribs = self.label_ribs.borrow_mut();
3878 let function_label_rib = @Rib::new(rib_kind);
3879 label_ribs.get().push(function_label_rib);
3882 // If this function has type parameters, add them now.
3883 self.with_type_parameter_rib(type_parameters, |this| {
3884 // Resolve the type parameters.
3885 match type_parameters {
3886 NoTypeParameters => {
3889 HasTypeParameters(ref generics, _, _, _) => {
3890 this.resolve_type_parameters(&generics.ty_params);
3894 // Add each argument to the rib.
3895 match optional_declaration {
3899 Some(declaration) => {
3900 for argument in declaration.inputs.iter() {
3901 let binding_mode = ArgumentIrrefutableMode;
3902 this.resolve_pattern(argument.pat,
3906 this.resolve_type(argument.ty);
3908 debug!("(resolving function) recorded argument");
3911 this.resolve_type(declaration.output);
3915 // Resolve the function body.
3916 this.resolve_block(block);
3918 debug!("(resolving function) leaving function");
3921 let mut label_ribs = self.label_ribs.borrow_mut();
3922 label_ribs.get().pop();
3924 let mut value_ribs = self.value_ribs.borrow_mut();
3925 value_ribs.get().pop();
3928 fn resolve_type_parameters(&mut self,
3929 type_parameters: &OptVec<TyParam>) {
3930 for type_parameter in type_parameters.iter() {
3931 for bound in type_parameter.bounds.iter() {
3932 self.resolve_type_parameter_bound(type_parameter.id, bound);
3934 match type_parameter.default {
3935 Some(ty) => self.resolve_type(ty),
3941 fn resolve_type_parameter_bound(&mut self,
3943 type_parameter_bound: &TyParamBound) {
3944 match *type_parameter_bound {
3945 TraitTyParamBound(ref tref) => {
3946 self.resolve_trait_reference(id, tref, TraitBoundingTypeParameter)
3948 RegionTyParamBound => {}
3952 fn resolve_trait_reference(&mut self,
3954 trait_reference: &TraitRef,
3955 reference_type: TraitReferenceType) {
3956 match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
3958 let path_str = self.path_idents_to_str(&trait_reference.path);
3959 let usage_str = match reference_type {
3960 TraitBoundingTypeParameter => "bound type parameter with",
3961 TraitImplementation => "implement",
3962 TraitDerivation => "derive"
3965 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
3966 self.resolve_error(trait_reference.path.span, msg);
3969 debug!("(resolving trait) found trait def: {:?}", def);
3970 self.record_def(trait_reference.ref_id, def);
3975 fn resolve_struct(&mut self,
3977 generics: &Generics,
3978 fields: &[StructField]) {
3979 let mut ident_map: HashMap<ast::Ident, &StructField> = HashMap::new();
3980 for field in fields.iter() {
3981 match field.node.kind {
3982 NamedField(ident, _) => {
3983 match ident_map.find(&ident) {
3984 Some(&prev_field) => {
3985 let ident_str = self.session.str_of(ident);
3986 self.resolve_error(field.span,
3987 format!("field `{}` is already declared", ident_str));
3988 self.session.span_note(prev_field.span,
3989 "Previously declared here");
3992 ident_map.insert(ident, field);
4000 // If applicable, create a rib for the type parameters.
4001 self.with_type_parameter_rib(HasTypeParameters(generics,
4004 OpaqueFunctionRibKind),
4006 // Resolve the type parameters.
4007 this.resolve_type_parameters(&generics.ty_params);
4010 for field in fields.iter() {
4011 this.resolve_type(field.node.ty);
4016 // Does this really need to take a RibKind or is it always going
4017 // to be NormalRibKind?
4018 fn resolve_method(&mut self,
4021 outer_type_parameter_count: uint) {
4022 let method_generics = &method.generics;
4023 let type_parameters =
4024 HasTypeParameters(method_generics,
4026 outer_type_parameter_count,
4029 self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
4032 fn resolve_implementation(&mut self,
4034 generics: &Generics,
4035 opt_trait_reference: &Option<TraitRef>,
4037 methods: &[@Method]) {
4038 // If applicable, create a rib for the type parameters.
4039 let outer_type_parameter_count = generics.ty_params.len();
4040 self.with_type_parameter_rib(HasTypeParameters(generics,
4045 // Resolve the type parameters.
4046 this.resolve_type_parameters(&generics.ty_params);
4048 // Resolve the trait reference, if necessary.
4049 let original_trait_refs;
4050 match opt_trait_reference {
4051 &Some(ref trait_reference) => {
4052 this.resolve_trait_reference(id, trait_reference,
4053 TraitImplementation);
4055 // Record the current set of trait references.
4056 let mut new_trait_refs = ~[];
4058 let def_map = this.def_map.borrow();
4059 let r = def_map.get().find(&trait_reference.ref_id);
4060 for &def in r.iter() {
4061 new_trait_refs.push(def_id_of_def(*def));
4064 original_trait_refs = Some(util::replace(
4065 &mut this.current_trait_refs,
4066 Some(new_trait_refs)));
4069 original_trait_refs = None;
4073 // Resolve the self type.
4074 this.resolve_type(self_type);
4076 for method in methods.iter() {
4077 // We also need a new scope for the method-specific
4079 this.resolve_method(MethodRibKind(
4081 Provided(method.id)),
4083 outer_type_parameter_count);
4085 let borrowed_type_parameters = &method.tps;
4086 self.resolve_function(MethodRibKind(
4088 Provided(method.id)),
4091 (borrowed_type_parameters,
4093 outer_type_parameter_count,
4099 // Restore the original trait references.
4100 match original_trait_refs {
4101 Some(r) => { this.current_trait_refs = r; }
4107 fn resolve_module(&mut self, module: &Mod, _span: Span,
4108 _name: Ident, id: NodeId) {
4109 // Write the implementations in scope into the module metadata.
4110 debug!("(resolving module) resolving module ID {}", id);
4111 visit::walk_mod(self, module, ());
4114 fn resolve_local(&mut self, local: &Local) {
4115 // Resolve the type.
4116 self.resolve_type(local.ty);
4118 // Resolve the initializer, if necessary.
4123 Some(initializer) => {
4124 self.resolve_expr(initializer);
4128 // Resolve the pattern.
4129 self.resolve_pattern(local.pat, LocalIrrefutableMode, None);
4132 // build a map from pattern identifiers to binding-info's.
4133 // this is done hygienically. This could arise for a macro
4134 // that expands into an or-pattern where one 'x' was from the
4135 // user and one 'x' came from the macro.
4136 fn binding_mode_map(&mut self, pat: @Pat) -> BindingMap {
4137 let mut result = HashMap::new();
4138 pat_bindings(self.def_map, pat, |binding_mode, _id, sp, path| {
4139 let name = mtwt_resolve(path_to_ident(path));
4141 binding_info {span: sp,
4142 binding_mode: binding_mode});
4147 // check that all of the arms in an or-pattern have exactly the
4148 // same set of bindings, with the same binding modes for each.
4149 fn check_consistent_bindings(&mut self, arm: &Arm) {
4150 if arm.pats.len() == 0 { return; }
4151 let map_0 = self.binding_mode_map(arm.pats[0]);
4152 for (i, p) in arm.pats.iter().enumerate() {
4153 let map_i = self.binding_mode_map(*p);
4155 for (&key, &binding_0) in map_0.iter() {
4156 match map_i.find(&key) {
4160 format!("variable `{}` from pattern \\#1 is \
4161 not bound in pattern \\#{}",
4162 interner_get(key), i + 1));
4164 Some(binding_i) => {
4165 if binding_0.binding_mode != binding_i.binding_mode {
4168 format!("variable `{}` is bound with different \
4169 mode in pattern \\#{} than in pattern \\#1",
4170 interner_get(key), i + 1));
4176 for (&key, &binding) in map_i.iter() {
4177 if !map_0.contains_key(&key) {
4180 format!("variable `{}` from pattern \\#{} is \
4181 not bound in pattern \\#1",
4182 interner_get(key), i + 1));
4188 fn resolve_arm(&mut self, arm: &Arm) {
4190 let mut value_ribs = self.value_ribs.borrow_mut();
4191 value_ribs.get().push(@Rib::new(NormalRibKind));
4194 let mut bindings_list = HashMap::new();
4195 for pattern in arm.pats.iter() {
4196 self.resolve_pattern(*pattern,
4198 Some(&mut bindings_list));
4201 // This has to happen *after* we determine which
4202 // pat_idents are variants
4203 self.check_consistent_bindings(arm);
4205 visit::walk_expr_opt(self, arm.guard, ());
4206 self.resolve_block(arm.body);
4208 let mut value_ribs = self.value_ribs.borrow_mut();
4209 value_ribs.get().pop();
4212 fn resolve_block(&mut self, block: &Block) {
4213 debug!("(resolving block) entering block");
4215 let mut value_ribs = self.value_ribs.borrow_mut();
4216 value_ribs.get().push(@Rib::new(NormalRibKind));
4219 // Move down in the graph, if there's an anonymous module rooted here.
4220 let orig_module = self.current_module;
4221 let anonymous_children = self.current_module
4224 match anonymous_children.get().find(&block.id) {
4225 None => { /* Nothing to do. */ }
4226 Some(&anonymous_module) => {
4227 debug!("(resolving block) found anonymous module, moving \
4229 self.current_module = anonymous_module;
4233 // Descend into the block.
4234 visit::walk_block(self, block, ());
4237 self.current_module = orig_module;
4239 let mut value_ribs = self.value_ribs.borrow_mut();
4240 value_ribs.get().pop();
4241 debug!("(resolving block) leaving block");
4244 fn resolve_type(&mut self, ty: &Ty) {
4246 // Like path expressions, the interpretation of path types depends
4247 // on whether the path has multiple elements in it or not.
4249 TyPath(ref path, ref bounds, path_id) => {
4250 // This is a path in the type namespace. Walk through scopes
4251 // scopes looking for it.
4252 let mut result_def = None;
4254 // First, check to see whether the name is a primitive type.
4255 if path.segments.len() == 1 {
4256 let id = path.segments.last().unwrap().identifier;
4258 match self.primitive_type_table
4262 Some(&primitive_type) => {
4264 Some((DefPrimTy(primitive_type), AllPublic));
4268 .any(|s| !s.lifetimes.is_empty()) {
4269 self.session.span_err(path.span,
4270 "lifetime parameters \
4271 are not allowed on \
4273 } else if path.segments
4275 .any(|s| s.types.len() > 0) {
4276 self.session.span_err(path.span,
4277 "type parameters are \
4278 not allowed on this \
4290 match self.resolve_path(ty.id, path, TypeNS, true) {
4292 debug!("(resolving type) resolved `{}` to \
4294 self.session.str_of(path.segments
4298 result_def = Some(def);
4305 Some(_) => {} // Continue.
4310 // Write the result into the def map.
4311 debug!("(resolving type) writing resolution for `{}` \
4313 self.path_idents_to_str(path),
4315 self.record_def(path_id, def);
4318 let msg = format!("use of undeclared type name `{}`",
4319 self.path_idents_to_str(path));
4320 self.resolve_error(ty.span, msg);
4324 bounds.as_ref().map(|bound_vec| {
4325 for bound in bound_vec.iter() {
4326 self.resolve_type_parameter_bound(ty.id, bound);
4332 c.bounds.as_ref().map(|bounds| {
4333 for bound in bounds.iter() {
4334 self.resolve_type_parameter_bound(ty.id, bound);
4337 visit::walk_ty(self, ty, ());
4341 // Just resolve embedded types.
4342 visit::walk_ty(self, ty, ());
4347 fn resolve_pattern(&mut self,
4349 mode: PatternBindingMode,
4350 // Maps idents to the node ID for the (outermost)
4351 // pattern that binds them
4352 mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4353 let pat_id = pattern.id;
4354 walk_pat(pattern, |pattern| {
4355 match pattern.node {
4356 PatIdent(binding_mode, ref path, _)
4357 if !path.global && path.segments.len() == 1 => {
4359 // The meaning of pat_ident with no type parameters
4360 // depends on whether an enum variant or unit-like struct
4361 // with that name is in scope. The probing lookup has to
4362 // be careful not to emit spurious errors. Only matching
4363 // patterns (match) can match nullary variants or
4364 // unit-like structs. For binding patterns (let), matching
4365 // such a value is simply disallowed (since it's rarely
4368 let ident = path.segments[0].identifier;
4369 let renamed = mtwt_resolve(ident);
4371 match self.resolve_bare_identifier_pattern(ident) {
4372 FoundStructOrEnumVariant(def, lp)
4373 if mode == RefutableMode => {
4374 debug!("(resolving pattern) resolving `{}` to \
4375 struct or enum variant",
4376 interner_get(renamed));
4378 self.enforce_default_binding_mode(
4382 self.record_def(pattern.id, (def, lp));
4384 FoundStructOrEnumVariant(..) => {
4385 self.resolve_error(pattern.span,
4386 format!("declaration of `{}` \
4388 variant or unit-like \
4390 interner_get(renamed)));
4392 FoundConst(def, lp) if mode == RefutableMode => {
4393 debug!("(resolving pattern) resolving `{}` to \
4395 interner_get(renamed));
4397 self.enforce_default_binding_mode(
4401 self.record_def(pattern.id, (def, lp));
4404 self.resolve_error(pattern.span,
4405 "only irrefutable patterns \
4408 BareIdentifierPatternUnresolved => {
4409 debug!("(resolving pattern) binding `{}`",
4410 interner_get(renamed));
4412 let def = match mode {
4414 // For pattern arms, we must use
4415 // `def_binding` definitions.
4417 DefBinding(pattern.id, binding_mode)
4419 LocalIrrefutableMode => {
4420 // But for locals, we use `def_local`.
4421 DefLocal(pattern.id, binding_mode)
4423 ArgumentIrrefutableMode => {
4424 // And for function arguments, `def_arg`.
4425 DefArg(pattern.id, binding_mode)
4429 // Record the definition so that later passes
4430 // will be able to distinguish variants from
4431 // locals in patterns.
4433 self.record_def(pattern.id, (def, AllPublic));
4435 // Add the binding to the local ribs, if it
4436 // doesn't already exist in the bindings list. (We
4437 // must not add it if it's in the bindings list
4438 // because that breaks the assumptions later
4439 // passes make about or-patterns.)
4441 match bindings_list {
4442 Some(ref mut bindings_list)
4443 if !bindings_list.contains_key(&renamed) => {
4444 let this = &mut *self;
4446 let mut value_ribs =
4447 this.value_ribs.borrow_mut();
4448 let last_rib = value_ribs.get()[
4449 value_ribs.get().len() - 1];
4451 last_rib.bindings.borrow_mut();
4452 bindings.get().insert(renamed,
4455 bindings_list.insert(renamed, pat_id);
4457 Some(ref mut b) => {
4458 if b.find(&renamed) == Some(&pat_id) {
4459 // Then this is a duplicate variable
4460 // in the same disjunct, which is an
4462 self.resolve_error(pattern.span,
4463 format!("Identifier `{}` is bound more \
4464 than once in the same pattern",
4465 path_to_str(path, self.session
4468 // Not bound in the same pattern: do nothing
4471 let this = &mut *self;
4473 let mut value_ribs =
4474 this.value_ribs.borrow_mut();
4475 let last_rib = value_ribs.get()[
4476 value_ribs.get().len() - 1];
4478 last_rib.bindings.borrow_mut();
4479 bindings.get().insert(renamed,
4487 // Check the types in the path pattern.
4488 for &ty in path.segments
4490 .flat_map(|seg| seg.types.iter()) {
4491 self.resolve_type(ty);
4495 PatIdent(binding_mode, ref path, _) => {
4496 // This must be an enum variant, struct, or constant.
4497 match self.resolve_path(pat_id, path, ValueNS, false) {
4498 Some(def @ (DefVariant(..), _)) |
4499 Some(def @ (DefStruct(..), _)) => {
4500 self.record_def(pattern.id, def);
4502 Some(def @ (DefStatic(..), _)) => {
4503 self.enforce_default_binding_mode(
4507 self.record_def(pattern.id, def);
4512 format!("`{}` is not an enum variant or constant",
4513 self.session.str_of(
4514 path.segments.last().unwrap().identifier)))
4517 self.resolve_error(path.span,
4518 "unresolved enum variant");
4522 // Check the types in the path pattern.
4523 for &ty in path.segments
4525 .flat_map(|s| s.types.iter()) {
4526 self.resolve_type(ty);
4530 PatEnum(ref path, _) => {
4531 // This must be an enum variant, struct or const.
4532 match self.resolve_path(pat_id, path, ValueNS, false) {
4533 Some(def @ (DefFn(..), _)) |
4534 Some(def @ (DefVariant(..), _)) |
4535 Some(def @ (DefStruct(..), _)) |
4536 Some(def @ (DefStatic(..), _)) => {
4537 self.record_def(pattern.id, def);
4542 format!("`{}` is not an enum variant, struct or const",
4544 .str_of(path.segments
4549 self.resolve_error(path.span,
4550 format!("unresolved enum variant, \
4551 struct or const `{}`",
4553 .str_of(path.segments
4559 // Check the types in the path pattern.
4560 for &ty in path.segments
4562 .flat_map(|s| s.types.iter()) {
4563 self.resolve_type(ty);
4568 self.resolve_expr(expr);
4571 PatRange(first_expr, last_expr) => {
4572 self.resolve_expr(first_expr);
4573 self.resolve_expr(last_expr);
4576 PatStruct(ref path, _, _) => {
4577 match self.resolve_path(pat_id, path, TypeNS, false) {
4578 Some((DefTy(class_id), lp))
4579 if self.structs.contains(&class_id) => {
4580 let class_def = DefStruct(class_id);
4581 self.record_def(pattern.id, (class_def, lp));
4583 Some(definition @ (DefStruct(class_id), _)) => {
4584 assert!(self.structs.contains(&class_id));
4585 self.record_def(pattern.id, definition);
4587 Some(definition @ (DefVariant(_, variant_id, _), _))
4588 if self.structs.contains(&variant_id) => {
4589 self.record_def(pattern.id, definition);
4592 debug!("(resolving pattern) didn't find struct \
4593 def: {:?}", result);
4594 let msg = format!("`{}` does not name a structure",
4595 self.path_idents_to_str(path));
4596 self.resolve_error(path.span, msg);
4609 fn resolve_bare_identifier_pattern(&mut self, name: Ident)
4611 BareIdentifierPatternResolution {
4612 match self.resolve_item_in_lexical_scope(self.current_module,
4615 SearchThroughModules) {
4616 Success((target, _)) => {
4617 debug!("(resolve bare identifier pattern) succeeded in \
4618 finding {} at {:?}",
4619 self.session.str_of(name),
4620 target.bindings.value_def.get());
4621 match target.bindings.value_def.get() {
4623 fail!("resolved name in the value namespace to a \
4624 set of name bindings with no def?!");
4627 // For the two success cases, this lookup can be
4628 // considered as not having a private component because
4629 // the lookup happened only within the current module.
4631 def @ DefVariant(..) | def @ DefStruct(..) => {
4632 return FoundStructOrEnumVariant(def, AllPublic);
4634 def @ DefStatic(_, false) => {
4635 return FoundConst(def, AllPublic);
4638 return BareIdentifierPatternUnresolved;
4646 fail!("unexpected indeterminate result");
4650 debug!("(resolve bare identifier pattern) failed to find {}",
4651 self.session.str_of(name));
4652 return BareIdentifierPatternUnresolved;
4657 /// If `check_ribs` is true, checks the local definitions first; i.e.
4658 /// doesn't skip straight to the containing module.
4659 fn resolve_path(&mut self,
4662 namespace: Namespace,
4663 check_ribs: bool) -> Option<(Def, LastPrivate)> {
4664 // First, resolve the types.
4665 for &ty in path.segments.iter().flat_map(|s| s.types.iter()) {
4666 self.resolve_type(ty);
4670 return self.resolve_crate_relative_path(path, namespace);
4673 let unqualified_def =
4674 self.resolve_identifier(path.segments
4681 if path.segments.len() > 1 {
4682 let def = self.resolve_module_relative_path(path, namespace);
4683 match (def, unqualified_def) {
4684 (Some((d, _)), Some((ud, _))) if d == ud => {
4685 self.session.add_lint(UnnecessaryQualification,
4688 ~"unnecessary qualification");
4696 return unqualified_def;
4699 // resolve a single identifier (used as a varref)
4700 fn resolve_identifier(&mut self,
4702 namespace: Namespace,
4705 -> Option<(Def, LastPrivate)> {
4707 match self.resolve_identifier_in_local_ribs(identifier,
4711 return Some((def, AllPublic));
4719 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4723 // FIXME #4952: Merge me with resolve_name_in_module?
4724 fn resolve_definition_of_name_in_module(&mut self,
4725 containing_module: @Module,
4727 namespace: Namespace)
4729 // First, search children.
4730 self.populate_module_if_necessary(containing_module);
4733 let children = containing_module.children.borrow();
4734 match children.get().find(&name.name) {
4735 Some(child_name_bindings) => {
4736 match child_name_bindings.def_for_namespace(namespace) {
4738 // Found it. Stop the search here.
4739 let p = child_name_bindings.defined_in_public_namespace(
4741 let lp = if p {AllPublic} else {
4742 DependsOn(def_id_of_def(def))
4744 return ChildNameDefinition(def, lp);
4753 // Next, search import resolutions.
4754 let import_resolutions = containing_module.import_resolutions
4756 match import_resolutions.get().find(&name.name) {
4757 Some(import_resolution) if import_resolution.is_public.get() => {
4758 match (*import_resolution).target_for_namespace(namespace) {
4760 match target.bindings.def_for_namespace(namespace) {
4763 let id = import_resolution.id(namespace);
4764 self.used_imports.insert(id);
4765 return ImportNameDefinition(def, AllPublic);
4768 // This can happen with external impls, due to
4769 // the imperfect way we read the metadata.
4776 Some(..) | None => {} // Continue.
4779 // Finally, search through external children.
4780 if namespace == TypeNS {
4782 let external_module_children =
4783 containing_module.external_module_children.borrow();
4784 external_module_children.get().find_copy(&name.name)
4789 match module.def_id.get() {
4790 None => {} // Continue.
4792 let lp = if module.is_public {AllPublic} else {
4795 return ChildNameDefinition(DefMod(def_id), lp);
4802 return NoNameDefinition;
4805 // resolve a "module-relative" path, e.g. a::b::c
4806 fn resolve_module_relative_path(&mut self,
4808 namespace: Namespace)
4809 -> Option<(Def, LastPrivate)> {
4810 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4812 let containing_module;
4814 match self.resolve_module_path(self.current_module,
4820 let msg = format!("use of undeclared module `{}`",
4821 self.idents_to_str(module_path_idents));
4822 self.resolve_error(path.span, msg);
4827 fail!("indeterminate unexpected");
4830 Success((resulting_module, resulting_last_private)) => {
4831 containing_module = resulting_module;
4832 last_private = resulting_last_private;
4836 let ident = path.segments.last().unwrap().identifier;
4837 let def = match self.resolve_definition_of_name_in_module(containing_module,
4840 NoNameDefinition => {
4841 // We failed to resolve the name. Report an error.
4844 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4845 (def, last_private.or(lp))
4848 match containing_module.kind.get() {
4849 TraitModuleKind | ImplModuleKind => {
4850 let method_map = self.method_map.borrow();
4851 match method_map.get().find(&ident.name) {
4853 match containing_module.def_id.get() {
4854 Some(def_id) if s.contains(&def_id) => {
4855 debug!("containing module was a trait or impl \
4856 and name was a method -> not resolved");
4870 /// Invariant: This must be called only during main resolution, not during
4871 /// import resolution.
4872 fn resolve_crate_relative_path(&mut self,
4874 namespace: Namespace)
4875 -> Option<(Def, LastPrivate)> {
4876 let module_path_idents = path.segments.init().map(|ps| ps.identifier);
4878 let root_module = self.graph_root.get_module();
4880 let containing_module;
4882 match self.resolve_module_path_from_root(root_module,
4889 let msg = format!("use of undeclared module `::{}`",
4890 self.idents_to_str(module_path_idents));
4891 self.resolve_error(path.span, msg);
4896 fail!("indeterminate unexpected");
4899 Success((resulting_module, resulting_last_private)) => {
4900 containing_module = resulting_module;
4901 last_private = resulting_last_private;
4905 let name = path.segments.last().unwrap().identifier;
4906 match self.resolve_definition_of_name_in_module(containing_module,
4909 NoNameDefinition => {
4910 // We failed to resolve the name. Report an error.
4913 ChildNameDefinition(def, lp) | ImportNameDefinition(def, lp) => {
4914 return Some((def, last_private.or(lp)));
4919 fn resolve_identifier_in_local_ribs(&mut self,
4921 namespace: Namespace,
4924 // Check the local set of ribs.
4928 let renamed = mtwt_resolve(ident);
4929 let mut value_ribs = self.value_ribs.borrow_mut();
4930 search_result = self.search_ribs(value_ribs.get(),
4935 let name = ident.name;
4936 let mut type_ribs = self.type_ribs.borrow_mut();
4937 search_result = self.search_ribs(type_ribs.get(),
4943 match search_result {
4944 Some(DlDef(def)) => {
4945 debug!("(resolving path in local ribs) resolved `{}` to \
4947 self.session.str_of(ident),
4951 Some(DlField) | Some(DlImpl(_)) | None => {
4957 fn resolve_item_by_identifier_in_lexical_scope(&mut self,
4959 namespace: Namespace)
4960 -> Option<(Def, LastPrivate)> {
4962 match self.resolve_item_in_lexical_scope(self.current_module,
4965 DontSearchThroughModules) {
4966 Success((target, _)) => {
4967 match (*target.bindings).def_for_namespace(namespace) {
4969 // This can happen if we were looking for a type and
4970 // found a module instead. Modules don't have defs.
4971 debug!("(resolving item path by identifier in lexical \
4972 scope) failed to resolve {} after success...",
4973 self.session.str_of(ident));
4977 debug!("(resolving item path in lexical scope) \
4978 resolved `{}` to item",
4979 self.session.str_of(ident));
4980 // This lookup is "all public" because it only searched
4981 // for one identifier in the current module (couldn't
4982 // have passed through reexports or anything like that.
4983 return Some((def, AllPublic));
4988 fail!("unexpected indeterminate result");
4991 debug!("(resolving item path by identifier in lexical scope) \
4992 failed to resolve {}", self.session.str_of(ident));
4998 fn with_no_errors<T>(&mut self, f: |&mut Resolver| -> T) -> T {
4999 self.emit_errors = false;
5001 self.emit_errors = true;
5005 fn resolve_error(&mut self, span: Span, s: &str) {
5006 if self.emit_errors {
5007 self.session.span_err(span, s);
5011 fn find_best_match_for_name(&mut self, name: &str, max_distance: uint)
5013 let this = &mut *self;
5015 let mut maybes: ~[@str] = ~[];
5016 let mut values: ~[uint] = ~[];
5019 let value_ribs = this.value_ribs.borrow();
5020 value_ribs.get().len()
5024 let value_ribs = this.value_ribs.borrow();
5025 let bindings = value_ribs.get()[j].bindings.borrow();
5026 for (&k, _) in bindings.get().iter() {
5027 maybes.push(interner_get(k));
5028 values.push(uint::MAX);
5032 let mut smallest = 0;
5033 for (i, &other) in maybes.iter().enumerate() {
5034 values[i] = name.lev_distance(other);
5036 if values[i] <= values[smallest] {
5041 if values.len() > 0 &&
5042 values[smallest] != uint::MAX &&
5043 values[smallest] < name.len() + 2 &&
5044 values[smallest] <= max_distance &&
5045 name != maybes[smallest] {
5047 Some(maybes.swap_remove(smallest))
5054 fn resolve_expr(&mut self, expr: &Expr) {
5055 // First, record candidate traits for this expression if it could
5056 // result in the invocation of a method call.
5058 self.record_candidate_traits_for_expr_if_necessary(expr);
5060 // Next, resolve the node.
5062 // The interpretation of paths depends on whether the path has
5063 // multiple elements in it or not.
5065 ExprPath(ref path) => {
5066 // This is a local path in the value namespace. Walk through
5067 // scopes looking for it.
5069 match self.resolve_path(expr.id, path, ValueNS, true) {
5071 // Write the result into the def map.
5072 debug!("(resolving expr) resolved `{}`",
5073 self.path_idents_to_str(path));
5075 // First-class methods are not supported yet; error
5078 (DefMethod(..), _) => {
5079 self.resolve_error(expr.span,
5080 "first-class methods \
5081 are not supported");
5082 self.session.span_note(expr.span,
5090 self.record_def(expr.id, def);
5093 let wrong_name = self.path_idents_to_str(path);
5094 // Be helpful if the name refers to a struct
5095 // (The pattern matching def_tys where the id is in self.structs
5096 // matches on regular structs while excluding tuple- and enum-like
5097 // structs, which wouldn't result in this error.)
5098 match self.with_no_errors(|this|
5099 this.resolve_path(expr.id, path, TypeNS, false)) {
5100 Some((DefTy(struct_id), _))
5101 if self.structs.contains(&struct_id) => {
5102 self.resolve_error(expr.span,
5103 format!("`{}` is a structure name, but \
5105 uses it like a function name",
5108 self.session.span_note(expr.span,
5109 format!("Did you mean to write: \
5110 `{} \\{ /* fields */ \\}`?",
5115 // limit search to 5 to reduce the number
5116 // of stupid suggestions
5117 match self.find_best_match_for_name(wrong_name, 5) {
5119 self.resolve_error(expr.span,
5120 format!("unresolved name `{}`. \
5121 Did you mean `{}`?",
5125 self.resolve_error(expr.span,
5126 format!("unresolved name `{}`.",
5134 visit::walk_expr(self, expr, ());
5137 ExprFnBlock(fn_decl, block) |
5138 ExprProc(fn_decl, block) => {
5139 self.resolve_function(FunctionRibKind(expr.id, block.id),
5140 Some(fn_decl), NoTypeParameters,
5144 ExprStruct(ref path, _, _) => {
5145 // Resolve the path to the structure it goes to.
5146 match self.resolve_path(expr.id, path, TypeNS, false) {
5147 Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
5148 if self.structs.contains(&class_id) => {
5149 let class_def = DefStruct(class_id);
5150 self.record_def(expr.id, (class_def, lp));
5152 Some(definition @ (DefVariant(_, class_id, _), _))
5153 if self.structs.contains(&class_id) => {
5154 self.record_def(expr.id, definition);
5157 debug!("(resolving expression) didn't find struct \
5158 def: {:?}", result);
5159 let msg = format!("`{}` does not name a structure",
5160 self.path_idents_to_str(path));
5161 self.resolve_error(path.span, msg);
5165 visit::walk_expr(self, expr, ());
5168 ExprLoop(_, Some(label)) => {
5169 self.with_label_rib(|this| {
5170 let def_like = DlDef(DefLabel(expr.id));
5171 // plain insert (no renaming)
5173 let mut label_ribs = this.label_ribs.borrow_mut();
5174 let rib = label_ribs.get()[label_ribs.get().len() -
5176 let mut bindings = rib.bindings.borrow_mut();
5177 bindings.get().insert(label.name, def_like);
5180 visit::walk_expr(this, expr, ());
5184 ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
5186 ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
5187 let mut label_ribs = self.label_ribs.borrow_mut();
5188 match self.search_ribs(label_ribs.get(), label, expr.span) {
5190 self.resolve_error(expr.span,
5191 format!("use of undeclared label \
5193 interner_get(label))),
5194 Some(DlDef(def @ DefLabel(_))) => {
5195 // FIXME: is AllPublic correct?
5196 self.record_def(expr.id, (def, AllPublic))
5199 self.session.span_bug(expr.span,
5200 "label wasn't mapped to a \
5207 visit::walk_expr(self, expr, ());
5212 fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
5214 ExprField(_, ident, _) => {
5215 // FIXME(#6890): Even though you can't treat a method like a
5216 // field, we need to add any trait methods we find that match
5217 // the field name so that we can do some nice error reporting
5218 // later on in typeck.
5219 let traits = self.search_for_traits_containing_method(ident);
5220 self.trait_map.insert(expr.id, @RefCell::new(traits));
5222 ExprMethodCall(_, ident, _, _, _) => {
5223 debug!("(recording candidate traits for expr) recording \
5226 let traits = self.search_for_traits_containing_method(ident);
5227 self.trait_map.insert(expr.id, @RefCell::new(traits));
5229 ExprBinary(_, BiAdd, _, _) | ExprAssignOp(_, BiAdd, _, _) => {
5230 let i = self.lang_items.add_trait();
5231 self.add_fixed_trait_for_expr(expr.id, i);
5233 ExprBinary(_, BiSub, _, _) | ExprAssignOp(_, BiSub, _, _) => {
5234 let i = self.lang_items.sub_trait();
5235 self.add_fixed_trait_for_expr(expr.id, i);
5237 ExprBinary(_, BiMul, _, _) | ExprAssignOp(_, BiMul, _, _) => {
5238 let i = self.lang_items.mul_trait();
5239 self.add_fixed_trait_for_expr(expr.id, i);
5241 ExprBinary(_, BiDiv, _, _) | ExprAssignOp(_, BiDiv, _, _) => {
5242 let i = self.lang_items.div_trait();
5243 self.add_fixed_trait_for_expr(expr.id, i);
5245 ExprBinary(_, BiRem, _, _) | ExprAssignOp(_, BiRem, _, _) => {
5246 let i = self.lang_items.rem_trait();
5247 self.add_fixed_trait_for_expr(expr.id, i);
5249 ExprBinary(_, BiBitXor, _, _) | ExprAssignOp(_, BiBitXor, _, _) => {
5250 let i = self.lang_items.bitxor_trait();
5251 self.add_fixed_trait_for_expr(expr.id, i);
5253 ExprBinary(_, BiBitAnd, _, _) | ExprAssignOp(_, BiBitAnd, _, _) => {
5254 let i = self.lang_items.bitand_trait();
5255 self.add_fixed_trait_for_expr(expr.id, i);
5257 ExprBinary(_, BiBitOr, _, _) | ExprAssignOp(_, BiBitOr, _, _) => {
5258 let i = self.lang_items.bitor_trait();
5259 self.add_fixed_trait_for_expr(expr.id, i);
5261 ExprBinary(_, BiShl, _, _) | ExprAssignOp(_, BiShl, _, _) => {
5262 let i = self.lang_items.shl_trait();
5263 self.add_fixed_trait_for_expr(expr.id, i);
5265 ExprBinary(_, BiShr, _, _) | ExprAssignOp(_, BiShr, _, _) => {
5266 let i = self.lang_items.shr_trait();
5267 self.add_fixed_trait_for_expr(expr.id, i);
5269 ExprBinary(_, BiLt, _, _) | ExprBinary(_, BiLe, _, _) |
5270 ExprBinary(_, BiGe, _, _) | ExprBinary(_, BiGt, _, _) => {
5271 let i = self.lang_items.ord_trait();
5272 self.add_fixed_trait_for_expr(expr.id, i);
5274 ExprBinary(_, BiEq, _, _) | ExprBinary(_, BiNe, _, _) => {
5275 let i = self.lang_items.eq_trait();
5276 self.add_fixed_trait_for_expr(expr.id, i);
5278 ExprUnary(_, UnNeg, _) => {
5279 let i = self.lang_items.neg_trait();
5280 self.add_fixed_trait_for_expr(expr.id, i);
5282 ExprUnary(_, UnNot, _) => {
5283 let i = self.lang_items.not_trait();
5284 self.add_fixed_trait_for_expr(expr.id, i);
5287 let i = self.lang_items.index_trait();
5288 self.add_fixed_trait_for_expr(expr.id, i);
5296 fn search_for_traits_containing_method(&mut self, name: Ident) -> ~[DefId] {
5297 debug!("(searching for traits containing method) looking for '{}'",
5298 self.session.str_of(name));
5300 let mut found_traits = ~[];
5301 let mut search_module = self.current_module;
5302 let method_map = self.method_map.borrow();
5303 match method_map.get().find(&name.name) {
5304 Some(candidate_traits) => loop {
5305 // Look for the current trait.
5306 match self.current_trait_refs {
5307 Some(ref trait_def_ids) => {
5308 for trait_def_id in trait_def_ids.iter() {
5309 if candidate_traits.contains(trait_def_id) {
5310 self.add_trait_info(&mut found_traits,
5321 // Look for trait children.
5322 self.populate_module_if_necessary(search_module);
5324 let children = search_module.children.borrow();
5325 for (_, &child_names) in children.get().iter() {
5326 let def = match child_names.def_for_namespace(TypeNS) {
5330 let trait_def_id = match def {
5331 DefTrait(trait_def_id) => trait_def_id,
5334 if candidate_traits.contains(&trait_def_id) {
5335 self.add_trait_info(&mut found_traits, trait_def_id,
5340 // Look for imports.
5341 let import_resolutions = search_module.import_resolutions
5343 for (_, &import) in import_resolutions.get().iter() {
5344 let target = match import.target_for_namespace(TypeNS) {
5346 Some(target) => target,
5348 let did = match target.bindings.def_for_namespace(TypeNS) {
5349 Some(DefTrait(trait_def_id)) => trait_def_id,
5350 Some(..) | None => continue,
5352 if candidate_traits.contains(&did) {
5353 self.add_trait_info(&mut found_traits, did, name);
5354 self.used_imports.insert(import.type_id.get());
5358 match search_module.parent_link {
5359 NoParentLink | ModuleParentLink(..) => break,
5360 BlockParentLink(parent_module, _) => {
5361 search_module = parent_module;
5368 return found_traits;
5371 fn add_trait_info(&self,
5372 found_traits: &mut ~[DefId],
5373 trait_def_id: DefId,
5375 debug!("(adding trait info) found trait {}:{} for method '{}'",
5378 self.session.str_of(name));
5379 found_traits.push(trait_def_id);
5382 fn add_fixed_trait_for_expr(&mut self,
5384 trait_id: Option<DefId>) {
5387 self.trait_map.insert(expr_id, @RefCell::new(~[trait_id]));
5393 fn record_def(&mut self, node_id: NodeId, (def, lp): (Def, LastPrivate)) {
5394 debug!("(recording def) recording {:?} for {:?}, last private {:?}",
5396 self.last_private.insert(node_id, lp);
5397 let mut def_map = self.def_map.borrow_mut();
5398 def_map.get().insert_or_update_with(node_id, def, |_, old_value| {
5399 // Resolve appears to "resolve" the same ID multiple
5400 // times, so here is a sanity check it at least comes to
5401 // the same conclusion! - nmatsakis
5402 if def != *old_value {
5403 self.session.bug(format!("node_id {:?} resolved first to {:?} \
5404 and then {:?}", node_id, *old_value, def));
5409 fn enforce_default_binding_mode(&mut self,
5411 pat_binding_mode: BindingMode,
5413 match pat_binding_mode {
5414 BindByValue(_) => {}
5418 format!("cannot use `ref` binding mode with {}",
5425 // Unused import checking
5427 // Although this is a lint pass, it lives in here because it depends on
5428 // resolve data structures.
5431 fn check_for_unused_imports(&self, crate: &ast::Crate) {
5432 let mut visitor = UnusedImportCheckVisitor{ resolver: self };
5433 visit::walk_crate(&mut visitor, crate, ());
5436 fn check_for_item_unused_imports(&self, vi: &ViewItem) {
5437 // Ignore is_public import statements because there's no way to be sure
5438 // whether they're used or not. Also ignore imports with a dummy span
5439 // because this means that they were generated in some fashion by the
5440 // compiler and we don't need to consider them.
5441 if vi.vis == Public { return }
5442 if vi.span == DUMMY_SP { return }
5445 ViewItemExternMod(..) => {} // ignore
5446 ViewItemUse(ref path) => {
5447 for p in path.iter() {
5449 ViewPathSimple(_, _, id) | ViewPathGlob(_, id) => {
5450 if !self.used_imports.contains(&id) {
5451 self.session.add_lint(UnusedImports,
5457 ViewPathList(_, ref list, _) => {
5458 for i in list.iter() {
5459 if !self.used_imports.contains(&i.node.id) {
5460 self.session.add_lint(UnusedImports,
5475 // Diagnostics are not particularly efficient, because they're rarely
5479 /// A somewhat inefficient routine to obtain the name of a module.
5480 fn module_to_str(&mut self, module_: @Module) -> ~str {
5481 let mut idents = ~[];
5482 let mut current_module = module_;
5484 match current_module.parent_link {
5488 ModuleParentLink(module_, name) => {
5490 current_module = module_;
5492 BlockParentLink(module_, _) => {
5493 idents.push(special_idents::opaque);
5494 current_module = module_;
5499 if idents.len() == 0 {
5502 return self.idents_to_str(idents.move_rev_iter().collect::<~[ast::Ident]>());
5505 #[allow(dead_code)] // useful for debugging
5506 fn dump_module(&mut self, module_: @Module) {
5507 debug!("Dump of module `{}`:", self.module_to_str(module_));
5509 debug!("Children:");
5510 self.populate_module_if_necessary(module_);
5511 let children = module_.children.borrow();
5512 for (&name, _) in children.get().iter() {
5513 debug!("* {}", interner_get(name));
5516 debug!("Import resolutions:");
5517 let import_resolutions = module_.import_resolutions.borrow();
5518 for (name, import_resolution) in import_resolutions.get().iter() {
5520 match import_resolution.target_for_namespace(ValueNS) {
5521 None => { value_repr = ~""; }
5523 value_repr = ~" value:?";
5529 match import_resolution.target_for_namespace(TypeNS) {
5530 None => { type_repr = ~""; }
5532 type_repr = ~" type:?";
5537 debug!("* {}:{}{}", interner_get(*name),
5538 value_repr, type_repr);
5543 pub struct CrateMap {
5545 exp_map2: ExportMap2,
5546 trait_map: TraitMap,
5547 external_exports: ExternalExports,
5548 last_private_map: LastPrivateMap,
5551 /// Entry point to crate resolution.
5552 pub fn resolve_crate(session: Session,
5553 lang_items: @LanguageItems,
5556 let mut resolver = Resolver(session, lang_items, crate.span);
5557 resolver.resolve(crate);
5558 let Resolver { def_map, export_map2, trait_map, last_private,
5559 external_exports, .. } = resolver;
5562 exp_map2: export_map2,
5563 trait_map: trait_map,
5564 external_exports: external_exports,
5565 last_private_map: last_private,