1 // Copyright 2012 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::{each_path, get_trait_method_def_ids};
14 use metadata::csearch::get_method_name_and_explicit_self;
15 use metadata::csearch::get_static_methods_if_impl;
16 use metadata::csearch::get_type_name_if_impl;
17 use metadata::cstore::find_extern_mod_stmt_cnum;
18 use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
19 use middle::lang_items::LanguageItems;
20 use middle::lint::{unnecessary_qualification, unused_imports};
21 use middle::pat_util::pat_bindings;
25 use syntax::ast_util::{def_id_of_def, local_def};
26 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
27 use syntax::ast_util::{Privacy, Public, Private};
28 use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy};
30 use syntax::oldvisit::{mk_simple_visitor, default_simple_visitor};
31 use syntax::oldvisit::{default_visitor, mk_vt, Visitor, visit_block};
32 use syntax::oldvisit::{visit_crate, visit_expr, visit_expr_opt};
33 use syntax::oldvisit::{visit_foreign_item, visit_item};
34 use syntax::oldvisit::{visit_mod, visit_ty, vt, SimpleVisitor};
35 use syntax::parse::token;
36 use syntax::parse::token::ident_interner;
37 use syntax::parse::token::special_idents;
38 use syntax::print::pprust::path_to_str;
39 use syntax::codemap::{span, dummy_sp, BytePos};
40 use syntax::opt_vec::OptVec;
44 use std::hashmap::{HashMap, HashSet};
48 pub type DefMap = @mut HashMap<NodeId,def>;
50 pub struct binding_info {
52 binding_mode: binding_mode,
55 // Map from the name in a pattern to its binding mode.
56 pub type BindingMap = HashMap<ident,binding_info>;
58 // Trait method resolution
59 pub type TraitMap = HashMap<NodeId,@mut ~[def_id]>;
61 // This is the replacement export map. It maps a module to all of the exports
63 pub type ExportMap2 = @mut HashMap<NodeId, ~[Export2]>;
66 name: @str, // The name of the target.
67 def_id: def_id, // The definition of the target.
68 reexport: bool, // Whether this is a reexport.
72 pub enum PatternBindingMode {
75 ArgumentIrrefutableMode,
85 pub enum NamespaceError {
92 /// A NamespaceResult represents the result of resolving an import in
93 /// a particular namespace. The result is either definitely-resolved,
94 /// definitely- unresolved, or unknown.
95 pub enum NamespaceResult {
96 /// Means that resolve hasn't gathered enough information yet to determine
97 /// whether the name is bound in this namespace. (That is, it hasn't
98 /// resolved all `use` directives yet.)
100 /// Means that resolve has determined that the name is definitely
101 /// not bound in the namespace.
103 /// Means that resolve has determined that the name is bound in the Module
104 /// argument, and specified by the NameBindings argument.
105 BoundResult(@mut Module, @mut NameBindings)
108 impl NamespaceResult {
109 pub fn is_unknown(&self) -> bool {
111 UnknownResult => true,
117 pub enum NameDefinition {
118 NoNameDefinition, //< The name was unbound.
119 ChildNameDefinition(def), //< The name identifies an immediate child.
120 ImportNameDefinition(def) //< The name identifies an import.
124 pub enum Mutability {
129 pub enum SelfBinding {
131 HasSelfBinding(NodeId, bool /* is implicit */)
134 pub type ResolveVisitor = vt<()>;
136 /// Contains data for specific types of import directives.
137 pub enum ImportDirectiveSubclass {
138 SingleImport(ident /* target */, ident /* source */),
142 /// The context that we thread through while building the reduced graph.
144 pub enum ReducedGraphParent {
145 ModuleReducedGraphParent(@mut Module)
148 pub enum ResolveResult<T> {
149 Failed, // Failed to resolve the name.
150 Indeterminate, // Couldn't determine due to unresolved globs.
151 Success(T) // Successfully resolved the import.
154 impl<T> ResolveResult<T> {
155 pub fn failed(&self) -> bool {
156 match *self { Failed => true, _ => false }
158 pub fn indeterminate(&self) -> bool {
159 match *self { Indeterminate => true, _ => false }
163 pub enum TypeParameters<'self> {
164 NoTypeParameters, //< No type parameters.
165 HasTypeParameters(&'self Generics, //< Type parameters.
166 NodeId, //< ID of the enclosing item
168 // The index to start numbering the type parameters at.
169 // This is zero if this is the outermost set of type
170 // parameters, or equal to the number of outer type
171 // parameters. For example, if we have:
174 // fn method<U>() { ... }
177 // The index at the method site will be 1, because the
178 // outer T had index 0.
181 // The kind of the rib used for type parameters.
185 // The rib kind controls the translation of argument or local definitions
186 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
189 // No translation needs to be applied.
192 // We passed through a function scope at the given node ID. Translate
193 // upvars as appropriate.
194 FunctionRibKind(NodeId /* func id */, NodeId /* body id */),
196 // We passed through an impl or trait and are now in one of its
197 // methods. Allow references to ty params that impl or trait
198 // binds. Disallow any other upvars (including other ty params that are
200 // parent; method itself
201 MethodRibKind(NodeId, MethodSort),
203 // We passed through a function *item* scope. Disallow upvars.
204 OpaqueFunctionRibKind,
206 // We're in a constant item. Can't refer to dynamic stuff.
210 // Methods can be required or provided. Required methods only occur in traits.
211 pub enum MethodSort {
216 // The X-ray flag indicates that a context has the X-ray privilege, which
217 // allows it to reference private names. Currently, this is used for the test
220 // FIXME #4947: The X-ray flag is kind of questionable in the first
221 // place. It might be better to introduce an expr_xray_path instead.
225 NoXray, //< Private items cannot be accessed.
226 Xray //< Private items can be accessed.
229 pub enum UseLexicalScopeFlag {
234 pub enum SearchThroughModulesFlag {
235 DontSearchThroughModules,
239 pub enum ModulePrefixResult {
241 PrefixFound(@mut Module, uint)
245 pub enum AllowCapturingSelfFlag {
246 AllowCapturingSelf, //< The "self" definition can be captured.
247 DontAllowCapturingSelf, //< The "self" definition cannot be captured.
251 enum NameSearchType {
252 /// We're doing a name search in order to resolve a `use` directive.
255 /// We're doing a name search in order to resolve a path type, a path
256 /// expression, or a path pattern. We can select public or private
259 /// XXX: This should be ripped out of resolve and handled later, in
260 /// the privacy checking phase.
261 PathPublicOrPrivateSearch,
263 /// We're doing a name search in order to resolve a path type, a path
264 /// expression, or a path pattern. Allow only public names to be selected.
265 PathPublicOnlySearch,
268 pub enum BareIdentifierPatternResolution {
269 FoundStructOrEnumVariant(def),
271 BareIdentifierPatternUnresolved
274 // Specifies how duplicates should be handled when adding a child item if
275 // another item exists with the same name in some namespace.
277 pub enum DuplicateCheckingMode {
278 ForbidDuplicateModules,
279 ForbidDuplicateTypes,
280 ForbidDuplicateValues,
281 ForbidDuplicateTypesAndValues,
287 bindings: @mut HashMap<ident,def_like>,
288 self_binding: @mut Option<def_like>,
292 pub fn Rib(kind: RibKind) -> Rib {
294 bindings: @mut HashMap::new(),
295 self_binding: @mut None,
301 /// One import directive.
302 pub struct ImportDirective {
304 module_path: ~[ident],
305 subclass: @ImportDirectiveSubclass,
310 pub fn ImportDirective(privacy: Privacy,
311 module_path: ~[ident],
312 subclass: @ImportDirectiveSubclass,
318 module_path: module_path,
325 /// The item that an import resolves to.
327 target_module: @mut Module,
328 bindings: @mut NameBindings,
331 pub fn Target(target_module: @mut Module,
332 bindings: @mut NameBindings)
335 target_module: target_module,
340 /// An ImportResolution represents a particular `use` directive.
341 pub struct ImportResolution {
342 /// The privacy of this `use` directive (whether it's `use` or
346 // The number of outstanding references to this name. When this reaches
347 // zero, outside modules can count on the targets being correct. Before
348 // then, all bets are off; future imports could override this name.
349 outstanding_references: uint,
351 /// The value that this `use` directive names, if there is one.
352 value_target: Option<Target>,
353 /// The source node of the `use` directive leading to the value target
357 /// The type that this `use` directive names, if there is one.
358 type_target: Option<Target>,
359 /// The source node of the `use` directive leading to the type target
364 pub fn ImportResolution(privacy: Privacy,
365 id: NodeId) -> ImportResolution {
370 outstanding_references: 0,
376 impl ImportResolution {
377 pub fn target_for_namespace(&self, namespace: Namespace)
380 TypeNS => return self.type_target,
381 ValueNS => return self.value_target,
385 fn id(&self, namespace: Namespace) -> NodeId {
387 TypeNS => self.type_id,
388 ValueNS => self.value_id,
393 /// The link from a module up to its nearest parent node.
394 pub enum ParentLink {
396 ModuleParentLink(@mut Module, ident),
397 BlockParentLink(@mut Module, NodeId)
400 /// The type of module this is.
402 pub enum ModuleKind {
410 /// One node in the tree of modules.
412 parent_link: ParentLink,
413 def_id: Option<def_id>,
416 children: @mut HashMap<ident, @mut NameBindings>,
417 imports: @mut ~[@ImportDirective],
419 // The external module children of this node that were declared with
421 external_module_children: @mut HashMap<ident, @mut Module>,
423 // The anonymous children of this node. Anonymous children are pseudo-
424 // modules that are implicitly created around items contained within
427 // For example, if we have this:
435 // There will be an anonymous module created around `g` with the ID of the
436 // entry block for `f`.
437 anonymous_children: @mut HashMap<NodeId,@mut Module>,
439 // The status of resolving each import in this module.
440 import_resolutions: @mut HashMap<ident, @mut ImportResolution>,
442 // The number of unresolved globs that this module exports.
445 // The index of the import we're resolving.
446 resolved_import_count: uint,
449 pub fn Module(parent_link: ParentLink,
450 def_id: Option<def_id>,
454 parent_link: parent_link,
457 children: @mut HashMap::new(),
459 external_module_children: @mut HashMap::new(),
460 anonymous_children: @mut HashMap::new(),
461 import_resolutions: @mut HashMap::new(),
463 resolved_import_count: 0
468 pub fn all_imports_resolved(&self) -> bool {
469 let imports = &mut *self.imports;
470 return imports.len() == self.resolved_import_count;
474 // Records a possibly-private type definition.
475 pub struct TypeNsDef {
477 module_def: Option<@mut Module>,
478 type_def: Option<def>,
479 type_span: Option<span>
482 // Records a possibly-private value definition.
483 pub struct ValueNsDef {
486 value_span: Option<span>,
489 // Records the definitions (at most one for each namespace) that a name is
491 pub struct NameBindings {
492 type_def: Option<TypeNsDef>, //< Meaning in type namespace.
493 value_def: Option<ValueNsDef>, //< Meaning in value namespace.
496 /// Ways in which a trait can be referenced
497 enum TraitReferenceType {
498 TraitImplementation, // impl SomeTrait for T { ... }
499 TraitDerivation, // trait T : SomeTrait { ... }
500 TraitBoundingTypeParameter, // fn f<T:SomeTrait>() { ... }
504 /// Creates a new module in this set of name bindings.
505 pub fn define_module(@mut self,
507 parent_link: ParentLink,
508 def_id: Option<def_id>,
511 // Merges the module with the existing type def or creates a new one.
512 let module_ = @mut Module(parent_link, def_id, kind);
513 match self.type_def {
515 self.type_def = Some(TypeNsDef {
517 module_def: Some(module_),
523 self.type_def = Some(TypeNsDef {
525 module_def: Some(module_),
527 type_def: type_def.type_def
533 /// Sets the kind of the module, creating a new one if necessary.
534 pub fn set_module_kind(@mut self,
536 parent_link: ParentLink,
537 def_id: Option<def_id>,
540 match self.type_def {
542 let module = @mut Module(parent_link, def_id, kind);
543 self.type_def = Some(TypeNsDef {
545 module_def: Some(module),
551 match type_def.module_def {
553 let module = @mut Module(parent_link, def_id, kind);
554 self.type_def = Some(TypeNsDef {
556 module_def: Some(module),
557 type_def: type_def.type_def,
561 Some(module_def) => module_def.kind = kind,
567 /// Records a type definition.
568 pub fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
569 // Merges the type with the existing type def or creates a new one.
570 match self.type_def {
572 self.type_def = Some(TypeNsDef {
580 self.type_def = Some(TypeNsDef {
584 module_def: type_def.module_def
590 /// Records a value definition.
591 pub fn define_value(@mut self, privacy: Privacy, def: def, sp: span) {
592 self.value_def = Some(ValueNsDef { privacy: privacy, def: def, value_span: Some(sp) });
595 /// Returns the module node if applicable.
596 pub fn get_module_if_available(&self) -> Option<@mut Module> {
597 match self.type_def {
598 Some(ref type_def) => (*type_def).module_def,
604 * Returns the module node. Fails if this node does not have a module
607 pub fn get_module(@mut self) -> @mut Module {
608 match self.get_module_if_available() {
610 fail!("get_module called on a node with no module \
613 Some(module_def) => module_def
617 pub fn defined_in_namespace(&self, namespace: Namespace) -> bool {
619 TypeNS => return self.type_def.is_some(),
620 ValueNS => return self.value_def.is_some()
624 pub fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
626 TypeNS => match self.type_def {
627 Some(def) => def.privacy != Private,
630 ValueNS => match self.value_def {
631 Some(def) => def.privacy != Private,
637 pub fn def_for_namespace(&self, namespace: Namespace) -> Option<def> {
640 match self.type_def {
642 Some(ref type_def) => {
643 match (*type_def).type_def {
644 Some(type_def) => Some(type_def),
646 match type_def.module_def {
648 match module.def_id {
649 Some(did) => Some(def_mod(did)),
661 match self.value_def {
663 Some(value_def) => Some(value_def.def)
669 pub fn privacy_for_namespace(&self, namespace: Namespace)
673 match self.type_def {
675 Some(ref type_def) => Some((*type_def).privacy)
679 match self.value_def {
681 Some(value_def) => Some(value_def.privacy)
687 pub fn span_for_namespace(&self, namespace: Namespace) -> Option<span> {
688 if self.defined_in_namespace(namespace) {
691 match self.type_def {
693 Some(type_def) => type_def.type_span
697 match self.value_def {
699 Some(value_def) => value_def.value_span
709 pub fn NameBindings() -> NameBindings {
716 /// Interns the names of the primitive types.
717 pub struct PrimitiveTypeTable {
718 primitive_types: HashMap<ident,prim_ty>,
721 impl PrimitiveTypeTable {
722 pub fn intern(&mut self,
724 primitive_type: prim_ty) {
725 let ident = token::str_to_ident(string);
726 self.primitive_types.insert(ident, primitive_type);
730 pub fn PrimitiveTypeTable() -> PrimitiveTypeTable {
731 let mut table = PrimitiveTypeTable {
732 primitive_types: HashMap::new()
735 table.intern("bool", ty_bool);
736 table.intern("char", ty_int(ty_char));
737 table.intern("float", ty_float(ty_f));
738 table.intern("f32", ty_float(ty_f32));
739 table.intern("f64", ty_float(ty_f64));
740 table.intern("int", ty_int(ty_i));
741 table.intern("i8", ty_int(ty_i8));
742 table.intern("i16", ty_int(ty_i16));
743 table.intern("i32", ty_int(ty_i32));
744 table.intern("i64", ty_int(ty_i64));
745 table.intern("str", ty_str);
746 table.intern("uint", ty_uint(ty_u));
747 table.intern("u8", ty_uint(ty_u8));
748 table.intern("u16", ty_uint(ty_u16));
749 table.intern("u32", ty_uint(ty_u32));
750 table.intern("u64", ty_uint(ty_u64));
756 pub fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
759 ModuleError => "module",
761 ValueError => "value",
765 pub fn Resolver(session: Session,
766 lang_items: LanguageItems,
769 let graph_root = @mut NameBindings();
771 graph_root.define_module(Public,
773 Some(def_id { crate: 0, node: 0 }),
777 let current_module = graph_root.get_module();
779 let this = Resolver {
781 lang_items: lang_items,
784 // The outermost module has def ID 0; this is not reflected in the
787 graph_root: graph_root,
789 method_map: @mut HashMap::new(),
790 structs: HashSet::new(),
792 unresolved_imports: 0,
794 current_module: current_module,
795 value_ribs: @mut ~[],
797 label_ribs: @mut ~[],
799 xray_context: NoXray,
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: @mut HashMap::new(),
810 export_map2: @mut HashMap::new(),
811 trait_map: HashMap::new(),
812 used_imports: HashSet::new(),
820 /// The main resolver class.
821 pub struct Resolver {
823 lang_items: LanguageItems,
826 intr: @ident_interner,
828 graph_root: @mut NameBindings,
830 method_map: @mut HashMap<ident, HashSet<def_id>>,
831 structs: HashSet<def_id>,
833 // The number of imports that are currently unresolved.
834 unresolved_imports: uint,
836 // The module that represents the current item scope.
837 current_module: @mut Module,
839 // The current set of local scopes, for values.
840 // FIXME #4948: Reuse ribs to avoid allocation.
841 value_ribs: @mut ~[@Rib],
843 // The current set of local scopes, for types.
844 type_ribs: @mut ~[@Rib],
846 // The current set of local scopes, for labels.
847 label_ribs: @mut ~[@Rib],
849 // Whether the current context is an X-ray context. An X-ray context is
850 // allowed to access private names of any module.
851 xray_context: XrayFlag,
853 // The trait that the current context can refer to.
854 current_trait_refs: Option<~[def_id]>,
856 // The ident for the keyword "self".
858 // The ident for the non-keyword "Self".
859 type_self_ident: ident,
861 // The idents for the primitive types.
862 primitive_type_table: @PrimitiveTypeTable,
864 // The four namespaces.
865 namespaces: ~[Namespace],
868 export_map2: ExportMap2,
871 used_imports: HashSet<NodeId>,
875 /// The main name resolution procedure.
876 pub fn resolve(@mut self) {
877 self.build_reduced_graph();
878 self.session.abort_if_errors();
880 self.resolve_imports();
881 self.session.abort_if_errors();
883 self.record_exports();
884 self.session.abort_if_errors();
886 self.resolve_crate();
887 self.session.abort_if_errors();
889 self.check_for_unused_imports();
893 // Reduced graph building
895 // Here we build the "reduced graph": the graph of the module tree without
896 // any imports resolved.
899 /// Constructs the reduced graph for the entire crate.
900 pub fn build_reduced_graph(@mut self) {
902 ModuleReducedGraphParent(self.graph_root.get_module());
903 visit_crate(self.crate, (initial_parent, mk_vt(@Visitor {
904 visit_item: |item, (context, visitor)|
905 self.build_reduced_graph_for_item(item, (context, visitor)),
907 visit_foreign_item: |foreign_item, (context, visitor)|
908 self.build_reduced_graph_for_foreign_item(foreign_item,
912 visit_view_item: |view_item, (context, visitor)|
913 self.build_reduced_graph_for_view_item(view_item,
917 visit_block: |block, (context, visitor)|
918 self.build_reduced_graph_for_block(block,
922 .. *default_visitor()
926 /// Returns the current module tracked by the reduced graph parent.
927 pub fn get_module_from_parent(@mut self,
928 reduced_graph_parent: ReducedGraphParent)
930 match reduced_graph_parent {
931 ModuleReducedGraphParent(module_) => {
938 * Adds a new child item to the module definition of the parent node and
939 * returns its corresponding name bindings as well as the current parent.
940 * Or, if we're inside a block, creates (or reuses) an anonymous module
941 * corresponding to the innermost block ID and returns the name bindings
942 * as well as the newly-created parent.
944 * If this node does not have a module definition and we are not inside
947 pub fn add_child(@mut self,
949 reduced_graph_parent: ReducedGraphParent,
950 duplicate_checking_mode: DuplicateCheckingMode,
951 // For printing errors
953 -> (@mut NameBindings, ReducedGraphParent) {
954 // If this is the immediate descendant of a module, then we add the
955 // child name directly. Otherwise, we create or reuse an anonymous
956 // module and add the child to that.
959 match reduced_graph_parent {
960 ModuleReducedGraphParent(parent_module) => {
961 module_ = parent_module;
965 // Add or reuse the child.
966 let new_parent = ModuleReducedGraphParent(module_);
967 match module_.children.find(&name) {
969 let child = @mut NameBindings();
970 module_.children.insert(name, child);
971 return (child, new_parent);
974 // Enforce the duplicate checking mode:
976 // * If we're requesting duplicate module checking, check that
977 // there isn't a module in the module with the same name.
979 // * If we're requesting duplicate type checking, check that
980 // there isn't a type in the module with the same name.
982 // * If we're requesting duplicate value checking, check that
983 // there isn't a value in the module with the same name.
985 // * If we're requesting duplicate type checking and duplicate
986 // value checking, check that there isn't a duplicate type
987 // and a duplicate value with the same name.
989 // * If no duplicate checking was requested at all, do
992 let mut duplicate_type = NoError;
993 let ns = match duplicate_checking_mode {
994 ForbidDuplicateModules => {
995 if (child.get_module_if_available().is_some()) {
996 duplicate_type = ModuleError;
1000 ForbidDuplicateTypes => {
1001 match child.def_for_namespace(TypeNS) {
1002 Some(def_mod(_)) | None => {}
1003 Some(_) => duplicate_type = TypeError
1007 ForbidDuplicateValues => {
1008 if child.defined_in_namespace(ValueNS) {
1009 duplicate_type = ValueError;
1013 ForbidDuplicateTypesAndValues => {
1015 match child.def_for_namespace(TypeNS) {
1016 Some(def_mod(_)) | None => {}
1019 duplicate_type = TypeError;
1022 if child.defined_in_namespace(ValueNS) {
1023 duplicate_type = ValueError;
1028 OverwriteDuplicates => None
1030 if (duplicate_type != NoError) {
1031 // Return an error here by looking up the namespace that
1032 // had the duplicate.
1033 let ns = ns.unwrap();
1034 self.session.span_err(sp,
1035 fmt!("duplicate definition of %s `%s`",
1036 namespace_error_to_str(duplicate_type),
1037 self.session.str_of(name)));
1039 let r = child.span_for_namespace(ns);
1040 for sp in r.iter() {
1041 self.session.span_note(*sp,
1042 fmt!("first definition of %s `%s` here",
1043 namespace_error_to_str(duplicate_type),
1044 self.session.str_of(name)));
1048 return (child, new_parent);
1053 pub fn block_needs_anonymous_module(@mut self, block: &Block) -> bool {
1054 // If the block has view items, we need an anonymous module.
1055 if block.view_items.len() > 0 {
1059 // Check each statement.
1060 for statement in block.stmts.iter() {
1061 match statement.node {
1062 stmt_decl(declaration, _) => {
1063 match declaration.node {
1078 // If we found neither view items nor items, we don't need to create
1079 // an anonymous module.
1084 pub fn get_parent_link(@mut self, parent: ReducedGraphParent, name: ident)
1087 ModuleReducedGraphParent(module_) => {
1088 return ModuleParentLink(module_, name);
1093 /// Constructs the reduced graph for one item.
1094 pub fn build_reduced_graph_for_item(@mut self,
1096 (parent, visitor): (ReducedGraphParent,
1097 vt<ReducedGraphParent>)) {
1098 let ident = item.ident;
1100 let privacy = visibility_to_privacy(item.vis);
1103 item_mod(ref module_) => {
1104 let (name_bindings, new_parent) =
1105 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1107 let parent_link = self.get_parent_link(new_parent, ident);
1108 let def_id = def_id { crate: 0, node: item.id };
1109 name_bindings.define_module(privacy,
1116 ModuleReducedGraphParent(name_bindings.get_module());
1118 visit_mod(module_, sp, item.id, (new_parent, visitor));
1121 item_foreign_mod(ref fm) => {
1122 let new_parent = match fm.sort {
1124 let (name_bindings, new_parent) =
1125 self.add_child(ident, parent,
1126 ForbidDuplicateModules, sp);
1128 let parent_link = self.get_parent_link(new_parent,
1130 let def_id = def_id { crate: 0, node: item.id };
1131 name_bindings.define_module(privacy,
1137 ModuleReducedGraphParent(name_bindings.get_module())
1140 // For anon foreign mods, the contents just go in the
1145 visit_item(item, (new_parent, visitor));
1148 // These items live in the value namespace.
1149 item_static(_, m, _) => {
1150 let (name_bindings, _) =
1151 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1152 let mutbl = m == ast::m_mutbl;
1154 name_bindings.define_value
1155 (privacy, def_static(local_def(item.id), mutbl), sp);
1157 item_fn(_, purity, _, _, _) => {
1158 let (name_bindings, new_parent) =
1159 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1161 let def = def_fn(local_def(item.id), purity);
1162 name_bindings.define_value(privacy, def, sp);
1163 visit_item(item, (new_parent, visitor));
1166 // These items live in the type namespace.
1168 let (name_bindings, _) =
1169 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1171 name_bindings.define_type
1172 (privacy, def_ty(local_def(item.id)), sp);
1175 item_enum(ref enum_definition, _) => {
1176 let (name_bindings, new_parent) =
1177 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1179 name_bindings.define_type
1180 (privacy, def_ty(local_def(item.id)), sp);
1182 for variant in (*enum_definition).variants.iter() {
1183 self.build_reduced_graph_for_variant(
1186 // inherited => privacy of the enum item
1187 variant_visibility_to_privacy(variant.node.vis,
1189 (new_parent, visitor));
1193 // These items live in both the type and value namespaces.
1194 item_struct(struct_def, _) => {
1195 // Adding to both Type and Value namespaces or just Type?
1196 let (forbid, ctor_id) = match struct_def.ctor_id {
1197 Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
1198 None => (ForbidDuplicateTypes, None)
1201 let (name_bindings, new_parent) = self.add_child(ident, parent, forbid, sp);
1203 // Define a name in the type namespace.
1204 name_bindings.define_type(privacy, def_ty(local_def(item.id)), sp);
1206 // If this is a newtype or unit-like struct, define a name
1207 // in the value namespace as well
1208 do ctor_id.while_some |cid| {
1209 name_bindings.define_value(privacy, def_struct(local_def(cid)), sp);
1213 // Record the def ID of this struct.
1214 self.structs.insert(local_def(item.id));
1216 visit_item(item, (new_parent, visitor));
1219 item_impl(_, None, ref ty, ref methods) => {
1220 // If this implements an anonymous trait, then add all the
1221 // methods within to a new module, if the type was defined
1222 // within this module.
1224 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1225 // should modify anonymous traits to only be implementable in
1226 // the same module that declared the type.
1228 // Create the module and add all methods.
1231 node: ty_path(ref path, _, _),
1233 } if path.idents.len() == 1 => {
1234 let name = path_to_ident(path);
1236 let new_parent = match parent.children.find(&name) {
1237 // It already exists
1238 Some(&child) if child.get_module_if_available()
1240 child.get_module().kind ==
1242 ModuleReducedGraphParent(child.get_module())
1244 // Create the module
1246 let (name_bindings, new_parent) =
1247 self.add_child(name,
1249 ForbidDuplicateModules,
1253 self.get_parent_link(new_parent, ident);
1254 let def_id = local_def(item.id);
1255 name_bindings.define_module(Public,
1261 ModuleReducedGraphParent(
1262 name_bindings.get_module())
1266 // For each method...
1267 for method in methods.iter() {
1268 // Add the method to the module.
1269 let ident = method.ident;
1270 let (method_name_bindings, _) =
1271 self.add_child(ident,
1273 ForbidDuplicateValues,
1275 let def = match method.explicit_self.node {
1277 // Static methods become `def_fn`s.
1278 def_fn(local_def(method.id),
1282 // Non-static methods become
1284 def_method(local_def(method.id), None)
1288 method_name_bindings.define_value(Public,
1296 visit_item(item, (parent, visitor));
1299 item_impl(_, Some(_), _, _) => {
1300 visit_item(item, (parent, visitor));
1303 item_trait(_, _, ref methods) => {
1304 let (name_bindings, new_parent) =
1305 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1307 // Add all the methods within to a new module.
1308 let parent_link = self.get_parent_link(parent, ident);
1309 name_bindings.define_module(privacy,
1311 Some(local_def(item.id)),
1314 let module_parent = ModuleReducedGraphParent(name_bindings.
1317 // Add the names of all the methods to the trait info.
1318 let mut method_names = HashMap::new();
1319 for method in methods.iter() {
1320 let ty_m = trait_method_to_ty_method(method);
1322 let ident = ty_m.ident;
1324 // Add it as a name in the trait module.
1325 let def = match ty_m.explicit_self.node {
1327 // Static methods become `def_static_method`s.
1328 def_static_method(local_def(ty_m.id),
1329 Some(local_def(item.id)),
1333 // Non-static methods become `def_method`s.
1334 def_method(local_def(ty_m.id),
1335 Some(local_def(item.id)))
1339 let (method_name_bindings, _) =
1340 self.add_child(ident,
1342 ForbidDuplicateValues,
1344 method_name_bindings.define_value(Public, def, ty_m.span);
1346 // Add it to the trait info if not static.
1347 match ty_m.explicit_self.node {
1350 method_names.insert(ident, ());
1355 let def_id = local_def(item.id);
1356 for (name, _) in method_names.iter() {
1357 if !self.method_map.contains_key(name) {
1358 self.method_map.insert(*name, HashSet::new());
1360 match self.method_map.find_mut(name) {
1361 Some(s) => { s.insert(def_id); },
1362 _ => fail!("Can't happen"),
1366 name_bindings.define_type(privacy, def_trait(def_id), sp);
1367 visit_item(item, (new_parent, visitor));
1371 fail!("item macros unimplemented")
1376 // Constructs the reduced graph for one variant. Variants exist in the
1377 // type and/or value namespaces.
1378 pub fn build_reduced_graph_for_variant(@mut self,
1381 parent_privacy: Privacy,
1383 (ReducedGraphParent,
1384 vt<ReducedGraphParent>)) {
1385 let ident = variant.node.name;
1388 match variant.node.vis {
1391 inherited => parent_privacy
1394 match variant.node.kind {
1395 tuple_variant_kind(_) => {
1396 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1398 child.define_value(privacy,
1399 def_variant(item_id,
1400 local_def(variant.node.id)),
1403 struct_variant_kind(_) => {
1404 let (child, _) = self.add_child(ident, parent, ForbidDuplicateTypesAndValues,
1406 child.define_type(privacy,
1407 def_variant(item_id,
1408 local_def(variant.node.id)),
1410 self.structs.insert(local_def(variant.node.id));
1415 /// Constructs the reduced graph for one 'view item'. View items consist
1416 /// of imports and use directives.
1417 pub fn build_reduced_graph_for_view_item(@mut self,
1418 view_item: &view_item,
1420 (ReducedGraphParent,
1421 vt<ReducedGraphParent>)) {
1422 let privacy = visibility_to_privacy(view_item.vis);
1423 match view_item.node {
1424 view_item_use(ref view_paths) => {
1425 for view_path in view_paths.iter() {
1426 // Extract and intern the module part of the path. For
1427 // globs and lists, the path is found directly in the AST;
1428 // for simple paths we have to munge the path a little.
1430 let mut module_path = ~[];
1431 match view_path.node {
1432 view_path_simple(_, ref full_path, _) => {
1433 let path_len = full_path.idents.len();
1434 assert!(path_len != 0);
1436 for (i, ident) in full_path.idents.iter().enumerate() {
1437 if i != path_len - 1 {
1438 module_path.push(*ident);
1443 view_path_glob(ref module_ident_path, _) |
1444 view_path_list(ref module_ident_path, _, _) => {
1445 for ident in module_ident_path.idents.iter() {
1446 module_path.push(*ident);
1451 // Build up the import directives.
1452 let module_ = self.get_module_from_parent(parent);
1453 match view_path.node {
1454 view_path_simple(binding, ref full_path, id) => {
1455 let source_ident = *full_path.idents.last();
1456 let subclass = @SingleImport(binding,
1458 self.build_import_directive(privacy,
1465 view_path_list(_, ref source_idents, _) => {
1466 for source_ident in source_idents.iter() {
1467 let name = source_ident.node.name;
1468 let subclass = @SingleImport(name, name);
1469 self.build_import_directive(
1472 module_path.clone(),
1475 source_ident.node.id);
1478 view_path_glob(_, id) => {
1479 self.build_import_directive(privacy,
1490 view_item_extern_mod(name, _, node_id) => {
1491 match find_extern_mod_stmt_cnum(self.session.cstore,
1494 let def_id = def_id { crate: crate_id, node: 0 };
1495 let parent_link = ModuleParentLink
1496 (self.get_module_from_parent(parent), name);
1497 let external_module = @mut Module(parent_link,
1501 parent.external_module_children.insert(
1505 self.build_reduced_graph_for_external_crate(
1508 None => {} // Ignore.
1514 /// Constructs the reduced graph for one foreign item.
1515 pub fn build_reduced_graph_for_foreign_item(@mut self,
1516 foreign_item: @foreign_item,
1518 (ReducedGraphParent,
1519 vt<ReducedGraphParent>)) {
1520 let name = foreign_item.ident;
1521 let (name_bindings, new_parent) =
1522 self.add_child(name, parent, ForbidDuplicateValues,
1525 match foreign_item.node {
1526 foreign_item_fn(_, ref generics) => {
1527 let def = def_fn(local_def(foreign_item.id), unsafe_fn);
1528 name_bindings.define_value(Public, def, foreign_item.span);
1530 do self.with_type_parameter_rib(
1532 generics, foreign_item.id, 0, NormalRibKind))
1534 visit_foreign_item(foreign_item, (new_parent, visitor));
1537 foreign_item_static(_, m) => {
1538 let def = def_static(local_def(foreign_item.id), m);
1539 name_bindings.define_value(Public, def, foreign_item.span);
1541 visit_foreign_item(foreign_item, (new_parent, visitor));
1546 pub fn build_reduced_graph_for_block(@mut self,
1549 (ReducedGraphParent,
1550 vt<ReducedGraphParent>)) {
1552 if self.block_needs_anonymous_module(block) {
1553 let block_id = block.id;
1555 debug!("(building reduced graph for block) creating a new \
1556 anonymous module for block %d",
1559 let parent_module = self.get_module_from_parent(parent);
1560 let new_module = @mut Module(
1561 BlockParentLink(parent_module, block_id),
1563 AnonymousModuleKind);
1564 parent_module.anonymous_children.insert(block_id, new_module);
1565 new_parent = ModuleReducedGraphParent(new_module);
1567 new_parent = parent;
1570 visit_block(block, (new_parent, visitor));
1573 pub fn handle_external_def(@mut self,
1575 visibility: ast::visibility,
1576 modules: &mut HashMap<def_id, @mut Module>,
1577 child_name_bindings: @mut NameBindings,
1580 new_parent: ReducedGraphParent) {
1581 let privacy = visibility_to_privacy(visibility);
1583 def_mod(def_id) | def_foreign_mod(def_id) => {
1584 match child_name_bindings.type_def {
1585 Some(TypeNsDef { module_def: Some(module_def), _ }) => {
1586 debug!("(building reduced graph for external crate) \
1587 already created module");
1588 module_def.def_id = Some(def_id);
1589 modules.insert(def_id, module_def);
1592 debug!("(building reduced graph for \
1593 external crate) building module \
1595 let parent_link = self.get_parent_link(new_parent, ident);
1597 // FIXME (#5074): this should be a match on find
1598 if !modules.contains_key(&def_id) {
1599 child_name_bindings.define_module(privacy,
1604 modules.insert(def_id,
1605 child_name_bindings.get_module());
1607 let existing_module = *modules.get(&def_id);
1609 // Create an import resolution to avoid creating cycles in
1610 // the module graph.
1612 let resolution = @mut ImportResolution(Public, 0);
1613 resolution.outstanding_references = 0;
1615 match existing_module.parent_link {
1617 BlockParentLink(*) => {
1618 fail!("can't happen");
1620 ModuleParentLink(parent_module, ident) => {
1621 let name_bindings = parent_module.children.get(
1623 resolution.type_target =
1624 Some(Target(parent_module, *name_bindings));
1628 debug!("(building reduced graph for external crate) \
1629 ... creating import resolution");
1631 new_parent.import_resolutions.insert(ident, resolution);
1637 debug!("(building reduced graph for external crate) building \
1640 // We assume the parent is visible, or else we wouldn't have seen
1642 let privacy = variant_visibility_to_privacy(visibility, true);
1643 child_name_bindings.define_value(privacy, def, dummy_sp());
1645 def_fn(*) | def_static_method(*) | def_static(*) => {
1646 debug!("(building reduced graph for external \
1647 crate) building value %s", final_ident);
1648 child_name_bindings.define_value(privacy, def, dummy_sp());
1650 def_trait(def_id) => {
1651 debug!("(building reduced graph for external \
1652 crate) building type %s", final_ident);
1654 // If this is a trait, add all the method names
1655 // to the trait info.
1657 let method_def_ids =
1658 get_trait_method_def_ids(self.session.cstore, def_id);
1659 let mut interned_method_names = HashSet::new();
1660 for &method_def_id in method_def_ids.iter() {
1661 let (method_name, explicit_self) =
1662 get_method_name_and_explicit_self(self.session.cstore,
1665 debug!("(building reduced graph for \
1666 external crate) ... adding \
1668 self.session.str_of(method_name));
1670 // Add it to the trait info if not static.
1671 if explicit_self != sty_static {
1672 interned_method_names.insert(method_name);
1675 for name in interned_method_names.iter() {
1676 if !self.method_map.contains_key(name) {
1677 self.method_map.insert(*name, HashSet::new());
1679 match self.method_map.find_mut(name) {
1680 Some(s) => { s.insert(def_id); },
1681 _ => fail!("Can't happen"),
1685 child_name_bindings.define_type(privacy, def, dummy_sp());
1687 // Define a module if necessary.
1688 let parent_link = self.get_parent_link(new_parent, ident);
1689 child_name_bindings.set_module_kind(privacy,
1696 debug!("(building reduced graph for external \
1697 crate) building type %s", final_ident);
1699 child_name_bindings.define_type(privacy, def, dummy_sp());
1701 def_struct(def_id) => {
1702 debug!("(building reduced graph for external \
1703 crate) building type %s",
1705 child_name_bindings.define_type(privacy, def, dummy_sp());
1706 self.structs.insert(def_id);
1709 // Ignored; handled elsewhere.
1711 def_self(*) | def_arg(*) | def_local(*) |
1712 def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
1713 def_use(*) | def_upvar(*) | def_region(*) |
1714 def_typaram_binder(*) | def_label(*) | def_self_ty(*) => {
1715 fail!("didn't expect `%?`", def);
1721 * Builds the reduced graph rooted at the 'use' directive for an external
1724 pub fn build_reduced_graph_for_external_crate(@mut self,
1725 root: @mut Module) {
1726 let mut modules = HashMap::new();
1728 // Create all the items reachable by paths.
1729 do each_path(self.session.cstore, root.def_id.unwrap().crate)
1730 |path_string, def_like, visibility| {
1732 debug!("(building reduced graph for external crate) found path \
1734 path_string, def_like);
1736 let mut pieces: ~[&str] = path_string.split_str_iter("::").collect();
1737 let final_ident_str = pieces.pop();
1738 let final_ident = self.session.ident_of(final_ident_str);
1740 // Find the module we need, creating modules along the way if we
1743 let mut current_module = root;
1744 for ident_str in pieces.iter() {
1745 let ident = self.session.ident_of(*ident_str);
1746 // Create or reuse a graph node for the child.
1747 let (child_name_bindings, new_parent) =
1748 self.add_child(ident,
1749 ModuleReducedGraphParent(current_module),
1750 OverwriteDuplicates,
1753 // Define or reuse the module node.
1754 match child_name_bindings.type_def {
1756 debug!("(building reduced graph for external crate) \
1757 autovivifying missing type def %s",
1759 let parent_link = self.get_parent_link(new_parent,
1761 child_name_bindings.define_module(Public,
1768 if type_ns_def.module_def.is_none() => {
1769 debug!("(building reduced graph for external crate) \
1770 autovivifying missing module def %s",
1772 let parent_link = self.get_parent_link(new_parent,
1774 child_name_bindings.define_module(Public,
1780 _ => {} // Fall through.
1783 current_module = child_name_bindings.get_module();
1788 // Add the new child item.
1789 let (child_name_bindings, new_parent) =
1790 self.add_child(final_ident,
1791 ModuleReducedGraphParent(
1793 OverwriteDuplicates,
1796 self.handle_external_def(def,
1799 child_name_bindings,
1800 self.session.str_of(
1806 // We only process static methods of impls here.
1807 match get_type_name_if_impl(self.session.cstore, def) {
1809 Some(final_ident) => {
1810 let static_methods_opt =
1811 get_static_methods_if_impl(
1812 self.session.cstore, def);
1813 match static_methods_opt {
1814 Some(ref static_methods) if
1815 static_methods.len() >= 1 => {
1816 debug!("(building reduced graph for \
1817 external crate) processing \
1818 static methods for type name %s",
1819 self.session.str_of(
1822 let (child_name_bindings, new_parent) =
1823 self.add_child(final_ident,
1824 ModuleReducedGraphParent(
1826 OverwriteDuplicates,
1829 // Process the static methods. First,
1830 // create the module.
1832 match child_name_bindings.type_def {
1834 module_def: Some(module_def),
1837 // We already have a module. This
1839 type_module = module_def;
1841 // Mark it as an impl module if
1843 type_module.kind = ImplModuleKind;
1847 self.get_parent_link(
1848 new_parent, final_ident);
1849 child_name_bindings.define_module(
1856 child_name_bindings.
1861 // Add each static method to the module.
1862 let new_parent = ModuleReducedGraphParent(
1864 for static_method_info in static_methods.iter() {
1865 let ident = static_method_info.ident;
1866 debug!("(building reduced graph for \
1867 external crate) creating \
1868 static method '%s'",
1869 self.session.str_of(ident));
1871 let (method_name_bindings, _) =
1875 OverwriteDuplicates,
1878 static_method_info.def_id,
1879 static_method_info.purity);
1880 method_name_bindings.define_value(
1881 Public, def, dummy_sp());
1885 // Otherwise, do nothing.
1886 Some(_) | None => {}
1892 debug!("(building reduced graph for external crate) \
1900 /// Creates and adds an import directive to the given module.
1901 pub fn build_import_directive(@mut self,
1903 module_: @mut Module,
1904 module_path: ~[ident],
1905 subclass: @ImportDirectiveSubclass,
1908 let directive = @ImportDirective(privacy, module_path,
1909 subclass, span, id);
1910 module_.imports.push(directive);
1912 // Bump the reference count on the name. Or, if this is a glob, set
1913 // the appropriate flag.
1916 SingleImport(target, _) => {
1917 debug!("(building import directive) building import \
1918 directive: privacy %? %s::%s",
1920 self.idents_to_str(directive.module_path),
1921 self.session.str_of(target));
1923 match module_.import_resolutions.find(&target) {
1924 Some(&resolution) => {
1925 debug!("(building import directive) bumping \
1927 resolution.outstanding_references += 1;
1929 // the source of this name is different now
1930 resolution.privacy = privacy;
1931 resolution.type_id = id;
1932 resolution.value_id = id;
1935 debug!("(building import directive) creating new");
1936 let resolution = @mut ImportResolution(privacy, id);
1937 resolution.outstanding_references = 1;
1938 module_.import_resolutions.insert(target, resolution);
1943 // Set the glob flag. This tells us that we don't know the
1944 // module's exports ahead of time.
1946 module_.glob_count += 1;
1950 self.unresolved_imports += 1;
1953 // Import resolution
1955 // This is a fixed-point algorithm. We resolve imports until our efforts
1956 // are stymied by an unresolved import; then we bail out of the current
1957 // module and continue. We terminate successfully once no more imports
1958 // remain or unsuccessfully when no forward progress in resolving imports
1961 /// Resolves all imports for the crate. This method performs the fixed-
1962 /// point iteration.
1963 pub fn resolve_imports(@mut self) {
1965 let mut prev_unresolved_imports = 0;
1967 debug!("(resolving imports) iteration %u, %u imports left",
1968 i, self.unresolved_imports);
1970 let module_root = self.graph_root.get_module();
1971 self.resolve_imports_for_module_subtree(module_root);
1973 if self.unresolved_imports == 0 {
1974 debug!("(resolving imports) success");
1978 if self.unresolved_imports == prev_unresolved_imports {
1979 self.report_unresolved_imports(module_root);
1984 prev_unresolved_imports = self.unresolved_imports;
1988 /// Attempts to resolve imports for the given module and all of its
1990 pub fn resolve_imports_for_module_subtree(@mut self,
1991 module_: @mut Module) {
1992 debug!("(resolving imports for module subtree) resolving %s",
1993 self.module_to_str(module_));
1994 self.resolve_imports_for_module(module_);
1996 for (_, &child_node) in module_.children.iter() {
1997 match child_node.get_module_if_available() {
2001 Some(child_module) => {
2002 self.resolve_imports_for_module_subtree(child_module);
2007 for (_, &child_module) in module_.anonymous_children.iter() {
2008 self.resolve_imports_for_module_subtree(child_module);
2012 /// Attempts to resolve imports for the given module only.
2013 pub fn resolve_imports_for_module(@mut self, module: @mut Module) {
2014 if module.all_imports_resolved() {
2015 debug!("(resolving imports for module) all imports resolved for \
2017 self.module_to_str(module));
2021 let imports = &mut *module.imports;
2022 let import_count = imports.len();
2023 while module.resolved_import_count < import_count {
2024 let import_index = module.resolved_import_count;
2025 let import_directive = imports[import_index];
2026 match self.resolve_import_for_module(module, import_directive) {
2028 // We presumably emitted an error. Continue.
2029 let msg = fmt!("failed to resolve import `%s`",
2030 self.import_path_to_str(
2031 import_directive.module_path,
2032 *import_directive.subclass));
2033 self.session.span_err(import_directive.span, msg);
2036 // Bail out. We'll come around next time.
2044 module.resolved_import_count += 1;
2048 pub fn idents_to_str(@mut self, idents: &[ident]) -> ~str {
2049 let mut first = true;
2050 let mut result = ~"";
2051 for ident in idents.iter() {
2055 result.push_str("::")
2057 result.push_str(self.session.str_of(*ident));
2062 pub fn import_directive_subclass_to_str(@mut self,
2063 subclass: ImportDirectiveSubclass)
2066 SingleImport(_target, source) => self.session.str_of(source),
2071 pub fn import_path_to_str(@mut self,
2073 subclass: ImportDirectiveSubclass)
2075 if idents.is_empty() {
2076 self.import_directive_subclass_to_str(subclass)
2079 self.idents_to_str(idents),
2080 self.import_directive_subclass_to_str(subclass))).to_managed()
2084 /// Attempts to resolve the given import. The return value indicates
2085 /// failure if we're certain the name does not exist, indeterminate if we
2086 /// don't know whether the name exists at the moment due to other
2087 /// currently-unresolved imports, or success if we know the name exists.
2088 /// If successful, the resolved bindings are written into the module.
2089 pub fn resolve_import_for_module(@mut self,
2090 module_: @mut Module,
2091 import_directive: @ImportDirective)
2092 -> ResolveResult<()> {
2093 let mut resolution_result = Failed;
2094 let module_path = &import_directive.module_path;
2096 debug!("(resolving import for module) resolving import `%s::...` in \
2098 self.idents_to_str(*module_path),
2099 self.module_to_str(module_));
2101 // First, resolve the module path for the directive, if necessary.
2102 let containing_module = if module_path.len() == 0 {
2103 // Use the crate root.
2104 Some(self.graph_root.get_module())
2106 match self.resolve_module_path(module_,
2108 DontUseLexicalScope,
2109 import_directive.span,
2114 resolution_result = Indeterminate;
2117 Success(containing_module) => Some(containing_module),
2121 match containing_module {
2123 Some(containing_module) => {
2124 // We found the module that the target is contained
2125 // within. Attempt to resolve the import within it.
2127 match *import_directive.subclass {
2128 SingleImport(target, source) => {
2130 self.resolve_single_import(module_,
2137 let privacy = import_directive.privacy;
2139 self.resolve_glob_import(privacy,
2142 import_directive.id);
2148 // Decrement the count of unresolved imports.
2149 match resolution_result {
2151 assert!(self.unresolved_imports >= 1);
2152 self.unresolved_imports -= 1;
2155 // Nothing to do here; just return the error.
2159 // Decrement the count of unresolved globs if necessary. But only if
2160 // the resolution result is indeterminate -- otherwise we'll stop
2161 // processing imports here. (See the loop in
2162 // resolve_imports_for_module.)
2164 if !resolution_result.indeterminate() {
2165 match *import_directive.subclass {
2167 assert!(module_.glob_count >= 1);
2168 module_.glob_count -= 1;
2170 SingleImport(*) => {
2176 return resolution_result;
2179 pub fn create_name_bindings_from_module(module: @mut Module)
2182 type_def: Some(TypeNsDef {
2184 module_def: Some(module),
2192 pub fn resolve_single_import(@mut self,
2193 module_: @mut Module,
2194 containing_module: @mut Module,
2197 directive: &ImportDirective)
2198 -> ResolveResult<()> {
2199 debug!("(resolving single import) resolving `%s` = `%s::%s` from \
2201 self.session.str_of(target),
2202 self.module_to_str(containing_module),
2203 self.session.str_of(source),
2204 self.module_to_str(module_));
2206 // We need to resolve both namespaces for this to succeed.
2208 // FIXME #4949: See if there's some way of handling namespaces in
2209 // a more generic way. We have two of them; it seems worth
2212 let mut value_result = UnknownResult;
2213 let mut type_result = UnknownResult;
2215 // Search for direct children of the containing module.
2216 match containing_module.children.find(&source) {
2220 Some(child_name_bindings) => {
2221 if child_name_bindings.defined_in_namespace(ValueNS) {
2222 value_result = BoundResult(containing_module,
2223 *child_name_bindings);
2225 if child_name_bindings.defined_in_namespace(TypeNS) {
2226 type_result = BoundResult(containing_module,
2227 *child_name_bindings);
2232 // Unless we managed to find a result in both namespaces (unlikely),
2233 // search imports as well.
2234 match (value_result, type_result) {
2235 (BoundResult(*), BoundResult(*)) => {} // Continue.
2237 // If there is an unresolved glob at this point in the
2238 // containing module, bail out. We don't know enough to be
2239 // able to resolve this import.
2241 if containing_module.glob_count > 0 {
2242 debug!("(resolving single import) unresolved glob; \
2244 return Indeterminate;
2247 // Now search the exported imports within the containing
2250 match containing_module.import_resolutions.find(&source) {
2252 // The containing module definitely doesn't have an
2253 // exported import with the name in question. We can
2254 // therefore accurately report that the names are
2257 if value_result.is_unknown() {
2258 value_result = UnboundResult;
2260 if type_result.is_unknown() {
2261 type_result = UnboundResult;
2264 Some(import_resolution)
2265 if import_resolution.outstanding_references
2268 fn get_binding(this: @mut Resolver,
2270 @mut ImportResolution,
2271 namespace: Namespace)
2272 -> NamespaceResult {
2274 // Import resolutions must be declared with "pub"
2275 // in order to be exported.
2276 if import_resolution.privacy == Private {
2277 return UnboundResult;
2280 match (*import_resolution).
2281 target_for_namespace(namespace) {
2283 return UnboundResult;
2286 let id = import_resolution.id(namespace);
2287 this.used_imports.insert(id);
2288 return BoundResult(target.target_module,
2294 // The name is an import which has been fully
2295 // resolved. We can, therefore, just follow it.
2296 if value_result.is_unknown() {
2297 value_result = get_binding(self, *import_resolution,
2300 if type_result.is_unknown() {
2301 type_result = get_binding(self, *import_resolution,
2306 // The import is unresolved. Bail out.
2307 debug!("(resolving single import) unresolved import; \
2309 return Indeterminate;
2315 // If we didn't find a result in the type namespace, search the
2316 // external modules.
2318 BoundResult(*) => {}
2320 match containing_module.external_module_children
2322 None => {} // Continue.
2325 @mut Resolver::create_name_bindings_from_module(
2327 type_result = BoundResult(containing_module,
2334 // We've successfully resolved the import. Write the results in.
2335 assert!(module_.import_resolutions.contains_key(&target));
2336 let import_resolution = module_.import_resolutions.get(&target);
2338 match value_result {
2339 BoundResult(target_module, name_bindings) => {
2340 debug!("(resolving single import) found value target");
2341 import_resolution.value_target =
2342 Some(Target(target_module, name_bindings));
2343 import_resolution.value_id = directive.id;
2345 UnboundResult => { /* Continue. */ }
2347 fail!("value result should be known at this point");
2351 BoundResult(target_module, name_bindings) => {
2352 debug!("(resolving single import) found type target: %?",
2353 name_bindings.type_def.unwrap().type_def);
2354 import_resolution.type_target =
2355 Some(Target(target_module, name_bindings));
2356 import_resolution.type_id = directive.id;
2358 UnboundResult => { /* Continue. */ }
2360 fail!("type result should be known at this point");
2364 let i = import_resolution;
2365 let mut resolve_fail = false;
2366 let mut priv_fail = false;
2367 match (i.value_target, i.type_target) {
2368 // If this name wasn't found in either namespace, it's definitely
2370 (None, None) => { resolve_fail = true; }
2371 // If it's private, it's also unresolved.
2372 (Some(t), None) | (None, Some(t)) => {
2373 let bindings = &mut *t.bindings;
2374 match bindings.type_def {
2375 Some(ref type_def) => {
2376 if type_def.privacy == Private {
2382 match bindings.value_def {
2383 Some(ref value_def) => {
2384 if value_def.privacy == Private {
2391 // It's also an error if there's both a type and a value with this
2392 // name, but both are private
2393 (Some(val), Some(ty)) => {
2394 match (val.bindings.value_def, ty.bindings.value_def) {
2395 (Some(ref value_def), Some(ref type_def)) =>
2396 if value_def.privacy == Private
2397 && type_def.privacy == Private {
2405 let span = directive.span;
2407 self.session.span_err(span, fmt!("unresolved import: there is no `%s` in `%s`",
2408 self.session.str_of(source),
2409 self.module_to_str(containing_module)));
2411 } else if priv_fail {
2412 self.session.span_err(span, fmt!("unresolved import: found `%s` in `%s` but it is \
2413 private", self.session.str_of(source),
2414 self.module_to_str(containing_module)));
2418 assert!(import_resolution.outstanding_references >= 1);
2419 import_resolution.outstanding_references -= 1;
2421 debug!("(resolving single import) successfully resolved import");
2425 // Resolves a glob import. Note that this function cannot fail; it either
2426 // succeeds or bails out (as importing * from an empty module or a module
2427 // that exports nothing is valid).
2428 pub fn resolve_glob_import(@mut self,
2430 module_: @mut Module,
2431 containing_module: @mut Module,
2433 -> ResolveResult<()> {
2434 // This function works in a highly imperative manner; it eagerly adds
2435 // everything it can to the list of import resolutions of the module
2437 debug!("(resolving glob import) resolving %? glob import", privacy);
2439 // We must bail out if the node has unresolved imports of any kind
2440 // (including globs).
2441 if !(*containing_module).all_imports_resolved() {
2442 debug!("(resolving glob import) target module has unresolved \
2443 imports; bailing out");
2444 return Indeterminate;
2447 assert_eq!(containing_module.glob_count, 0);
2449 // Add all resolved imports from the containing module.
2450 for (ident, target_import_resolution) in containing_module.import_resolutions.iter() {
2452 debug!("(resolving glob import) writing module resolution \
2454 target_import_resolution.type_target.is_none(),
2455 self.module_to_str(module_));
2457 // Here we merge two import resolutions.
2458 match module_.import_resolutions.find(ident) {
2459 None if target_import_resolution.privacy == Public => {
2460 // Simple: just copy the old import resolution.
2461 let new_import_resolution =
2462 @mut ImportResolution(privacy, id);
2463 new_import_resolution.value_target =
2464 target_import_resolution.value_target;
2465 new_import_resolution.type_target =
2466 target_import_resolution.type_target;
2468 module_.import_resolutions.insert
2469 (*ident, new_import_resolution);
2471 None => { /* continue ... */ }
2472 Some(&dest_import_resolution) => {
2473 // Merge the two import resolutions at a finer-grained
2476 match target_import_resolution.value_target {
2480 Some(value_target) => {
2481 dest_import_resolution.value_target =
2485 match target_import_resolution.type_target {
2489 Some(type_target) => {
2490 dest_import_resolution.type_target =
2498 let merge_import_resolution = |ident,
2499 name_bindings: @mut NameBindings| {
2500 let dest_import_resolution;
2501 match module_.import_resolutions.find(&ident) {
2503 // Create a new import resolution from this child.
2504 dest_import_resolution = @mut ImportResolution(privacy, id);
2505 module_.import_resolutions.insert
2506 (ident, dest_import_resolution);
2508 Some(&existing_import_resolution) => {
2509 dest_import_resolution = existing_import_resolution;
2513 debug!("(resolving glob import) writing resolution `%s` in `%s` \
2514 to `%s`, privacy=%?",
2515 self.session.str_of(ident),
2516 self.module_to_str(containing_module),
2517 self.module_to_str(module_),
2518 dest_import_resolution.privacy);
2520 // Merge the child item into the import resolution.
2521 if name_bindings.defined_in_public_namespace(ValueNS) {
2522 debug!("(resolving glob import) ... for value target");
2523 dest_import_resolution.value_target =
2524 Some(Target(containing_module, name_bindings));
2526 if name_bindings.defined_in_public_namespace(TypeNS) {
2527 debug!("(resolving glob import) ... for type target");
2528 dest_import_resolution.type_target =
2529 Some(Target(containing_module, name_bindings));
2533 // Add all children from the containing module.
2534 for (&ident, name_bindings) in containing_module.children.iter() {
2535 merge_import_resolution(ident, *name_bindings);
2538 // Add external module children from the containing module.
2539 for (&ident, module) in containing_module.external_module_children.iter() {
2541 @mut Resolver::create_name_bindings_from_module(*module);
2542 merge_import_resolution(ident, name_bindings);
2545 debug!("(resolving glob import) successfully resolved import");
2549 /// Resolves the given module path from the given root `module_`.
2550 pub fn resolve_module_path_from_root(@mut self,
2551 module_: @mut Module,
2552 module_path: &[ident],
2555 mut name_search_type: NameSearchType)
2556 -> ResolveResult<@mut Module> {
2557 let mut search_module = module_;
2558 let mut index = index;
2559 let module_path_len = module_path.len();
2561 // Resolve the module part of the path. This does not involve looking
2562 // upward though scope chains; we simply resolve names directly in
2563 // modules as we go.
2564 while index < module_path_len {
2565 let name = module_path[index];
2566 match self.resolve_name_in_module(search_module,
2571 let segment_name = self.session.str_of(name);
2572 let module_name = self.module_to_str(search_module);
2573 if "???" == module_name {
2576 hi: span.lo + BytePos(segment_name.len()),
2577 expn_info: span.expn_info,
2579 self.session.span_err(span,
2580 fmt!("unresolved import. maybe \
2581 a missing `extern mod \
2586 self.session.span_err(span, fmt!("unresolved import: could not find `%s` in \
2587 `%s`.", segment_name, module_name));
2591 debug!("(resolving module path for import) module \
2592 resolution is indeterminate: %s",
2593 self.session.str_of(name));
2594 return Indeterminate;
2596 Success(target) => {
2597 // Check to see whether there are type bindings, and, if
2598 // so, whether there is a module within.
2599 match target.bindings.type_def {
2601 match type_def.module_def {
2604 self.session.span_err(span,
2612 Some(module_def) => {
2613 // If we're doing the search for an
2614 // import, do not allow traits and impls
2616 match (name_search_type,
2618 (ImportSearch, TraitModuleKind) |
2619 (ImportSearch, ImplModuleKind) => {
2620 self.session.span_err(
2622 "cannot import from a trait \
2623 or type implementation");
2626 (_, _) => search_module = module_def,
2632 // There are no type bindings at all.
2633 self.session.span_err(span,
2634 fmt!("not a module `%s`",
2635 self.session.str_of(
2645 // After the first element of the path, allow searching only
2646 // through public identifiers.
2648 // XXX: Rip this out and move it to the privacy checker.
2649 if name_search_type == PathPublicOrPrivateSearch {
2650 name_search_type = PathPublicOnlySearch
2654 return Success(search_module);
2657 /// Attempts to resolve the module part of an import directive or path
2658 /// rooted at the given module.
2659 pub fn resolve_module_path(@mut self,
2660 module_: @mut Module,
2661 module_path: &[ident],
2662 use_lexical_scope: UseLexicalScopeFlag,
2664 name_search_type: NameSearchType)
2665 -> ResolveResult<@mut Module> {
2666 let module_path_len = module_path.len();
2667 assert!(module_path_len > 0);
2669 debug!("(resolving module path for import) processing `%s` rooted at \
2671 self.idents_to_str(module_path),
2672 self.module_to_str(module_));
2674 // Resolve the module prefix, if any.
2675 let module_prefix_result = self.resolve_module_prefix(module_,
2680 match module_prefix_result {
2682 let mpath = self.idents_to_str(module_path);
2683 match mpath.rfind(':') {
2685 self.session.span_err(span, fmt!("unresolved import: could not find `%s` \
2687 // idx +- 1 to account for the colons
2689 mpath.slice_from(idx + 1),
2690 mpath.slice_to(idx - 1)));
2697 debug!("(resolving module path for import) indeterminate; \
2699 return Indeterminate;
2701 Success(NoPrefixFound) => {
2702 // There was no prefix, so we're considering the first element
2703 // of the path. How we handle this depends on whether we were
2704 // instructed to use lexical scope or not.
2705 match use_lexical_scope {
2706 DontUseLexicalScope => {
2707 // This is a crate-relative path. We will start the
2708 // resolution process at index zero.
2709 search_module = self.graph_root.get_module();
2712 UseLexicalScope => {
2713 // This is not a crate-relative path. We resolve the
2714 // first component of the path in the current lexical
2715 // scope and then proceed to resolve below that.
2716 let result = self.resolve_module_in_lexical_scope(
2721 self.session.span_err(span,
2726 debug!("(resolving module path for import) \
2727 indeterminate; bailing");
2728 return Indeterminate;
2730 Success(containing_module) => {
2731 search_module = containing_module;
2738 Success(PrefixFound(containing_module, index)) => {
2739 search_module = containing_module;
2740 start_index = index;
2744 self.resolve_module_path_from_root(search_module,
2751 /// Invariant: This must only be called during main resolution, not during
2752 /// import resolution.
2753 pub fn resolve_item_in_lexical_scope(@mut self,
2754 module_: @mut Module,
2756 namespace: Namespace,
2757 search_through_modules:
2758 SearchThroughModulesFlag)
2759 -> ResolveResult<Target> {
2760 debug!("(resolving item in lexical scope) resolving `%s` in \
2761 namespace %? in `%s`",
2762 self.session.str_of(name),
2764 self.module_to_str(module_));
2766 // The current module node is handled specially. First, check for
2767 // its immediate children.
2768 match module_.children.find(&name) {
2770 if name_bindings.defined_in_namespace(namespace) => {
2771 return Success(Target(module_, *name_bindings));
2773 Some(_) | None => { /* Not found; continue. */ }
2776 // Now check for its import directives. We don't have to have resolved
2777 // all its imports in the usual way; this is because chains of
2778 // adjacent import statements are processed as though they mutated the
2780 match module_.import_resolutions.find(&name) {
2782 // Not found; continue.
2784 Some(import_resolution) => {
2785 match (*import_resolution).target_for_namespace(namespace) {
2787 // Not found; continue.
2788 debug!("(resolving item in lexical scope) found \
2789 import resolution, but not in namespace %?",
2793 debug!("(resolving item in lexical scope) using \
2794 import resolution");
2795 self.used_imports.insert(import_resolution.id(namespace));
2796 return Success(target);
2802 // Search for external modules.
2803 if namespace == TypeNS {
2804 match module_.external_module_children.find(&name) {
2808 @mut Resolver::create_name_bindings_from_module(
2810 return Success(Target(module_, name_bindings));
2815 // Finally, proceed up the scope chain looking for parent modules.
2816 let mut search_module = module_;
2818 // Go to the next parent.
2819 match search_module.parent_link {
2821 // No more parents. This module was unresolved.
2822 debug!("(resolving item in lexical scope) unresolved \
2826 ModuleParentLink(parent_module_node, _) => {
2827 match search_through_modules {
2828 DontSearchThroughModules => {
2829 match search_module.kind {
2830 NormalModuleKind => {
2831 // We stop the search here.
2832 debug!("(resolving item in lexical \
2833 scope) unresolved module: not \
2834 searching through module \
2841 AnonymousModuleKind => {
2842 search_module = parent_module_node;
2846 SearchThroughModules => {
2847 search_module = parent_module_node;
2851 BlockParentLink(parent_module_node, _) => {
2852 search_module = parent_module_node;
2856 // Resolve the name in the parent module.
2857 match self.resolve_name_in_module(search_module,
2860 PathPublicOrPrivateSearch) {
2862 // Continue up the search chain.
2865 // We couldn't see through the higher scope because of an
2866 // unresolved import higher up. Bail.
2868 debug!("(resolving item in lexical scope) indeterminate \
2869 higher scope; bailing");
2870 return Indeterminate;
2872 Success(target) => {
2873 // We found the module.
2874 return Success(target);
2880 /// Resolves a module name in the current lexical scope.
2881 pub fn resolve_module_in_lexical_scope(@mut self,
2882 module_: @mut Module,
2884 -> ResolveResult<@mut Module> {
2885 // If this module is an anonymous module, resolve the item in the
2886 // lexical scope. Otherwise, resolve the item from the crate root.
2887 let resolve_result = self.resolve_item_in_lexical_scope(
2888 module_, name, TypeNS, DontSearchThroughModules);
2889 match resolve_result {
2890 Success(target) => {
2891 let bindings = &mut *target.bindings;
2892 match bindings.type_def {
2893 Some(ref type_def) => {
2894 match (*type_def).module_def {
2896 error!("!!! (resolving module in lexical \
2897 scope) module wasn't actually a \
2901 Some(module_def) => {
2902 return Success(module_def);
2907 error!("!!! (resolving module in lexical scope) module
2908 wasn't actually a module!");
2914 debug!("(resolving module in lexical scope) indeterminate; \
2916 return Indeterminate;
2919 debug!("(resolving module in lexical scope) failed to \
2926 /// Returns the nearest normal module parent of the given module.
2927 pub fn get_nearest_normal_module_parent(@mut self, module_: @mut Module)
2928 -> Option<@mut Module> {
2929 let mut module_ = module_;
2931 match module_.parent_link {
2932 NoParentLink => return None,
2933 ModuleParentLink(new_module, _) |
2934 BlockParentLink(new_module, _) => {
2935 match new_module.kind {
2936 NormalModuleKind => return Some(new_module),
2940 AnonymousModuleKind => module_ = new_module,
2947 /// Returns the nearest normal module parent of the given module, or the
2948 /// module itself if it is a normal module.
2949 pub fn get_nearest_normal_module_parent_or_self(@mut self,
2950 module_: @mut Module)
2952 match module_.kind {
2953 NormalModuleKind => return module_,
2957 AnonymousModuleKind => {
2958 match self.get_nearest_normal_module_parent(module_) {
2960 Some(new_module) => new_module
2966 /// Resolves a "module prefix". A module prefix is one of (a) `self::`;
2967 /// (b) some chain of `super::`.
2968 pub fn resolve_module_prefix(@mut self,
2969 module_: @mut Module,
2970 module_path: &[ident])
2971 -> ResolveResult<ModulePrefixResult> {
2972 // Start at the current module if we see `self` or `super`, or at the
2973 // top of the crate otherwise.
2974 let mut containing_module;
2976 if "self" == token::ident_to_str(&module_path[0]) {
2978 self.get_nearest_normal_module_parent_or_self(module_);
2980 } else if "super" == token::ident_to_str(&module_path[0]) {
2982 self.get_nearest_normal_module_parent_or_self(module_);
2983 i = 0; // We'll handle `super` below.
2985 return Success(NoPrefixFound);
2988 // Now loop through all the `super`s we find.
2989 while i < module_path.len() &&
2990 "super" == token::ident_to_str(&module_path[i]) {
2991 debug!("(resolving module prefix) resolving `super` at %s",
2992 self.module_to_str(containing_module));
2993 match self.get_nearest_normal_module_parent(containing_module) {
2994 None => return Failed,
2995 Some(new_module) => {
2996 containing_module = new_module;
3002 debug!("(resolving module prefix) finished resolving prefix at %s",
3003 self.module_to_str(containing_module));
3005 return Success(PrefixFound(containing_module, i));
3008 /// Attempts to resolve the supplied name in the given module for the
3009 /// given namespace. If successful, returns the target corresponding to
3011 pub fn resolve_name_in_module(@mut self,
3012 module_: @mut Module,
3014 namespace: Namespace,
3015 name_search_type: NameSearchType)
3016 -> ResolveResult<Target> {
3017 debug!("(resolving name in module) resolving `%s` in `%s`",
3018 self.session.str_of(name),
3019 self.module_to_str(module_));
3021 // First, check the direct children of the module.
3022 match module_.children.find(&name) {
3024 if name_bindings.defined_in_namespace(namespace) => {
3025 debug!("(resolving name in module) found node as child");
3026 return Success(Target(module_, *name_bindings));
3033 // Next, check the module's imports if necessary.
3035 // If this is a search of all imports, we should be done with glob
3036 // resolution at this point.
3037 if name_search_type == PathPublicOrPrivateSearch ||
3038 name_search_type == PathPublicOnlySearch {
3039 assert_eq!(module_.glob_count, 0);
3042 // Check the list of resolved imports.
3043 match module_.import_resolutions.find(&name) {
3044 Some(import_resolution) => {
3045 if import_resolution.privacy == Public &&
3046 import_resolution.outstanding_references != 0 {
3047 debug!("(resolving name in module) import \
3048 unresolved; bailing out");
3049 return Indeterminate;
3052 match import_resolution.target_for_namespace(namespace) {
3054 debug!("(resolving name in module) name found, \
3055 but not in namespace %?",
3059 if name_search_type ==
3060 PathPublicOrPrivateSearch ||
3061 import_resolution.privacy == Public => {
3062 debug!("(resolving name in module) resolved to \
3064 self.used_imports.insert(import_resolution.id(namespace));
3065 return Success(target);
3068 debug!("(resolving name in module) name found, \
3073 None => {} // Continue.
3076 // Finally, search through external children.
3077 if namespace == TypeNS {
3078 match module_.external_module_children.find(&name) {
3082 @mut Resolver::create_name_bindings_from_module(
3084 return Success(Target(module_, name_bindings));
3089 // We're out of luck.
3090 debug!("(resolving name in module) failed to resolve `%s`",
3091 self.session.str_of(name));
3095 pub fn report_unresolved_imports(@mut self, module_: @mut Module) {
3096 let index = module_.resolved_import_count;
3097 let imports: &mut ~[@ImportDirective] = &mut *module_.imports;
3098 let import_count = imports.len();
3099 if index != import_count {
3100 let sn = self.session.codemap.span_to_snippet(imports[index].span).unwrap();
3101 if sn.contains("::") {
3102 self.session.span_err(imports[index].span, "unresolved import");
3104 let err = fmt!("unresolved import (maybe you meant `%s::*`?)",
3105 sn.slice(0, sn.len()));
3106 self.session.span_err(imports[index].span, err);
3110 // Descend into children and anonymous children.
3111 for (_, &child_node) in module_.children.iter() {
3112 match child_node.get_module_if_available() {
3116 Some(child_module) => {
3117 self.report_unresolved_imports(child_module);
3122 for (_, &module_) in module_.anonymous_children.iter() {
3123 self.report_unresolved_imports(module_);
3129 // This pass simply determines what all "export" keywords refer to and
3130 // writes the results into the export map.
3132 // FIXME #4953 This pass will be removed once exports change to per-item.
3133 // Then this operation can simply be performed as part of item (or import)
3136 pub fn record_exports(@mut self) {
3137 let root_module = self.graph_root.get_module();
3138 self.record_exports_for_module_subtree(root_module);
3141 pub fn record_exports_for_module_subtree(@mut self,
3142 module_: @mut Module) {
3143 // If this isn't a local crate, then bail out. We don't need to record
3144 // exports for nonlocal crates.
3146 match module_.def_id {
3147 Some(def_id) if def_id.crate == LOCAL_CRATE => {
3149 debug!("(recording exports for module subtree) recording \
3150 exports for local module `%s`",
3151 self.module_to_str(module_));
3154 // Record exports for the root module.
3155 debug!("(recording exports for module subtree) recording \
3156 exports for root module `%s`",
3157 self.module_to_str(module_));
3161 debug!("(recording exports for module subtree) not recording \
3163 self.module_to_str(module_));
3168 self.record_exports_for_module(module_);
3170 for (_, &child_name_bindings) in module_.children.iter() {
3171 match child_name_bindings.get_module_if_available() {
3175 Some(child_module) => {
3176 self.record_exports_for_module_subtree(child_module);
3181 for (_, &child_module) in module_.anonymous_children.iter() {
3182 self.record_exports_for_module_subtree(child_module);
3186 pub fn record_exports_for_module(@mut self, module_: @mut Module) {
3187 let mut exports2 = ~[];
3189 self.add_exports_for_module(&mut exports2, module_);
3190 match module_.def_id {
3192 self.export_map2.insert(def_id.node, exports2);
3193 debug!("(computing exports) writing exports for %d (some)",
3200 pub fn add_exports_of_namebindings(@mut self,
3201 exports2: &mut ~[Export2],
3203 namebindings: @mut NameBindings,
3206 match (namebindings.def_for_namespace(ns),
3207 namebindings.privacy_for_namespace(ns)) {
3208 (Some(d), Some(Public)) => {
3209 debug!("(computing exports) YES: %s '%s' => %?",
3210 if reexport { ~"reexport" } else { ~"export"},
3211 self.session.str_of(ident),
3213 exports2.push(Export2 {
3215 name: self.session.str_of(ident),
3216 def_id: def_id_of_def(d)
3219 (Some(_), Some(privacy)) => {
3220 debug!("(computing reexports) NO: privacy %?", privacy);
3223 debug!("(computing reexports) NO: %?, %?", d_opt, p_opt);
3228 pub fn add_exports_for_module(@mut self,
3229 exports2: &mut ~[Export2],
3230 module_: @mut Module) {
3231 for (ident, importresolution) in module_.import_resolutions.iter() {
3232 if importresolution.privacy != Public {
3233 debug!("(computing exports) not reexporting private `%s`",
3234 self.session.str_of(*ident));
3237 let xs = [TypeNS, ValueNS];
3238 for ns in xs.iter() {
3239 match importresolution.target_for_namespace(*ns) {
3241 debug!("(computing exports) maybe reexport '%s'",
3242 self.session.str_of(*ident));
3243 self.add_exports_of_namebindings(&mut *exports2,
3257 // We maintain a list of value ribs and type ribs.
3259 // Simultaneously, we keep track of the current position in the module
3260 // graph in the `current_module` pointer. When we go to resolve a name in
3261 // the value or type namespaces, we first look through all the ribs and
3262 // then query the module graph. When we resolve a name in the module
3263 // namespace, we can skip all the ribs (since nested modules are not
3264 // allowed within blocks in Rust) and jump straight to the current module
3267 // Named implementations are handled separately. When we find a method
3268 // call, we consult the module node to find all of the implementations in
3269 // scope. This information is lazily cached in the module node. We then
3270 // generate a fake "implementation scope" containing all the
3271 // implementations thus found, for compatibility with old resolve pass.
3273 pub fn with_scope(@mut self, name: Option<ident>, f: &fn()) {
3274 let orig_module = self.current_module;
3276 // Move down in the graph.
3282 match orig_module.children.find(&name) {
3284 debug!("!!! (with scope) didn't find `%s` in `%s`",
3285 self.session.str_of(name),
3286 self.module_to_str(orig_module));
3288 Some(name_bindings) => {
3289 match (*name_bindings).get_module_if_available() {
3291 debug!("!!! (with scope) didn't find module \
3293 self.session.str_of(name),
3294 self.module_to_str(orig_module));
3297 self.current_module = module_;
3307 self.current_module = orig_module;
3310 /// Wraps the given definition in the appropriate number of `def_upvar`
3312 pub fn upvarify(@mut self,
3317 allow_capturing_self: AllowCapturingSelfFlag)
3318 -> Option<def_like> {
3323 dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
3324 dl_def(d @ def_arg(*)) | dl_def(d @ def_binding(*)) => {
3326 is_ty_param = false;
3328 dl_def(d @ def_ty_param(*)) => {
3332 dl_def(d @ def_self(*))
3333 if allow_capturing_self == DontAllowCapturingSelf => {
3335 is_ty_param = false;
3338 return Some(def_like);
3342 let mut rib_index = rib_index + 1;
3343 while rib_index < ribs.len() {
3344 match ribs[rib_index].kind {
3346 // Nothing to do. Continue.
3348 FunctionRibKind(function_id, body_id) => {
3350 def = def_upvar(def_id_of_def(def).node,
3356 MethodRibKind(item_id, _) => {
3357 // If the def is a ty param, and came from the parent
3360 def_ty_param(did, _)
3361 if self.def_map.find(&did.node).map_consume(|x| *x)
3362 == Some(def_typaram_binder(item_id)) => {
3367 // This was an attempt to access an upvar inside a
3368 // named function item. This is not allowed, so we
3371 self.session.span_err(
3373 "can't capture dynamic environment in a fn item; \
3374 use the || { ... } closure form instead");
3376 // This was an attempt to use a type parameter outside
3379 self.session.span_err(span,
3380 "attempt to use a type \
3381 argument out of scope");
3388 OpaqueFunctionRibKind => {
3390 // This was an attempt to access an upvar inside a
3391 // named function item. This is not allowed, so we
3394 self.session.span_err(
3396 "can't capture dynamic environment in a fn item; \
3397 use the || { ... } closure form instead");
3399 // This was an attempt to use a type parameter outside
3402 self.session.span_err(span,
3403 "attempt to use a type \
3404 argument out of scope");
3409 ConstantItemRibKind => {
3410 // Still doesn't deal with upvars
3411 self.session.span_err(span,
3412 "attempt to use a non-constant \
3413 value in a constant");
3421 return Some(dl_def(def));
3424 pub fn search_ribs(@mut self,
3428 allow_capturing_self: AllowCapturingSelfFlag)
3429 -> Option<def_like> {
3430 // FIXME #4950: This should not use a while loop.
3431 // FIXME #4950: Try caching?
3433 let mut i = ribs.len();
3436 match ribs[i].bindings.find(&name) {
3437 Some(&def_like) => {
3438 return self.upvarify(ribs, i, def_like, span,
3439 allow_capturing_self);
3450 pub fn resolve_crate(@mut self) {
3451 debug!("(resolving crate) starting");
3453 visit_crate(self.crate, ((), mk_vt(@Visitor {
3454 visit_item: |item, (_context, visitor)|
3455 self.resolve_item(item, visitor),
3456 visit_arm: |arm, (_context, visitor)|
3457 self.resolve_arm(arm, visitor),
3458 visit_block: |block, (_context, visitor)|
3459 self.resolve_block(block, visitor),
3460 visit_expr: |expr, (_context, visitor)|
3461 self.resolve_expr(expr, visitor),
3462 visit_local: |local, (_context, visitor)|
3463 self.resolve_local(local, visitor),
3464 visit_ty: |ty, (_context, visitor)|
3465 self.resolve_type(ty, visitor),
3466 .. *default_visitor()
3470 pub fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
3471 debug!("(resolving item) resolving %s",
3472 self.session.str_of(item.ident));
3474 // Items with the !resolve_unexported attribute are X-ray contexts.
3475 // This is used to allow the test runner to run unexported tests.
3476 let orig_xray_flag = self.xray_context;
3477 if attr::contains_name(item.attrs, "!resolve_unexported") {
3478 self.xray_context = Xray;
3483 // enum item: resolve all the variants' discrs,
3484 // then resolve the ty params
3485 item_enum(ref enum_def, ref generics) => {
3486 for variant in (*enum_def).variants.iter() {
3487 for dis_expr in variant.node.disr_expr.iter() {
3488 // resolve the discriminator expr
3490 self.with_constant_rib(|| {
3491 self.resolve_expr(*dis_expr, visitor);
3496 // n.b. the discr expr gets visted twice.
3497 // but maybe it's okay since the first time will signal an
3498 // error if there is one? -- tjc
3499 do self.with_type_parameter_rib(
3501 generics, item.id, 0, NormalRibKind)) {
3502 visit_item(item, ((), visitor));
3506 item_ty(_, ref generics) => {
3507 do self.with_type_parameter_rib
3508 (HasTypeParameters(generics, item.id, 0,
3512 visit_item(item, ((), visitor));
3516 item_impl(ref generics,
3517 ref implemented_traits,
3520 self.resolve_implementation(item.id,
3528 item_trait(ref generics, ref traits, ref methods) => {
3529 // Create a new rib for the self type.
3530 let self_type_rib = @Rib(NormalRibKind);
3531 self.type_ribs.push(self_type_rib);
3532 self_type_rib.bindings.insert(self.type_self_ident,
3533 dl_def(def_self_ty(item.id)));
3535 // Create a new rib for the trait-wide type parameters.
3536 do self.with_type_parameter_rib
3537 (HasTypeParameters(generics, item.id, 0,
3540 self.resolve_type_parameters(&generics.ty_params,
3543 // Resolve derived traits.
3544 for trt in traits.iter() {
3545 self.resolve_trait_reference(item.id, trt, visitor, TraitDerivation);
3548 for method in (*methods).iter() {
3549 // Create a new rib for the method-specific type
3552 // FIXME #4951: Do we need a node ID here?
3555 required(ref ty_m) => {
3556 do self.with_type_parameter_rib
3557 (HasTypeParameters(&ty_m.generics,
3559 generics.ty_params.len(),
3560 MethodRibKind(item.id, Required))) {
3562 // Resolve the method-specific type
3564 self.resolve_type_parameters(
3565 &ty_m.generics.ty_params,
3568 for argument in ty_m.decl.inputs.iter() {
3569 self.resolve_type(&argument.ty, visitor);
3572 self.resolve_type(&ty_m.decl.output, visitor);
3576 self.resolve_method(MethodRibKind(item.id,
3579 generics.ty_params.len(),
3586 self.type_ribs.pop();
3589 item_struct(ref struct_def, ref generics) => {
3590 self.resolve_struct(item.id,
3596 item_mod(ref module_) => {
3597 do self.with_scope(Some(item.ident)) {
3598 self.resolve_module(module_, item.span, item.ident,
3603 item_foreign_mod(ref foreign_module) => {
3604 do self.with_scope(Some(item.ident)) {
3605 for foreign_item in foreign_module.items.iter() {
3606 match foreign_item.node {
3607 foreign_item_fn(_, ref generics) => {
3608 self.with_type_parameter_rib(
3610 generics, foreign_item.id, 0,
3612 || visit_foreign_item(*foreign_item,
3615 foreign_item_static(*) => {
3616 visit_foreign_item(*foreign_item,
3624 item_fn(ref fn_decl, _, _, ref generics, ref block) => {
3625 self.resolve_function(OpaqueFunctionRibKind,
3631 OpaqueFunctionRibKind),
3638 self.with_constant_rib(|| {
3639 visit_item(item, ((), visitor));
3644 fail!("item macros unimplemented")
3648 self.xray_context = orig_xray_flag;
3651 pub fn with_type_parameter_rib(@mut self,
3652 type_parameters: TypeParameters,
3654 match type_parameters {
3655 HasTypeParameters(generics, node_id, initial_index,
3658 let function_type_rib = @Rib(rib_kind);
3659 self.type_ribs.push(function_type_rib);
3661 for (index, type_parameter) in generics.ty_params.iter().enumerate() {
3662 let name = type_parameter.ident;
3663 debug!("with_type_parameter_rib: %d %d", node_id,
3665 let def_like = dl_def(def_ty_param
3666 (local_def(type_parameter.id),
3667 index + initial_index));
3668 // Associate this type parameter with
3669 // the item that bound it
3670 self.record_def(type_parameter.id,
3671 def_typaram_binder(node_id));
3672 function_type_rib.bindings.insert(name, def_like);
3676 NoTypeParameters => {
3683 match type_parameters {
3684 HasTypeParameters(*) => {
3685 self.type_ribs.pop();
3688 NoTypeParameters => {
3694 pub fn with_label_rib(@mut self, f: &fn()) {
3695 self.label_ribs.push(@Rib(NormalRibKind));
3697 self.label_ribs.pop();
3700 pub fn with_constant_rib(@mut self, f: &fn()) {
3701 self.value_ribs.push(@Rib(ConstantItemRibKind));
3703 self.value_ribs.pop();
3706 pub fn resolve_function(@mut self,
3708 optional_declaration: Option<&fn_decl>,
3709 type_parameters: TypeParameters,
3711 self_binding: SelfBinding,
3712 visitor: ResolveVisitor) {
3713 // Create a value rib for the function.
3714 let function_value_rib = @Rib(rib_kind);
3715 self.value_ribs.push(function_value_rib);
3717 // Create a label rib for the function.
3718 let function_label_rib = @Rib(rib_kind);
3719 self.label_ribs.push(function_label_rib);
3721 // If this function has type parameters, add them now.
3722 do self.with_type_parameter_rib(type_parameters) {
3723 // Resolve the type parameters.
3724 match type_parameters {
3725 NoTypeParameters => {
3728 HasTypeParameters(ref generics, _, _, _) => {
3729 self.resolve_type_parameters(&generics.ty_params,
3734 // Add self to the rib, if necessary.
3735 match self_binding {
3739 HasSelfBinding(self_node_id, is_implicit) => {
3740 let def_like = dl_def(def_self(self_node_id,
3742 *function_value_rib.self_binding = Some(def_like);
3746 // Add each argument to the rib.
3747 match optional_declaration {
3751 Some(declaration) => {
3752 for argument in declaration.inputs.iter() {
3753 let binding_mode = ArgumentIrrefutableMode;
3755 if argument.is_mutbl {Mutable} else {Immutable};
3756 self.resolve_pattern(argument.pat,
3762 self.resolve_type(&argument.ty, visitor);
3764 debug!("(resolving function) recorded argument");
3767 self.resolve_type(&declaration.output, visitor);
3771 // Resolve the function body.
3772 self.resolve_block(block, visitor);
3774 debug!("(resolving function) leaving function");
3777 self.label_ribs.pop();
3778 self.value_ribs.pop();
3781 pub fn resolve_type_parameters(@mut self,
3782 type_parameters: &OptVec<TyParam>,
3783 visitor: ResolveVisitor) {
3784 for type_parameter in type_parameters.iter() {
3785 for bound in type_parameter.bounds.iter() {
3786 self.resolve_type_parameter_bound(type_parameter.id, bound, visitor);
3791 pub fn resolve_type_parameter_bound(@mut self,
3793 type_parameter_bound: &TyParamBound,
3794 visitor: ResolveVisitor) {
3795 match *type_parameter_bound {
3796 TraitTyParamBound(ref tref) => {
3797 self.resolve_trait_reference(id, tref, visitor, TraitBoundingTypeParameter)
3799 RegionTyParamBound => {}
3803 pub fn resolve_trait_reference(@mut self,
3805 trait_reference: &trait_ref,
3806 visitor: ResolveVisitor,
3807 reference_type: TraitReferenceType) {
3808 match self.resolve_path(id, &trait_reference.path, TypeNS, true, visitor) {
3810 let path_str = self.idents_to_str(trait_reference.path.idents);
3812 let usage_str = match reference_type {
3813 TraitBoundingTypeParameter => "bound type parameter with",
3814 TraitImplementation => "implement",
3815 TraitDerivation => "derive"
3818 let msg = fmt!("attempt to %s a nonexistent trait `%s`", usage_str, path_str);
3819 self.session.span_err(trait_reference.path.span, msg);
3822 debug!("(resolving trait) found trait def: %?", def);
3823 self.record_def(trait_reference.ref_id, def);
3828 pub fn resolve_struct(@mut self,
3830 generics: &Generics,
3831 fields: &[@struct_field],
3832 visitor: ResolveVisitor) {
3833 let mut ident_map = HashMap::new::<ast::ident, @struct_field>();
3834 for &field in fields.iter() {
3835 match field.node.kind {
3836 named_field(ident, _) => {
3837 match ident_map.find(&ident) {
3838 Some(&prev_field) => {
3839 let ident_str = self.session.str_of(ident);
3840 self.session.span_err(field.span,
3841 fmt!("field `%s` is already declared", ident_str));
3842 self.session.span_note(prev_field.span,
3843 "Previously declared here");
3846 ident_map.insert(ident, field);
3854 // If applicable, create a rib for the type parameters.
3855 do self.with_type_parameter_rib(HasTypeParameters
3857 OpaqueFunctionRibKind)) {
3859 // Resolve the type parameters.
3860 self.resolve_type_parameters(&generics.ty_params, visitor);
3863 for field in fields.iter() {
3864 self.resolve_type(&field.node.ty, visitor);
3869 // Does this really need to take a RibKind or is it always going
3870 // to be NormalRibKind?
3871 pub fn resolve_method(@mut self,
3874 outer_type_parameter_count: uint,
3875 visitor: ResolveVisitor) {
3876 let method_generics = &method.generics;
3877 let type_parameters =
3878 HasTypeParameters(method_generics,
3880 outer_type_parameter_count,
3882 // we only have self ty if it is a non static method
3883 let self_binding = match method.explicit_self.node {
3884 sty_static => { NoSelfBinding }
3885 _ => { HasSelfBinding(method.self_id, false) }
3888 self.resolve_function(rib_kind,
3896 pub fn resolve_implementation(@mut self,
3898 generics: &Generics,
3899 opt_trait_reference: &Option<trait_ref>,
3901 methods: &[@method],
3902 visitor: ResolveVisitor) {
3903 // If applicable, create a rib for the type parameters.
3904 let outer_type_parameter_count = generics.ty_params.len();
3905 do self.with_type_parameter_rib(HasTypeParameters
3908 // Resolve the type parameters.
3909 self.resolve_type_parameters(&generics.ty_params,
3912 // Resolve the trait reference, if necessary.
3913 let original_trait_refs;
3914 match opt_trait_reference {
3915 &Some(ref trait_reference) => {
3916 self.resolve_trait_reference(id, trait_reference, visitor,
3917 TraitImplementation);
3919 // Record the current set of trait references.
3920 let mut new_trait_refs = ~[];
3922 let r = self.def_map.find(&trait_reference.ref_id);
3923 for &def in r.iter() {
3924 new_trait_refs.push(def_id_of_def(*def));
3927 original_trait_refs = Some(util::replace(
3928 &mut self.current_trait_refs,
3929 Some(new_trait_refs)));
3932 original_trait_refs = None;
3936 // Resolve the self type.
3937 self.resolve_type(self_type, visitor);
3939 for method in methods.iter() {
3940 // We also need a new scope for the method-specific
3942 self.resolve_method(MethodRibKind(
3944 Provided(method.id)),
3946 outer_type_parameter_count,
3949 let borrowed_type_parameters = &method.tps;
3950 self.resolve_function(MethodRibKind(
3952 Provided(method.id)),
3955 (borrowed_type_parameters,
3957 outer_type_parameter_count,
3960 HasSelfBinding(method.self_id),
3965 // Restore the original trait references.
3966 match original_trait_refs {
3967 Some(r) => { self.current_trait_refs = r; }
3973 pub fn resolve_module(@mut self,
3978 visitor: ResolveVisitor) {
3979 // Write the implementations in scope into the module metadata.
3980 debug!("(resolving module) resolving module ID %d", id);
3981 visit_mod(module_, span, id, ((), visitor));
3984 pub fn resolve_local(@mut self, local: @Local, visitor: ResolveVisitor) {
3985 let mutability = if local.is_mutbl {Mutable} else {Immutable};
3987 // Resolve the type.
3988 self.resolve_type(&local.ty, visitor);
3990 // Resolve the initializer, if necessary.
3995 Some(initializer) => {
3996 self.resolve_expr(initializer, visitor);
4000 // Resolve the pattern.
4001 self.resolve_pattern(local.pat, LocalIrrefutableMode, mutability,
4005 pub fn binding_mode_map(@mut self, pat: @pat) -> BindingMap {
4006 let mut result = HashMap::new();
4007 do pat_bindings(self.def_map, pat) |binding_mode, _id, sp, path| {
4008 let ident = path_to_ident(path);
4009 result.insert(ident,
4010 binding_info {span: sp,
4011 binding_mode: binding_mode});
4016 pub fn check_consistent_bindings(@mut self, arm: &arm) {
4017 if arm.pats.len() == 0 { return; }
4018 let map_0 = self.binding_mode_map(arm.pats[0]);
4019 for (i, p) in arm.pats.iter().enumerate() {
4020 let map_i = self.binding_mode_map(*p);
4022 for (&key, &binding_0) in map_0.iter() {
4023 match map_i.find(&key) {
4025 self.session.span_err(
4027 fmt!("variable `%s` from pattern #1 is \
4028 not bound in pattern #%u",
4029 self.session.str_of(key), i + 1));
4031 Some(binding_i) => {
4032 if binding_0.binding_mode != binding_i.binding_mode {
4033 self.session.span_err(
4035 fmt!("variable `%s` is bound with different \
4036 mode in pattern #%u than in pattern #1",
4037 self.session.str_of(key), i + 1));
4043 for (&key, &binding) in map_i.iter() {
4044 if !map_0.contains_key(&key) {
4045 self.session.span_err(
4047 fmt!("variable `%s` from pattern #%u is \
4048 not bound in pattern #1",
4049 self.session.str_of(key), i + 1));
4055 pub fn resolve_arm(@mut self, arm: &arm, visitor: ResolveVisitor) {
4056 self.value_ribs.push(@Rib(NormalRibKind));
4058 let bindings_list = @mut HashMap::new();
4059 for pattern in arm.pats.iter() {
4060 self.resolve_pattern(*pattern, RefutableMode, Immutable,
4061 Some(bindings_list), visitor);
4064 // This has to happen *after* we determine which
4065 // pat_idents are variants
4066 self.check_consistent_bindings(arm);
4068 visit_expr_opt(arm.guard, ((), visitor));
4069 self.resolve_block(&arm.body, visitor);
4071 self.value_ribs.pop();
4074 pub fn resolve_block(@mut self, block: &Block, visitor: ResolveVisitor) {
4075 debug!("(resolving block) entering block");
4076 self.value_ribs.push(@Rib(NormalRibKind));
4078 // Move down in the graph, if there's an anonymous module rooted here.
4079 let orig_module = self.current_module;
4080 match self.current_module.anonymous_children.find(&block.id) {
4081 None => { /* Nothing to do. */ }
4082 Some(&anonymous_module) => {
4083 debug!("(resolving block) found anonymous module, moving \
4085 self.current_module = anonymous_module;
4089 // Descend into the block.
4090 visit_block(block, ((), visitor));
4093 self.current_module = orig_module;
4095 self.value_ribs.pop();
4096 debug!("(resolving block) leaving block");
4099 pub fn resolve_type(@mut self, ty: &Ty, visitor: ResolveVisitor) {
4101 // Like path expressions, the interpretation of path types depends
4102 // on whether the path has multiple elements in it or not.
4104 ty_path(ref path, ref bounds, path_id) => {
4105 // This is a path in the type namespace. Walk through scopes
4106 // scopes looking for it.
4107 let mut result_def = None;
4109 // First, check to see whether the name is a primitive type.
4110 if path.idents.len() == 1 {
4111 let name = *path.idents.last();
4113 match self.primitive_type_table
4117 Some(&primitive_type) => {
4119 Some(def_prim_ty(primitive_type));
4129 match self.resolve_path(ty.id, path, TypeNS, true, visitor) {
4131 debug!("(resolving type) resolved `%s` to \
4133 self.session.str_of(
4134 *path.idents.last()),
4136 result_def = Some(def);
4150 // Write the result into the def map.
4151 debug!("(resolving type) writing resolution for `%s` \
4153 self.idents_to_str(path.idents),
4155 self.record_def(path_id, def);
4158 self.session.span_err
4159 (ty.span, fmt!("use of undeclared type name `%s`",
4160 self.idents_to_str(path.idents)));
4164 do bounds.map |bound_vec| {
4165 for bound in bound_vec.iter() {
4166 self.resolve_type_parameter_bound(ty.id, bound, visitor);
4172 do c.bounds.map |bounds| {
4173 for bound in bounds.iter() {
4174 self.resolve_type_parameter_bound(ty.id, bound, visitor);
4177 visit_ty(ty, ((), visitor));
4181 // Just resolve embedded types.
4182 visit_ty(ty, ((), visitor));
4187 pub fn resolve_pattern(@mut self,
4189 mode: PatternBindingMode,
4190 mutability: Mutability,
4191 // Maps idents to the node ID for the (outermost)
4192 // pattern that binds them
4193 bindings_list: Option<@mut HashMap<ident,NodeId>>,
4194 visitor: ResolveVisitor) {
4195 let pat_id = pattern.id;
4196 do walk_pat(pattern) |pattern| {
4197 match pattern.node {
4198 pat_ident(binding_mode, ref path, _)
4199 if !path.global && path.idents.len() == 1 => {
4201 // The meaning of pat_ident with no type parameters
4202 // depends on whether an enum variant or unit-like struct
4203 // with that name is in scope. The probing lookup has to
4204 // be careful not to emit spurious errors. Only matching
4205 // patterns (match) can match nullary variants or
4206 // unit-like structs. For binding patterns (let), matching
4207 // such a value is simply disallowed (since it's rarely
4210 let ident = path.idents[0];
4212 match self.resolve_bare_identifier_pattern(ident) {
4213 FoundStructOrEnumVariant(def)
4214 if mode == RefutableMode => {
4215 debug!("(resolving pattern) resolving `%s` to \
4216 struct or enum variant",
4217 self.session.str_of(ident));
4219 self.enforce_default_binding_mode(
4223 self.record_def(pattern.id, def);
4225 FoundStructOrEnumVariant(_) => {
4226 self.session.span_err(pattern.span,
4227 fmt!("declaration of `%s` \
4229 variant or unit-like \
4234 FoundConst(def) if mode == RefutableMode => {
4235 debug!("(resolving pattern) resolving `%s` to \
4237 self.session.str_of(ident));
4239 self.enforce_default_binding_mode(
4243 self.record_def(pattern.id, def);
4246 self.session.span_err(pattern.span,
4247 "only refutable patterns \
4250 BareIdentifierPatternUnresolved => {
4251 debug!("(resolving pattern) binding `%s`",
4252 self.session.str_of(ident));
4254 let is_mutable = mutability == Mutable;
4256 let def = match mode {
4258 // For pattern arms, we must use
4259 // `def_binding` definitions.
4261 def_binding(pattern.id, binding_mode)
4263 LocalIrrefutableMode => {
4264 // But for locals, we use `def_local`.
4265 def_local(pattern.id, is_mutable)
4267 ArgumentIrrefutableMode => {
4268 // And for function arguments, `def_arg`.
4269 def_arg(pattern.id, is_mutable)
4273 // Record the definition so that later passes
4274 // will be able to distinguish variants from
4275 // locals in patterns.
4277 self.record_def(pattern.id, def);
4279 // Add the binding to the local ribs, if it
4280 // doesn't already exist in the bindings list. (We
4281 // must not add it if it's in the bindings list
4282 // because that breaks the assumptions later
4283 // passes make about or-patterns.)
4285 match bindings_list {
4287 if !bindings_list.contains_key(&ident) => {
4288 let this = &mut *self;
4289 let last_rib = this.value_ribs[
4290 this.value_ribs.len() - 1];
4291 last_rib.bindings.insert(ident,
4293 bindings_list.insert(ident, pat_id);
4296 if b.find(&ident) == Some(&pat_id) {
4297 // Then this is a duplicate variable
4298 // in the same disjunct, which is an
4300 self.session.span_err(pattern.span,
4301 fmt!("Identifier `%s` is bound more \
4302 than once in the same pattern",
4303 path_to_str(path, self.session
4306 // Not bound in the same pattern: do nothing
4309 let this = &mut *self;
4310 let last_rib = this.value_ribs[
4311 this.value_ribs.len() - 1];
4312 last_rib.bindings.insert(ident,
4319 // Check the types in the path pattern.
4320 for ty in path.types.iter() {
4321 self.resolve_type(ty, visitor);
4325 pat_ident(binding_mode, ref path, _) => {
4326 // This must be an enum variant, struct, or constant.
4327 match self.resolve_path(pat_id, path, ValueNS, false, visitor) {
4328 Some(def @ def_variant(*)) |
4329 Some(def @ def_struct(*)) => {
4330 self.record_def(pattern.id, def);
4332 Some(def @ def_static(*)) => {
4333 self.enforce_default_binding_mode(
4337 self.record_def(pattern.id, def);
4340 self.session.span_err(
4342 fmt!("`%s` is not an enum variant or constant",
4343 self.session.str_of(
4344 *path.idents.last())));
4347 self.session.span_err(path.span,
4348 "unresolved enum variant");
4352 // Check the types in the path pattern.
4353 for ty in path.types.iter() {
4354 self.resolve_type(ty, visitor);
4358 pat_enum(ref path, _) => {
4359 // This must be an enum variant, struct or const.
4360 match self.resolve_path(pat_id, path, ValueNS, false, visitor) {
4361 Some(def @ def_fn(*)) |
4362 Some(def @ def_variant(*)) |
4363 Some(def @ def_struct(*)) |
4364 Some(def @ def_static(*)) => {
4365 self.record_def(pattern.id, def);
4368 self.session.span_err(
4370 fmt!("`%s` is not an enum variant, struct or const",
4371 self.session.str_of(
4372 *path.idents.last())));
4375 self.session.span_err(path.span,
4376 "unresolved enum variant, \
4381 // Check the types in the path pattern.
4382 for ty in path.types.iter() {
4383 self.resolve_type(ty, visitor);
4388 self.resolve_expr(expr, visitor);
4391 pat_range(first_expr, last_expr) => {
4392 self.resolve_expr(first_expr, visitor);
4393 self.resolve_expr(last_expr, visitor);
4396 pat_struct(ref path, _, _) => {
4397 match self.resolve_path(pat_id, path, TypeNS, false, visitor) {
4398 Some(def_ty(class_id))
4399 if self.structs.contains(&class_id) => {
4400 let class_def = def_struct(class_id);
4401 self.record_def(pattern.id, class_def);
4403 Some(definition @ def_struct(class_id)) => {
4404 assert!(self.structs.contains(&class_id));
4405 self.record_def(pattern.id, definition);
4407 Some(definition @ def_variant(_, variant_id))
4408 if self.structs.contains(&variant_id) => {
4409 self.record_def(pattern.id, definition);
4412 debug!("(resolving pattern) didn't find struct \
4414 self.session.span_err(
4416 fmt!("`%s` does not name a structure",
4417 self.idents_to_str(path.idents)));
4430 pub fn resolve_bare_identifier_pattern(@mut self, name: ident)
4432 BareIdentifierPatternResolution {
4433 match self.resolve_item_in_lexical_scope(self.current_module,
4436 SearchThroughModules) {
4437 Success(target) => {
4438 match target.bindings.value_def {
4440 fail!("resolved name in the value namespace to a \
4441 set of name bindings with no def?!");
4445 def @ def_variant(*) | def @ def_struct(*) => {
4446 return FoundStructOrEnumVariant(def);
4448 def @ def_static(_, false) => {
4449 return FoundConst(def);
4452 return BareIdentifierPatternUnresolved;
4460 fail!("unexpected indeterminate result");
4464 return BareIdentifierPatternUnresolved;
4469 /// If `check_ribs` is true, checks the local definitions first; i.e.
4470 /// doesn't skip straight to the containing module.
4471 pub fn resolve_path(@mut self,
4474 namespace: Namespace,
4476 visitor: ResolveVisitor)
4478 // First, resolve the types.
4479 for ty in path.types.iter() {
4480 self.resolve_type(ty, visitor);
4484 return self.resolve_crate_relative_path(path,
4489 let unqualified_def = self.resolve_identifier(
4490 *path.idents.last(), namespace, check_ribs, path.span);
4492 if path.idents.len() > 1 {
4493 let def = self.resolve_module_relative_path(
4494 path, self.xray_context, namespace);
4495 match (def, unqualified_def) {
4496 (Some(d), Some(ud)) if d == ud => {
4497 self.session.add_lint(unnecessary_qualification,
4499 ~"unnecessary qualification");
4506 return unqualified_def;
4509 pub fn resolve_identifier(@mut self,
4511 namespace: Namespace,
4516 match self.resolve_identifier_in_local_ribs(identifier,
4528 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4532 // FIXME #4952: Merge me with resolve_name_in_module?
4533 pub fn resolve_definition_of_name_in_module(@mut self,
4534 containing_module: @mut Module,
4536 namespace: Namespace,
4539 // First, search children.
4540 match containing_module.children.find(&name) {
4541 Some(child_name_bindings) => {
4542 match (child_name_bindings.def_for_namespace(namespace),
4543 child_name_bindings.privacy_for_namespace(namespace)) {
4544 (Some(def), Some(Public)) => {
4545 // Found it. Stop the search here.
4546 return ChildNameDefinition(def);
4548 (Some(def), _) if xray == Xray => {
4549 // Found it. Stop the search here.
4550 return ChildNameDefinition(def);
4552 (Some(_), _) | (None, _) => {
4562 // Next, search import resolutions.
4563 match containing_module.import_resolutions.find(&name) {
4564 Some(import_resolution) if import_resolution.privacy == Public ||
4566 match (*import_resolution).target_for_namespace(namespace) {
4568 match (target.bindings.def_for_namespace(namespace),
4569 target.bindings.privacy_for_namespace(
4571 (Some(def), Some(Public)) => {
4573 let id = import_resolution.id(namespace);
4574 self.used_imports.insert(id);
4575 return ImportNameDefinition(def);
4577 (Some(_), _) | (None, _) => {
4578 // This can happen with external impls, due to
4579 // the imperfect way we read the metadata.
4586 Some(_) | None => {} // Continue.
4589 // Finally, search through external children.
4590 if namespace == TypeNS {
4591 match containing_module.external_module_children.find(&name) {
4594 match module.def_id {
4595 None => {} // Continue.
4597 return ChildNameDefinition(def_mod(def_id));
4604 return NoNameDefinition;
4607 pub fn intern_module_part_of_path(@mut self, path: &Path) -> ~[ident] {
4608 let mut module_path_idents = ~[];
4609 for (index, ident) in path.idents.iter().enumerate() {
4610 if index == path.idents.len() - 1 {
4614 module_path_idents.push(*ident);
4617 return module_path_idents;
4620 pub fn resolve_module_relative_path(@mut self,
4623 namespace: Namespace)
4625 let module_path_idents = self.intern_module_part_of_path(path);
4627 let containing_module;
4628 match self.resolve_module_path(self.current_module,
4632 PathPublicOnlySearch) {
4634 self.session.span_err(path.span,
4635 fmt!("use of undeclared module `%s`",
4637 module_path_idents)));
4642 fail!("indeterminate unexpected");
4645 Success(resulting_module) => {
4646 containing_module = resulting_module;
4650 let name = *path.idents.last();
4651 let def = match self.resolve_definition_of_name_in_module(containing_module,
4655 NoNameDefinition => {
4656 // We failed to resolve the name. Report an error.
4659 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4663 match containing_module.kind {
4664 TraitModuleKind | ImplModuleKind => {
4665 match self.method_map.find(&name) {
4667 match containing_module.def_id {
4668 Some(def_id) if s.contains(&def_id) => {
4669 debug!("containing module was a trait or impl \
4670 and name was a method -> not resolved");
4684 /// Invariant: This must be called only during main resolution, not during
4685 /// import resolution.
4686 pub fn resolve_crate_relative_path(@mut self,
4689 namespace: Namespace)
4691 let module_path_idents = self.intern_module_part_of_path(path);
4693 let root_module = self.graph_root.get_module();
4695 let containing_module;
4696 match self.resolve_module_path_from_root(root_module,
4700 PathPublicOrPrivateSearch) {
4702 self.session.span_err(path.span,
4703 fmt!("use of undeclared module `::%s`",
4705 module_path_idents)));
4710 fail!("indeterminate unexpected");
4713 Success(resulting_module) => {
4714 containing_module = resulting_module;
4718 let name = *path.idents.last();
4719 match self.resolve_definition_of_name_in_module(containing_module,
4723 NoNameDefinition => {
4724 // We failed to resolve the name. Report an error.
4727 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4733 pub fn resolve_identifier_in_local_ribs(@mut self,
4735 namespace: Namespace,
4738 // Check the local set of ribs.
4742 search_result = self.search_ribs(self.value_ribs, ident,
4744 DontAllowCapturingSelf);
4747 search_result = self.search_ribs(self.type_ribs, ident,
4748 span, AllowCapturingSelf);
4752 match search_result {
4753 Some(dl_def(def)) => {
4754 debug!("(resolving path in local ribs) resolved `%s` to \
4756 self.session.str_of(ident),
4760 Some(dl_field) | Some(dl_impl(_)) | None => {
4766 pub fn resolve_self_value_in_local_ribs(@mut self, span: span)
4768 // FIXME #4950: This should not use a while loop.
4769 let ribs = &mut self.value_ribs;
4770 let mut i = ribs.len();
4773 match *ribs[i].self_binding {
4775 match self.upvarify(*ribs,
4779 DontAllowCapturingSelf) {
4780 Some(dl_def(def)) => return Some(def),
4782 self.session.span_bug(span,
4783 "self wasn't mapped to a \
4795 pub fn resolve_item_by_identifier_in_lexical_scope(@mut self,
4797 namespace: Namespace)
4800 match self.resolve_item_in_lexical_scope(self.current_module,
4803 DontSearchThroughModules) {
4804 Success(target) => {
4805 match (*target.bindings).def_for_namespace(namespace) {
4807 // This can happen if we were looking for a type and
4808 // found a module instead. Modules don't have defs.
4812 debug!("(resolving item path in lexical scope) \
4813 resolved `%s` to item",
4814 self.session.str_of(ident));
4820 fail!("unexpected indeterminate result");
4828 pub fn find_best_match_for_name(@mut self,
4832 let this = &mut *self;
4834 let mut maybes: ~[@str] = ~[];
4835 let mut values: ~[uint] = ~[];
4837 let mut j = this.value_ribs.len();
4840 for (&k, _) in this.value_ribs[j].bindings.iter() {
4841 maybes.push(this.session.str_of(k));
4842 values.push(uint::max_value);
4846 let mut smallest = 0;
4847 for (i, &other) in maybes.iter().enumerate() {
4848 values[i] = name.lev_distance(other);
4850 if values[i] <= values[smallest] {
4855 if values.len() > 0 &&
4856 values[smallest] != uint::max_value &&
4857 values[smallest] < name.len() + 2 &&
4858 values[smallest] <= max_distance &&
4859 name != maybes[smallest] {
4861 Some(maybes.swap_remove(smallest))
4868 pub fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
4869 let this = &mut *self;
4871 let mut i = this.type_ribs.len();
4874 match this.type_ribs[i].kind {
4875 MethodRibKind(node_id, _) =>
4876 for item in this.crate.module.items.iter() {
4877 if item.id == node_id {
4879 item_struct(class_def, _) => {
4880 for field in class_def.fields.iter() {
4881 match field.node.kind {
4882 unnamed_field => {},
4883 named_field(ident, _) => {
4884 if str::eq_slice(this.session.str_of(ident),
4902 pub fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) {
4903 // First, record candidate traits for this expression if it could
4904 // result in the invocation of a method call.
4906 self.record_candidate_traits_for_expr_if_necessary(expr);
4908 // Next, resolve the node.
4910 // The interpretation of paths depends on whether the path has
4911 // multiple elements in it or not.
4913 expr_path(ref path) => {
4914 // This is a local path in the value namespace. Walk through
4915 // scopes looking for it.
4917 match self.resolve_path(expr.id, path, ValueNS, true, visitor) {
4919 // Write the result into the def map.
4920 debug!("(resolving expr) resolved `%s`",
4921 self.idents_to_str(path.idents));
4923 // First-class methods are not supported yet; error
4927 self.session.span_err(expr.span,
4928 "first-class methods \
4929 are not supported");
4930 self.session.span_note(expr.span,
4938 self.record_def(expr.id, def);
4941 let wrong_name = self.idents_to_str(
4943 if self.name_exists_in_scope_struct(wrong_name) {
4944 self.session.span_err(expr.span,
4945 fmt!("unresolved name `%s`. \
4946 Did you mean `self.%s`?",
4951 // limit search to 5 to reduce the number
4952 // of stupid suggestions
4953 match self.find_best_match_for_name(wrong_name, 5) {
4955 self.session.span_err(expr.span,
4956 fmt!("unresolved name `%s`. \
4957 Did you mean `%s`?",
4961 self.session.span_err(expr.span,
4962 fmt!("unresolved name `%s`.",
4970 visit_expr(expr, ((), visitor));
4973 expr_fn_block(ref fn_decl, ref block) => {
4974 self.resolve_function(FunctionRibKind(expr.id, block.id),
4982 expr_struct(ref path, _, _) => {
4983 // Resolve the path to the structure it goes to.
4984 match self.resolve_path(expr.id, path, TypeNS, false, visitor) {
4985 Some(def_ty(class_id)) | Some(def_struct(class_id))
4986 if self.structs.contains(&class_id) => {
4987 let class_def = def_struct(class_id);
4988 self.record_def(expr.id, class_def);
4990 Some(definition @ def_variant(_, class_id))
4991 if self.structs.contains(&class_id) => {
4992 self.record_def(expr.id, definition);
4995 self.session.span_err(
4997 fmt!("`%s` does not name a structure",
4998 self.idents_to_str(path.idents)));
5002 visit_expr(expr, ((), visitor));
5005 expr_loop(_, Some(label)) => {
5006 do self.with_label_rib {
5008 let this = &mut *self;
5009 let def_like = dl_def(def_label(expr.id));
5010 let rib = this.label_ribs[this.label_ribs.len() - 1];
5011 rib.bindings.insert(label, def_like);
5014 visit_expr(expr, ((), visitor));
5018 expr_for_loop(*) => fail!("non-desugared expr_for_loop"),
5020 expr_break(Some(label)) | expr_again(Some(label)) => {
5021 match self.search_ribs(self.label_ribs, label, expr.span,
5022 DontAllowCapturingSelf) {
5024 self.session.span_err(expr.span,
5025 fmt!("use of undeclared label \
5027 self.session.str_of(
5029 Some(dl_def(def @ def_label(_))) => {
5030 self.record_def(expr.id, def)
5033 self.session.span_bug(expr.span,
5034 "label wasn't mapped to a \
5041 match self.resolve_self_value_in_local_ribs(expr.span) {
5043 self.session.span_err(expr.span,
5044 "`self` is not allowed in \
5047 Some(def) => self.record_def(expr.id, def),
5052 visit_expr(expr, ((), visitor));
5057 pub fn record_candidate_traits_for_expr_if_necessary(@mut self,
5060 expr_field(_, ident, _) => {
5061 // FIXME(#6890): Even though you can't treat a method like a
5062 // field, we need to add any trait methods we find that match
5063 // the field name so that we can do some nice error reporting
5064 // later on in typeck.
5065 let traits = self.search_for_traits_containing_method(ident);
5066 self.trait_map.insert(expr.id, @mut traits);
5068 expr_method_call(_, _, ident, _, _, _) => {
5069 debug!("(recording candidate traits for expr) recording \
5072 let traits = self.search_for_traits_containing_method(ident);
5073 self.trait_map.insert(expr.id, @mut traits);
5075 expr_binary(_, add, _, _) | expr_assign_op(_, add, _, _) => {
5076 self.add_fixed_trait_for_expr(expr.id,
5077 self.lang_items.add_trait());
5079 expr_binary(_, subtract, _, _) | expr_assign_op(_, subtract, _, _) => {
5080 self.add_fixed_trait_for_expr(expr.id,
5081 self.lang_items.sub_trait());
5083 expr_binary(_, mul, _, _) | expr_assign_op(_, mul, _, _) => {
5084 self.add_fixed_trait_for_expr(expr.id,
5085 self.lang_items.mul_trait());
5087 expr_binary(_, div, _, _) | expr_assign_op(_, div, _, _) => {
5088 self.add_fixed_trait_for_expr(expr.id,
5089 self.lang_items.div_trait());
5091 expr_binary(_, rem, _, _) | expr_assign_op(_, rem, _, _) => {
5092 self.add_fixed_trait_for_expr(expr.id,
5093 self.lang_items.rem_trait());
5095 expr_binary(_, bitxor, _, _) | expr_assign_op(_, bitxor, _, _) => {
5096 self.add_fixed_trait_for_expr(expr.id,
5097 self.lang_items.bitxor_trait());
5099 expr_binary(_, bitand, _, _) | expr_assign_op(_, bitand, _, _) => {
5100 self.add_fixed_trait_for_expr(expr.id,
5101 self.lang_items.bitand_trait());
5103 expr_binary(_, bitor, _, _) | expr_assign_op(_, bitor, _, _) => {
5104 self.add_fixed_trait_for_expr(expr.id,
5105 self.lang_items.bitor_trait());
5107 expr_binary(_, shl, _, _) | expr_assign_op(_, shl, _, _) => {
5108 self.add_fixed_trait_for_expr(expr.id,
5109 self.lang_items.shl_trait());
5111 expr_binary(_, shr, _, _) | expr_assign_op(_, shr, _, _) => {
5112 self.add_fixed_trait_for_expr(expr.id,
5113 self.lang_items.shr_trait());
5115 expr_binary(_, lt, _, _) | expr_binary(_, le, _, _) |
5116 expr_binary(_, ge, _, _) | expr_binary(_, gt, _, _) => {
5117 self.add_fixed_trait_for_expr(expr.id,
5118 self.lang_items.ord_trait());
5120 expr_binary(_, eq, _, _) | expr_binary(_, ne, _, _) => {
5121 self.add_fixed_trait_for_expr(expr.id,
5122 self.lang_items.eq_trait());
5124 expr_unary(_, neg, _) => {
5125 self.add_fixed_trait_for_expr(expr.id,
5126 self.lang_items.neg_trait());
5128 expr_unary(_, not, _) => {
5129 self.add_fixed_trait_for_expr(expr.id,
5130 self.lang_items.not_trait());
5133 self.add_fixed_trait_for_expr(expr.id,
5134 self.lang_items.index_trait());
5142 pub fn search_for_traits_containing_method(@mut self, name: ident)
5144 debug!("(searching for traits containing method) looking for '%s'",
5145 self.session.str_of(name));
5147 let mut found_traits = ~[];
5148 let mut search_module = self.current_module;
5149 match self.method_map.find(&name) {
5150 Some(candidate_traits) => loop {
5151 // Look for the current trait.
5152 match self.current_trait_refs {
5153 Some(ref trait_def_ids) => {
5154 for trait_def_id in trait_def_ids.iter() {
5155 if candidate_traits.contains(trait_def_id) {
5156 self.add_trait_info(&mut found_traits,
5167 // Look for trait children.
5168 for (_, &child_name_bindings) in search_module.children.iter() {
5169 match child_name_bindings.def_for_namespace(TypeNS) {
5172 def_trait(trait_def_id) => {
5173 if candidate_traits.contains(&trait_def_id) {
5174 self.add_trait_info(
5176 trait_def_id, name);
5190 // Look for imports.
5191 for (_, &import_resolution) in search_module.import_resolutions.iter() {
5192 match import_resolution.target_for_namespace(TypeNS) {
5197 match target.bindings.def_for_namespace(TypeNS) {
5200 def_trait(trait_def_id) => {
5201 if candidate_traits.contains(&trait_def_id) {
5202 self.add_trait_info(
5204 trait_def_id, name);
5205 self.used_imports.insert(
5206 import_resolution.type_id);
5222 // Move to the next parent.
5223 match search_module.parent_link {
5228 ModuleParentLink(parent_module, _) |
5229 BlockParentLink(parent_module, _) => {
5230 search_module = parent_module;
5237 return found_traits;
5240 pub fn add_trait_info(&self,
5241 found_traits: &mut ~[def_id],
5242 trait_def_id: def_id,
5244 debug!("(adding trait info) found trait %d:%d for method '%s'",
5247 self.session.str_of(name));
5248 found_traits.push(trait_def_id);
5251 pub fn add_fixed_trait_for_expr(@mut self,
5253 trait_id: Option<def_id>) {
5256 self.trait_map.insert(expr_id, @mut ~[trait_id]);
5262 pub fn record_def(@mut self, node_id: NodeId, def: def) {
5263 debug!("(recording def) recording %? for %?", def, node_id);
5264 self.def_map.insert(node_id, def);
5267 pub fn enforce_default_binding_mode(@mut self,
5269 pat_binding_mode: binding_mode,
5271 match pat_binding_mode {
5274 self.session.span_err(
5276 fmt!("cannot use `ref` binding mode with %s",
5283 // Unused import checking
5285 // Although this is a lint pass, it lives in here because it depends on
5286 // resolve data structures.
5289 pub fn check_for_unused_imports(@mut self) {
5290 let vt = mk_simple_visitor(@SimpleVisitor {
5291 visit_view_item: |vi| self.check_for_item_unused_imports(vi),
5292 .. *default_simple_visitor()
5294 visit_crate(self.crate, ((), vt));
5297 pub fn check_for_item_unused_imports(&mut self, vi: &view_item) {
5298 // Ignore public import statements because there's no way to be sure
5299 // whether they're used or not. Also ignore imports with a dummy span
5300 // because this means that they were generated in some fashion by the
5301 // compiler and we don't need to consider them.
5302 if vi.vis == public { return }
5303 if vi.span == dummy_sp() { return }
5306 view_item_extern_mod(*) => {} // ignore
5307 view_item_use(ref path) => {
5308 for p in path.iter() {
5310 view_path_simple(_, _, id) | view_path_glob(_, id) => {
5311 if !self.used_imports.contains(&id) {
5312 self.session.add_lint(unused_imports,
5318 view_path_list(_, ref list, _) => {
5319 for i in list.iter() {
5320 if !self.used_imports.contains(&i.node.id) {
5321 self.session.add_lint(unused_imports,
5336 // Diagnostics are not particularly efficient, because they're rarely
5340 /// A somewhat inefficient routine to obtain the name of a module.
5341 pub fn module_to_str(@mut self, module_: @mut Module) -> ~str {
5342 let mut idents = ~[];
5343 let mut current_module = module_;
5345 match current_module.parent_link {
5349 ModuleParentLink(module_, name) => {
5351 current_module = module_;
5353 BlockParentLink(module_, _) => {
5354 idents.push(special_idents::opaque);
5355 current_module = module_;
5360 if idents.len() == 0 {
5363 return self.idents_to_str(idents.consume_rev_iter().collect::<~[ast::ident]>());
5366 pub fn dump_module(@mut self, module_: @mut Module) {
5367 debug!("Dump of module `%s`:", self.module_to_str(module_));
5369 debug!("Children:");
5370 for (&name, _) in module_.children.iter() {
5371 debug!("* %s", self.session.str_of(name));
5374 debug!("Import resolutions:");
5375 for (name, import_resolution) in module_.import_resolutions.iter() {
5377 match import_resolution.target_for_namespace(ValueNS) {
5378 None => { value_repr = ~""; }
5380 value_repr = ~" value:?";
5386 match import_resolution.target_for_namespace(TypeNS) {
5387 None => { type_repr = ~""; }
5389 type_repr = ~" type:?";
5394 debug!("* %s:%s%s", self.session.str_of(*name),
5395 value_repr, type_repr);
5400 pub struct CrateMap {
5402 exp_map2: ExportMap2,
5406 /// Entry point to crate resolution.
5407 pub fn resolve_crate(session: Session,
5408 lang_items: LanguageItems,
5411 let resolver = @mut Resolver(session, lang_items, crate);
5414 def_map: resolver.def_map,
5415 exp_map2: resolver.export_map2,
5416 trait_map: resolver.trait_map.clone(),