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.
14 use driver::session::Session;
15 use metadata::csearch::{each_path, get_method_names_if_trait};
16 use metadata::csearch::{get_static_methods_if_impl, get_struct_fields};
17 use metadata::csearch::{get_type_name_if_impl};
18 use metadata::cstore::find_extern_mod_stmt_cnum;
19 use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
20 use middle::lang_items::LanguageItems;
21 use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
22 use middle::lint::{get_lint_level, get_lint_settings_level};
23 use middle::pat_util::{pat_bindings};
27 use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
28 use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk};
29 use syntax::ast::{bind_infer, bind_by_ref, bind_by_copy};
30 use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
31 use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
32 use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
33 use syntax::ast::{def_self_ty, def_static_method, def_struct, def_ty};
34 use syntax::ast::{def_ty_param, def_typaram_binder};
35 use syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
36 use syntax::ast::{expr_binary, expr_break, expr_cast, expr_field};
37 use syntax::ast::{expr_fn_block, expr_index, expr_method_call, expr_path};
38 use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
39 use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
40 use syntax::ast::{enum_variant_kind, expr, expr_again, expr_assign_op};
41 use syntax::ast::{expr_index, expr_loop};
42 use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
43 use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
44 use syntax::ast::{Generics};
45 use syntax::ast::{gt, ident, impure_fn, inherited, item, item_struct};
46 use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
47 use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
48 use syntax::ast::{local, local_crate, lt, method, mode, module_ns, mul};
49 use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
50 use syntax::ast::{path, pat_box, pat_lit, pat_range, pat_struct};
51 use syntax::ast::{pat_tup, pat_uniq, pat_wild, prim_ty, private, provided};
52 use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl};
53 use syntax::ast::{struct_dtor, struct_field, struct_variant_kind, sty_by_ref};
54 use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty};
55 use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
56 use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, TyParam, ty_path};
57 use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
58 use syntax::ast::{type_value_ns, unnamed_field};
59 use syntax::ast::{variant, view_item, view_item_extern_mod};
60 use syntax::ast::{view_item_use, view_path_glob, view_path_list};
61 use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
62 use syntax::ast::{unsafe_fn};
63 use syntax::ast_util::{def_id_of_def, local_def};
64 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
65 use syntax::ast_util::{Privacy, Public, Private};
66 use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy};
67 use syntax::attr::{attr_metas, contains_name, attrs_contains_name};
68 use syntax::parse::token::ident_interner;
69 use syntax::parse::token::special_idents;
70 use syntax::print::pprust::{pat_to_str, path_to_str};
71 use syntax::codemap::{span, dummy_sp};
72 use syntax::visit::{default_visitor, fk_method, mk_vt, Visitor, visit_block};
73 use syntax::visit::{visit_crate, visit_expr, visit_expr_opt, visit_fn};
74 use syntax::visit::{visit_foreign_item, visit_item, visit_method_helper};
75 use syntax::visit::{visit_mod, visit_ty, vt};
76 use syntax::opt_vec::OptVec;
78 use core::option::{Some, get, is_some, is_none};
79 use core::str::{connect, split_str};
80 use std::oldmap::HashMap;
83 pub type DefMap = HashMap<node_id,def>;
85 pub struct binding_info {
87 binding_mode: binding_mode,
90 // Map from the name in a pattern to its binding mode.
91 pub type BindingMap = HashMap<ident,binding_info>;
93 // Implementation resolution
95 // FIXME #4946: This kind of duplicates information kept in
96 // ty::method. Maybe it should go away.
98 pub struct MethodInfo {
108 methods: ~[@MethodInfo]
111 // Trait method resolution
112 pub type TraitMap = @HashMap<node_id,@mut ~[def_id]>;
114 // This is the replacement export map. It maps a module to all of the exports
116 pub type ExportMap2 = HashMap<node_id, ~[Export2]>;
119 name: @~str, // The name of the target.
120 def_id: def_id, // The definition of the target.
121 reexport: bool, // Whether this is a reexport.
125 pub enum PatternBindingMode {
127 LocalIrrefutableMode,
128 ArgumentIrrefutableMode(mode)
136 /// A NamespaceResult represents the result of resolving an import in
137 /// a particular namespace. The result is either definitely-resolved,
138 /// definitely- unresolved, or unknown.
139 pub enum NamespaceResult {
140 /// Means that resolve hasn't gathered enough information yet to determine
141 /// whether the name is bound in this namespace. (That is, it hasn't
142 /// resolved all `use` directives yet.)
144 /// Means that resolve has determined that the name is definitely
145 /// not bound in the namespace.
147 /// Means that resolve has determined that the name is bound in the Module
148 /// argument, and specified by the NameBindings argument.
149 BoundResult(@mut Module, @mut NameBindings)
152 pub impl NamespaceResult {
153 pure fn is_unknown(&self) -> bool {
155 UnknownResult => true,
161 pub enum NameDefinition {
162 NoNameDefinition, //< The name was unbound.
163 ChildNameDefinition(def), //< The name identifies an immediate child.
164 ImportNameDefinition(def) //< The name identifies an import.
169 pub enum Mutability {
174 pub enum SelfBinding {
176 HasSelfBinding(node_id, bool /* is implicit */)
179 pub type ResolveVisitor = vt<()>;
182 pub enum ImportDirectiveNS {
187 /// Contains data for specific types of import directives.
188 pub enum ImportDirectiveSubclass {
189 SingleImport(ident /* target */, ident /* source */, ImportDirectiveNS),
193 /// The context that we thread through while building the reduced graph.
194 pub enum ReducedGraphParent {
195 ModuleReducedGraphParent(@mut Module)
198 pub enum ResolveResult<T> {
199 Failed, // Failed to resolve the name.
200 Indeterminate, // Couldn't determine due to unresolved globs.
201 Success(T) // Successfully resolved the import.
204 pub impl<T> ResolveResult<T> {
205 fn failed(&self) -> bool {
206 match *self { Failed => true, _ => false }
208 fn indeterminate(&self) -> bool {
209 match *self { Indeterminate => true, _ => false }
213 pub enum TypeParameters<'self> {
214 NoTypeParameters, //< No type parameters.
215 HasTypeParameters(&'self Generics, //< Type parameters.
216 node_id, //< ID of the enclosing item
218 // The index to start numbering the type parameters at.
219 // This is zero if this is the outermost set of type
220 // parameters, or equal to the number of outer type
221 // parameters. For example, if we have:
224 // fn method<U>() { ... }
227 // The index at the method site will be 1, because the
228 // outer T had index 0.
231 // The kind of the rib used for type parameters.
235 // The rib kind controls the translation of argument or local definitions
236 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
239 // No translation needs to be applied.
242 // We passed through a function scope at the given node ID. Translate
243 // upvars as appropriate.
244 FunctionRibKind(node_id /* func id */, node_id /* body id */),
246 // We passed through an impl or trait and are now in one of its
247 // methods. Allow references to ty params that that impl or trait
248 // binds. Disallow any other upvars (including other ty params that are
250 // parent; method itself
251 MethodRibKind(node_id, MethodSort),
253 // We passed through a function *item* scope. Disallow upvars.
254 OpaqueFunctionRibKind,
256 // We're in a constant item. Can't refer to dynamic stuff.
260 // Methods can be required or provided. Required methods only occur in traits.
261 pub enum MethodSort {
266 // The X-ray flag indicates that a context has the X-ray privilege, which
267 // allows it to reference private names. Currently, this is used for the test
270 // FIXME #4947: The X-ray flag is kind of questionable in the first
271 // place. It might be better to introduce an expr_xray_path instead.
275 NoXray, //< Private items cannot be accessed.
276 Xray //< Private items can be accessed.
279 pub enum UseLexicalScopeFlag {
284 pub enum SearchThroughModulesFlag {
285 DontSearchThroughModules,
289 pub enum ModulePrefixResult {
291 PrefixFound(@mut Module, uint)
295 pub enum AllowCapturingSelfFlag {
296 AllowCapturingSelf, //< The "self" definition can be captured.
297 DontAllowCapturingSelf, //< The "self" definition cannot be captured.
301 enum NameSearchType {
302 SearchItemsAndPublicImports, //< Search items and public imports.
303 SearchItemsAndAllImports, //< Search items and all imports.
306 pub enum BareIdentifierPatternResolution {
307 FoundStructOrEnumVariant(def),
309 BareIdentifierPatternUnresolved
312 // Specifies how duplicates should be handled when adding a child item if
313 // another item exists with the same name in some namespace.
315 pub enum DuplicateCheckingMode {
316 ForbidDuplicateModules,
317 ForbidDuplicateTypes,
318 ForbidDuplicateValues,
319 ForbidDuplicateTypesAndValues,
323 // Returns the namespace associated with the given duplicate checking mode,
324 // or fails for OverwriteDuplicates. This is used for error messages.
325 pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
328 ForbidDuplicateModules | ForbidDuplicateTypes |
329 ForbidDuplicateTypesAndValues => TypeNS,
330 ForbidDuplicateValues => ValueNS,
331 OverwriteDuplicates => fail!(~"OverwriteDuplicates has no namespace")
337 bindings: HashMap<ident,def_like>,
341 pub fn Rib(kind: RibKind) -> Rib {
349 /// One import directive.
350 pub struct ImportDirective {
352 module_path: ~[ident],
353 subclass: @ImportDirectiveSubclass,
357 pub fn ImportDirective(privacy: Privacy,
358 +module_path: ~[ident],
359 subclass: @ImportDirectiveSubclass,
364 module_path: module_path,
370 /// The item that an import resolves to.
372 target_module: @mut Module,
373 bindings: @mut NameBindings,
376 pub fn Target(target_module: @mut Module,
377 bindings: @mut NameBindings)
380 target_module: target_module,
385 /// An ImportResolution represents a particular `use` directive.
386 pub struct ImportResolution {
387 /// The privacy of this `use` directive (whether it's `use` or
392 // The number of outstanding references to this name. When this reaches
393 // zero, outside modules can count on the targets being correct. Before
394 // then, all bets are off; future imports could override this name.
396 outstanding_references: uint,
398 /// The value that this `use` directive names, if there is one.
399 value_target: Option<Target>,
400 /// The type that this `use` directive names, if there is one.
401 type_target: Option<Target>,
403 /// There exists one state per import statement
404 state: @mut ImportState,
407 pub fn ImportResolution(privacy: Privacy,
409 state: @mut ImportState) -> ImportResolution {
413 outstanding_references: 0,
420 pub impl ImportResolution {
421 fn target_for_namespace(&self, namespace: Namespace) -> Option<Target> {
423 TypeNS => return copy self.type_target,
424 ValueNS => return copy self.value_target
429 pub struct ImportState {
434 pub fn ImportState() -> ImportState {
435 ImportState{ used: false, warned: false }
438 /// The link from a module up to its nearest parent node.
439 pub enum ParentLink {
441 ModuleParentLink(@mut Module, ident),
442 BlockParentLink(@mut Module, node_id)
445 /// The type of module this is.
446 pub enum ModuleKind {
453 /// One node in the tree of modules.
455 parent_link: ParentLink,
456 def_id: Option<def_id>,
459 children: @HashMap<ident,@mut NameBindings>,
460 imports: @mut ~[@ImportDirective],
462 // The anonymous children of this node. Anonymous children are pseudo-
463 // modules that are implicitly created around items contained within
466 // For example, if we have this:
474 // There will be an anonymous module created around `g` with the ID of the
475 // entry block for `f`.
477 anonymous_children: @HashMap<node_id,@mut Module>,
479 // The status of resolving each import in this module.
480 import_resolutions: @HashMap<ident,@mut ImportResolution>,
482 // The number of unresolved globs that this module exports.
485 // The index of the import we're resolving.
486 resolved_import_count: uint,
489 pub fn Module(parent_link: ParentLink,
490 def_id: Option<def_id>,
494 parent_link: parent_link,
497 children: @HashMap(),
499 anonymous_children: @HashMap(),
500 import_resolutions: @HashMap(),
502 resolved_import_count: 0
507 fn all_imports_resolved(&self) -> bool {
508 let imports = &mut *self.imports;
509 return imports.len() == self.resolved_import_count;
513 // Records a possibly-private type definition.
514 pub struct TypeNsDef {
516 module_def: Option<@mut Module>,
517 type_def: Option<def>
520 // Records a possibly-private value definition.
521 pub struct ValueNsDef {
526 // Records the definitions (at most one for each namespace) that a name is
528 pub struct NameBindings {
529 type_def: Option<TypeNsDef>, //< Meaning in type namespace.
530 value_def: Option<ValueNsDef>, //< Meaning in value namespace.
532 // For error reporting
533 // FIXME (#3783): Merge me into TypeNsDef and ValueNsDef.
534 type_span: Option<span>,
535 value_span: Option<span>,
538 pub impl NameBindings {
539 /// Creates a new module in this set of name bindings.
540 fn define_module(@mut self,
542 parent_link: ParentLink,
543 def_id: Option<def_id>,
546 // Merges the module with the existing type def or creates a new one.
547 let module_ = @mut Module(parent_link, def_id, kind);
548 match self.type_def {
550 self.type_def = Some(TypeNsDef {
552 module_def: Some(module_),
556 Some(copy type_def) => {
557 self.type_def = Some(TypeNsDef {
559 module_def: Some(module_),
564 self.type_span = Some(sp);
567 /// Records a type definition.
568 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 {
578 Some(copy type_def) => {
579 self.type_def = Some(TypeNsDef {
586 self.type_span = Some(sp);
589 /// Records a value definition.
590 fn define_value(@mut self, privacy: Privacy, def: def, sp: span) {
591 self.value_def = Some(ValueNsDef { privacy: privacy, def: def });
592 self.value_span = Some(sp);
595 /// Returns the module node if applicable.
596 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 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 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 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 fn def_for_namespace(&self, namespace: Namespace) -> Option<def> {
640 match self.type_def {
642 Some(ref type_def) => {
643 // FIXME (#3784): This is reallllly questionable.
644 // Perhaps the right thing to do is to merge def_mod
646 match (*type_def).type_def {
647 Some(type_def) => Some(type_def),
649 match (*type_def).module_def {
650 Some(module_def) => {
651 let module_def = &mut *module_def;
652 module_def.def_id.map(|def_id|
663 match self.value_def {
665 Some(value_def) => Some(value_def.def)
671 fn privacy_for_namespace(&self, namespace: Namespace) -> Option<Privacy> {
674 match self.type_def {
676 Some(ref type_def) => Some((*type_def).privacy)
680 match self.value_def {
682 Some(value_def) => Some(value_def.privacy)
688 fn span_for_namespace(&self, namespace: Namespace) -> Option<span> {
689 if self.defined_in_namespace(namespace) {
691 TypeNS => self.type_span,
692 ValueNS => self.value_span,
700 pub fn NameBindings() -> NameBindings {
709 /// Interns the names of the primitive types.
710 pub struct PrimitiveTypeTable {
711 primitive_types: HashMap<ident,prim_ty>,
714 pub impl PrimitiveTypeTable {
715 fn intern(&self, intr: @ident_interner, string: @~str,
716 primitive_type: prim_ty) {
717 let ident = intr.intern(string);
718 self.primitive_types.insert(ident, primitive_type);
722 pub fn PrimitiveTypeTable(intr: @ident_interner) -> PrimitiveTypeTable {
723 let table = PrimitiveTypeTable {
724 primitive_types: HashMap()
727 table.intern(intr, @~"bool", ty_bool);
728 table.intern(intr, @~"char", ty_int(ty_char));
729 table.intern(intr, @~"float", ty_float(ty_f));
730 table.intern(intr, @~"f32", ty_float(ty_f32));
731 table.intern(intr, @~"f64", ty_float(ty_f64));
732 table.intern(intr, @~"int", ty_int(ty_i));
733 table.intern(intr, @~"i8", ty_int(ty_i8));
734 table.intern(intr, @~"i16", ty_int(ty_i16));
735 table.intern(intr, @~"i32", ty_int(ty_i32));
736 table.intern(intr, @~"i64", ty_int(ty_i64));
737 table.intern(intr, @~"str", ty_str);
738 table.intern(intr, @~"uint", ty_uint(ty_u));
739 table.intern(intr, @~"u8", ty_uint(ty_u8));
740 table.intern(intr, @~"u16", ty_uint(ty_u16));
741 table.intern(intr, @~"u32", ty_uint(ty_u32));
742 table.intern(intr, @~"u64", ty_uint(ty_u64));
748 pub fn namespace_to_str(ns: Namespace) -> ~str {
755 pub fn Resolver(session: Session,
756 lang_items: LanguageItems,
759 let graph_root = @mut NameBindings();
761 graph_root.define_module(Public,
763 Some(def_id { crate: 0, node: 0 }),
767 let current_module = graph_root.get_module();
769 let self = Resolver {
771 lang_items: copy lang_items,
774 // The outermost module has def ID 0; this is not reflected in the
777 graph_root: graph_root,
779 trait_info: @HashMap(),
782 unresolved_imports: 0,
784 current_module: current_module,
789 xray_context: NoXray,
790 current_trait_refs: None,
792 self_ident: special_idents::self_,
793 type_self_ident: special_idents::type_self,
795 primitive_type_table: @PrimitiveTypeTable(session.
796 parse_sess.interner),
798 namespaces: ~[ TypeNS, ValueNS ],
804 export_map2: @HashMap(),
805 trait_map: @HashMap(),
813 /// The main resolver class.
814 pub struct Resolver {
816 lang_items: LanguageItems,
819 intr: @ident_interner,
821 graph_root: @mut NameBindings,
823 trait_info: @HashMap<def_id,@HashMap<ident,()>>,
824 structs: @HashMap<def_id,()>,
826 // The number of imports that are currently unresolved.
827 unresolved_imports: uint,
829 // The module that represents the current item scope.
830 current_module: @mut Module,
832 // The current set of local scopes, for values.
833 // FIXME #4948: Reuse ribs to avoid allocation.
836 // The current set of local scopes, for types.
839 // The current set of local scopes, for labels.
842 // Whether the current context is an X-ray context. An X-ray context is
843 // allowed to access private names of any module.
844 xray_context: XrayFlag,
846 // The trait that the current context can refer to.
847 current_trait_refs: Option<~[def_id]>,
849 // The ident for the keyword "self".
851 // The ident for the non-keyword "Self".
852 type_self_ident: ident,
854 // The idents for the primitive types.
855 primitive_type_table: @PrimitiveTypeTable,
857 // The four namespaces.
858 namespaces: ~[Namespace],
860 // The function that has attribute named 'main'
861 attr_main_fn: Option<(node_id, span)>,
862 // The functions named 'main'
863 main_fns: ~[Option<(node_id, span)>],
866 export_map2: @ExportMap2,
871 /// The main name resolution procedure.
872 fn resolve(@mut self) {
873 self.build_reduced_graph();
874 self.session.abort_if_errors();
876 self.resolve_imports();
877 self.session.abort_if_errors();
879 self.record_exports();
880 self.session.abort_if_errors();
882 self.resolve_crate();
883 self.session.abort_if_errors();
885 self.check_duplicate_main();
886 self.check_for_unused_imports_if_necessary();
890 // Reduced graph building
892 // Here we build the "reduced graph": the graph of the module tree without
893 // any imports resolved.
896 /// Constructs the reduced graph for the entire crate.
897 fn build_reduced_graph(@mut self) {
899 ModuleReducedGraphParent(self.graph_root.get_module());
900 visit_crate(*self.crate, initial_parent, mk_vt(@Visitor {
901 visit_item: |item, context, visitor|
902 self.build_reduced_graph_for_item(item, context, visitor),
904 visit_foreign_item: |foreign_item, context, visitor|
905 self.build_reduced_graph_for_foreign_item(foreign_item,
909 visit_view_item: |view_item, context, visitor|
910 self.build_reduced_graph_for_view_item(view_item,
914 visit_block: |block, context, visitor|
915 self.build_reduced_graph_for_block(block,
919 .. *default_visitor()
923 /// Returns the current module tracked by the reduced graph parent.
924 fn get_module_from_parent(@mut self,
925 reduced_graph_parent: ReducedGraphParent)
927 match reduced_graph_parent {
928 ModuleReducedGraphParent(module_) => {
935 * Adds a new child item to the module definition of the parent node and
936 * returns its corresponding name bindings as well as the current parent.
937 * Or, if we're inside a block, creates (or reuses) an anonymous module
938 * corresponding to the innermost block ID and returns the name bindings
939 * as well as the newly-created parent.
941 * If this node does not have a module definition and we are not inside
944 fn add_child(@mut self,
946 reduced_graph_parent: ReducedGraphParent,
947 duplicate_checking_mode: DuplicateCheckingMode,
948 // For printing errors
950 -> (@mut NameBindings, ReducedGraphParent) {
952 // If this is the immediate descendant of a module, then we add the
953 // child name directly. Otherwise, we create or reuse an anonymous
954 // module and add the child to that.
957 match reduced_graph_parent {
958 ModuleReducedGraphParent(parent_module) => {
959 module_ = parent_module;
963 // Add or reuse the child.
964 let new_parent = ModuleReducedGraphParent(module_);
965 match module_.children.find(&name) {
967 let child = @mut NameBindings();
968 module_.children.insert(name, child);
969 return (child, new_parent);
972 // Enforce the duplicate checking mode. If we're requesting
973 // duplicate module checking, check that there isn't a module
974 // in the module with the same name. If we're requesting
975 // duplicate type checking, check that there isn't a type in
976 // the module with the same name. If we're requesting
977 // duplicate value checking, check that there isn't a value in
978 // the module with the same name. If we're requesting
979 // duplicate type checking and duplicate value checking, check
980 // that there isn't a duplicate type and a duplicate value
981 // with the same name. If no duplicate checking was requested
982 // at all, do nothing.
984 let mut is_duplicate = false;
985 match duplicate_checking_mode {
986 ForbidDuplicateModules => {
988 child.get_module_if_available().is_some();
990 ForbidDuplicateTypes => {
991 match child.def_for_namespace(TypeNS) {
992 Some(def_mod(_)) | None => {}
993 Some(_) => is_duplicate = true
996 ForbidDuplicateValues => {
997 is_duplicate = child.defined_in_namespace(ValueNS);
999 ForbidDuplicateTypesAndValues => {
1000 match child.def_for_namespace(TypeNS) {
1001 Some(def_mod(_)) | None => {}
1002 Some(_) => is_duplicate = true
1004 if child.defined_in_namespace(ValueNS) {
1005 is_duplicate = true;
1008 OverwriteDuplicates => {}
1010 if duplicate_checking_mode != OverwriteDuplicates &&
1012 // Return an error here by looking up the namespace that
1013 // had the duplicate.
1014 let ns = namespace_for_duplicate_checking_mode(
1015 duplicate_checking_mode);
1016 self.session.span_err(sp,
1017 fmt!("duplicate definition of %s %s",
1018 namespace_to_str(ns),
1019 *self.session.str_of(name)));
1020 for child.span_for_namespace(ns).each |sp| {
1021 self.session.span_note(*sp,
1022 fmt!("first definition of %s %s here:",
1023 namespace_to_str(ns),
1024 *self.session.str_of(name)));
1027 return (child, new_parent);
1032 fn block_needs_anonymous_module(@mut self, block: &blk) -> bool {
1033 // If the block has view items, we need an anonymous module.
1034 if block.node.view_items.len() > 0 {
1038 // Check each statement.
1039 for block.node.stmts.each |statement| {
1040 match statement.node {
1041 stmt_decl(declaration, _) => {
1042 match declaration.node {
1057 // If we found neither view items nor items, we don't need to create
1058 // an anonymous module.
1063 fn get_parent_link(@mut self,
1064 parent: ReducedGraphParent,
1068 ModuleReducedGraphParent(module_) => {
1069 return ModuleParentLink(module_, name);
1074 /// Constructs the reduced graph for one item.
1075 fn build_reduced_graph_for_item(@mut self,
1077 parent: ReducedGraphParent,
1078 &&visitor: vt<ReducedGraphParent>) {
1079 let ident = item.ident;
1081 let privacy = visibility_to_privacy(item.vis);
1084 item_mod(ref module_) => {
1085 let (name_bindings, new_parent) =
1086 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1088 let parent_link = self.get_parent_link(new_parent, ident);
1089 let def_id = def_id { crate: 0, node: item.id };
1090 name_bindings.define_module(privacy,
1097 ModuleReducedGraphParent(name_bindings.get_module());
1099 visit_mod(module_, sp, item.id, new_parent, visitor);
1102 item_foreign_mod(ref fm) => {
1103 let new_parent = match fm.sort {
1105 let (name_bindings, new_parent) =
1106 self.add_child(ident, parent,
1107 ForbidDuplicateModules, sp);
1109 let parent_link = self.get_parent_link(new_parent,
1111 let def_id = def_id { crate: 0, node: item.id };
1112 name_bindings.define_module(privacy,
1118 ModuleReducedGraphParent(name_bindings.get_module())
1121 // For anon foreign mods, the contents just go in the
1126 visit_item(item, new_parent, visitor);
1129 // These items live in the value namespace.
1131 let (name_bindings, _) =
1132 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1134 name_bindings.define_value
1135 (privacy, def_const(local_def(item.id)), sp);
1137 item_fn(_, purity, _, _) => {
1138 let (name_bindings, new_parent) =
1139 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1141 let def = def_fn(local_def(item.id), purity);
1142 name_bindings.define_value(privacy, def, sp);
1143 visit_item(item, new_parent, visitor);
1146 // These items live in the type namespace.
1148 let (name_bindings, _) =
1149 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1151 name_bindings.define_type
1152 (privacy, def_ty(local_def(item.id)), sp);
1155 item_enum(ref enum_definition, _) => {
1156 let (name_bindings, new_parent) =
1157 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1159 name_bindings.define_type
1160 (privacy, def_ty(local_def(item.id)), sp);
1162 for (*enum_definition).variants.each |variant| {
1163 self.build_reduced_graph_for_variant(*variant,
1165 // inherited => privacy of the enum item
1166 variant_visibility_to_privacy(variant.node.vis,
1173 // These items live in both the type and value namespaces.
1174 item_struct(struct_def, _) => {
1175 let (name_bindings, new_parent) =
1176 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1178 name_bindings.define_type(
1179 privacy, def_ty(local_def(item.id)), sp);
1181 // If this struct is tuple-like or enum-like, define a name
1182 // in the value namespace.
1183 match struct_def.ctor_id {
1186 name_bindings.define_value(
1188 def_struct(local_def(ctor_id)),
1193 // Record the def ID of this struct.
1194 self.structs.insert(local_def(item.id), ());
1196 visit_item(item, new_parent, visitor);
1199 item_impl(_, trait_ref_opt, ty, ref methods) => {
1200 // If this implements an anonymous trait and it has static
1201 // methods, then add all the static methods within to a new
1202 // module, if the type was defined within this module.
1204 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1205 // should modify anonymous traits to only be implementable in
1206 // the same module that declared the type.
1208 // Bail out early if there are no static methods.
1209 let mut has_static_methods = false;
1210 for methods.each |method| {
1211 match method.self_ty.node {
1212 sty_static => has_static_methods = true,
1217 // If there are static methods, then create the module
1219 match (trait_ref_opt, ty) {
1220 (None, @Ty { node: ty_path(path, _), _ }) if
1221 has_static_methods && path.idents.len() == 1 => {
1222 // Create the module.
1223 let name = path_to_ident(path);
1224 let (name_bindings, new_parent) =
1225 self.add_child(name,
1227 ForbidDuplicateModules,
1230 let parent_link = self.get_parent_link(new_parent,
1232 let def_id = local_def(item.id);
1233 name_bindings.define_module(Public,
1239 let new_parent = ModuleReducedGraphParent(
1240 name_bindings.get_module());
1242 // For each static method...
1243 for methods.each |method| {
1244 match method.self_ty.node {
1246 // Add the static method to the
1248 let ident = method.ident;
1249 let (method_name_bindings, _) =
1253 ForbidDuplicateValues,
1255 let def = def_fn(local_def(method.id),
1257 method_name_bindings.define_value(
1258 Public, def, method.span);
1267 visit_item(item, parent, visitor);
1270 item_trait(_, _, ref methods) => {
1271 let (name_bindings, new_parent) =
1272 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1274 // If the trait has static methods, then add all the static
1275 // methods within to a new module.
1277 // We only need to create the module if the trait has static
1278 // methods, so check that first.
1279 let mut has_static_methods = false;
1280 for (*methods).each |method| {
1281 let ty_m = trait_method_to_ty_method(method);
1282 match ty_m.self_ty.node {
1284 has_static_methods = true;
1291 // Create the module if necessary.
1292 let module_parent_opt;
1293 if has_static_methods {
1294 let parent_link = self.get_parent_link(parent, ident);
1295 name_bindings.define_module(privacy,
1297 Some(local_def(item.id)),
1300 module_parent_opt = Some(ModuleReducedGraphParent(
1301 name_bindings.get_module()));
1303 module_parent_opt = None;
1306 // Add the names of all the methods to the trait info.
1307 let method_names = @HashMap();
1308 for (*methods).each |method| {
1309 let ty_m = trait_method_to_ty_method(method);
1311 let ident = ty_m.ident;
1312 // Add it to the trait info if not static,
1313 // add it as a name in the trait module otherwise.
1314 match ty_m.self_ty.node {
1316 let def = def_static_method(
1318 Some(local_def(item.id)),
1321 let (method_name_bindings, _) =
1322 self.add_child(ident,
1323 module_parent_opt.get(),
1324 ForbidDuplicateValues,
1326 method_name_bindings.define_value(Public,
1331 method_names.insert(ident, ());
1336 let def_id = local_def(item.id);
1337 self.trait_info.insert(def_id, method_names);
1339 name_bindings.define_type(privacy, def_ty(def_id), sp);
1340 visit_item(item, new_parent, visitor);
1344 fail!(~"item macros unimplemented")
1349 // Constructs the reduced graph for one variant. Variants exist in the
1350 // type and/or value namespaces.
1351 fn build_reduced_graph_for_variant(@mut self,
1354 +parent_privacy: Privacy,
1355 parent: ReducedGraphParent,
1356 &&visitor: vt<ReducedGraphParent>) {
1357 let ident = variant.node.name;
1358 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1362 match variant.node.vis {
1363 public => privacy = Public,
1364 private => privacy = Private,
1365 inherited => privacy = parent_privacy
1368 match variant.node.kind {
1369 tuple_variant_kind(_) => {
1370 child.define_value(privacy,
1371 def_variant(item_id,
1372 local_def(variant.node.id)),
1375 struct_variant_kind(_) => {
1376 child.define_type(privacy,
1377 def_variant(item_id,
1378 local_def(variant.node.id)),
1380 self.structs.insert(local_def(variant.node.id), ());
1382 enum_variant_kind(ref enum_definition) => {
1383 child.define_type(privacy,
1384 def_ty(local_def(variant.node.id)),
1386 for (*enum_definition).variants.each |variant| {
1387 self.build_reduced_graph_for_variant(*variant, item_id,
1396 * Constructs the reduced graph for one 'view item'. View items consist
1397 * of imports and use directives.
1399 fn build_reduced_graph_for_view_item(@mut self,
1400 view_item: @view_item,
1401 parent: ReducedGraphParent,
1402 &&_visitor: vt<ReducedGraphParent>) {
1403 let privacy = visibility_to_privacy(view_item.vis);
1404 match view_item.node {
1405 view_item_use(ref view_paths) => {
1406 for view_paths.each |view_path| {
1407 // Extract and intern the module part of the path. For
1408 // globs and lists, the path is found directly in the AST;
1409 // for simple paths we have to munge the path a little.
1411 let mut module_path = ~[];
1412 match view_path.node {
1413 view_path_simple(_, full_path, _, _) => {
1414 let path_len = full_path.idents.len();
1415 fail_unless!(path_len != 0);
1417 for full_path.idents.eachi |i, ident| {
1418 if i != path_len - 1 {
1419 module_path.push(*ident);
1424 view_path_glob(module_ident_path, _) |
1425 view_path_list(module_ident_path, _, _) => {
1426 for module_ident_path.idents.each |ident| {
1427 module_path.push(*ident);
1432 // Build up the import directives.
1433 let module_ = self.get_module_from_parent(parent);
1434 let state = @mut ImportState();
1435 match view_path.node {
1436 view_path_simple(binding, full_path, ns, _) => {
1438 module_ns => TypeNSOnly,
1439 type_value_ns => AnyNS
1442 let source_ident = *full_path.idents.last();
1443 let subclass = @SingleImport(binding,
1446 self.build_import_directive(privacy,
1453 view_path_list(_, ref source_idents, _) => {
1454 for (*source_idents).each |source_ident| {
1455 let name = source_ident.node.name;
1456 let subclass = @SingleImport(name,
1459 self.build_import_directive(privacy,
1467 view_path_glob(_, _) => {
1468 self.build_import_directive(privacy,
1479 view_item_extern_mod(name, _, node_id) => {
1480 match find_extern_mod_stmt_cnum(self.session.cstore,
1483 let (child_name_bindings, new_parent) =
1484 self.add_child(name, parent, ForbidDuplicateTypes,
1487 let def_id = def_id { crate: crate_id, node: 0 };
1488 let parent_link = ModuleParentLink
1489 (self.get_module_from_parent(new_parent), name);
1491 child_name_bindings.define_module(Public,
1496 self.build_reduced_graph_for_external_crate
1497 (child_name_bindings.get_module());
1507 /// Constructs the reduced graph for one foreign item.
1508 fn build_reduced_graph_for_foreign_item(@mut self,
1509 foreign_item: @foreign_item,
1510 parent: ReducedGraphParent,
1512 vt<ReducedGraphParent>) {
1513 let name = foreign_item.ident;
1514 let (name_bindings, new_parent) =
1515 self.add_child(name, parent, ForbidDuplicateValues,
1518 match foreign_item.node {
1519 foreign_item_fn(_, _, ref generics) => {
1520 let def = def_fn(local_def(foreign_item.id), unsafe_fn);
1521 name_bindings.define_value(Public, def, foreign_item.span);
1523 do self.with_type_parameter_rib(
1525 generics, foreign_item.id, 0, NormalRibKind))
1527 visit_foreign_item(foreign_item, new_parent, visitor);
1530 foreign_item_const(*) => {
1531 let def = def_const(local_def(foreign_item.id));
1532 name_bindings.define_value(Public, def, foreign_item.span);
1534 visit_foreign_item(foreign_item, new_parent, visitor);
1539 fn build_reduced_graph_for_block(@mut self,
1541 parent: ReducedGraphParent,
1542 &&visitor: vt<ReducedGraphParent>) {
1544 if self.block_needs_anonymous_module(block) {
1545 let block_id = block.node.id;
1547 debug!("(building reduced graph for block) creating a new \
1548 anonymous module for block %d",
1551 let parent_module = self.get_module_from_parent(parent);
1552 let new_module = @mut Module(
1553 BlockParentLink(parent_module, block_id),
1555 AnonymousModuleKind);
1556 parent_module.anonymous_children.insert(block_id, new_module);
1557 new_parent = ModuleReducedGraphParent(new_module);
1559 new_parent = parent;
1562 visit_block(block, new_parent, visitor);
1565 fn handle_external_def(@mut self,
1567 modules: HashMap<def_id, @mut Module>,
1568 child_name_bindings: @mut NameBindings,
1571 new_parent: ReducedGraphParent) {
1573 def_mod(def_id) | def_foreign_mod(def_id) => {
1574 match child_name_bindings.type_def {
1575 Some(TypeNsDef { module_def: Some(copy module_def), _ }) => {
1576 debug!("(building reduced graph for external crate) \
1577 already created module");
1578 module_def.def_id = Some(def_id);
1579 modules.insert(def_id, module_def);
1582 debug!("(building reduced graph for \
1583 external crate) building module \
1585 let parent_link = self.get_parent_link(new_parent, ident);
1587 match modules.find(&def_id) {
1589 child_name_bindings.define_module(Public,
1594 modules.insert(def_id,
1595 child_name_bindings.get_module());
1597 Some(existing_module) => {
1598 // Create an import resolution to
1599 // avoid creating cycles in the
1603 @mut ImportResolution(Public,
1605 @mut ImportState());
1606 resolution.outstanding_references = 0;
1608 match existing_module.parent_link {
1610 BlockParentLink(*) => {
1611 fail!(~"can't happen");
1613 ModuleParentLink(parent_module, ident) => {
1614 let name_bindings = parent_module.children.get(
1616 resolution.type_target =
1617 Some(Target(parent_module, name_bindings));
1621 debug!("(building reduced graph for external crate) \
1622 ... creating import resolution");
1624 new_parent.import_resolutions.insert(ident, resolution);
1630 def_fn(*) | def_static_method(*) | def_const(*) |
1632 debug!("(building reduced graph for external \
1633 crate) building value %s", final_ident);
1634 child_name_bindings.define_value(Public, def, dummy_sp());
1637 debug!("(building reduced graph for external \
1638 crate) building type %s", final_ident);
1640 // If this is a trait, add all the method names
1641 // to the trait info.
1643 match get_method_names_if_trait(self.session.cstore, def_id) {
1647 Some(method_names) => {
1648 let interned_method_names = @HashMap();
1649 for method_names.each |method_data| {
1650 let (method_name, self_ty) = *method_data;
1651 debug!("(building reduced graph for \
1652 external crate) ... adding \
1654 *self.session.str_of(method_name));
1656 // Add it to the trait info if not static.
1657 if self_ty != sty_static {
1658 interned_method_names.insert(method_name, ());
1661 self.trait_info.insert(def_id, interned_method_names);
1665 child_name_bindings.define_type(Public, def, dummy_sp());
1667 def_struct(def_id) => {
1668 debug!("(building reduced graph for external \
1669 crate) building type %s",
1671 child_name_bindings.define_type(Public, def, dummy_sp());
1672 self.structs.insert(def_id, ());
1674 def_self(*) | def_arg(*) | def_local(*) |
1675 def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
1676 def_use(*) | def_upvar(*) | def_region(*) |
1677 def_typaram_binder(*) | def_label(*) | def_self_ty(*) => {
1678 fail!(fmt!("didn't expect `%?`", def));
1684 * Builds the reduced graph rooted at the 'use' directive for an external
1687 fn build_reduced_graph_for_external_crate(@mut self, root: @mut Module) {
1688 let modules = HashMap();
1690 // Create all the items reachable by paths.
1691 for each_path(self.session.cstore, root.def_id.get().crate)
1692 |path_string, def_like| {
1694 debug!("(building reduced graph for external crate) found path \
1696 path_string, def_like);
1698 let mut pieces = split_str(path_string, ~"::");
1699 let final_ident_str = pieces.pop();
1700 let final_ident = self.session.ident_of(final_ident_str);
1702 // Find the module we need, creating modules along the way if we
1705 let mut current_module = root;
1706 for pieces.each |ident_str| {
1707 let ident = self.session.ident_of(/*bad*/copy *ident_str);
1708 // Create or reuse a graph node for the child.
1709 let (child_name_bindings, new_parent) =
1710 self.add_child(ident,
1711 ModuleReducedGraphParent(current_module),
1712 OverwriteDuplicates,
1715 // Define or reuse the module node.
1716 match child_name_bindings.type_def {
1718 debug!("(building reduced graph for external crate) \
1719 autovivifying missing type def %s",
1721 let parent_link = self.get_parent_link(new_parent,
1723 child_name_bindings.define_module(Public,
1729 Some(copy type_ns_def)
1730 if type_ns_def.module_def.is_none() => {
1731 debug!("(building reduced graph for external crate) \
1732 autovivifying missing module def %s",
1734 let parent_link = self.get_parent_link(new_parent,
1736 child_name_bindings.define_module(Public,
1742 _ => {} // Fall through.
1745 current_module = child_name_bindings.get_module();
1750 // Add the new child item.
1751 let (child_name_bindings, new_parent) =
1752 self.add_child(final_ident,
1753 ModuleReducedGraphParent(
1755 OverwriteDuplicates,
1758 self.handle_external_def(def,
1760 child_name_bindings,
1761 *self.session.str_of(
1767 // We only process static methods of impls here.
1768 match get_type_name_if_impl(self.session.cstore, def) {
1770 Some(final_ident) => {
1771 let static_methods_opt =
1772 get_static_methods_if_impl(
1773 self.session.cstore, def);
1774 match static_methods_opt {
1775 Some(ref static_methods) if
1776 static_methods.len() >= 1 => {
1777 debug!("(building reduced graph for \
1778 external crate) processing \
1779 static methods for type name %s",
1780 *self.session.str_of(
1783 let (child_name_bindings, new_parent) =
1784 self.add_child(final_ident,
1785 ModuleReducedGraphParent(
1787 OverwriteDuplicates,
1790 // Process the static methods. First,
1791 // create the module.
1793 match child_name_bindings.type_def {
1795 module_def: Some(copy module_def),
1798 // We already have a module. This
1800 type_module = module_def;
1804 self.get_parent_link(
1805 new_parent, final_ident);
1806 child_name_bindings.define_module(
1813 child_name_bindings.
1818 // Add each static method to the module.
1819 let new_parent = ModuleReducedGraphParent(
1821 for static_methods.each
1822 |static_method_info| {
1823 let ident = static_method_info.ident;
1824 debug!("(building reduced graph for \
1825 external crate) creating \
1826 static method '%s'",
1827 *self.session.str_of(ident));
1829 let (method_name_bindings, _) =
1833 OverwriteDuplicates,
1836 static_method_info.def_id,
1837 static_method_info.purity);
1838 method_name_bindings.define_value(
1839 Public, def, dummy_sp());
1843 // Otherwise, do nothing.
1844 Some(_) | None => {}
1850 debug!("(building reduced graph for external crate) \
1857 /// Creates and adds an import directive to the given module.
1858 fn build_import_directive(@mut self,
1860 module_: @mut Module,
1861 +module_path: ~[ident],
1862 subclass: @ImportDirectiveSubclass,
1864 state: @mut ImportState) {
1865 let directive = @ImportDirective(privacy, module_path,
1867 module_.imports.push(directive);
1869 // Bump the reference count on the name. Or, if this is a glob, set
1870 // the appropriate flag.
1873 SingleImport(target, _, _) => {
1874 debug!("(building import directive) building import \
1875 directive: privacy %? %s::%s",
1877 self.idents_to_str(directive.module_path),
1878 *self.session.str_of(target));
1880 match module_.import_resolutions.find(&target) {
1881 Some(resolution) => {
1882 debug!("(building import directive) bumping \
1884 resolution.outstanding_references += 1;
1887 debug!("(building import directive) creating new");
1888 let resolution = @mut ImportResolution(privacy,
1891 let name = self.idents_to_str(directive.module_path);
1892 // Don't warn about unused intrinsics because they're
1893 // automatically appended to all files
1894 if name == ~"intrinsic::rusti" {
1895 resolution.state.warned = true;
1897 resolution.outstanding_references = 1;
1898 module_.import_resolutions.insert(target, resolution);
1903 // Set the glob flag. This tells us that we don't know the
1904 // module's exports ahead of time.
1906 module_.glob_count += 1;
1910 self.unresolved_imports += 1;
1913 // Import resolution
1915 // This is a fixed-point algorithm. We resolve imports until our efforts
1916 // are stymied by an unresolved import; then we bail out of the current
1917 // module and continue. We terminate successfully once no more imports
1918 // remain or unsuccessfully when no forward progress in resolving imports
1922 * Resolves all imports for the crate. This method performs the fixed-
1925 fn resolve_imports(@mut self) {
1927 let mut prev_unresolved_imports = 0;
1929 debug!("(resolving imports) iteration %u, %u imports left",
1930 i, self.unresolved_imports);
1932 let module_root = self.graph_root.get_module();
1933 self.resolve_imports_for_module_subtree(module_root);
1935 if self.unresolved_imports == 0 {
1936 debug!("(resolving imports) success");
1940 if self.unresolved_imports == prev_unresolved_imports {
1941 self.session.err(~"failed to resolve imports");
1942 self.report_unresolved_imports(module_root);
1947 prev_unresolved_imports = self.unresolved_imports;
1951 /// Attempts to resolve imports for the given module and all of its
1953 fn resolve_imports_for_module_subtree(@mut self, module_: @mut Module) {
1954 debug!("(resolving imports for module subtree) resolving %s",
1955 self.module_to_str(module_));
1956 self.resolve_imports_for_module(module_);
1958 for module_.children.each_value |&child_node| {
1959 match child_node.get_module_if_available() {
1963 Some(child_module) => {
1964 self.resolve_imports_for_module_subtree(child_module);
1969 for module_.anonymous_children.each_value |&child_module| {
1970 self.resolve_imports_for_module_subtree(child_module);
1974 /// Attempts to resolve imports for the given module only.
1975 fn resolve_imports_for_module(@mut self, module: @mut Module) {
1976 if module.all_imports_resolved() {
1977 debug!("(resolving imports for module) all imports resolved for \
1979 self.module_to_str(module));
1983 let imports = &mut *module.imports;
1984 let import_count = imports.len();
1985 while module.resolved_import_count < import_count {
1986 let import_index = module.resolved_import_count;
1987 let import_directive = imports[import_index];
1988 match self.resolve_import_for_module(module, import_directive) {
1990 // We presumably emitted an error. Continue.
1991 let msg = fmt!("failed to resolve import: %s",
1992 *self.import_path_to_str(
1993 import_directive.module_path,
1994 *import_directive.subclass));
1995 self.session.span_err(import_directive.span, msg);
1998 // Bail out. We'll come around next time.
2006 module.resolved_import_count += 1;
2010 fn idents_to_str(@mut self, idents: &[ident]) -> ~str {
2011 let mut first = true;
2012 let mut result = ~"";
2013 for idents.each |ident| {
2014 if first { first = false; } else { result += "::" };
2015 result += *self.session.str_of(*ident);
2020 fn import_directive_subclass_to_str(@mut self,
2021 subclass: ImportDirectiveSubclass)
2024 SingleImport(_target, source, _ns) => self.session.str_of(source),
2029 fn import_path_to_str(@mut self,
2031 subclass: ImportDirectiveSubclass)
2033 if idents.is_empty() {
2034 self.import_directive_subclass_to_str(subclass)
2037 self.idents_to_str(idents),
2038 *self.import_directive_subclass_to_str(subclass))
2042 /// Attempts to resolve the given import. The return value indicates
2043 /// failure if we're certain the name does not exist, indeterminate if we
2044 /// don't know whether the name exists at the moment due to other
2045 /// currently-unresolved imports, or success if we know the name exists.
2046 /// If successful, the resolved bindings are written into the module.
2047 fn resolve_import_for_module(@mut self, module_: @mut Module,
2048 import_directive: @ImportDirective)
2049 -> ResolveResult<()> {
2050 let mut resolution_result = Failed;
2051 let module_path = &import_directive.module_path;
2053 debug!("(resolving import for module) resolving import `%s::...` in \
2055 self.idents_to_str(*module_path),
2056 self.module_to_str(module_));
2058 // First, resolve the module path for the directive, if necessary.
2059 let containing_module = if module_path.len() == 0 {
2060 // Use the crate root.
2061 Some(self.graph_root.get_module())
2063 match self.resolve_module_path_for_import(module_,
2065 DontUseLexicalScope,
2066 import_directive.span) {
2070 resolution_result = Indeterminate;
2073 Success(containing_module) => Some(containing_module),
2077 match containing_module {
2079 Some(containing_module) => {
2080 // We found the module that the target is contained
2081 // within. Attempt to resolve the import within it.
2083 match *import_directive.subclass {
2084 SingleImport(target, source, AnyNS) => {
2086 self.resolve_single_import(module_,
2091 SingleImport(target, source, TypeNSOnly) => {
2093 self.resolve_single_module_import(
2100 let span = import_directive.span;
2101 let privacy = import_directive.privacy;
2103 self.resolve_glob_import(privacy,
2112 // Decrement the count of unresolved imports.
2113 match resolution_result {
2115 fail_unless!(self.unresolved_imports >= 1);
2116 self.unresolved_imports -= 1;
2119 // Nothing to do here; just return the error.
2123 // Decrement the count of unresolved globs if necessary. But only if
2124 // the resolution result is indeterminate -- otherwise we'll stop
2125 // processing imports here. (See the loop in
2126 // resolve_imports_for_module.)
2128 if !resolution_result.indeterminate() {
2129 match *import_directive.subclass {
2131 fail_unless!(module_.glob_count >= 1);
2132 module_.glob_count -= 1;
2134 SingleImport(*) => {
2140 return resolution_result;
2143 fn resolve_single_import(@mut self,
2144 module_: @mut Module,
2145 containing_module: @mut Module,
2148 -> ResolveResult<()> {
2149 debug!("(resolving single import) resolving `%s` = `%s::%s` from \
2151 *self.session.str_of(target),
2152 self.module_to_str(containing_module),
2153 *self.session.str_of(source),
2154 self.module_to_str(module_));
2156 // We need to resolve both namespaces for this to succeed.
2158 // FIXME #4949: See if there's some way of handling namespaces in
2159 // a more generic way. We have two of them; it seems worth
2162 let mut value_result = UnknownResult;
2163 let mut type_result = UnknownResult;
2165 // Search for direct children of the containing module.
2166 match containing_module.children.find(&source) {
2170 Some(child_name_bindings) => {
2171 if (*child_name_bindings).defined_in_namespace(ValueNS) {
2172 value_result = BoundResult(containing_module,
2173 child_name_bindings);
2175 if (*child_name_bindings).defined_in_namespace(TypeNS) {
2176 type_result = BoundResult(containing_module,
2177 child_name_bindings);
2182 // Unless we managed to find a result in both namespaces (unlikely),
2183 // search imports as well.
2184 match (value_result, type_result) {
2185 (BoundResult(*), BoundResult(*)) => {
2189 // If there is an unresolved glob at this point in the
2190 // containing module, bail out. We don't know enough to be
2191 // able to resolve this import.
2193 if containing_module.glob_count > 0 {
2194 debug!("(resolving single import) unresolved glob; \
2196 return Indeterminate;
2199 // Now search the exported imports within the containing
2202 match containing_module.import_resolutions.find(&source) {
2204 // The containing module definitely doesn't have an
2205 // exported import with the name in question. We can
2206 // therefore accurately report that the names are
2209 if value_result.is_unknown() {
2210 value_result = UnboundResult;
2212 if type_result.is_unknown() {
2213 type_result = UnboundResult;
2216 Some(import_resolution)
2217 if import_resolution.outstanding_references
2220 fn get_binding(import_resolution:
2221 @mut ImportResolution,
2222 namespace: Namespace)
2223 -> NamespaceResult {
2225 // Import resolutions must be declared with "pub"
2226 // in order to be exported.
2227 if import_resolution.privacy == Private {
2228 return UnboundResult;
2231 match (*import_resolution).
2232 target_for_namespace(namespace) {
2234 return UnboundResult;
2237 import_resolution.state.used = true;
2238 return BoundResult(target.target_module,
2244 // The name is an import which has been fully
2245 // resolved. We can, therefore, just follow it.
2246 if value_result.is_unknown() {
2247 value_result = get_binding(import_resolution,
2250 if type_result.is_unknown() {
2251 type_result = get_binding(import_resolution,
2256 // The import is unresolved. Bail out.
2257 debug!("(resolving single import) unresolved import; \
2259 return Indeterminate;
2265 // We've successfully resolved the import. Write the results in.
2266 fail_unless!(module_.import_resolutions.contains_key(&target));
2267 let import_resolution = module_.import_resolutions.get(&target);
2269 match value_result {
2270 BoundResult(target_module, name_bindings) => {
2271 import_resolution.value_target =
2272 Some(Target(target_module, name_bindings));
2274 UnboundResult => { /* Continue. */ }
2276 fail!(~"value result should be known at this point");
2280 BoundResult(target_module, name_bindings) => {
2281 import_resolution.type_target =
2282 Some(Target(target_module, name_bindings));
2284 UnboundResult => { /* Continue. */ }
2286 fail!(~"type result should be known at this point");
2290 let i = import_resolution;
2291 match (i.value_target, i.type_target) {
2292 // If this name wasn't found in either namespace, it's definitely
2294 (None, None) => { return Failed; }
2295 // If it's private, it's also unresolved.
2296 (Some(t), None) | (None, Some(t)) => {
2297 let bindings = &mut *t.bindings;
2298 match bindings.type_def {
2299 Some(ref type_def) => {
2300 if type_def.privacy == Private {
2306 match bindings.value_def {
2307 Some(ref value_def) => {
2308 if value_def.privacy == Private {
2315 // It's also an error if there's both a type and a value with this
2316 // name, but both are private
2317 (Some(val), Some(ty)) => {
2318 match (val.bindings.value_def, ty.bindings.value_def) {
2319 (Some(ref value_def), Some(ref type_def)) =>
2320 if value_def.privacy == Private
2321 && type_def.privacy == Private {
2329 fail_unless!(import_resolution.outstanding_references >= 1);
2330 import_resolution.outstanding_references -= 1;
2332 debug!("(resolving single import) successfully resolved import");
2336 fn resolve_single_module_import(@mut self,
2337 module_: @mut Module,
2338 containing_module: @mut Module,
2341 -> ResolveResult<()> {
2342 debug!("(resolving single module import) resolving `%s` = `%s::%s` \
2344 *self.session.str_of(target),
2345 self.module_to_str(containing_module),
2346 *self.session.str_of(source),
2347 self.module_to_str(module_));
2349 // We need to resolve the module namespace for this to succeed.
2350 let mut module_result = UnknownResult;
2352 // Search for direct children of the containing module.
2353 match containing_module.children.find(&source) {
2357 Some(child_name_bindings) => {
2358 if (*child_name_bindings).defined_in_namespace(TypeNS) {
2359 module_result = BoundResult(containing_module,
2360 child_name_bindings);
2365 // Unless we managed to find a result, search imports as well.
2366 match module_result {
2371 // If there is an unresolved glob at this point in the
2372 // containing module, bail out. We don't know enough to be
2373 // able to resolve this import.
2375 if containing_module.glob_count > 0 {
2376 debug!("(resolving single module import) unresolved \
2377 glob; bailing out");
2378 return Indeterminate;
2381 // Now search the exported imports within the containing
2383 match containing_module.import_resolutions.find(&source) {
2385 // The containing module definitely doesn't have an
2386 // exported import with the name in question. We can
2387 // therefore accurately report that the names are
2390 if module_result.is_unknown() {
2391 module_result = UnboundResult;
2394 Some(import_resolution)
2395 if import_resolution.outstanding_references
2397 // The name is an import which has been fully
2398 // resolved. We can, therefore, just follow it.
2400 if module_result.is_unknown() {
2401 match (*import_resolution).target_for_namespace(
2404 module_result = UnboundResult;
2407 import_resolution.state.used = true;
2408 module_result = BoundResult
2409 (target.target_module,
2416 // The import is unresolved. Bail out.
2417 debug!("(resolving single module import) unresolved \
2418 import; bailing out");
2419 return Indeterminate;
2425 // We've successfully resolved the import. Write the results in.
2426 fail_unless!(module_.import_resolutions.contains_key(&target));
2427 let import_resolution = module_.import_resolutions.get(&target);
2429 match module_result {
2430 BoundResult(target_module, name_bindings) => {
2431 debug!("(resolving single import) found module binding");
2432 import_resolution.type_target =
2433 Some(Target(target_module, name_bindings));
2436 debug!("(resolving single import) didn't find module \
2440 fail!(~"module result should be known at this point");
2444 let i = import_resolution;
2445 if i.type_target.is_none() {
2446 // If this name wasn't found in the type namespace, it's
2447 // definitely unresolved.
2451 fail_unless!(import_resolution.outstanding_references >= 1);
2452 import_resolution.outstanding_references -= 1;
2454 debug!("(resolving single module import) successfully resolved \
2461 * Resolves a glob import. Note that this function cannot fail; it either
2462 * succeeds or bails out (as importing * from an empty module or a module
2463 * that exports nothing is valid).
2465 fn resolve_glob_import(@mut self,
2467 module_: @mut Module,
2468 containing_module: @mut Module,
2470 -> ResolveResult<()> {
2471 // This function works in a highly imperative manner; it eagerly adds
2472 // everything it can to the list of import resolutions of the module
2474 debug!("(resolving glob import) resolving %? glob import", privacy);
2475 let state = @mut ImportState();
2477 // We must bail out if the node has unresolved imports of any kind
2478 // (including globs).
2479 if !(*containing_module).all_imports_resolved() {
2480 debug!("(resolving glob import) target module has unresolved \
2481 imports; bailing out");
2482 return Indeterminate;
2485 fail_unless!(containing_module.glob_count == 0);
2487 // Add all resolved imports from the containing module.
2488 for containing_module.import_resolutions.each
2489 |&ident, &target_import_resolution| {
2491 debug!("(resolving glob import) writing module resolution \
2493 is_none(&mut target_import_resolution.type_target),
2494 self.module_to_str(module_));
2496 // Here we merge two import resolutions.
2497 match module_.import_resolutions.find(&ident) {
2498 None if target_import_resolution.privacy == Public => {
2499 // Simple: just copy the old import resolution.
2500 let new_import_resolution =
2501 @mut ImportResolution(privacy,
2502 target_import_resolution.span,
2504 new_import_resolution.value_target =
2505 copy target_import_resolution.value_target;
2506 new_import_resolution.type_target =
2507 copy target_import_resolution.type_target;
2509 module_.import_resolutions.insert
2510 (ident, new_import_resolution);
2512 None => { /* continue ... */ }
2513 Some(dest_import_resolution) => {
2514 // Merge the two import resolutions at a finer-grained
2517 match target_import_resolution.value_target {
2521 Some(copy value_target) => {
2522 dest_import_resolution.value_target =
2526 match target_import_resolution.type_target {
2530 Some(copy type_target) => {
2531 dest_import_resolution.type_target =
2539 // Add all children from the containing module.
2540 for containing_module.children.each |&ident, &name_bindings| {
2541 let mut dest_import_resolution;
2542 match module_.import_resolutions.find(&ident) {
2544 // Create a new import resolution from this child.
2545 dest_import_resolution = @mut ImportResolution(privacy,
2548 module_.import_resolutions.insert
2549 (ident, dest_import_resolution);
2551 Some(existing_import_resolution) => {
2552 dest_import_resolution = existing_import_resolution;
2556 debug!("(resolving glob import) writing resolution `%s` in `%s` \
2557 to `%s`, privacy=%?",
2558 *self.session.str_of(ident),
2559 self.module_to_str(containing_module),
2560 self.module_to_str(module_),
2561 copy dest_import_resolution.privacy);
2563 // Merge the child item into the import resolution.
2564 if (*name_bindings).defined_in_public_namespace(ValueNS) {
2565 debug!("(resolving glob import) ... for value target");
2566 dest_import_resolution.value_target =
2567 Some(Target(containing_module, name_bindings));
2569 if (*name_bindings).defined_in_public_namespace(TypeNS) {
2570 debug!("(resolving glob import) ... for type target");
2571 dest_import_resolution.type_target =
2572 Some(Target(containing_module, name_bindings));
2576 debug!("(resolving glob import) successfully resolved import");
2580 /// Resolves the given module path from the given root `module_`.
2581 fn resolve_module_path_from_root(@mut self,
2582 module_: @mut Module,
2583 module_path: &[ident],
2586 mut name_search_type: NameSearchType)
2587 -> ResolveResult<@mut Module> {
2588 let mut search_module = module_;
2589 let mut index = index;
2590 let module_path_len = module_path.len();
2592 // Resolve the module part of the path. This does not involve looking
2593 // upward though scope chains; we simply resolve names directly in
2594 // modules as we go.
2596 while index < module_path_len {
2597 let name = module_path[index];
2598 match self.resolve_name_in_module(search_module,
2603 self.session.span_err(span, ~"unresolved name");
2607 debug!("(resolving module path for import) module \
2608 resolution is indeterminate: %s",
2609 *self.session.str_of(name));
2610 return Indeterminate;
2612 Success(target) => {
2613 // Check to see whether there are type bindings, and, if
2614 // so, whether there is a module within.
2615 match target.bindings.type_def {
2616 Some(copy type_def) => {
2617 match type_def.module_def {
2620 self.session.span_err(span,
2628 Some(copy module_def) => {
2629 search_module = module_def;
2634 // There are no type bindings at all.
2635 self.session.span_err(span,
2636 fmt!("not a module: %s",
2637 *self.session.str_of(
2647 // After the first element of the path, allow searching through
2648 // items and imports unconditionally. This allows things like:
2654 // pub mod something_else {
2658 name_search_type = SearchItemsAndPublicImports;
2661 return Success(search_module);
2664 /// Attempts to resolve the module part of an import directive or path
2665 /// rooted at the given module.
2666 fn resolve_module_path_for_import(@mut self,
2667 module_: @mut Module,
2668 module_path: &[ident],
2669 use_lexical_scope: UseLexicalScopeFlag,
2671 -> ResolveResult<@mut Module> {
2672 let module_path_len = module_path.len();
2673 fail_unless!(module_path_len > 0);
2675 debug!("(resolving module path for import) processing `%s` rooted at \
2677 self.idents_to_str(module_path),
2678 self.module_to_str(module_));
2680 // Resolve the module prefix, if any.
2681 let module_prefix_result = self.resolve_module_prefix(module_,
2684 let mut search_module;
2685 let mut start_index;
2686 match module_prefix_result {
2688 self.session.span_err(span, ~"unresolved name");
2692 debug!("(resolving module path for import) indeterminate; \
2694 return Indeterminate;
2696 Success(NoPrefixFound) => {
2697 // There was no prefix, so we're considering the first element
2698 // of the path. How we handle this depends on whether we were
2699 // instructed to use lexical scope or not.
2700 match use_lexical_scope {
2701 DontUseLexicalScope => {
2702 // This is a crate-relative path. We will start the
2703 // resolution process at index zero.
2704 search_module = self.graph_root.get_module();
2707 UseLexicalScope => {
2708 // This is not a crate-relative path. We resolve the
2709 // first component of the path in the current lexical
2710 // scope and then proceed to resolve below that.
2711 let result = self.resolve_module_in_lexical_scope(
2716 self.session.span_err(span,
2717 ~"unresolved name");
2721 debug!("(resolving module path for import) \
2722 indeterminate; bailing");
2723 return Indeterminate;
2725 Success(containing_module) => {
2726 search_module = containing_module;
2733 Success(PrefixFound(containing_module, index)) => {
2734 search_module = containing_module;
2735 start_index = index;
2739 self.resolve_module_path_from_root(search_module,
2743 SearchItemsAndPublicImports)
2746 /// Invariant: This must only be called during main resolution, not during
2747 /// import resolution.
2748 fn resolve_item_in_lexical_scope(@mut self,
2749 module_: @mut Module,
2751 namespace: Namespace,
2752 search_through_modules:
2753 SearchThroughModulesFlag)
2754 -> ResolveResult<Target> {
2755 debug!("(resolving item in lexical scope) resolving `%s` in \
2756 namespace %? in `%s`",
2757 *self.session.str_of(name),
2759 self.module_to_str(module_));
2761 // The current module node is handled specially. First, check for
2762 // its immediate children.
2764 match module_.children.find(&name) {
2766 if (*name_bindings).defined_in_namespace(namespace) => {
2767 return Success(Target(module_, name_bindings));
2769 Some(_) | None => { /* Not found; continue. */ }
2772 // Now check for its import directives. We don't have to have resolved
2773 // all its imports in the usual way; this is because chains of
2774 // adjacent import statements are processed as though they mutated the
2777 match module_.import_resolutions.find(&name) {
2779 // Not found; continue.
2781 Some(import_resolution) => {
2782 match (*import_resolution).target_for_namespace(namespace) {
2784 // Not found; continue.
2785 debug!("(resolving item in lexical scope) found \
2786 import resolution, but not in namespace %?",
2790 debug!("(resolving item in lexical scope) using \
2791 import resolution");
2792 import_resolution.state.used = true;
2793 return Success(copy target);
2799 // Finally, proceed up the scope chain looking for parent modules.
2800 let mut search_module = module_;
2802 // Go to the next parent.
2803 match search_module.parent_link {
2805 // No more parents. This module was unresolved.
2806 debug!("(resolving item in lexical scope) unresolved \
2810 ModuleParentLink(parent_module_node, _) => {
2811 match search_through_modules {
2812 DontSearchThroughModules => {
2813 match search_module.kind {
2814 NormalModuleKind => {
2815 // We stop the search here.
2816 debug!("(resolving item in lexical \
2817 scope) unresolved module: not \
2818 searching through module \
2824 AnonymousModuleKind => {
2825 search_module = parent_module_node;
2829 SearchThroughModules => {
2830 search_module = parent_module_node;
2834 BlockParentLink(parent_module_node, _) => {
2835 search_module = parent_module_node;
2839 // Resolve the name in the parent module.
2840 match self.resolve_name_in_module(search_module,
2843 SearchItemsAndAllImports) {
2845 // Continue up the search chain.
2848 // We couldn't see through the higher scope because of an
2849 // unresolved import higher up. Bail.
2851 debug!("(resolving item in lexical scope) indeterminate \
2852 higher scope; bailing");
2853 return Indeterminate;
2855 Success(target) => {
2856 // We found the module.
2857 return Success(copy target);
2863 /** Resolves a module name in the current lexical scope. */
2864 fn resolve_module_in_lexical_scope(@mut self,
2865 module_: @mut Module,
2867 -> ResolveResult<@mut Module> {
2868 // If this module is an anonymous module, resolve the item in the
2869 // lexical scope. Otherwise, resolve the item from the crate root.
2870 let resolve_result = self.resolve_item_in_lexical_scope(
2871 module_, name, TypeNS, DontSearchThroughModules);
2872 match resolve_result {
2873 Success(target) => {
2874 let bindings = &mut *target.bindings;
2875 match bindings.type_def {
2876 Some(ref type_def) => {
2877 match (*type_def).module_def {
2879 error!("!!! (resolving module in lexical \
2880 scope) module wasn't actually a \
2884 Some(module_def) => {
2885 return Success(module_def);
2890 error!("!!! (resolving module in lexical scope) module
2891 wasn't actually a module!");
2897 debug!("(resolving module in lexical scope) indeterminate; \
2899 return Indeterminate;
2902 debug!("(resolving module in lexical scope) failed to \
2910 * Returns the nearest normal module parent of the given module.
2912 fn get_nearest_normal_module_parent(@mut self, module_: @mut Module)
2913 -> Option<@mut Module> {
2914 let mut module_ = module_;
2916 match module_.parent_link {
2917 NoParentLink => return None,
2918 ModuleParentLink(new_module, _) |
2919 BlockParentLink(new_module, _) => {
2920 match new_module.kind {
2921 NormalModuleKind => return Some(new_module),
2924 AnonymousModuleKind => module_ = new_module,
2932 * Returns the nearest normal module parent of the given module, or the
2933 * module itself if it is a normal module.
2935 fn get_nearest_normal_module_parent_or_self(@mut self,
2936 module_: @mut Module)
2938 match module_.kind {
2939 NormalModuleKind => return module_,
2940 ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2941 match self.get_nearest_normal_module_parent(module_) {
2943 Some(new_module) => new_module
2950 * Resolves a "module prefix". A module prefix is one of (a) `self::`;
2951 * (b) some chain of `super::`.
2953 fn resolve_module_prefix(@mut self,
2954 module_: @mut Module,
2955 module_path: &[ident])
2956 -> ResolveResult<ModulePrefixResult> {
2957 let interner = self.session.parse_sess.interner;
2959 // Start at the current module if we see `self` or `super`, or at the
2960 // top of the crate otherwise.
2961 let mut containing_module;
2963 if *interner.get(module_path[0]) == ~"self" {
2965 self.get_nearest_normal_module_parent_or_self(module_);
2967 } else if *interner.get(module_path[0]) == ~"super" {
2969 self.get_nearest_normal_module_parent_or_self(module_);
2970 i = 0; // We'll handle `super` below.
2972 return Success(NoPrefixFound);
2975 // Now loop through all the `super`s we find.
2976 while i < module_path.len() &&
2977 *interner.get(module_path[i]) == ~"super" {
2978 debug!("(resolving module prefix) resolving `super` at %s",
2979 self.module_to_str(containing_module));
2980 match self.get_nearest_normal_module_parent(containing_module) {
2981 None => return Failed,
2982 Some(new_module) => {
2983 containing_module = new_module;
2989 debug!("(resolving module prefix) finished resolving prefix at %s",
2990 self.module_to_str(containing_module));
2992 return Success(PrefixFound(containing_module, i));
2995 /// Attempts to resolve the supplied name in the given module for the
2996 /// given namespace. If successful, returns the target corresponding to
2998 fn resolve_name_in_module(@mut self,
2999 module_: @mut Module,
3001 namespace: Namespace,
3002 +name_search_type: NameSearchType)
3003 -> ResolveResult<Target> {
3004 debug!("(resolving name in module) resolving `%s` in `%s`",
3005 *self.session.str_of(name),
3006 self.module_to_str(module_));
3008 // First, check the direct children of the module.
3009 match module_.children.find(&name) {
3011 if (*name_bindings).defined_in_namespace(namespace) => {
3013 debug!("(resolving name in module) found node as child");
3014 return Success(Target(module_, name_bindings));
3021 // Next, check the module's imports if necessary.
3023 // If this is a search of all imports, we should be done with glob
3024 // resolution at this point.
3025 if name_search_type == SearchItemsAndAllImports {
3026 fail_unless!(module_.glob_count == 0);
3029 // Check the list of resolved imports.
3030 match module_.import_resolutions.find(&name) {
3031 Some(import_resolution) => {
3032 if import_resolution.outstanding_references != 0 {
3033 debug!("(resolving name in module) import \
3034 unresolved; bailing out");
3035 return Indeterminate;
3038 match import_resolution.target_for_namespace(namespace) {
3040 debug!("(resolving name in module) name found, \
3041 but not in namespace %?",
3045 if name_search_type ==
3046 SearchItemsAndAllImports ||
3047 import_resolution.privacy == Public => {
3048 debug!("(resolving name in module) resolved to \
3050 import_resolution.state.used = true;
3051 return Success(copy target);
3054 debug!("(resolving name in module) name found, \
3064 // We're out of luck.
3065 debug!("(resolving name in module) failed to resolve %s",
3066 *self.session.str_of(name));
3070 fn report_unresolved_imports(@mut self, module_: @mut Module) {
3071 let index = module_.resolved_import_count;
3072 let imports: &mut ~[@ImportDirective] = &mut *module_.imports;
3073 let import_count = imports.len();
3074 if index != import_count {
3075 self.session.span_err(imports[index].span, ~"unresolved import");
3078 // Descend into children and anonymous children.
3079 for module_.children.each_value |&child_node| {
3080 match child_node.get_module_if_available() {
3084 Some(child_module) => {
3085 self.report_unresolved_imports(child_module);
3090 for module_.anonymous_children.each_value |&module_| {
3091 self.report_unresolved_imports(module_);
3097 // This pass simply determines what all "export" keywords refer to and
3098 // writes the results into the export map.
3100 // FIXME #4953 This pass will be removed once exports change to per-item.
3101 // Then this operation can simply be performed as part of item (or import)
3104 fn record_exports(@mut self) {
3105 let root_module = self.graph_root.get_module();
3106 self.record_exports_for_module_subtree(root_module);
3109 fn record_exports_for_module_subtree(@mut self, module_: @mut Module) {
3110 // If this isn't a local crate, then bail out. We don't need to record
3111 // exports for nonlocal crates.
3113 match module_.def_id {
3114 Some(def_id) if def_id.crate == local_crate => {
3116 debug!("(recording exports for module subtree) recording \
3117 exports for local module");
3120 // Record exports for the root module.
3121 debug!("(recording exports for module subtree) recording \
3122 exports for root module");
3126 debug!("(recording exports for module subtree) not recording \
3128 self.module_to_str(module_));
3133 self.record_exports_for_module(module_);
3135 for module_.children.each_value |&child_name_bindings| {
3136 match child_name_bindings.get_module_if_available() {
3140 Some(child_module) => {
3141 self.record_exports_for_module_subtree(child_module);
3146 for module_.anonymous_children.each_value |&child_module| {
3147 self.record_exports_for_module_subtree(child_module);
3151 fn record_exports_for_module(@mut self, module_: @mut Module) {
3152 let mut exports2 = ~[];
3154 self.add_exports_for_module(&mut exports2, module_);
3155 match /*bad*/copy module_.def_id {
3157 self.export_map2.insert(def_id.node, exports2);
3158 debug!("(computing exports) writing exports for %d (some)",
3165 fn add_exports_of_namebindings(@mut self,
3166 exports2: &mut ~[Export2],
3168 namebindings: @mut NameBindings,
3171 match (namebindings.def_for_namespace(ns),
3172 namebindings.privacy_for_namespace(ns)) {
3173 (Some(d), Some(Public)) => {
3174 debug!("(computing exports) YES: %s '%s' => %?",
3175 if reexport { ~"reexport" } else { ~"export"},
3176 *self.session.str_of(ident),
3178 exports2.push(Export2 {
3180 name: self.session.str_of(ident),
3181 def_id: def_id_of_def(d)
3184 (Some(_), Some(privacy)) => {
3185 debug!("(computing reexports) NO: privacy %?", privacy);
3188 debug!("(computing reexports) NO: %?, %?", d_opt, p_opt);
3193 fn add_exports_for_module(@mut self,
3194 exports2: &mut ~[Export2],
3195 module_: @mut Module) {
3196 for module_.children.each |ident, namebindings| {
3197 debug!("(computing exports) maybe export '%s'",
3198 *self.session.str_of(*ident));
3199 self.add_exports_of_namebindings(&mut *exports2,
3204 self.add_exports_of_namebindings(&mut *exports2,
3211 for module_.import_resolutions.each |ident, importresolution| {
3212 if importresolution.privacy != Public {
3213 debug!("(computing exports) not reexporting private `%s`",
3214 *self.session.str_of(*ident));
3217 for [ TypeNS, ValueNS ].each |ns| {
3218 match importresolution.target_for_namespace(*ns) {
3220 debug!("(computing exports) maybe reexport '%s'",
3221 *self.session.str_of(*ident));
3222 self.add_exports_of_namebindings(&mut *exports2,
3236 // We maintain a list of value ribs and type ribs.
3238 // Simultaneously, we keep track of the current position in the module
3239 // graph in the `current_module` pointer. When we go to resolve a name in
3240 // the value or type namespaces, we first look through all the ribs and
3241 // then query the module graph. When we resolve a name in the module
3242 // namespace, we can skip all the ribs (since nested modules are not
3243 // allowed within blocks in Rust) and jump straight to the current module
3246 // Named implementations are handled separately. When we find a method
3247 // call, we consult the module node to find all of the implementations in
3248 // scope. This information is lazily cached in the module node. We then
3249 // generate a fake "implementation scope" containing all the
3250 // implementations thus found, for compatibility with old resolve pass.
3252 fn with_scope(@mut self, name: Option<ident>, f: &fn()) {
3253 let orig_module = self.current_module;
3255 // Move down in the graph.
3261 match orig_module.children.find(&name) {
3263 debug!("!!! (with scope) didn't find `%s` in `%s`",
3264 *self.session.str_of(name),
3265 self.module_to_str(orig_module));
3267 Some(name_bindings) => {
3268 match (*name_bindings).get_module_if_available() {
3270 debug!("!!! (with scope) didn't find module \
3272 *self.session.str_of(name),
3273 self.module_to_str(orig_module));
3276 self.current_module = module_;
3286 self.current_module = orig_module;
3289 // Wraps the given definition in the appropriate number of `def_upvar`
3292 fn upvarify(@mut self,
3297 allow_capturing_self: AllowCapturingSelfFlag)
3298 -> Option<def_like> {
3300 let mut is_ty_param;
3303 dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
3304 dl_def(d @ def_arg(*)) | dl_def(d @ def_binding(*)) => {
3306 is_ty_param = false;
3308 dl_def(d @ def_ty_param(*)) => {
3312 dl_def(d @ def_self(*))
3313 if allow_capturing_self == DontAllowCapturingSelf => {
3315 is_ty_param = false;
3318 return Some(def_like);
3322 let mut rib_index = rib_index + 1;
3323 while rib_index < ribs.len() {
3324 match ribs[rib_index].kind {
3326 // Nothing to do. Continue.
3328 FunctionRibKind(function_id, body_id) => {
3330 def = def_upvar(def_id_of_def(def).node,
3336 MethodRibKind(item_id, _) => {
3337 // If the def is a ty param, and came from the parent
3340 def_ty_param(did, _) if self.def_map.find(&did.node)
3341 == Some(def_typaram_binder(item_id)) => {
3346 // This was an attempt to access an upvar inside a
3347 // named function item. This is not allowed, so we
3350 self.session.span_err(
3352 ~"attempted dynamic environment-capture");
3354 // This was an attempt to use a type parameter outside
3357 self.session.span_err(span,
3358 ~"attempt to use a type \
3359 argument out of scope");
3366 OpaqueFunctionRibKind => {
3368 // This was an attempt to access an upvar inside a
3369 // named function item. This is not allowed, so we
3372 self.session.span_err(
3374 ~"attempted dynamic environment-capture");
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");
3386 ConstantItemRibKind => {
3387 // Still doesn't deal with upvars
3388 self.session.span_err(span,
3389 ~"attempt to use a non-constant \
3390 value in a constant");
3398 return Some(dl_def(def));
3401 fn search_ribs(@mut self,
3405 allow_capturing_self: AllowCapturingSelfFlag)
3406 -> Option<def_like> {
3407 // FIXME #4950: This should not use a while loop.
3408 // FIXME #4950: Try caching?
3410 let mut i = ribs.len();
3413 match ribs[i].bindings.find(&name) {
3415 return self.upvarify(ribs, i, def_like, span,
3416 allow_capturing_self);
3427 fn resolve_crate(@mut self) {
3428 debug!("(resolving crate) starting");
3430 visit_crate(*self.crate, (), mk_vt(@Visitor {
3431 visit_item: |item, _context, visitor|
3432 self.resolve_item(item, visitor),
3433 visit_arm: |arm, _context, visitor|
3434 self.resolve_arm(arm, visitor),
3435 visit_block: |block, _context, visitor|
3436 self.resolve_block(block, visitor),
3437 visit_expr: |expr, _context, visitor|
3438 self.resolve_expr(expr, visitor),
3439 visit_local: |local, _context, visitor|
3440 self.resolve_local(local, visitor),
3441 visit_ty: |ty, _context, visitor|
3442 self.resolve_type(ty, visitor),
3443 .. *default_visitor()
3447 fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
3448 debug!("(resolving item) resolving %s",
3449 *self.session.str_of(item.ident));
3451 // Items with the !resolve_unexported attribute are X-ray contexts.
3452 // This is used to allow the test runner to run unexported tests.
3453 let orig_xray_flag = self.xray_context;
3454 if contains_name(attr_metas(item.attrs),
3455 ~"!resolve_unexported") {
3456 self.xray_context = Xray;
3461 // enum item: resolve all the variants' discrs,
3462 // then resolve the ty params
3463 item_enum(ref enum_def, ref generics) => {
3464 for (*enum_def).variants.each() |variant| {
3465 for variant.node.disr_expr.each |dis_expr| {
3466 // resolve the discriminator expr
3468 self.with_constant_rib(|| {
3469 self.resolve_expr(*dis_expr, visitor);
3474 // n.b. the discr expr gets visted twice.
3475 // but maybe it's okay since the first time will signal an
3476 // error if there is one? -- tjc
3477 do self.with_type_parameter_rib(
3479 generics, item.id, 0, NormalRibKind)) {
3480 visit_item(item, (), visitor);
3484 item_ty(_, ref generics) => {
3485 do self.with_type_parameter_rib
3486 (HasTypeParameters(generics, item.id, 0,
3490 visit_item(item, (), visitor);
3494 item_impl(ref generics,
3498 self.resolve_implementation(item.id,
3507 item_trait(ref generics, ref traits, ref methods) => {
3508 // Create a new rib for the self type.
3509 let self_type_rib = @Rib(NormalRibKind);
3510 self.type_ribs.push(self_type_rib);
3511 self_type_rib.bindings.insert(self.type_self_ident,
3512 dl_def(def_self_ty(item.id)));
3514 // Create a new rib for the trait-wide type parameters.
3515 do self.with_type_parameter_rib
3516 (HasTypeParameters(generics, item.id, 0,
3519 self.resolve_type_parameters(&generics.ty_params,
3522 // Resolve derived traits.
3523 for traits.each |trt| {
3524 match self.resolve_path(trt.path, TypeNS, true,
3527 self.session.span_err(trt.path.span,
3528 ~"attempt to derive a \
3529 nonexistent trait"),
3531 // Write a mapping from the trait ID to the
3532 // definition of the trait into the definition
3535 debug!("(resolving trait) found trait def: \
3538 self.record_def(trt.ref_id, def);
3543 for (*methods).each |method| {
3544 // Create a new rib for the method-specific type
3547 // FIXME #4951: Do we need a node ID here?
3550 required(ref ty_m) => {
3551 do self.with_type_parameter_rib
3552 (HasTypeParameters(&ty_m.generics,
3554 generics.ty_params.len(),
3555 MethodRibKind(item.id, Required))) {
3557 // Resolve the method-specific type
3559 self.resolve_type_parameters(
3560 &ty_m.generics.ty_params,
3563 for ty_m.decl.inputs.each |argument| {
3564 self.resolve_type(argument.ty, visitor);
3567 self.resolve_type(ty_m.decl.output, visitor);
3571 self.resolve_method(MethodRibKind(item.id,
3574 generics.ty_params.len(),
3581 self.type_ribs.pop();
3584 item_struct(ref struct_def, ref generics) => {
3585 self.resolve_struct(item.id,
3592 item_mod(ref module_) => {
3593 do self.with_scope(Some(item.ident)) {
3594 self.resolve_module(module_, item.span, item.ident,
3599 item_foreign_mod(ref foreign_module) => {
3600 do self.with_scope(Some(item.ident)) {
3601 for foreign_module.items.each |foreign_item| {
3602 match foreign_item.node {
3603 foreign_item_fn(_, _, ref generics) => {
3604 self.with_type_parameter_rib(
3606 generics, foreign_item.id, 0,
3608 || visit_foreign_item(*foreign_item, (),
3611 foreign_item_const(_) => {
3612 visit_foreign_item(*foreign_item, (),
3620 item_fn(ref fn_decl, _, ref generics, ref block) => {
3621 // If this is the main function, we must record it in the
3623 // FIXME #4404 android JNI hacks
3624 if !*self.session.building_library ||
3625 self.session.targ_cfg.os == session::os_android {
3627 if self.attr_main_fn.is_none() &&
3628 item.ident == special_idents::main {
3630 self.main_fns.push(Some((item.id, item.span)));
3633 if attrs_contains_name(item.attrs, ~"main") {
3634 if self.attr_main_fn.is_none() {
3635 self.attr_main_fn = Some((item.id, item.span));
3637 self.session.span_err(
3639 ~"multiple 'main' functions");
3644 self.resolve_function(OpaqueFunctionRibKind,
3650 OpaqueFunctionRibKind),
3657 self.with_constant_rib(|| {
3658 visit_item(item, (), visitor);
3663 fail!(~"item macros unimplemented")
3667 self.xray_context = orig_xray_flag;
3670 fn with_type_parameter_rib(@mut self,
3671 type_parameters: TypeParameters,
3673 match type_parameters {
3674 HasTypeParameters(generics, node_id, initial_index,
3677 let function_type_rib = @Rib(rib_kind);
3678 self.type_ribs.push(function_type_rib);
3680 for generics.ty_params.eachi |index, type_parameter| {
3681 let name = type_parameter.ident;
3682 debug!("with_type_parameter_rib: %d %d", node_id,
3684 let def_like = dl_def(def_ty_param
3685 (local_def(type_parameter.id),
3686 index + initial_index));
3687 // Associate this type parameter with
3688 // the item that bound it
3689 self.record_def(type_parameter.id,
3690 def_typaram_binder(node_id));
3691 function_type_rib.bindings.insert(name, def_like);
3695 NoTypeParameters => {
3702 match type_parameters {
3703 HasTypeParameters(*) => {
3704 self.type_ribs.pop();
3707 NoTypeParameters => {
3713 fn with_label_rib(@mut self, f: &fn()) {
3714 self.label_ribs.push(@Rib(NormalRibKind));
3716 self.label_ribs.pop();
3719 fn with_constant_rib(@mut self, f: &fn()) {
3720 self.value_ribs.push(@Rib(ConstantItemRibKind));
3722 self.value_ribs.pop();
3725 fn resolve_function(@mut self,
3727 optional_declaration: Option<&fn_decl>,
3728 type_parameters: TypeParameters,
3730 self_binding: SelfBinding,
3731 visitor: ResolveVisitor) {
3732 // Create a value rib for the function.
3733 let function_value_rib = @Rib(rib_kind);
3734 self.value_ribs.push(function_value_rib);
3736 // Create a label rib for the function.
3737 let function_label_rib = @Rib(rib_kind);
3738 self.label_ribs.push(function_label_rib);
3740 // If this function has type parameters, add them now.
3741 do self.with_type_parameter_rib(type_parameters) {
3742 // Resolve the type parameters.
3743 match type_parameters {
3744 NoTypeParameters => {
3747 HasTypeParameters(ref generics, _, _, _) => {
3748 self.resolve_type_parameters(&generics.ty_params,
3753 // Add self to the rib, if necessary.
3754 match self_binding {
3758 HasSelfBinding(self_node_id, is_implicit) => {
3759 let def_like = dl_def(def_self(self_node_id,
3761 (*function_value_rib).bindings.insert(self.self_ident,
3766 // Add each argument to the rib.
3767 match optional_declaration {
3771 Some(declaration) => {
3772 for declaration.inputs.each |argument| {
3774 ArgumentIrrefutableMode(argument.mode);
3776 if argument.is_mutbl {Mutable} else {Immutable};
3777 self.resolve_pattern(argument.pat,
3783 self.resolve_type(argument.ty, visitor);
3785 debug!("(resolving function) recorded argument");
3788 self.resolve_type(declaration.output, visitor);
3792 // Resolve the function body.
3793 self.resolve_block(block, visitor);
3795 debug!("(resolving function) leaving function");
3798 self.label_ribs.pop();
3799 self.value_ribs.pop();
3802 fn resolve_type_parameters(@mut self,
3803 type_parameters: &OptVec<TyParam>,
3804 visitor: ResolveVisitor) {
3805 for type_parameters.each |type_parameter| {
3806 for type_parameter.bounds.each |&bound| {
3808 TraitTyParamBound(ty) => self.resolve_type(ty, visitor),
3809 RegionTyParamBound => {}
3815 fn resolve_struct(@mut self,
3817 generics: &Generics,
3818 fields: &[@struct_field],
3819 optional_destructor: Option<struct_dtor>,
3820 visitor: ResolveVisitor) {
3821 // If applicable, create a rib for the type parameters.
3822 do self.with_type_parameter_rib(HasTypeParameters
3824 OpaqueFunctionRibKind)) {
3826 // Resolve the type parameters.
3827 self.resolve_type_parameters(&generics.ty_params, visitor);
3830 for fields.each |field| {
3831 self.resolve_type(field.node.ty, visitor);
3834 // Resolve the destructor, if applicable.
3835 match optional_destructor {
3839 Some(ref destructor) => {
3840 self.resolve_function(NormalRibKind,
3843 &destructor.node.body,
3845 ((*destructor).node.self_id,
3853 // Does this really need to take a RibKind or is it always going
3854 // to be NormalRibKind?
3855 fn resolve_method(@mut self,
3858 outer_type_parameter_count: uint,
3859 visitor: ResolveVisitor) {
3860 let method_generics = &method.generics;
3861 let type_parameters =
3862 HasTypeParameters(method_generics,
3864 outer_type_parameter_count,
3866 // we only have self ty if it is a non static method
3867 let self_binding = match method.self_ty.node {
3868 sty_static => { NoSelfBinding }
3869 sty_by_ref => { HasSelfBinding(method.self_id, true) }
3870 _ => { HasSelfBinding(method.self_id, false) }
3873 self.resolve_function(rib_kind,
3881 fn resolve_implementation(@mut self,
3884 generics: &Generics,
3885 opt_trait_reference: Option<@trait_ref>,
3887 methods: &[@method],
3888 visitor: ResolveVisitor) {
3889 // If applicable, create a rib for the type parameters.
3890 let outer_type_parameter_count = generics.ty_params.len();
3891 do self.with_type_parameter_rib(HasTypeParameters
3894 // Resolve the type parameters.
3895 self.resolve_type_parameters(&generics.ty_params,
3898 // Resolve the trait reference, if necessary.
3899 let original_trait_refs;
3900 match opt_trait_reference {
3901 Some(trait_reference) => {
3902 let mut new_trait_refs = ~[];
3903 match self.resolve_path(
3904 trait_reference.path, TypeNS, true, visitor) {
3906 self.session.span_err(span,
3907 ~"attempt to implement an \
3911 self.record_def(trait_reference.ref_id, def);
3913 // Record the current trait reference.
3914 new_trait_refs.push(def_id_of_def(def));
3917 // Record the current set of trait references.
3918 let mut old = Some(new_trait_refs);
3919 self.current_trait_refs <-> old;
3920 original_trait_refs = Some(old);
3923 original_trait_refs = None;
3927 // Resolve the self type.
3928 self.resolve_type(self_type, visitor);
3930 for methods.each |method| {
3931 // We also need a new scope for the method-specific
3933 self.resolve_method(MethodRibKind(
3935 Provided(method.id)),
3937 outer_type_parameter_count,
3940 let borrowed_type_parameters = &method.tps;
3941 self.resolve_function(MethodRibKind(
3943 Provided(method.id)),
3946 (borrowed_type_parameters,
3948 outer_type_parameter_count,
3951 HasSelfBinding(method.self_id),
3956 // Restore the original trait references.
3957 match original_trait_refs {
3958 Some(r) => { self.current_trait_refs = r; }
3964 fn resolve_module(@mut self,
3969 visitor: ResolveVisitor) {
3970 // Write the implementations in scope into the module metadata.
3971 debug!("(resolving module) resolving module ID %d", id);
3972 visit_mod(module_, span, id, (), visitor);
3975 fn resolve_local(@mut self, local: @local, visitor: ResolveVisitor) {
3976 let mutability = if local.node.is_mutbl {Mutable} else {Immutable};
3978 // Resolve the type.
3979 self.resolve_type(local.node.ty, visitor);
3981 // Resolve the initializer, if necessary.
3982 match local.node.init {
3986 Some(initializer) => {
3987 self.resolve_expr(initializer, visitor);
3991 // Resolve the pattern.
3992 self.resolve_pattern(local.node.pat, LocalIrrefutableMode, mutability,
3996 fn binding_mode_map(@mut self, pat: @pat) -> BindingMap {
3997 let result = HashMap();
3998 do pat_bindings(*self.def_map, pat) |binding_mode, _id, sp, path| {
3999 let ident = path_to_ident(path);
4000 result.insert(ident,
4001 binding_info {span: sp,
4002 binding_mode: binding_mode});
4007 fn check_consistent_bindings(@mut self, arm: &arm) {
4008 if arm.pats.len() == 0 { return; }
4009 let map_0 = self.binding_mode_map(arm.pats[0]);
4010 for arm.pats.eachi() |i, p| {
4011 let map_i = self.binding_mode_map(*p);
4013 for map_0.each |&key, &binding_0| {
4014 match map_i.find(&key) {
4016 self.session.span_err(
4018 fmt!("variable `%s` from pattern #1 is \
4019 not bound in pattern #%u",
4020 *self.session.str_of(key), i + 1));
4022 Some(binding_i) => {
4023 if binding_0.binding_mode != binding_i.binding_mode {
4024 self.session.span_err(
4026 fmt!("variable `%s` is bound with different \
4027 mode in pattern #%u than in pattern #1",
4028 *self.session.str_of(key), i + 1));
4034 for map_i.each |&key, &binding| {
4035 if !map_0.contains_key(&key) {
4036 self.session.span_err(
4038 fmt!("variable `%s` from pattern #%u is \
4039 not bound in pattern #1",
4040 *self.session.str_of(key), i + 1));
4046 fn resolve_arm(@mut self, arm: &arm, visitor: ResolveVisitor) {
4047 self.value_ribs.push(@Rib(NormalRibKind));
4049 let bindings_list = HashMap();
4050 for arm.pats.each |pattern| {
4051 self.resolve_pattern(*pattern, RefutableMode, Immutable,
4052 Some(bindings_list), visitor);
4055 // This has to happen *after* we determine which
4056 // pat_idents are variants
4057 self.check_consistent_bindings(arm);
4059 visit_expr_opt(arm.guard, (), visitor);
4060 self.resolve_block(&arm.body, visitor);
4062 self.value_ribs.pop();
4065 fn resolve_block(@mut self, block: &blk, visitor: ResolveVisitor) {
4066 debug!("(resolving block) entering block");
4067 self.value_ribs.push(@Rib(NormalRibKind));
4069 // Move down in the graph, if there's an anonymous module rooted here.
4070 let orig_module = self.current_module;
4071 match self.current_module.anonymous_children.find(&block.node.id) {
4072 None => { /* Nothing to do. */ }
4073 Some(anonymous_module) => {
4074 debug!("(resolving block) found anonymous module, moving \
4076 self.current_module = anonymous_module;
4080 // Descend into the block.
4081 visit_block(block, (), visitor);
4084 self.current_module = orig_module;
4086 self.value_ribs.pop();
4087 debug!("(resolving block) leaving block");
4090 fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) {
4092 // Like path expressions, the interpretation of path types depends
4093 // on whether the path has multiple elements in it or not.
4095 ty_path(path, path_id) => {
4096 // This is a path in the type namespace. Walk through scopes
4097 // scopes looking for it.
4098 let mut result_def = None;
4100 // First, check to see whether the name is a primitive type.
4101 if path.idents.len() == 1 {
4102 let name = *path.idents.last();
4104 match self.primitive_type_table
4108 Some(primitive_type) => {
4110 Some(def_prim_ty(primitive_type));
4120 match self.resolve_path(path, TypeNS, true, visitor) {
4122 debug!("(resolving type) resolved `%s` to \
4124 *self.session.str_of(
4125 *path.idents.last()),
4127 result_def = Some(def);
4141 // Write the result into the def map.
4142 debug!("(resolving type) writing resolution for `%s` \
4144 self.idents_to_str(path.idents),
4146 self.record_def(path_id, def);
4149 self.session.span_err
4150 (ty.span, fmt!("use of undeclared type name `%s`",
4151 self.idents_to_str(path.idents)));
4157 // Just resolve embedded types.
4158 visit_ty(ty, (), visitor);
4163 fn resolve_pattern(@mut self,
4165 mode: PatternBindingMode,
4166 mutability: Mutability,
4167 // Maps idents to the node ID for the (outermost)
4168 // pattern that binds them
4169 bindings_list: Option<HashMap<ident,node_id>>,
4170 visitor: ResolveVisitor) {
4171 let pat_id = pattern.id;
4172 do walk_pat(pattern) |pattern| {
4173 match pattern.node {
4174 pat_ident(binding_mode, path, _)
4175 if !path.global && path.idents.len() == 1 => {
4177 // The meaning of pat_ident with no type parameters
4178 // depends on whether an enum variant or unit-like struct
4179 // with that name is in scope. The probing lookup has to
4180 // be careful not to emit spurious errors. Only matching
4181 // patterns (match) can match nullary variants or
4182 // unit-like structs. For binding patterns (let), matching
4183 // such a value is simply disallowed (since it's rarely
4186 let ident = path.idents[0];
4188 match self.resolve_bare_identifier_pattern(ident) {
4189 FoundStructOrEnumVariant(def)
4190 if mode == RefutableMode => {
4191 debug!("(resolving pattern) resolving `%s` to \
4192 struct or enum variant",
4193 *self.session.str_of(ident));
4195 self.enforce_default_binding_mode(
4199 self.record_def(pattern.id, def);
4201 FoundStructOrEnumVariant(_) => {
4202 self.session.span_err(pattern.span,
4203 fmt!("declaration of `%s` \
4205 variant or unit-like \
4210 FoundConst(def) if mode == RefutableMode => {
4211 debug!("(resolving pattern) resolving `%s` to \
4213 *self.session.str_of(ident));
4215 self.enforce_default_binding_mode(
4219 self.record_def(pattern.id, def);
4222 self.session.span_err(pattern.span,
4223 ~"only refutable patterns \
4226 BareIdentifierPatternUnresolved => {
4227 debug!("(resolving pattern) binding `%s`",
4228 *self.session.str_of(ident));
4230 let is_mutable = mutability == Mutable;
4232 let def = match mode {
4234 // For pattern arms, we must use
4235 // `def_binding` definitions.
4237 def_binding(pattern.id, binding_mode)
4239 LocalIrrefutableMode => {
4240 // But for locals, we use `def_local`.
4241 def_local(pattern.id, is_mutable)
4243 ArgumentIrrefutableMode(argument_mode) => {
4244 // And for function arguments, `def_arg`.
4245 def_arg(pattern.id, argument_mode,
4250 // Record the definition so that later passes
4251 // will be able to distinguish variants from
4252 // locals in patterns.
4254 self.record_def(pattern.id, def);
4256 // Add the binding to the local ribs, if it
4257 // doesn't already exist in the bindings list. (We
4258 // must not add it if it's in the bindings list
4259 // because that breaks the assumptions later
4260 // passes make about or-patterns.)
4262 match bindings_list {
4264 if !bindings_list.contains_key(&ident) => {
4265 let this = &mut *self;
4266 let last_rib = this.value_ribs[
4267 this.value_ribs.len() - 1];
4268 last_rib.bindings.insert(ident,
4270 bindings_list.insert(ident, pat_id);
4273 if b.find(&ident) == Some(pat_id) {
4274 // Then this is a duplicate variable
4275 // in the same disjunct, which is an
4277 self.session.span_err(pattern.span,
4278 fmt!("Identifier %s is bound more \
4279 than once in the same pattern",
4280 path_to_str(path, self.session
4283 // Not bound in the same pattern: do nothing
4286 let this = &mut *self;
4287 let last_rib = this.value_ribs[
4288 this.value_ribs.len() - 1];
4289 last_rib.bindings.insert(ident,
4296 // Check the types in the path pattern.
4297 for path.types.each |ty| {
4298 self.resolve_type(*ty, visitor);
4302 pat_ident(binding_mode, path, _) => {
4303 // This must be an enum variant, struct, or constant.
4304 match self.resolve_path(path, ValueNS, false, visitor) {
4305 Some(def @ def_variant(*)) |
4306 Some(def @ def_struct(*)) => {
4307 self.record_def(pattern.id, def);
4309 Some(def @ def_const(*)) => {
4310 self.enforce_default_binding_mode(
4314 self.record_def(pattern.id, def);
4317 self.session.span_err(
4319 fmt!("not an enum variant or constant: %s",
4320 *self.session.str_of(
4321 *path.idents.last())));
4324 self.session.span_err(path.span,
4325 ~"unresolved enum variant");
4329 // Check the types in the path pattern.
4330 for path.types.each |ty| {
4331 self.resolve_type(*ty, visitor);
4335 pat_enum(path, _) => {
4336 // This must be an enum variant, struct or const.
4337 match self.resolve_path(path, ValueNS, false, visitor) {
4338 Some(def @ def_variant(*)) |
4339 Some(def @ def_struct(*)) |
4340 Some(def @ def_const(*)) => {
4341 self.record_def(pattern.id, def);
4344 self.session.span_err(
4346 fmt!("not an enum variant, struct or const: %s",
4347 *self.session.str_of(
4348 *path.idents.last())));
4351 self.session.span_err(path.span,
4352 ~"unresolved enum variant, \
4357 // Check the types in the path pattern.
4358 for path.types.each |ty| {
4359 self.resolve_type(*ty, visitor);
4364 self.resolve_expr(expr, visitor);
4367 pat_range(first_expr, last_expr) => {
4368 self.resolve_expr(first_expr, visitor);
4369 self.resolve_expr(last_expr, visitor);
4372 pat_struct(path, _, _) => {
4373 match self.resolve_path(path, TypeNS, false, visitor) {
4374 Some(def_ty(class_id))
4375 if self.structs.contains_key(&class_id)
4377 let class_def = def_struct(class_id);
4378 self.record_def(pattern.id, class_def);
4380 Some(definition @ def_struct(class_id))
4381 if self.structs.contains_key(&class_id)
4383 self.record_def(pattern.id, definition);
4385 Some(definition @ def_variant(_, variant_id))
4386 if self.structs.contains_key(&variant_id)
4388 self.record_def(pattern.id, definition);
4391 debug!("(resolving pattern) didn't find struct \
4393 self.session.span_err(
4395 fmt!("`%s` does not name a structure",
4396 self.idents_to_str(path.idents)));
4408 fn resolve_bare_identifier_pattern(@mut self, name: ident)
4409 -> BareIdentifierPatternResolution {
4410 match self.resolve_item_in_lexical_scope(self.current_module,
4413 SearchThroughModules) {
4414 Success(target) => {
4415 match target.bindings.value_def {
4417 fail!(~"resolved name in the value namespace to a \
4418 set of name bindings with no def?!");
4422 def @ def_variant(*) | def @ def_struct(*) => {
4423 return FoundStructOrEnumVariant(def);
4425 def @ def_const(*) => {
4426 return FoundConst(def);
4429 return BareIdentifierPatternUnresolved;
4437 fail!(~"unexpected indeterminate result");
4441 return BareIdentifierPatternUnresolved;
4446 /// If `check_ribs` is true, checks the local definitions first; i.e.
4447 /// doesn't skip straight to the containing module.
4448 fn resolve_path(@mut self,
4450 namespace: Namespace,
4452 visitor: ResolveVisitor)
4454 // First, resolve the types.
4455 for path.types.each |ty| {
4456 self.resolve_type(*ty, visitor);
4460 return self.resolve_crate_relative_path(path,
4465 if path.idents.len() > 1 {
4466 return self.resolve_module_relative_path(path,
4471 return self.resolve_identifier(*path.idents.last(),
4477 fn resolve_identifier(@mut self,
4479 namespace: Namespace,
4484 match self.resolve_identifier_in_local_ribs(identifier,
4496 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4500 // FIXME #4952: Merge me with resolve_name_in_module?
4501 fn resolve_definition_of_name_in_module(@mut self,
4502 containing_module: @mut Module,
4504 namespace: Namespace,
4507 // First, search children.
4508 match containing_module.children.find(&name) {
4509 Some(child_name_bindings) => {
4510 match (child_name_bindings.def_for_namespace(namespace),
4511 child_name_bindings.privacy_for_namespace(namespace)) {
4512 (Some(def), Some(Public)) => {
4513 // Found it. Stop the search here.
4514 return ChildNameDefinition(def);
4516 (Some(def), _) if xray == Xray => {
4517 // Found it. Stop the search here.
4518 return ChildNameDefinition(def);
4520 (Some(_), _) | (None, _) => {
4530 // Next, search import resolutions.
4531 match containing_module.import_resolutions.find(&name) {
4532 Some(import_resolution) if import_resolution.privacy == Public ||
4534 match (*import_resolution).target_for_namespace(namespace) {
4536 match (target.bindings.def_for_namespace(namespace),
4537 target.bindings.privacy_for_namespace(
4539 (Some(def), Some(Public)) => {
4541 import_resolution.state.used = true;
4542 return ImportNameDefinition(def);
4544 (Some(_), _) | (None, _) => {
4545 // This can happen with external impls, due to
4546 // the imperfect way we read the metadata.
4548 return NoNameDefinition;
4553 return NoNameDefinition;
4558 return NoNameDefinition;
4563 fn intern_module_part_of_path(@mut self, path: @path) -> ~[ident] {
4564 let mut module_path_idents = ~[];
4565 for path.idents.eachi |index, ident| {
4566 if index == path.idents.len() - 1 {
4570 module_path_idents.push(*ident);
4573 return module_path_idents;
4576 fn resolve_module_relative_path(@mut self,
4579 namespace: Namespace)
4581 let module_path_idents = self.intern_module_part_of_path(path);
4583 let mut containing_module;
4584 match self.resolve_module_path_for_import(self.current_module,
4589 self.session.span_err(path.span,
4590 fmt!("use of undeclared module `%s`",
4592 module_path_idents)));
4597 fail!(~"indeterminate unexpected");
4600 Success(resulting_module) => {
4601 containing_module = resulting_module;
4605 let name = *path.idents.last();
4606 match self.resolve_definition_of_name_in_module(containing_module,
4610 NoNameDefinition => {
4611 // We failed to resolve the name. Report an error.
4614 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4620 /// Invariant: This must be called only during main resolution, not during
4621 /// import resolution.
4622 fn resolve_crate_relative_path(@mut self,
4625 namespace: Namespace)
4627 let module_path_idents = self.intern_module_part_of_path(path);
4629 let root_module = self.graph_root.get_module();
4631 let mut containing_module;
4632 match self.resolve_module_path_from_root(root_module,
4636 SearchItemsAndAllImports) {
4638 self.session.span_err(path.span,
4639 fmt!("use of undeclared module `::%s`",
4641 module_path_idents)));
4646 fail!(~"indeterminate unexpected");
4649 Success(resulting_module) => {
4650 containing_module = resulting_module;
4654 let name = *path.idents.last();
4655 match self.resolve_definition_of_name_in_module(containing_module,
4659 NoNameDefinition => {
4660 // We failed to resolve the name. Report an error.
4663 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4669 fn resolve_identifier_in_local_ribs(@mut self,
4671 namespace: Namespace,
4674 // Check the local set of ribs.
4675 let mut search_result;
4678 search_result = self.search_ribs(&mut self.value_ribs, ident,
4680 DontAllowCapturingSelf);
4683 search_result = self.search_ribs(&mut self.type_ribs, ident,
4684 span, AllowCapturingSelf);
4688 match search_result {
4689 Some(dl_def(def)) => {
4690 debug!("(resolving path in local ribs) resolved `%s` to \
4692 *self.session.str_of(ident),
4696 Some(dl_field) | Some(dl_impl(_)) | None => {
4702 fn resolve_item_by_identifier_in_lexical_scope(@mut self,
4704 namespace: Namespace)
4707 match self.resolve_item_in_lexical_scope(self.current_module,
4710 DontSearchThroughModules) {
4711 Success(target) => {
4712 match (*target.bindings).def_for_namespace(namespace) {
4714 // This can happen if we were looking for a type and
4715 // found a module instead. Modules don't have defs.
4719 debug!("(resolving item path in lexical scope) \
4720 resolved `%s` to item",
4721 *self.session.str_of(ident));
4727 fail!(~"unexpected indeterminate result");
4735 fn find_best_match_for_name(@mut self, name: &str) -> Option<~str> {
4736 let this = &mut *self;
4738 let mut maybes: ~[~str] = ~[];
4739 let mut values: ~[uint] = ~[];
4741 let mut j = this.value_ribs.len();
4744 for this.value_ribs[j].bindings.each_entry |e| {
4745 vec::push(&mut maybes, copy *this.session.str_of(e.key));
4746 vec::push(&mut values, uint::max_value);
4750 let mut smallest = 0;
4751 for vec::eachi(maybes) |i, &other| {
4753 values[i] = str::levdistance(name, other);
4755 if values[i] <= values[smallest] {
4760 if vec::len(values) > 0 &&
4761 values[smallest] != uint::max_value &&
4762 values[smallest] < str::len(name) + 2 &&
4763 maybes[smallest] != name.to_owned() {
4765 Some(vec::swap_remove(&mut maybes, smallest))
4772 fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
4773 let this = &mut *self;
4775 let mut i = this.type_ribs.len();
4778 match this.type_ribs[i].kind {
4779 MethodRibKind(node_id, _) =>
4780 for this.crate.node.module.items.each |item| {
4781 if item.id == node_id {
4783 item_struct(class_def, _) => {
4784 for vec::each(class_def.fields) |field| {
4785 match field.node.kind {
4786 unnamed_field => {},
4787 named_field(ident, _, _) => {
4788 if str::eq_slice(*this.session.str_of(ident),
4806 fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) {
4807 // First, record candidate traits for this expression if it could
4808 // result in the invocation of a method call.
4810 self.record_candidate_traits_for_expr_if_necessary(expr);
4812 // Next, resolve the node.
4814 // The interpretation of paths depends on whether the path has
4815 // multiple elements in it or not.
4817 expr_path(path) => {
4818 // This is a local path in the value namespace. Walk through
4819 // scopes looking for it.
4821 match self.resolve_path(path, ValueNS, true, visitor) {
4823 // Write the result into the def map.
4824 debug!("(resolving expr) resolved `%s`",
4825 self.idents_to_str(path.idents));
4826 self.record_def(expr.id, def);
4829 let wrong_name = self.idents_to_str(
4831 if self.name_exists_in_scope_struct(wrong_name) {
4832 self.session.span_err(expr.span,
4833 fmt!("unresolved name: `%s`. \
4834 Did you mean: `self.%s`?",
4839 match self.find_best_match_for_name(wrong_name) {
4842 self.session.span_err(expr.span,
4843 fmt!("unresolved name: `%s`. \
4844 Did you mean: `%s`?",
4848 self.session.span_err(expr.span,
4849 fmt!("unresolved name: `%s`.",
4857 visit_expr(expr, (), visitor);
4860 expr_fn_block(ref fn_decl, ref block) => {
4861 self.resolve_function(FunctionRibKind(expr.id, block.node.id),
4869 expr_struct(path, _, _) => {
4870 // Resolve the path to the structure it goes to.
4871 match self.resolve_path(path, TypeNS, false, visitor) {
4872 Some(def_ty(class_id)) | Some(def_struct(class_id))
4873 if self.structs.contains_key(&class_id) => {
4874 let class_def = def_struct(class_id);
4875 self.record_def(expr.id, class_def);
4877 Some(definition @ def_variant(_, class_id))
4878 if self.structs.contains_key(&class_id) => {
4879 self.record_def(expr.id, definition);
4882 self.session.span_err(
4884 fmt!("`%s` does not name a structure",
4885 self.idents_to_str(path.idents)));
4889 visit_expr(expr, (), visitor);
4892 expr_loop(_, Some(label)) => {
4893 do self.with_label_rib {
4894 let this = &mut *self;
4895 let def_like = dl_def(def_label(expr.id));
4896 let rib = this.label_ribs[this.label_ribs.len() - 1];
4897 rib.bindings.insert(label, def_like);
4899 visit_expr(expr, (), visitor);
4903 expr_break(Some(label)) | expr_again(Some(label)) => {
4904 match self.search_ribs(&mut self.label_ribs, label, expr.span,
4905 DontAllowCapturingSelf) {
4907 self.session.span_err(expr.span,
4908 fmt!("use of undeclared label \
4910 *self.session.str_of(
4912 Some(dl_def(def @ def_label(_))) =>
4913 self.record_def(expr.id, def),
4915 self.session.span_bug(expr.span,
4916 ~"label wasn't mapped to a \
4922 visit_expr(expr, (), visitor);
4927 fn record_candidate_traits_for_expr_if_necessary(@mut self, expr: @expr) {
4929 expr_field(_, ident, _) => {
4930 let traits = self.search_for_traits_containing_method(ident);
4931 self.trait_map.insert(expr.id, @mut traits);
4933 expr_method_call(_, ident, _, _, _) => {
4934 let traits = self.search_for_traits_containing_method(ident);
4935 self.trait_map.insert(expr.id, @mut traits);
4937 expr_binary(add, _, _) | expr_assign_op(add, _, _) => {
4938 self.add_fixed_trait_for_expr(expr.id,
4939 self.lang_items.add_trait());
4941 expr_binary(subtract, _, _) | expr_assign_op(subtract, _, _) => {
4942 self.add_fixed_trait_for_expr(expr.id,
4943 self.lang_items.sub_trait());
4945 expr_binary(mul, _, _) | expr_assign_op(mul, _, _) => {
4946 self.add_fixed_trait_for_expr(expr.id,
4947 self.lang_items.mul_trait());
4949 expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
4950 self.add_fixed_trait_for_expr(expr.id,
4951 self.lang_items.div_trait());
4953 expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
4954 self.add_fixed_trait_for_expr(expr.id,
4955 self.lang_items.modulo_trait());
4957 expr_binary(bitxor, _, _) | expr_assign_op(bitxor, _, _) => {
4958 self.add_fixed_trait_for_expr(expr.id,
4959 self.lang_items.bitxor_trait());
4961 expr_binary(bitand, _, _) | expr_assign_op(bitand, _, _) => {
4962 self.add_fixed_trait_for_expr(expr.id,
4963 self.lang_items.bitand_trait());
4965 expr_binary(bitor, _, _) | expr_assign_op(bitor, _, _) => {
4966 self.add_fixed_trait_for_expr(expr.id,
4967 self.lang_items.bitor_trait());
4969 expr_binary(shl, _, _) | expr_assign_op(shl, _, _) => {
4970 self.add_fixed_trait_for_expr(expr.id,
4971 self.lang_items.shl_trait());
4973 expr_binary(shr, _, _) | expr_assign_op(shr, _, _) => {
4974 self.add_fixed_trait_for_expr(expr.id,
4975 self.lang_items.shr_trait());
4977 expr_binary(lt, _, _) | expr_binary(le, _, _) |
4978 expr_binary(ge, _, _) | expr_binary(gt, _, _) => {
4979 self.add_fixed_trait_for_expr(expr.id,
4980 self.lang_items.ord_trait());
4982 expr_binary(eq, _, _) | expr_binary(ne, _, _) => {
4983 self.add_fixed_trait_for_expr(expr.id,
4984 self.lang_items.eq_trait());
4986 expr_unary(neg, _) => {
4987 self.add_fixed_trait_for_expr(expr.id,
4988 self.lang_items.neg_trait());
4990 expr_unary(not, _) => {
4991 self.add_fixed_trait_for_expr(expr.id,
4992 self.lang_items.not_trait());
4995 self.add_fixed_trait_for_expr(expr.id,
4996 self.lang_items.index_trait());
5004 fn search_for_traits_containing_method(@mut self,
5007 debug!("(searching for traits containing method) looking for '%s'",
5008 *self.session.str_of(name));
5010 let mut found_traits = ~[];
5011 let mut search_module = self.current_module;
5013 // Look for the current trait.
5014 match /*bad*/copy self.current_trait_refs {
5015 Some(trait_def_ids) => {
5016 for trait_def_ids.each |trait_def_id| {
5017 self.add_trait_info_if_containing_method(
5018 &mut found_traits, *trait_def_id, name);
5026 // Look for trait children.
5027 for search_module.children.each_value |&child_name_bindings| {
5028 match child_name_bindings.def_for_namespace(TypeNS) {
5031 def_ty(trait_def_id) => {
5032 self.add_trait_info_if_containing_method(
5033 &mut found_traits, trait_def_id, name);
5046 // Look for imports.
5047 for search_module.import_resolutions.each_value
5048 |&import_resolution| {
5050 match import_resolution.target_for_namespace(TypeNS) {
5055 match target.bindings.def_for_namespace(TypeNS) {
5058 def_ty(trait_def_id) => {
5060 add_trait_info_if_containing_method(
5062 trait_def_id, name);
5064 import_resolution.state.used =
5081 // Move to the next parent.
5082 match search_module.parent_link {
5087 ModuleParentLink(parent_module, _) |
5088 BlockParentLink(parent_module, _) => {
5089 search_module = parent_module;
5094 return found_traits;
5097 fn add_trait_info_if_containing_method(@mut self,
5098 found_traits: &mut ~[def_id],
5099 trait_def_id: def_id,
5102 debug!("(adding trait info if containing method) trying trait %d:%d \
5106 *self.session.str_of(name));
5108 match self.trait_info.find(&trait_def_id) {
5109 Some(trait_info) if trait_info.contains_key(&name) => {
5110 debug!("(adding trait info if containing method) found trait \
5111 %d:%d for method '%s'",
5114 *self.session.str_of(name));
5115 found_traits.push(trait_def_id);
5124 fn add_fixed_trait_for_expr(@mut self,
5126 +trait_id: def_id) {
5127 self.trait_map.insert(expr_id, @mut ~[trait_id]);
5130 fn record_def(@mut self, node_id: node_id, def: def) {
5131 debug!("(recording def) recording %? for %?", def, node_id);
5132 self.def_map.insert(node_id, def);
5135 fn enforce_default_binding_mode(@mut self,
5137 pat_binding_mode: binding_mode,
5139 match pat_binding_mode {
5142 self.session.span_err(
5144 fmt!("cannot use `copy` binding mode with %s",
5148 self.session.span_err(
5150 fmt!("cannot use `ref` binding mode with %s",
5157 // main function checking
5159 // be sure that there is only one main function
5161 fn check_duplicate_main(@mut self) {
5162 let this = &mut *self;
5163 if this.attr_main_fn.is_none() {
5164 if this.main_fns.len() >= 1u {
5166 while i < this.main_fns.len() {
5167 let (_, dup_main_span) = option::unwrap(this.main_fns[i]);
5168 this.session.span_err(
5170 ~"multiple 'main' functions");
5173 *this.session.main_fn = this.main_fns[0];
5176 *this.session.main_fn = this.attr_main_fn;
5181 // Unused import checking
5183 // Although this is a lint pass, it lives in here because it depends on
5184 // resolve data structures.
5187 fn unused_import_lint_level(@mut self, m: @mut Module) -> level {
5188 let settings = self.session.lint_settings;
5190 Some(def) => get_lint_settings_level(settings, unused_imports,
5191 def.node, def.node),
5192 None => get_lint_level(settings.default_settings, unused_imports)
5196 fn check_for_unused_imports_if_necessary(@mut self) {
5197 if self.unused_import_lint_level(self.current_module) == allow {
5201 let root_module = self.graph_root.get_module();
5202 self.check_for_unused_imports_in_module_subtree(root_module);
5205 fn check_for_unused_imports_in_module_subtree(@mut self,
5206 module_: @mut Module) {
5207 // If this isn't a local crate, then bail out. We don't need to check
5208 // for unused imports in external crates.
5210 match module_.def_id {
5211 Some(def_id) if def_id.crate == local_crate => {
5215 // Check for unused imports in the root module.
5219 debug!("(checking for unused imports in module subtree) not \
5220 checking for unused imports for `%s`",
5221 self.module_to_str(module_));
5226 self.check_for_unused_imports_in_module(module_);
5228 for module_.children.each_value |&child_name_bindings| {
5229 match (*child_name_bindings).get_module_if_available() {
5233 Some(child_module) => {
5234 self.check_for_unused_imports_in_module_subtree
5240 for module_.anonymous_children.each_value |&child_module| {
5241 self.check_for_unused_imports_in_module_subtree(child_module);
5245 fn check_for_unused_imports_in_module(@mut self, module_: @mut Module) {
5246 for module_.import_resolutions.each_value |&import_resolution| {
5247 // Ignore dummy spans for things like automatically injected
5248 // imports for the prelude, and also don't warn about the same
5249 // import statement being unused more than once. Furthermore, if
5250 // the import is public, then we can't be sure whether it's unused
5251 // or not so don't warn about it.
5252 if !import_resolution.state.used &&
5253 !import_resolution.state.warned &&
5254 import_resolution.span != dummy_sp() &&
5255 import_resolution.privacy != Public {
5256 import_resolution.state.warned = true;
5257 match self.unused_import_lint_level(module_) {
5259 self.session.span_warn(copy import_resolution.span,
5263 self.session.span_err(copy import_resolution.span,
5276 // Diagnostics are not particularly efficient, because they're rarely
5280 /// A somewhat inefficient routine to obtain the name of a module.
5281 fn module_to_str(@mut self, module_: @mut Module) -> ~str {
5282 let mut idents = ~[];
5283 let mut current_module = module_;
5285 match current_module.parent_link {
5289 ModuleParentLink(module_, name) => {
5291 current_module = module_;
5293 BlockParentLink(module_, _) => {
5294 idents.push(special_idents::opaque);
5295 current_module = module_;
5300 if idents.len() == 0 {
5303 return self.idents_to_str(vec::reversed(idents));
5306 fn dump_module(@mut self, module_: @mut Module) {
5307 debug!("Dump of module `%s`:", self.module_to_str(module_));
5309 debug!("Children:");
5310 for module_.children.each_key |&name| {
5311 debug!("* %s", *self.session.str_of(name));
5314 debug!("Import resolutions:");
5315 for module_.import_resolutions.each |&name, &import_resolution| {
5317 match (*import_resolution).target_for_namespace(ValueNS) {
5318 None => { value_repr = ~""; }
5320 value_repr = ~" value:?";
5326 match (*import_resolution).target_for_namespace(TypeNS) {
5327 None => { type_repr = ~""; }
5329 type_repr = ~" type:?";
5334 debug!("* %s:%s%s", *self.session.str_of(name),
5335 value_repr, type_repr);
5340 pub struct CrateMap {
5342 exp_map2: ExportMap2,
5346 /// Entry point to crate resolution.
5347 pub fn resolve_crate(session: Session,
5348 lang_items: LanguageItems,
5351 let resolver = @mut Resolver(session, lang_items, crate);
5354 def_map: *resolver.def_map,
5355 exp_map2: *resolver.export_map2,
5356 trait_map: resolver.trait_map