1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use driver::session::Session;
13 use metadata::csearch::{each_path, get_trait_method_def_ids};
14 use metadata::csearch::get_method_name_and_self_ty;
15 use metadata::csearch::get_static_methods_if_impl;
16 use metadata::csearch::get_type_name_if_impl;
17 use metadata::cstore::find_extern_mod_stmt_cnum;
18 use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
19 use middle::lang_items::LanguageItems;
20 use middle::lint::{allow, level, unused_imports};
21 use middle::lint::{get_lint_level, get_lint_settings_level};
22 use middle::pat_util::pat_bindings;
24 use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
25 use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk};
26 use syntax::ast::{bind_infer, bind_by_ref, bind_by_copy};
27 use syntax::ast::{crate, decl_item, def, def_arg, def_binding};
28 use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
29 use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
30 use syntax::ast::{def_self_ty, def_static_method, def_struct, def_ty};
31 use syntax::ast::{def_ty_param, def_typaram_binder, def_trait};
32 use syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
33 use syntax::ast::{expr_binary, expr_break, expr_field};
34 use syntax::ast::{expr_fn_block, expr_index, expr_method_call, expr_path};
35 use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
36 use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
37 use syntax::ast::{expr, expr_again, expr_assign_op};
38 use syntax::ast::{expr_index, expr_loop};
39 use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
40 use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
41 use syntax::ast::Generics;
42 use syntax::ast::{gt, ident, inherited, item, item_struct};
43 use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
44 use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
45 use syntax::ast::{local, local_crate, lt, method, mul};
46 use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
47 use syntax::ast::{Path, pat_lit, pat_range, pat_struct};
48 use syntax::ast::{prim_ty, private, provided};
49 use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl};
50 use syntax::ast::{struct_dtor, struct_field, struct_variant_kind};
51 use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty};
52 use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
53 use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, TyParam, ty_path};
54 use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
55 use syntax::ast::unnamed_field;
56 use syntax::ast::{variant, view_item, view_item_extern_mod};
57 use syntax::ast::{view_item_use, view_path_glob, view_path_list};
58 use syntax::ast::{view_path_simple, anonymous, named, not};
59 use syntax::ast::{unsafe_fn};
60 use syntax::ast_util::{def_id_of_def, local_def};
61 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
62 use syntax::ast_util::{Privacy, Public, Private};
63 use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy};
64 use syntax::attr::{attr_metas, contains_name, attrs_contains_name};
65 use syntax::parse::token::ident_interner;
66 use syntax::parse::token::special_idents;
67 use syntax::print::pprust::path_to_str;
68 use syntax::codemap::{span, dummy_sp};
69 use syntax::visit::{default_visitor, mk_vt, Visitor, visit_block};
70 use syntax::visit::{visit_crate, visit_expr, visit_expr_opt};
71 use syntax::visit::{visit_foreign_item, visit_item};
72 use syntax::visit::{visit_mod, visit_ty, vt};
73 use syntax::opt_vec::OptVec;
75 use core::option::Some;
76 use core::str::each_split_str;
77 use core::hashmap::{HashMap, HashSet};
81 pub type DefMap = @mut HashMap<node_id,def>;
83 pub struct binding_info {
85 binding_mode: binding_mode,
88 // Map from the name in a pattern to its binding mode.
89 pub type BindingMap = HashMap<ident,binding_info>;
91 // Implementation resolution
93 // FIXME #4946: This kind of duplicates information kept in
94 // ty::method. Maybe it should go away.
96 pub struct MethodInfo {
106 methods: ~[@MethodInfo]
109 // Trait method resolution
110 pub type TraitMap = HashMap<node_id,@mut ~[def_id]>;
112 // This is the replacement export map. It maps a module to all of the exports
114 pub type ExportMap2 = @mut HashMap<node_id, ~[Export2]>;
117 name: @~str, // The name of the target.
118 def_id: def_id, // The definition of the target.
119 reexport: bool, // Whether this is a reexport.
123 pub enum PatternBindingMode {
125 LocalIrrefutableMode,
126 ArgumentIrrefutableMode,
135 /// A NamespaceResult represents the result of resolving an import in
136 /// a particular namespace. The result is either definitely-resolved,
137 /// definitely- unresolved, or unknown.
138 pub enum NamespaceResult {
139 /// Means that resolve hasn't gathered enough information yet to determine
140 /// whether the name is bound in this namespace. (That is, it hasn't
141 /// resolved all `use` directives yet.)
143 /// Means that resolve has determined that the name is definitely
144 /// not bound in the namespace.
146 /// Means that resolve has determined that the name is bound in the Module
147 /// argument, and specified by the NameBindings argument.
148 BoundResult(@mut Module, @mut NameBindings)
151 pub impl NamespaceResult {
152 fn is_unknown(&self) -> bool {
154 UnknownResult => true,
160 pub enum NameDefinition {
161 NoNameDefinition, //< The name was unbound.
162 ChildNameDefinition(def), //< The name identifies an immediate child.
163 ImportNameDefinition(def) //< The name identifies an import.
167 pub enum Mutability {
172 pub enum SelfBinding {
174 HasSelfBinding(node_id, bool /* is implicit */)
177 pub type ResolveVisitor = vt<()>;
179 /// Contains data for specific types of import directives.
180 pub enum ImportDirectiveSubclass {
181 SingleImport(ident /* target */, ident /* source */),
185 /// The context that we thread through while building the reduced graph.
186 pub enum ReducedGraphParent {
187 ModuleReducedGraphParent(@mut Module)
190 pub enum ResolveResult<T> {
191 Failed, // Failed to resolve the name.
192 Indeterminate, // Couldn't determine due to unresolved globs.
193 Success(T) // Successfully resolved the import.
196 pub impl<T> ResolveResult<T> {
197 fn failed(&self) -> bool {
198 match *self { Failed => true, _ => false }
200 fn indeterminate(&self) -> bool {
201 match *self { Indeterminate => true, _ => false }
205 pub enum TypeParameters<'self> {
206 NoTypeParameters, //< No type parameters.
207 HasTypeParameters(&'self Generics, //< Type parameters.
208 node_id, //< ID of the enclosing item
210 // The index to start numbering the type parameters at.
211 // This is zero if this is the outermost set of type
212 // parameters, or equal to the number of outer type
213 // parameters. For example, if we have:
216 // fn method<U>() { ... }
219 // The index at the method site will be 1, because the
220 // outer T had index 0.
223 // The kind of the rib used for type parameters.
227 // The rib kind controls the translation of argument or local definitions
228 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
231 // No translation needs to be applied.
234 // We passed through a function scope at the given node ID. Translate
235 // upvars as appropriate.
236 FunctionRibKind(node_id /* func id */, node_id /* body id */),
238 // We passed through an impl or trait and are now in one of its
239 // methods. Allow references to ty params that that impl or trait
240 // binds. Disallow any other upvars (including other ty params that are
242 // parent; method itself
243 MethodRibKind(node_id, MethodSort),
245 // We passed through a function *item* scope. Disallow upvars.
246 OpaqueFunctionRibKind,
248 // We're in a constant item. Can't refer to dynamic stuff.
252 // Methods can be required or provided. Required methods only occur in traits.
253 pub enum MethodSort {
258 // The X-ray flag indicates that a context has the X-ray privilege, which
259 // allows it to reference private names. Currently, this is used for the test
262 // FIXME #4947: The X-ray flag is kind of questionable in the first
263 // place. It might be better to introduce an expr_xray_path instead.
267 NoXray, //< Private items cannot be accessed.
268 Xray //< Private items can be accessed.
271 pub enum UseLexicalScopeFlag {
276 pub enum SearchThroughModulesFlag {
277 DontSearchThroughModules,
281 pub enum ModulePrefixResult {
283 PrefixFound(@mut Module, uint)
287 pub enum AllowCapturingSelfFlag {
288 AllowCapturingSelf, //< The "self" definition can be captured.
289 DontAllowCapturingSelf, //< The "self" definition cannot be captured.
293 enum NameSearchType {
294 SearchItemsAndPublicImports, //< Search items and public imports.
295 SearchItemsAndAllImports, //< Search items and all imports.
298 pub enum BareIdentifierPatternResolution {
299 FoundStructOrEnumVariant(def),
301 BareIdentifierPatternUnresolved
304 // Specifies how duplicates should be handled when adding a child item if
305 // another item exists with the same name in some namespace.
307 pub enum DuplicateCheckingMode {
308 ForbidDuplicateModules,
309 ForbidDuplicateTypes,
310 ForbidDuplicateValues,
311 ForbidDuplicateTypesAndValues,
315 // Returns the namespace associated with the given duplicate checking mode,
316 // or fails for OverwriteDuplicates. This is used for error messages.
317 pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
320 ForbidDuplicateModules | ForbidDuplicateTypes |
321 ForbidDuplicateTypesAndValues => TypeNS,
322 ForbidDuplicateValues => ValueNS,
323 OverwriteDuplicates => fail!(~"OverwriteDuplicates has no namespace")
329 bindings: @mut HashMap<ident,def_like>,
333 pub fn Rib(kind: RibKind) -> Rib {
335 bindings: @mut HashMap::new(),
341 /// One import directive.
342 pub struct ImportDirective {
344 module_path: ~[ident],
345 subclass: @ImportDirectiveSubclass,
349 pub fn ImportDirective(privacy: Privacy,
350 module_path: ~[ident],
351 subclass: @ImportDirectiveSubclass,
356 module_path: module_path,
362 /// The item that an import resolves to.
364 target_module: @mut Module,
365 bindings: @mut NameBindings,
368 pub fn Target(target_module: @mut Module,
369 bindings: @mut NameBindings)
372 target_module: target_module,
377 /// An ImportResolution represents a particular `use` directive.
378 pub struct ImportResolution {
379 /// The privacy of this `use` directive (whether it's `use` or
384 // The number of outstanding references to this name. When this reaches
385 // zero, outside modules can count on the targets being correct. Before
386 // then, all bets are off; future imports could override this name.
388 outstanding_references: uint,
390 /// The value that this `use` directive names, if there is one.
391 value_target: Option<Target>,
392 /// The type that this `use` directive names, if there is one.
393 type_target: Option<Target>,
395 /// There exists one state per import statement
396 state: @mut ImportState,
399 pub fn ImportResolution(privacy: Privacy,
401 state: @mut ImportState) -> ImportResolution {
405 outstanding_references: 0,
412 pub impl ImportResolution {
413 fn target_for_namespace(&self, namespace: Namespace) -> Option<Target> {
415 TypeNS => return copy self.type_target,
416 ValueNS => return copy self.value_target
421 pub struct ImportState {
426 pub fn ImportState() -> ImportState {
427 ImportState{ used: false, warned: false }
430 /// The link from a module up to its nearest parent node.
431 pub enum ParentLink {
433 ModuleParentLink(@mut Module, ident),
434 BlockParentLink(@mut Module, node_id)
437 /// The type of module this is.
438 pub enum ModuleKind {
445 /// One node in the tree of modules.
447 parent_link: ParentLink,
448 def_id: Option<def_id>,
451 children: @mut HashMap<ident, @mut NameBindings>,
452 imports: @mut ~[@ImportDirective],
454 // The external module children of this node that were declared with
456 external_module_children: @mut HashMap<ident, @mut Module>,
458 // The anonymous children of this node. Anonymous children are pseudo-
459 // modules that are implicitly created around items contained within
462 // For example, if we have this:
470 // There will be an anonymous module created around `g` with the ID of the
471 // entry block for `f`.
473 anonymous_children: @mut HashMap<node_id,@mut Module>,
475 // The status of resolving each import in this module.
476 import_resolutions: @mut HashMap<ident, @mut ImportResolution>,
478 // The number of unresolved globs that this module exports.
481 // The index of the import we're resolving.
482 resolved_import_count: uint,
485 pub fn Module(parent_link: ParentLink,
486 def_id: Option<def_id>,
490 parent_link: parent_link,
493 children: @mut HashMap::new(),
495 external_module_children: @mut HashMap::new(),
496 anonymous_children: @mut HashMap::new(),
497 import_resolutions: @mut HashMap::new(),
499 resolved_import_count: 0
504 fn all_imports_resolved(&self) -> bool {
505 let imports = &mut *self.imports;
506 return imports.len() == self.resolved_import_count;
510 // Records a possibly-private type definition.
511 pub struct TypeNsDef {
513 module_def: Option<@mut Module>,
514 type_def: Option<def>
517 // Records a possibly-private value definition.
518 pub struct ValueNsDef {
523 // Records the definitions (at most one for each namespace) that a name is
525 pub struct NameBindings {
526 type_def: Option<TypeNsDef>, //< Meaning in type namespace.
527 value_def: Option<ValueNsDef>, //< Meaning in value namespace.
529 // For error reporting
530 // FIXME (#3783): Merge me into TypeNsDef and ValueNsDef.
531 type_span: Option<span>,
532 value_span: Option<span>,
535 pub impl NameBindings {
536 /// Creates a new module in this set of name bindings.
537 fn define_module(@mut self,
539 parent_link: ParentLink,
540 def_id: Option<def_id>,
543 // Merges the module with the existing type def or creates a new one.
544 let module_ = @mut Module(parent_link, def_id, kind);
545 match self.type_def {
547 self.type_def = Some(TypeNsDef {
549 module_def: Some(module_),
553 Some(copy type_def) => {
554 self.type_def = Some(TypeNsDef {
556 module_def: Some(module_),
561 self.type_span = Some(sp);
564 /// Records a type definition.
565 fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
566 // Merges the type with the existing type def or creates a new one.
567 match self.type_def {
569 self.type_def = Some(TypeNsDef {
575 Some(copy type_def) => {
576 self.type_def = Some(TypeNsDef {
583 self.type_span = Some(sp);
586 /// Records a value definition.
587 fn define_value(@mut self, privacy: Privacy, def: def, sp: span) {
588 self.value_def = Some(ValueNsDef { privacy: privacy, def: def });
589 self.value_span = Some(sp);
592 /// Returns the module node if applicable.
593 fn get_module_if_available(&self) -> Option<@mut Module> {
594 match self.type_def {
595 Some(ref type_def) => (*type_def).module_def,
601 * Returns the module node. Fails if this node does not have a module
604 fn get_module(@mut self) -> @mut Module {
605 match self.get_module_if_available() {
607 fail!(~"get_module called on a node with no module \
610 Some(module_def) => module_def
614 fn defined_in_namespace(&self, namespace: Namespace) -> bool {
616 TypeNS => return self.type_def.is_some(),
617 ValueNS => return self.value_def.is_some()
621 fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
623 TypeNS => match self.type_def {
624 Some(def) => def.privacy != Private,
627 ValueNS => match self.value_def {
628 Some(def) => def.privacy != Private,
634 fn def_for_namespace(&self, namespace: Namespace) -> Option<def> {
637 match self.type_def {
639 Some(ref type_def) => {
640 // FIXME (#3784): This is reallllly questionable.
641 // Perhaps the right thing to do is to merge def_mod
643 match (*type_def).type_def {
644 Some(type_def) => Some(type_def),
646 match (*type_def).module_def {
647 Some(module_def) => {
648 let module_def = &mut *module_def;
649 module_def.def_id.map(|def_id|
660 match self.value_def {
662 Some(value_def) => Some(value_def.def)
668 fn privacy_for_namespace(&self, namespace: Namespace) -> Option<Privacy> {
671 match self.type_def {
673 Some(ref type_def) => Some((*type_def).privacy)
677 match self.value_def {
679 Some(value_def) => Some(value_def.privacy)
685 fn span_for_namespace(&self, namespace: Namespace) -> Option<span> {
686 if self.defined_in_namespace(namespace) {
688 TypeNS => self.type_span,
689 ValueNS => self.value_span,
697 pub fn NameBindings() -> NameBindings {
706 /// Interns the names of the primitive types.
707 pub struct PrimitiveTypeTable {
708 primitive_types: HashMap<ident,prim_ty>,
711 pub impl PrimitiveTypeTable {
712 fn intern(&mut self, intr: @ident_interner, string: @~str,
713 primitive_type: prim_ty) {
714 let ident = intr.intern(string);
715 self.primitive_types.insert(ident, primitive_type);
719 pub fn PrimitiveTypeTable(intr: @ident_interner) -> PrimitiveTypeTable {
720 let mut table = PrimitiveTypeTable {
721 primitive_types: HashMap::new()
724 table.intern(intr, @~"bool", ty_bool);
725 table.intern(intr, @~"char", ty_int(ty_char));
726 table.intern(intr, @~"float", ty_float(ty_f));
727 table.intern(intr, @~"f32", ty_float(ty_f32));
728 table.intern(intr, @~"f64", ty_float(ty_f64));
729 table.intern(intr, @~"int", ty_int(ty_i));
730 table.intern(intr, @~"i8", ty_int(ty_i8));
731 table.intern(intr, @~"i16", ty_int(ty_i16));
732 table.intern(intr, @~"i32", ty_int(ty_i32));
733 table.intern(intr, @~"i64", ty_int(ty_i64));
734 table.intern(intr, @~"str", ty_str);
735 table.intern(intr, @~"uint", ty_uint(ty_u));
736 table.intern(intr, @~"u8", ty_uint(ty_u8));
737 table.intern(intr, @~"u16", ty_uint(ty_u16));
738 table.intern(intr, @~"u32", ty_uint(ty_u32));
739 table.intern(intr, @~"u64", ty_uint(ty_u64));
745 pub fn namespace_to_str(ns: Namespace) -> ~str {
752 pub fn Resolver(session: Session,
753 lang_items: LanguageItems,
756 let graph_root = @mut NameBindings();
758 graph_root.define_module(Public,
760 Some(def_id { crate: 0, node: 0 }),
764 let current_module = graph_root.get_module();
766 let self = Resolver {
768 lang_items: copy lang_items,
771 // The outermost module has def ID 0; this is not reflected in the
774 graph_root: graph_root,
776 trait_info: HashMap::new(),
777 structs: HashSet::new(),
779 unresolved_imports: 0,
781 current_module: current_module,
786 xray_context: NoXray,
787 current_trait_refs: None,
789 self_ident: special_idents::self_,
790 type_self_ident: special_idents::type_self,
792 primitive_type_table: @PrimitiveTypeTable(session.
793 parse_sess.interner),
795 namespaces: ~[ TypeNS, ValueNS ],
802 def_map: @mut HashMap::new(),
803 export_map2: @mut HashMap::new(),
804 trait_map: HashMap::new(),
812 /// The main resolver class.
813 pub struct Resolver {
815 lang_items: LanguageItems,
818 intr: @ident_interner,
820 graph_root: @mut NameBindings,
822 trait_info: HashMap<def_id, HashSet<ident>>,
823 structs: HashSet<def_id>,
825 // The number of imports that are currently unresolved.
826 unresolved_imports: uint,
828 // The module that represents the current item scope.
829 current_module: @mut Module,
831 // The current set of local scopes, for values.
832 // FIXME #4948: Reuse ribs to avoid allocation.
835 // The current set of local scopes, for types.
838 // The current set of local scopes, for labels.
841 // Whether the current context is an X-ray context. An X-ray context is
842 // allowed to access private names of any module.
843 xray_context: XrayFlag,
845 // The trait that the current context can refer to.
846 current_trait_refs: Option<~[def_id]>,
848 // The ident for the keyword "self".
850 // The ident for the non-keyword "Self".
851 type_self_ident: ident,
853 // The idents for the primitive types.
854 primitive_type_table: @PrimitiveTypeTable,
856 // The four namespaces.
857 namespaces: ~[Namespace],
859 // The function that has attribute named 'main'
860 attr_main_fn: Option<(node_id, span)>,
862 // The functions that could be main functions
863 main_fns: ~[Option<(node_id, span)>],
865 // The function that has the attribute 'start' on it
866 start_fn: Option<(node_id, span)>,
869 export_map2: ExportMap2,
874 /// The main name resolution procedure.
875 fn resolve(@mut self) {
876 self.build_reduced_graph();
877 self.session.abort_if_errors();
879 self.resolve_imports();
880 self.session.abort_if_errors();
882 self.record_exports();
883 self.session.abort_if_errors();
885 self.resolve_crate();
886 self.session.abort_if_errors();
888 self.check_duplicate_main();
889 self.check_for_unused_imports_if_necessary();
893 // Reduced graph building
895 // Here we build the "reduced graph": the graph of the module tree without
896 // any imports resolved.
899 /// Constructs the reduced graph for the entire crate.
900 fn build_reduced_graph(@mut self) {
902 ModuleReducedGraphParent(self.graph_root.get_module());
903 visit_crate(self.crate, initial_parent, mk_vt(@Visitor {
904 visit_item: |item, context, visitor|
905 self.build_reduced_graph_for_item(item, context, visitor),
907 visit_foreign_item: |foreign_item, context, visitor|
908 self.build_reduced_graph_for_foreign_item(foreign_item,
912 visit_view_item: |view_item, context, visitor|
913 self.build_reduced_graph_for_view_item(view_item,
917 visit_block: |block, context, visitor|
918 self.build_reduced_graph_for_block(block,
922 .. *default_visitor()
926 /// Returns the current module tracked by the reduced graph parent.
927 fn get_module_from_parent(@mut self,
928 reduced_graph_parent: ReducedGraphParent)
930 match reduced_graph_parent {
931 ModuleReducedGraphParent(module_) => {
938 * Adds a new child item to the module definition of the parent node and
939 * returns its corresponding name bindings as well as the current parent.
940 * Or, if we're inside a block, creates (or reuses) an anonymous module
941 * corresponding to the innermost block ID and returns the name bindings
942 * as well as the newly-created parent.
944 * If this node does not have a module definition and we are not inside
947 fn add_child(@mut self,
949 reduced_graph_parent: ReducedGraphParent,
950 duplicate_checking_mode: DuplicateCheckingMode,
951 // For printing errors
953 -> (@mut NameBindings, ReducedGraphParent) {
955 // If this is the immediate descendant of a module, then we add the
956 // child name directly. Otherwise, we create or reuse an anonymous
957 // module and add the child to that.
960 match reduced_graph_parent {
961 ModuleReducedGraphParent(parent_module) => {
962 module_ = parent_module;
966 // Add or reuse the child.
967 let new_parent = ModuleReducedGraphParent(module_);
968 match module_.children.find(&name) {
970 let child = @mut NameBindings();
971 module_.children.insert(name, child);
972 return (child, new_parent);
975 // Enforce the duplicate checking mode:
977 // * If we're requesting duplicate module checking, check that
978 // there isn't a module in the module with the same name.
980 // * If we're requesting duplicate type checking, check that
981 // there isn't a type in the module with the same name.
983 // * If we're requesting duplicate value checking, check that
984 // there isn't a value in the module with the same name.
986 // * If we're requesting duplicate type checking and duplicate
987 // value checking, check that there isn't a duplicate type
988 // and a duplicate value with the same name.
990 // * If no duplicate checking was requested at all, do
993 let mut is_duplicate = false;
994 match duplicate_checking_mode {
995 ForbidDuplicateModules => {
997 child.get_module_if_available().is_some();
999 ForbidDuplicateTypes => {
1000 match child.def_for_namespace(TypeNS) {
1001 Some(def_mod(_)) | None => {}
1002 Some(_) => is_duplicate = true
1005 ForbidDuplicateValues => {
1006 is_duplicate = child.defined_in_namespace(ValueNS);
1008 ForbidDuplicateTypesAndValues => {
1009 match child.def_for_namespace(TypeNS) {
1010 Some(def_mod(_)) | None => {}
1011 Some(_) => is_duplicate = true
1013 if child.defined_in_namespace(ValueNS) {
1014 is_duplicate = true;
1017 OverwriteDuplicates => {}
1019 if duplicate_checking_mode != OverwriteDuplicates &&
1021 // Return an error here by looking up the namespace that
1022 // had the duplicate.
1023 let ns = namespace_for_duplicate_checking_mode(
1024 duplicate_checking_mode);
1025 self.session.span_err(sp,
1026 fmt!("duplicate definition of %s %s",
1027 namespace_to_str(ns),
1028 *self.session.str_of(name)));
1029 for child.span_for_namespace(ns).each |sp| {
1030 self.session.span_note(*sp,
1031 fmt!("first definition of %s %s here:",
1032 namespace_to_str(ns),
1033 *self.session.str_of(name)));
1036 return (*child, new_parent);
1041 fn block_needs_anonymous_module(@mut self, block: &blk) -> bool {
1042 // If the block has view items, we need an anonymous module.
1043 if block.node.view_items.len() > 0 {
1047 // Check each statement.
1048 for block.node.stmts.each |statement| {
1049 match statement.node {
1050 stmt_decl(declaration, _) => {
1051 match declaration.node {
1066 // If we found neither view items nor items, we don't need to create
1067 // an anonymous module.
1072 fn get_parent_link(@mut self,
1073 parent: ReducedGraphParent,
1077 ModuleReducedGraphParent(module_) => {
1078 return ModuleParentLink(module_, name);
1083 /// Constructs the reduced graph for one item.
1084 fn build_reduced_graph_for_item(@mut self,
1086 parent: ReducedGraphParent,
1087 visitor: vt<ReducedGraphParent>) {
1088 let ident = item.ident;
1090 let privacy = visibility_to_privacy(item.vis);
1093 item_mod(ref module_) => {
1094 let (name_bindings, new_parent) =
1095 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1097 let parent_link = self.get_parent_link(new_parent, ident);
1098 let def_id = def_id { crate: 0, node: item.id };
1099 name_bindings.define_module(privacy,
1106 ModuleReducedGraphParent(name_bindings.get_module());
1108 visit_mod(module_, sp, item.id, new_parent, visitor);
1111 item_foreign_mod(ref fm) => {
1112 let new_parent = match fm.sort {
1114 let (name_bindings, new_parent) =
1115 self.add_child(ident, parent,
1116 ForbidDuplicateModules, sp);
1118 let parent_link = self.get_parent_link(new_parent,
1120 let def_id = def_id { crate: 0, node: item.id };
1121 name_bindings.define_module(privacy,
1127 ModuleReducedGraphParent(name_bindings.get_module())
1130 // For anon foreign mods, the contents just go in the
1135 visit_item(item, new_parent, visitor);
1138 // These items live in the value namespace.
1140 let (name_bindings, _) =
1141 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1143 name_bindings.define_value
1144 (privacy, def_const(local_def(item.id)), sp);
1146 item_fn(_, purity, _, _, _) => {
1147 let (name_bindings, new_parent) =
1148 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1150 let def = def_fn(local_def(item.id), purity);
1151 name_bindings.define_value(privacy, def, sp);
1152 visit_item(item, new_parent, visitor);
1155 // These items live in the type namespace.
1157 let (name_bindings, _) =
1158 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1160 name_bindings.define_type
1161 (privacy, def_ty(local_def(item.id)), sp);
1164 item_enum(ref enum_definition, _) => {
1165 let (name_bindings, new_parent) =
1166 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1168 name_bindings.define_type
1169 (privacy, def_ty(local_def(item.id)), sp);
1171 for (*enum_definition).variants.each |variant| {
1172 self.build_reduced_graph_for_variant(variant,
1174 // inherited => privacy of the enum item
1175 variant_visibility_to_privacy(variant.node.vis,
1182 // These items live in both the type and value namespaces.
1183 item_struct(struct_def, _) => {
1184 let (name_bindings, new_parent) =
1185 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1187 name_bindings.define_type(
1188 privacy, def_ty(local_def(item.id)), sp);
1190 // If this struct is tuple-like or enum-like, define a name
1191 // in the value namespace.
1192 match struct_def.ctor_id {
1195 name_bindings.define_value(
1197 def_struct(local_def(ctor_id)),
1202 // Record the def ID of this struct.
1203 self.structs.insert(local_def(item.id));
1205 visit_item(item, new_parent, visitor);
1208 item_impl(_, trait_ref_opt, ty, ref methods) => {
1209 // If this implements an anonymous trait and it has static
1210 // methods, then add all the static methods within to a new
1211 // module, if the type was defined within this module.
1213 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1214 // should modify anonymous traits to only be implementable in
1215 // the same module that declared the type.
1217 // Bail out early if there are no static methods.
1218 let mut has_static_methods = false;
1219 for methods.each |method| {
1220 match method.self_ty.node {
1221 sty_static => has_static_methods = true,
1226 // If there are static methods, then create the module
1228 match (trait_ref_opt, ty) {
1229 (None, @Ty { node: ty_path(path, _), _ }) if
1230 has_static_methods && path.idents.len() == 1 => {
1231 // Create the module.
1232 let name = path_to_ident(path);
1233 let (name_bindings, new_parent) =
1234 self.add_child(name,
1236 ForbidDuplicateModules,
1239 let parent_link = self.get_parent_link(new_parent,
1241 let def_id = local_def(item.id);
1242 name_bindings.define_module(Public,
1248 let new_parent = ModuleReducedGraphParent(
1249 name_bindings.get_module());
1251 // For each static method...
1252 for methods.each |method| {
1253 match method.self_ty.node {
1255 // Add the static method to the
1257 let ident = method.ident;
1258 let (method_name_bindings, _) =
1262 ForbidDuplicateValues,
1264 let def = def_fn(local_def(method.id),
1266 method_name_bindings.define_value(
1267 Public, def, method.span);
1276 visit_item(item, parent, visitor);
1279 item_trait(_, _, ref methods) => {
1280 let (name_bindings, new_parent) =
1281 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1283 // If the trait has static methods, then add all the static
1284 // methods within to a new module.
1286 // We only need to create the module if the trait has static
1287 // methods, so check that first.
1288 let mut has_static_methods = false;
1289 for (*methods).each |method| {
1290 let ty_m = trait_method_to_ty_method(method);
1291 match ty_m.self_ty.node {
1293 has_static_methods = true;
1300 // Create the module if necessary.
1301 let module_parent_opt;
1302 if has_static_methods {
1303 let parent_link = self.get_parent_link(parent, ident);
1304 name_bindings.define_module(privacy,
1306 Some(local_def(item.id)),
1309 module_parent_opt = Some(ModuleReducedGraphParent(
1310 name_bindings.get_module()));
1312 module_parent_opt = None;
1315 // Add the names of all the methods to the trait info.
1316 let mut method_names = HashSet::new();
1317 for methods.each |method| {
1318 let ty_m = trait_method_to_ty_method(method);
1320 let ident = ty_m.ident;
1321 // Add it to the trait info if not static,
1322 // add it as a name in the trait module otherwise.
1323 match ty_m.self_ty.node {
1325 let def = def_static_method(
1327 Some(local_def(item.id)),
1330 let (method_name_bindings, _) =
1331 self.add_child(ident,
1332 module_parent_opt.get(),
1333 ForbidDuplicateValues,
1335 method_name_bindings.define_value(Public,
1340 method_names.insert(ident);
1345 let def_id = local_def(item.id);
1346 self.trait_info.insert(def_id, method_names);
1348 name_bindings.define_type(privacy, def_trait(def_id), sp);
1349 visit_item(item, new_parent, visitor);
1353 fail!(~"item macros unimplemented")
1358 // Constructs the reduced graph for one variant. Variants exist in the
1359 // type and/or value namespaces.
1360 fn build_reduced_graph_for_variant(@mut self,
1363 parent_privacy: Privacy,
1364 parent: ReducedGraphParent,
1365 _visitor: vt<ReducedGraphParent>) {
1366 let ident = variant.node.name;
1367 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1371 match variant.node.vis {
1372 public => privacy = Public,
1373 private => privacy = Private,
1374 inherited => privacy = parent_privacy
1377 match variant.node.kind {
1378 tuple_variant_kind(_) => {
1379 child.define_value(privacy,
1380 def_variant(item_id,
1381 local_def(variant.node.id)),
1384 struct_variant_kind(_) => {
1385 child.define_type(privacy,
1386 def_variant(item_id,
1387 local_def(variant.node.id)),
1389 self.structs.insert(local_def(variant.node.id));
1395 * Constructs the reduced graph for one 'view item'. View items consist
1396 * of imports and use directives.
1398 fn build_reduced_graph_for_view_item(@mut self,
1399 view_item: @view_item,
1400 parent: ReducedGraphParent,
1401 _visitor: vt<ReducedGraphParent>) {
1402 let privacy = visibility_to_privacy(view_item.vis);
1403 match view_item.node {
1404 view_item_use(ref view_paths) => {
1405 for view_paths.each |view_path| {
1406 // Extract and intern the module part of the path. For
1407 // globs and lists, the path is found directly in the AST;
1408 // for simple paths we have to munge the path a little.
1410 let mut module_path = ~[];
1411 match view_path.node {
1412 view_path_simple(_, full_path, _) => {
1413 let path_len = full_path.idents.len();
1414 assert!(path_len != 0);
1416 for full_path.idents.eachi |i, ident| {
1417 if i != path_len - 1 {
1418 module_path.push(*ident);
1423 view_path_glob(module_ident_path, _) |
1424 view_path_list(module_ident_path, _, _) => {
1425 for module_ident_path.idents.each |ident| {
1426 module_path.push(*ident);
1431 // Build up the import directives.
1432 let module_ = self.get_module_from_parent(parent);
1433 match view_path.node {
1434 view_path_simple(binding, full_path, _) => {
1435 let source_ident = *full_path.idents.last();
1436 let subclass = @SingleImport(binding,
1438 self.build_import_directive(privacy,
1444 view_path_list(_, ref source_idents, _) => {
1445 for source_idents.each |source_ident| {
1446 let name = source_ident.node.name;
1447 let subclass = @SingleImport(name, name);
1448 self.build_import_directive(privacy,
1455 view_path_glob(_, _) => {
1456 self.build_import_directive(privacy,
1466 view_item_extern_mod(name, _, node_id) => {
1467 match find_extern_mod_stmt_cnum(self.session.cstore,
1470 let def_id = def_id { crate: crate_id, node: 0 };
1471 let parent_link = ModuleParentLink
1472 (self.get_module_from_parent(parent), name);
1473 let external_module = @mut Module(parent_link,
1477 parent.external_module_children.insert(
1481 self.build_reduced_graph_for_external_crate(
1484 None => {} // Ignore.
1490 /// Constructs the reduced graph for one foreign item.
1491 fn build_reduced_graph_for_foreign_item(@mut self,
1492 foreign_item: @foreign_item,
1493 parent: ReducedGraphParent,
1495 vt<ReducedGraphParent>) {
1496 let name = foreign_item.ident;
1497 let (name_bindings, new_parent) =
1498 self.add_child(name, parent, ForbidDuplicateValues,
1501 match foreign_item.node {
1502 foreign_item_fn(_, _, ref generics) => {
1503 let def = def_fn(local_def(foreign_item.id), unsafe_fn);
1504 name_bindings.define_value(Public, def, foreign_item.span);
1506 do self.with_type_parameter_rib(
1508 generics, foreign_item.id, 0, NormalRibKind))
1510 visit_foreign_item(foreign_item, new_parent, visitor);
1513 foreign_item_const(*) => {
1514 let def = def_const(local_def(foreign_item.id));
1515 name_bindings.define_value(Public, def, foreign_item.span);
1517 visit_foreign_item(foreign_item, new_parent, visitor);
1522 fn build_reduced_graph_for_block(@mut self,
1524 parent: ReducedGraphParent,
1525 visitor: vt<ReducedGraphParent>) {
1527 if self.block_needs_anonymous_module(block) {
1528 let block_id = block.node.id;
1530 debug!("(building reduced graph for block) creating a new \
1531 anonymous module for block %d",
1534 let parent_module = self.get_module_from_parent(parent);
1535 let new_module = @mut Module(
1536 BlockParentLink(parent_module, block_id),
1538 AnonymousModuleKind);
1539 parent_module.anonymous_children.insert(block_id, new_module);
1540 new_parent = ModuleReducedGraphParent(new_module);
1542 new_parent = parent;
1545 visit_block(block, new_parent, visitor);
1548 fn handle_external_def(@mut self,
1550 modules: &mut HashMap<def_id, @mut Module>,
1551 child_name_bindings: @mut NameBindings,
1554 new_parent: ReducedGraphParent) {
1556 def_mod(def_id) | def_foreign_mod(def_id) => {
1557 match child_name_bindings.type_def {
1558 Some(TypeNsDef { module_def: Some(copy module_def), _ }) => {
1559 debug!("(building reduced graph for external crate) \
1560 already created module");
1561 module_def.def_id = Some(def_id);
1562 modules.insert(def_id, module_def);
1565 debug!("(building reduced graph for \
1566 external crate) building module \
1568 let parent_link = self.get_parent_link(new_parent, ident);
1570 // FIXME (#5074): this should be a match on find
1571 if !modules.contains_key(&def_id) {
1572 child_name_bindings.define_module(Public,
1577 modules.insert(def_id,
1578 child_name_bindings.get_module());
1580 let existing_module = *modules.get(&def_id);
1581 // Create an import resolution to
1582 // avoid creating cycles in the
1586 @mut ImportResolution(Public,
1588 @mut ImportState());
1589 resolution.outstanding_references = 0;
1591 match existing_module.parent_link {
1593 BlockParentLink(*) => {
1594 fail!(~"can't happen");
1596 ModuleParentLink(parent_module, ident) => {
1597 let name_bindings = parent_module.children.get(
1599 resolution.type_target =
1600 Some(Target(parent_module, *name_bindings));
1604 debug!("(building reduced graph for external crate) \
1605 ... creating import resolution");
1607 new_parent.import_resolutions.insert(ident, resolution);
1612 def_fn(*) | def_static_method(*) | def_const(*) |
1614 debug!("(building reduced graph for external \
1615 crate) building value %s", final_ident);
1616 child_name_bindings.define_value(Public, def, dummy_sp());
1618 def_trait(def_id) => {
1619 debug!("(building reduced graph for external \
1620 crate) building type %s", final_ident);
1622 // If this is a trait, add all the method names
1623 // to the trait info.
1625 let method_def_ids = get_trait_method_def_ids(self.session.cstore,
1627 let mut interned_method_names = HashSet::new();
1628 for method_def_ids.each |&method_def_id| {
1629 let (method_name, self_ty) =
1630 get_method_name_and_self_ty(self.session.cstore,
1633 debug!("(building reduced graph for \
1634 external crate) ... adding \
1636 *self.session.str_of(method_name));
1638 // Add it to the trait info if not static.
1639 if self_ty != sty_static {
1640 interned_method_names.insert(method_name);
1643 self.trait_info.insert(def_id, interned_method_names);
1645 child_name_bindings.define_type(Public, def, dummy_sp());
1648 debug!("(building reduced graph for external \
1649 crate) building type %s", final_ident);
1651 child_name_bindings.define_type(Public, def, dummy_sp());
1653 def_struct(def_id) => {
1654 debug!("(building reduced graph for external \
1655 crate) building type %s",
1657 child_name_bindings.define_type(Public, def, dummy_sp());
1658 self.structs.insert(def_id);
1660 def_self(*) | def_arg(*) | def_local(*) |
1661 def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
1662 def_use(*) | def_upvar(*) | def_region(*) |
1663 def_typaram_binder(*) | def_label(*) | def_self_ty(*) => {
1664 fail!(fmt!("didn't expect `%?`", def));
1670 * Builds the reduced graph rooted at the 'use' directive for an external
1673 fn build_reduced_graph_for_external_crate(@mut self, root: @mut Module) {
1674 let mut modules = HashMap::new();
1676 // Create all the items reachable by paths.
1677 for each_path(self.session.cstore, root.def_id.get().crate)
1678 |path_string, def_like| {
1680 debug!("(building reduced graph for external crate) found path \
1682 path_string, def_like);
1684 let mut pieces = ~[];
1685 for each_split_str(path_string, "::") |s| { pieces.push(s.to_owned()) }
1686 let final_ident_str = pieces.pop();
1687 let final_ident = self.session.ident_of(final_ident_str);
1689 // Find the module we need, creating modules along the way if we
1692 let mut current_module = root;
1693 for pieces.each |ident_str| {
1694 let ident = self.session.ident_of(/*bad*/copy *ident_str);
1695 // Create or reuse a graph node for the child.
1696 let (child_name_bindings, new_parent) =
1697 self.add_child(ident,
1698 ModuleReducedGraphParent(current_module),
1699 OverwriteDuplicates,
1702 // Define or reuse the module node.
1703 match child_name_bindings.type_def {
1705 debug!("(building reduced graph for external crate) \
1706 autovivifying missing type def %s",
1708 let parent_link = self.get_parent_link(new_parent,
1710 child_name_bindings.define_module(Public,
1716 Some(copy type_ns_def)
1717 if type_ns_def.module_def.is_none() => {
1718 debug!("(building reduced graph for external crate) \
1719 autovivifying missing module def %s",
1721 let parent_link = self.get_parent_link(new_parent,
1723 child_name_bindings.define_module(Public,
1729 _ => {} // Fall through.
1732 current_module = child_name_bindings.get_module();
1737 // Add the new child item.
1738 let (child_name_bindings, new_parent) =
1739 self.add_child(final_ident,
1740 ModuleReducedGraphParent(
1742 OverwriteDuplicates,
1745 self.handle_external_def(def,
1747 child_name_bindings,
1748 *self.session.str_of(
1754 // We only process static methods of impls here.
1755 match get_type_name_if_impl(self.session.cstore, def) {
1757 Some(final_ident) => {
1758 let static_methods_opt =
1759 get_static_methods_if_impl(
1760 self.session.cstore, def);
1761 match static_methods_opt {
1762 Some(ref static_methods) if
1763 static_methods.len() >= 1 => {
1764 debug!("(building reduced graph for \
1765 external crate) processing \
1766 static methods for type name %s",
1767 *self.session.str_of(
1770 let (child_name_bindings, new_parent) =
1771 self.add_child(final_ident,
1772 ModuleReducedGraphParent(
1774 OverwriteDuplicates,
1777 // Process the static methods. First,
1778 // create the module.
1780 match child_name_bindings.type_def {
1782 module_def: Some(copy module_def),
1785 // We already have a module. This
1787 type_module = module_def;
1791 self.get_parent_link(
1792 new_parent, final_ident);
1793 child_name_bindings.define_module(
1800 child_name_bindings.
1805 // Add each static method to the module.
1806 let new_parent = ModuleReducedGraphParent(
1808 for static_methods.each
1809 |static_method_info| {
1810 let ident = static_method_info.ident;
1811 debug!("(building reduced graph for \
1812 external crate) creating \
1813 static method '%s'",
1814 *self.session.str_of(ident));
1816 let (method_name_bindings, _) =
1820 OverwriteDuplicates,
1823 static_method_info.def_id,
1824 static_method_info.purity);
1825 method_name_bindings.define_value(
1826 Public, def, dummy_sp());
1830 // Otherwise, do nothing.
1831 Some(_) | None => {}
1837 debug!("(building reduced graph for external crate) \
1844 /// Creates and adds an import directive to the given module.
1845 fn build_import_directive(@mut self,
1847 module_: @mut Module,
1848 module_path: ~[ident],
1849 subclass: @ImportDirectiveSubclass,
1851 let directive = @ImportDirective(privacy, module_path,
1853 module_.imports.push(directive);
1855 // Bump the reference count on the name. Or, if this is a glob, set
1856 // the appropriate flag.
1859 SingleImport(target, _) => {
1860 debug!("(building import directive) building import \
1861 directive: privacy %? %s::%s",
1863 self.idents_to_str(directive.module_path),
1864 *self.session.str_of(target));
1866 match module_.import_resolutions.find(&target) {
1867 Some(resolution) => {
1868 debug!("(building import directive) bumping \
1870 resolution.outstanding_references += 1;
1873 debug!("(building import directive) creating new");
1874 let state = @mut ImportState();
1875 let resolution = @mut ImportResolution(privacy,
1878 let name = self.idents_to_str(directive.module_path);
1879 // Don't warn about unused intrinsics because they're
1880 // automatically appended to all files
1881 if name == ~"intrinsic::rusti" {
1882 resolution.state.warned = true;
1884 resolution.outstanding_references = 1;
1885 module_.import_resolutions.insert(target, resolution);
1890 // Set the glob flag. This tells us that we don't know the
1891 // module's exports ahead of time.
1893 module_.glob_count += 1;
1897 self.unresolved_imports += 1;
1900 // Import resolution
1902 // This is a fixed-point algorithm. We resolve imports until our efforts
1903 // are stymied by an unresolved import; then we bail out of the current
1904 // module and continue. We terminate successfully once no more imports
1905 // remain or unsuccessfully when no forward progress in resolving imports
1909 * Resolves all imports for the crate. This method performs the fixed-
1912 fn resolve_imports(@mut self) {
1914 let mut prev_unresolved_imports = 0;
1916 debug!("(resolving imports) iteration %u, %u imports left",
1917 i, self.unresolved_imports);
1919 let module_root = self.graph_root.get_module();
1920 self.resolve_imports_for_module_subtree(module_root);
1922 if self.unresolved_imports == 0 {
1923 debug!("(resolving imports) success");
1927 if self.unresolved_imports == prev_unresolved_imports {
1928 self.session.err(~"failed to resolve imports");
1929 self.report_unresolved_imports(module_root);
1934 prev_unresolved_imports = self.unresolved_imports;
1938 /// Attempts to resolve imports for the given module and all of its
1940 fn resolve_imports_for_module_subtree(@mut self, module_: @mut Module) {
1941 debug!("(resolving imports for module subtree) resolving %s",
1942 self.module_to_str(module_));
1943 self.resolve_imports_for_module(module_);
1945 for module_.children.each_value |&child_node| {
1946 match child_node.get_module_if_available() {
1950 Some(child_module) => {
1951 self.resolve_imports_for_module_subtree(child_module);
1956 for module_.anonymous_children.each_value |&child_module| {
1957 self.resolve_imports_for_module_subtree(child_module);
1961 /// Attempts to resolve imports for the given module only.
1962 fn resolve_imports_for_module(@mut self, module: @mut Module) {
1963 if module.all_imports_resolved() {
1964 debug!("(resolving imports for module) all imports resolved for \
1966 self.module_to_str(module));
1970 let imports = &mut *module.imports;
1971 let import_count = imports.len();
1972 while module.resolved_import_count < import_count {
1973 let import_index = module.resolved_import_count;
1974 let import_directive = imports[import_index];
1975 match self.resolve_import_for_module(module, import_directive) {
1977 // We presumably emitted an error. Continue.
1978 let msg = fmt!("failed to resolve import: %s",
1979 *self.import_path_to_str(
1980 import_directive.module_path,
1981 *import_directive.subclass));
1982 self.session.span_err(import_directive.span, msg);
1985 // Bail out. We'll come around next time.
1993 module.resolved_import_count += 1;
1997 fn idents_to_str(@mut self, idents: &[ident]) -> ~str {
1998 let mut first = true;
1999 let mut result = ~"";
2000 for idents.each |ident| {
2001 if first { first = false; } else { result += "::" };
2002 result += *self.session.str_of(*ident);
2007 fn import_directive_subclass_to_str(@mut self,
2008 subclass: ImportDirectiveSubclass)
2011 SingleImport(_target, source) => self.session.str_of(source),
2016 fn import_path_to_str(@mut self,
2018 subclass: ImportDirectiveSubclass)
2020 if idents.is_empty() {
2021 self.import_directive_subclass_to_str(subclass)
2024 self.idents_to_str(idents),
2025 *self.import_directive_subclass_to_str(subclass))
2029 /// Attempts to resolve the given import. The return value indicates
2030 /// failure if we're certain the name does not exist, indeterminate if we
2031 /// don't know whether the name exists at the moment due to other
2032 /// currently-unresolved imports, or success if we know the name exists.
2033 /// If successful, the resolved bindings are written into the module.
2034 fn resolve_import_for_module(@mut self, module_: @mut Module,
2035 import_directive: @ImportDirective)
2036 -> ResolveResult<()> {
2037 let mut resolution_result = Failed;
2038 let module_path = &import_directive.module_path;
2040 debug!("(resolving import for module) resolving import `%s::...` in \
2042 self.idents_to_str(*module_path),
2043 self.module_to_str(module_));
2045 // First, resolve the module path for the directive, if necessary.
2046 let containing_module = if module_path.len() == 0 {
2047 // Use the crate root.
2048 Some(self.graph_root.get_module())
2050 match self.resolve_module_path_for_import(module_,
2052 DontUseLexicalScope,
2053 import_directive.span) {
2057 resolution_result = Indeterminate;
2060 Success(containing_module) => Some(containing_module),
2064 match containing_module {
2066 Some(containing_module) => {
2067 // We found the module that the target is contained
2068 // within. Attempt to resolve the import within it.
2070 match *import_directive.subclass {
2071 SingleImport(target, source) => {
2073 self.resolve_single_import(module_,
2079 let span = import_directive.span;
2080 let privacy = import_directive.privacy;
2082 self.resolve_glob_import(privacy,
2091 // Decrement the count of unresolved imports.
2092 match resolution_result {
2094 assert!(self.unresolved_imports >= 1);
2095 self.unresolved_imports -= 1;
2098 // Nothing to do here; just return the error.
2102 // Decrement the count of unresolved globs if necessary. But only if
2103 // the resolution result is indeterminate -- otherwise we'll stop
2104 // processing imports here. (See the loop in
2105 // resolve_imports_for_module.)
2107 if !resolution_result.indeterminate() {
2108 match *import_directive.subclass {
2110 assert!(module_.glob_count >= 1);
2111 module_.glob_count -= 1;
2113 SingleImport(*) => {
2119 return resolution_result;
2122 fn create_name_bindings_from_module(module: @mut Module) -> NameBindings {
2124 type_def: Some(TypeNsDef {
2126 module_def: Some(module),
2135 fn resolve_single_import(@mut self,
2136 module_: @mut Module,
2137 containing_module: @mut Module,
2140 -> ResolveResult<()> {
2141 debug!("(resolving single import) resolving `%s` = `%s::%s` from \
2143 *self.session.str_of(target),
2144 self.module_to_str(containing_module),
2145 *self.session.str_of(source),
2146 self.module_to_str(module_));
2148 // We need to resolve both namespaces for this to succeed.
2150 // FIXME #4949: See if there's some way of handling namespaces in
2151 // a more generic way. We have two of them; it seems worth
2154 let mut value_result = UnknownResult;
2155 let mut type_result = UnknownResult;
2157 // Search for direct children of the containing module.
2158 match containing_module.children.find(&source) {
2162 Some(child_name_bindings) => {
2163 if child_name_bindings.defined_in_namespace(ValueNS) {
2164 value_result = BoundResult(containing_module,
2165 *child_name_bindings);
2167 if child_name_bindings.defined_in_namespace(TypeNS) {
2168 type_result = BoundResult(containing_module,
2169 *child_name_bindings);
2174 // Unless we managed to find a result in both namespaces (unlikely),
2175 // search imports as well.
2176 match (value_result, type_result) {
2177 (BoundResult(*), BoundResult(*)) => {
2181 // If there is an unresolved glob at this point in the
2182 // containing module, bail out. We don't know enough to be
2183 // able to resolve this import.
2185 if containing_module.glob_count > 0 {
2186 debug!("(resolving single import) unresolved glob; \
2188 return Indeterminate;
2191 // Now search the exported imports within the containing
2194 match containing_module.import_resolutions.find(&source) {
2196 // The containing module definitely doesn't have an
2197 // exported import with the name in question. We can
2198 // therefore accurately report that the names are
2201 if value_result.is_unknown() {
2202 value_result = UnboundResult;
2204 if type_result.is_unknown() {
2205 type_result = UnboundResult;
2208 Some(import_resolution)
2209 if import_resolution.outstanding_references
2212 fn get_binding(import_resolution:
2213 @mut ImportResolution,
2214 namespace: Namespace)
2215 -> NamespaceResult {
2217 // Import resolutions must be declared with "pub"
2218 // in order to be exported.
2219 if import_resolution.privacy == Private {
2220 return UnboundResult;
2223 match (*import_resolution).
2224 target_for_namespace(namespace) {
2226 return UnboundResult;
2229 import_resolution.state.used = true;
2230 return BoundResult(target.target_module,
2236 // The name is an import which has been fully
2237 // resolved. We can, therefore, just follow it.
2238 if value_result.is_unknown() {
2239 value_result = get_binding(*import_resolution,
2242 if type_result.is_unknown() {
2243 type_result = get_binding(*import_resolution,
2248 // The import is unresolved. Bail out.
2249 debug!("(resolving single import) unresolved import; \
2251 return Indeterminate;
2257 // If we didn't find a result in the type namespace, search the
2258 // external modules.
2260 BoundResult(*) => {}
2262 match containing_module.external_module_children
2264 None => {} // Continue.
2267 @mut Resolver::create_name_bindings_from_module(
2269 type_result = BoundResult(containing_module,
2276 // We've successfully resolved the import. Write the results in.
2277 assert!(module_.import_resolutions.contains_key(&target));
2278 let import_resolution = module_.import_resolutions.get(&target);
2280 match value_result {
2281 BoundResult(target_module, name_bindings) => {
2282 import_resolution.value_target =
2283 Some(Target(target_module, name_bindings));
2285 UnboundResult => { /* Continue. */ }
2287 fail!(~"value result should be known at this point");
2291 BoundResult(target_module, name_bindings) => {
2292 import_resolution.type_target =
2293 Some(Target(target_module, name_bindings));
2295 UnboundResult => { /* Continue. */ }
2297 fail!(~"type result should be known at this point");
2301 let i = import_resolution;
2302 match (i.value_target, i.type_target) {
2303 // If this name wasn't found in either namespace, it's definitely
2305 (None, None) => { return Failed; }
2306 // If it's private, it's also unresolved.
2307 (Some(t), None) | (None, Some(t)) => {
2308 let bindings = &mut *t.bindings;
2309 match bindings.type_def {
2310 Some(ref type_def) => {
2311 if type_def.privacy == Private {
2317 match bindings.value_def {
2318 Some(ref value_def) => {
2319 if value_def.privacy == Private {
2326 // It's also an error if there's both a type and a value with this
2327 // name, but both are private
2328 (Some(val), Some(ty)) => {
2329 match (val.bindings.value_def, ty.bindings.value_def) {
2330 (Some(ref value_def), Some(ref type_def)) =>
2331 if value_def.privacy == Private
2332 && type_def.privacy == Private {
2340 assert!(import_resolution.outstanding_references >= 1);
2341 import_resolution.outstanding_references -= 1;
2343 debug!("(resolving single import) successfully resolved import");
2347 // Resolves a glob import. Note that this function cannot fail; it either
2348 // succeeds or bails out (as importing * from an empty module or a module
2349 // that exports nothing is valid).
2350 fn resolve_glob_import(@mut self,
2352 module_: @mut Module,
2353 containing_module: @mut Module,
2355 -> ResolveResult<()> {
2356 // This function works in a highly imperative manner; it eagerly adds
2357 // everything it can to the list of import resolutions of the module
2359 debug!("(resolving glob import) resolving %? glob import", privacy);
2360 let state = @mut ImportState();
2362 // We must bail out if the node has unresolved imports of any kind
2363 // (including globs).
2364 if !(*containing_module).all_imports_resolved() {
2365 debug!("(resolving glob import) target module has unresolved \
2366 imports; bailing out");
2367 return Indeterminate;
2370 assert!(containing_module.glob_count == 0);
2372 // Add all resolved imports from the containing module.
2373 for containing_module.import_resolutions.each
2374 |ident, target_import_resolution| {
2376 debug!("(resolving glob import) writing module resolution \
2378 target_import_resolution.type_target.is_none(),
2379 self.module_to_str(module_));
2381 // Here we merge two import resolutions.
2382 match module_.import_resolutions.find(ident) {
2383 None if target_import_resolution.privacy == Public => {
2384 // Simple: just copy the old import resolution.
2385 let new_import_resolution =
2386 @mut ImportResolution(privacy,
2387 target_import_resolution.span,
2389 new_import_resolution.value_target =
2390 copy target_import_resolution.value_target;
2391 new_import_resolution.type_target =
2392 copy target_import_resolution.type_target;
2394 module_.import_resolutions.insert
2395 (*ident, new_import_resolution);
2397 None => { /* continue ... */ }
2398 Some(dest_import_resolution) => {
2399 // Merge the two import resolutions at a finer-grained
2402 match target_import_resolution.value_target {
2406 Some(copy value_target) => {
2407 dest_import_resolution.value_target =
2411 match target_import_resolution.type_target {
2415 Some(copy type_target) => {
2416 dest_import_resolution.type_target =
2424 let merge_import_resolution = |ident,
2425 name_bindings: @mut NameBindings| {
2426 let dest_import_resolution;
2427 match module_.import_resolutions.find(ident) {
2429 // Create a new import resolution from this child.
2430 dest_import_resolution = @mut ImportResolution(privacy,
2433 module_.import_resolutions.insert
2434 (*ident, dest_import_resolution);
2436 Some(existing_import_resolution) => {
2437 dest_import_resolution = *existing_import_resolution;
2441 debug!("(resolving glob import) writing resolution `%s` in `%s` \
2442 to `%s`, privacy=%?",
2443 *self.session.str_of(*ident),
2444 self.module_to_str(containing_module),
2445 self.module_to_str(module_),
2446 copy dest_import_resolution.privacy);
2448 // Merge the child item into the import resolution.
2449 if name_bindings.defined_in_public_namespace(ValueNS) {
2450 debug!("(resolving glob import) ... for value target");
2451 dest_import_resolution.value_target =
2452 Some(Target(containing_module, name_bindings));
2454 if name_bindings.defined_in_public_namespace(TypeNS) {
2455 debug!("(resolving glob import) ... for type target");
2456 dest_import_resolution.type_target =
2457 Some(Target(containing_module, name_bindings));
2461 // Add all children from the containing module.
2462 for containing_module.children.each |ident, name_bindings| {
2463 merge_import_resolution(ident, *name_bindings);
2466 // Add external module children from the containing module.
2467 for containing_module.external_module_children.each
2470 @mut Resolver::create_name_bindings_from_module(*module);
2471 merge_import_resolution(ident, name_bindings);
2474 debug!("(resolving glob import) successfully resolved import");
2478 /// Resolves the given module path from the given root `module_`.
2479 fn resolve_module_path_from_root(@mut self,
2480 module_: @mut Module,
2481 module_path: &[ident],
2484 mut name_search_type: NameSearchType)
2485 -> ResolveResult<@mut Module> {
2486 let mut search_module = module_;
2487 let mut index = index;
2488 let module_path_len = module_path.len();
2490 // Resolve the module part of the path. This does not involve looking
2491 // upward though scope chains; we simply resolve names directly in
2492 // modules as we go.
2494 while index < module_path_len {
2495 let name = module_path[index];
2496 match self.resolve_name_in_module(search_module,
2501 self.session.span_err(span, ~"unresolved name");
2505 debug!("(resolving module path for import) module \
2506 resolution is indeterminate: %s",
2507 *self.session.str_of(name));
2508 return Indeterminate;
2510 Success(target) => {
2511 // Check to see whether there are type bindings, and, if
2512 // so, whether there is a module within.
2513 match target.bindings.type_def {
2514 Some(copy type_def) => {
2515 match type_def.module_def {
2518 self.session.span_err(span,
2526 Some(copy module_def) => {
2527 search_module = module_def;
2532 // There are no type bindings at all.
2533 self.session.span_err(span,
2534 fmt!("not a module: %s",
2535 *self.session.str_of(
2545 // After the first element of the path, allow searching through
2546 // items and imports unconditionally. This allows things like:
2552 // pub mod something_else {
2556 name_search_type = SearchItemsAndPublicImports;
2559 return Success(search_module);
2562 /// Attempts to resolve the module part of an import directive or path
2563 /// rooted at the given module.
2564 fn resolve_module_path_for_import(@mut self,
2565 module_: @mut Module,
2566 module_path: &[ident],
2567 use_lexical_scope: UseLexicalScopeFlag,
2569 -> ResolveResult<@mut Module> {
2570 let module_path_len = module_path.len();
2571 assert!(module_path_len > 0);
2573 debug!("(resolving module path for import) processing `%s` rooted at \
2575 self.idents_to_str(module_path),
2576 self.module_to_str(module_));
2578 // Resolve the module prefix, if any.
2579 let module_prefix_result = self.resolve_module_prefix(module_,
2584 match module_prefix_result {
2586 self.session.span_err(span, ~"unresolved name");
2590 debug!("(resolving module path for import) indeterminate; \
2592 return Indeterminate;
2594 Success(NoPrefixFound) => {
2595 // There was no prefix, so we're considering the first element
2596 // of the path. How we handle this depends on whether we were
2597 // instructed to use lexical scope or not.
2598 match use_lexical_scope {
2599 DontUseLexicalScope => {
2600 // This is a crate-relative path. We will start the
2601 // resolution process at index zero.
2602 search_module = self.graph_root.get_module();
2605 UseLexicalScope => {
2606 // This is not a crate-relative path. We resolve the
2607 // first component of the path in the current lexical
2608 // scope and then proceed to resolve below that.
2609 let result = self.resolve_module_in_lexical_scope(
2614 self.session.span_err(span,
2615 ~"unresolved name");
2619 debug!("(resolving module path for import) \
2620 indeterminate; bailing");
2621 return Indeterminate;
2623 Success(containing_module) => {
2624 search_module = containing_module;
2631 Success(PrefixFound(containing_module, index)) => {
2632 search_module = containing_module;
2633 start_index = index;
2637 self.resolve_module_path_from_root(search_module,
2641 SearchItemsAndPublicImports)
2644 /// Invariant: This must only be called during main resolution, not during
2645 /// import resolution.
2646 fn resolve_item_in_lexical_scope(@mut self,
2647 module_: @mut Module,
2649 namespace: Namespace,
2650 search_through_modules:
2651 SearchThroughModulesFlag)
2652 -> ResolveResult<Target> {
2653 debug!("(resolving item in lexical scope) resolving `%s` in \
2654 namespace %? in `%s`",
2655 *self.session.str_of(name),
2657 self.module_to_str(module_));
2659 // The current module node is handled specially. First, check for
2660 // its immediate children.
2661 match module_.children.find(&name) {
2663 if name_bindings.defined_in_namespace(namespace) => {
2664 return Success(Target(module_, *name_bindings));
2666 Some(_) | None => { /* Not found; continue. */ }
2669 // Now check for its import directives. We don't have to have resolved
2670 // all its imports in the usual way; this is because chains of
2671 // adjacent import statements are processed as though they mutated the
2673 match module_.import_resolutions.find(&name) {
2675 // Not found; continue.
2677 Some(import_resolution) => {
2678 match (*import_resolution).target_for_namespace(namespace) {
2680 // Not found; continue.
2681 debug!("(resolving item in lexical scope) found \
2682 import resolution, but not in namespace %?",
2686 debug!("(resolving item in lexical scope) using \
2687 import resolution");
2688 import_resolution.state.used = true;
2689 return Success(copy target);
2695 // Search for external modules.
2696 if namespace == TypeNS {
2697 match module_.external_module_children.find(&name) {
2701 @mut Resolver::create_name_bindings_from_module(
2703 return Success(Target(module_, name_bindings));
2708 // Finally, proceed up the scope chain looking for parent modules.
2709 let mut search_module = module_;
2711 // Go to the next parent.
2712 match search_module.parent_link {
2714 // No more parents. This module was unresolved.
2715 debug!("(resolving item in lexical scope) unresolved \
2719 ModuleParentLink(parent_module_node, _) => {
2720 match search_through_modules {
2721 DontSearchThroughModules => {
2722 match search_module.kind {
2723 NormalModuleKind => {
2724 // We stop the search here.
2725 debug!("(resolving item in lexical \
2726 scope) unresolved module: not \
2727 searching through module \
2733 AnonymousModuleKind => {
2734 search_module = parent_module_node;
2738 SearchThroughModules => {
2739 search_module = parent_module_node;
2743 BlockParentLink(parent_module_node, _) => {
2744 search_module = parent_module_node;
2748 // Resolve the name in the parent module.
2749 match self.resolve_name_in_module(search_module,
2752 SearchItemsAndAllImports) {
2754 // Continue up the search chain.
2757 // We couldn't see through the higher scope because of an
2758 // unresolved import higher up. Bail.
2760 debug!("(resolving item in lexical scope) indeterminate \
2761 higher scope; bailing");
2762 return Indeterminate;
2764 Success(target) => {
2765 // We found the module.
2766 return Success(copy target);
2772 /** Resolves a module name in the current lexical scope. */
2773 fn resolve_module_in_lexical_scope(@mut self,
2774 module_: @mut Module,
2776 -> ResolveResult<@mut Module> {
2777 // If this module is an anonymous module, resolve the item in the
2778 // lexical scope. Otherwise, resolve the item from the crate root.
2779 let resolve_result = self.resolve_item_in_lexical_scope(
2780 module_, name, TypeNS, DontSearchThroughModules);
2781 match resolve_result {
2782 Success(target) => {
2783 let bindings = &mut *target.bindings;
2784 match bindings.type_def {
2785 Some(ref type_def) => {
2786 match (*type_def).module_def {
2788 error!("!!! (resolving module in lexical \
2789 scope) module wasn't actually a \
2793 Some(module_def) => {
2794 return Success(module_def);
2799 error!("!!! (resolving module in lexical scope) module
2800 wasn't actually a module!");
2806 debug!("(resolving module in lexical scope) indeterminate; \
2808 return Indeterminate;
2811 debug!("(resolving module in lexical scope) failed to \
2819 * Returns the nearest normal module parent of the given module.
2821 fn get_nearest_normal_module_parent(@mut self, module_: @mut Module)
2822 -> Option<@mut Module> {
2823 let mut module_ = module_;
2825 match module_.parent_link {
2826 NoParentLink => return None,
2827 ModuleParentLink(new_module, _) |
2828 BlockParentLink(new_module, _) => {
2829 match new_module.kind {
2830 NormalModuleKind => return Some(new_module),
2833 AnonymousModuleKind => module_ = new_module,
2841 * Returns the nearest normal module parent of the given module, or the
2842 * module itself if it is a normal module.
2844 fn get_nearest_normal_module_parent_or_self(@mut self,
2845 module_: @mut Module)
2847 match module_.kind {
2848 NormalModuleKind => return module_,
2849 ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2850 match self.get_nearest_normal_module_parent(module_) {
2852 Some(new_module) => new_module
2859 * Resolves a "module prefix". A module prefix is one of (a) `self::`;
2860 * (b) some chain of `super::`.
2862 fn resolve_module_prefix(@mut self,
2863 module_: @mut Module,
2864 module_path: &[ident])
2865 -> ResolveResult<ModulePrefixResult> {
2866 let interner = self.session.parse_sess.interner;
2868 // Start at the current module if we see `self` or `super`, or at the
2869 // top of the crate otherwise.
2870 let mut containing_module;
2872 if *interner.get(module_path[0]) == ~"self" {
2874 self.get_nearest_normal_module_parent_or_self(module_);
2876 } else if *interner.get(module_path[0]) == ~"super" {
2878 self.get_nearest_normal_module_parent_or_self(module_);
2879 i = 0; // We'll handle `super` below.
2881 return Success(NoPrefixFound);
2884 // Now loop through all the `super`s we find.
2885 while i < module_path.len() &&
2886 *interner.get(module_path[i]) == ~"super" {
2887 debug!("(resolving module prefix) resolving `super` at %s",
2888 self.module_to_str(containing_module));
2889 match self.get_nearest_normal_module_parent(containing_module) {
2890 None => return Failed,
2891 Some(new_module) => {
2892 containing_module = new_module;
2898 debug!("(resolving module prefix) finished resolving prefix at %s",
2899 self.module_to_str(containing_module));
2901 return Success(PrefixFound(containing_module, i));
2904 /// Attempts to resolve the supplied name in the given module for the
2905 /// given namespace. If successful, returns the target corresponding to
2907 fn resolve_name_in_module(@mut self,
2908 module_: @mut Module,
2910 namespace: Namespace,
2911 name_search_type: NameSearchType)
2912 -> ResolveResult<Target> {
2913 debug!("(resolving name in module) resolving `%s` in `%s`",
2914 *self.session.str_of(name),
2915 self.module_to_str(module_));
2917 // First, check the direct children of the module.
2918 match module_.children.find(&name) {
2920 if name_bindings.defined_in_namespace(namespace) => {
2921 debug!("(resolving name in module) found node as child");
2922 return Success(Target(module_, *name_bindings));
2929 // Next, check the module's imports if necessary.
2931 // If this is a search of all imports, we should be done with glob
2932 // resolution at this point.
2933 if name_search_type == SearchItemsAndAllImports {
2934 assert!(module_.glob_count == 0);
2937 // Check the list of resolved imports.
2938 match module_.import_resolutions.find(&name) {
2939 Some(import_resolution) => {
2940 if import_resolution.privacy == Public &&
2941 import_resolution.outstanding_references != 0 {
2942 debug!("(resolving name in module) import \
2943 unresolved; bailing out");
2944 return Indeterminate;
2947 match import_resolution.target_for_namespace(namespace) {
2949 debug!("(resolving name in module) name found, \
2950 but not in namespace %?",
2954 if name_search_type ==
2955 SearchItemsAndAllImports ||
2956 import_resolution.privacy == Public => {
2957 debug!("(resolving name in module) resolved to \
2959 import_resolution.state.used = true;
2960 return Success(copy target);
2963 debug!("(resolving name in module) name found, \
2968 None => {} // Continue.
2971 // Finally, search through external children.
2972 if namespace == TypeNS {
2973 match module_.external_module_children.find(&name) {
2977 @mut Resolver::create_name_bindings_from_module(
2979 return Success(Target(module_, name_bindings));
2984 // We're out of luck.
2985 debug!("(resolving name in module) failed to resolve %s",
2986 *self.session.str_of(name));
2990 fn report_unresolved_imports(@mut self, module_: @mut Module) {
2991 let index = module_.resolved_import_count;
2992 let imports: &mut ~[@ImportDirective] = &mut *module_.imports;
2993 let import_count = imports.len();
2994 if index != import_count {
2995 let sn = self.session.codemap.span_to_snippet(imports[index].span);
2996 if str::contains(sn, "::") {
2997 self.session.span_err(imports[index].span, ~"unresolved import");
2999 let err = fmt!("unresolved import (maybe you meant `%s::*`?)",
3000 sn.slice(0, sn.len() - 1)); // -1 to adjust for semicolon
3001 self.session.span_err(imports[index].span, err);
3005 // Descend into children and anonymous children.
3006 for module_.children.each_value |&child_node| {
3007 match child_node.get_module_if_available() {
3011 Some(child_module) => {
3012 self.report_unresolved_imports(child_module);
3017 for module_.anonymous_children.each_value |&module_| {
3018 self.report_unresolved_imports(module_);
3024 // This pass simply determines what all "export" keywords refer to and
3025 // writes the results into the export map.
3027 // FIXME #4953 This pass will be removed once exports change to per-item.
3028 // Then this operation can simply be performed as part of item (or import)
3031 fn record_exports(@mut self) {
3032 let root_module = self.graph_root.get_module();
3033 self.record_exports_for_module_subtree(root_module);
3036 fn record_exports_for_module_subtree(@mut self, module_: @mut Module) {
3037 // If this isn't a local crate, then bail out. We don't need to record
3038 // exports for nonlocal crates.
3040 match module_.def_id {
3041 Some(def_id) if def_id.crate == local_crate => {
3043 debug!("(recording exports for module subtree) recording \
3044 exports for local module");
3047 // Record exports for the root module.
3048 debug!("(recording exports for module subtree) recording \
3049 exports for root module");
3053 debug!("(recording exports for module subtree) not recording \
3055 self.module_to_str(module_));
3060 self.record_exports_for_module(module_);
3062 for module_.children.each_value |&child_name_bindings| {
3063 match child_name_bindings.get_module_if_available() {
3067 Some(child_module) => {
3068 self.record_exports_for_module_subtree(child_module);
3073 for module_.anonymous_children.each_value |&child_module| {
3074 self.record_exports_for_module_subtree(child_module);
3078 fn record_exports_for_module(@mut self, module_: @mut Module) {
3079 let mut exports2 = ~[];
3081 self.add_exports_for_module(&mut exports2, module_);
3082 match /*bad*/copy module_.def_id {
3084 self.export_map2.insert(def_id.node, exports2);
3085 debug!("(computing exports) writing exports for %d (some)",
3092 fn add_exports_of_namebindings(@mut self,
3093 exports2: &mut ~[Export2],
3095 namebindings: @mut NameBindings,
3098 match (namebindings.def_for_namespace(ns),
3099 namebindings.privacy_for_namespace(ns)) {
3100 (Some(d), Some(Public)) => {
3101 debug!("(computing exports) YES: %s '%s' => %?",
3102 if reexport { ~"reexport" } else { ~"export"},
3103 *self.session.str_of(ident),
3105 exports2.push(Export2 {
3107 name: self.session.str_of(ident),
3108 def_id: def_id_of_def(d)
3111 (Some(_), Some(privacy)) => {
3112 debug!("(computing reexports) NO: privacy %?", privacy);
3115 debug!("(computing reexports) NO: %?, %?", d_opt, p_opt);
3120 fn add_exports_for_module(@mut self,
3121 exports2: &mut ~[Export2],
3122 module_: @mut Module) {
3123 for module_.children.each |ident, namebindings| {
3124 debug!("(computing exports) maybe export '%s'",
3125 *self.session.str_of(*ident));
3126 self.add_exports_of_namebindings(&mut *exports2,
3131 self.add_exports_of_namebindings(&mut *exports2,
3138 for module_.import_resolutions.each |ident, importresolution| {
3139 if importresolution.privacy != Public {
3140 debug!("(computing exports) not reexporting private `%s`",
3141 *self.session.str_of(*ident));
3144 for [ TypeNS, ValueNS ].each |ns| {
3145 match importresolution.target_for_namespace(*ns) {
3147 debug!("(computing exports) maybe reexport '%s'",
3148 *self.session.str_of(*ident));
3149 self.add_exports_of_namebindings(&mut *exports2,
3163 // We maintain a list of value ribs and type ribs.
3165 // Simultaneously, we keep track of the current position in the module
3166 // graph in the `current_module` pointer. When we go to resolve a name in
3167 // the value or type namespaces, we first look through all the ribs and
3168 // then query the module graph. When we resolve a name in the module
3169 // namespace, we can skip all the ribs (since nested modules are not
3170 // allowed within blocks in Rust) and jump straight to the current module
3173 // Named implementations are handled separately. When we find a method
3174 // call, we consult the module node to find all of the implementations in
3175 // scope. This information is lazily cached in the module node. We then
3176 // generate a fake "implementation scope" containing all the
3177 // implementations thus found, for compatibility with old resolve pass.
3179 fn with_scope(@mut self, name: Option<ident>, f: &fn()) {
3180 let orig_module = self.current_module;
3182 // Move down in the graph.
3188 match orig_module.children.find(&name) {
3190 debug!("!!! (with scope) didn't find `%s` in `%s`",
3191 *self.session.str_of(name),
3192 self.module_to_str(orig_module));
3194 Some(name_bindings) => {
3195 match (*name_bindings).get_module_if_available() {
3197 debug!("!!! (with scope) didn't find module \
3199 *self.session.str_of(name),
3200 self.module_to_str(orig_module));
3203 self.current_module = module_;
3213 self.current_module = orig_module;
3216 // Wraps the given definition in the appropriate number of `def_upvar`
3219 fn upvarify(@mut self,
3224 allow_capturing_self: AllowCapturingSelfFlag)
3225 -> Option<def_like> {
3230 dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
3231 dl_def(d @ def_arg(*)) | dl_def(d @ def_binding(*)) => {
3233 is_ty_param = false;
3235 dl_def(d @ def_ty_param(*)) => {
3239 dl_def(d @ def_self(*))
3240 if allow_capturing_self == DontAllowCapturingSelf => {
3242 is_ty_param = false;
3245 return Some(def_like);
3249 let mut rib_index = rib_index + 1;
3250 while rib_index < ribs.len() {
3251 match ribs[rib_index].kind {
3253 // Nothing to do. Continue.
3255 FunctionRibKind(function_id, body_id) => {
3257 def = def_upvar(def_id_of_def(def).node,
3263 MethodRibKind(item_id, _) => {
3264 // If the def is a ty param, and came from the parent
3267 def_ty_param(did, _)
3268 if self.def_map.find(&did.node).map_consume(|x| *x)
3269 == Some(def_typaram_binder(item_id)) => {
3274 // This was an attempt to access an upvar inside a
3275 // named function item. This is not allowed, so we
3278 self.session.span_err(
3280 ~"attempted dynamic environment-capture");
3282 // This was an attempt to use a type parameter outside
3285 self.session.span_err(span,
3286 ~"attempt to use a type \
3287 argument out of scope");
3294 OpaqueFunctionRibKind => {
3296 // This was an attempt to access an upvar inside a
3297 // named function item. This is not allowed, so we
3300 self.session.span_err(
3302 ~"attempted dynamic environment-capture");
3304 // This was an attempt to use a type parameter outside
3307 self.session.span_err(span,
3308 ~"attempt to use a type \
3309 argument out of scope");
3314 ConstantItemRibKind => {
3315 // Still doesn't deal with upvars
3316 self.session.span_err(span,
3317 ~"attempt to use a non-constant \
3318 value in a constant");
3326 return Some(dl_def(def));
3329 fn search_ribs(@mut self,
3333 allow_capturing_self: AllowCapturingSelfFlag)
3334 -> Option<def_like> {
3335 // FIXME #4950: This should not use a while loop.
3336 // FIXME #4950: Try caching?
3338 let mut i = ribs.len();
3341 match ribs[i].bindings.find(&name) {
3342 Some(&def_like) => {
3343 return self.upvarify(ribs, i, def_like, span,
3344 allow_capturing_self);
3355 fn resolve_crate(@mut self) {
3356 debug!("(resolving crate) starting");
3358 visit_crate(self.crate, (), mk_vt(@Visitor {
3359 visit_item: |item, _context, visitor|
3360 self.resolve_item(item, visitor),
3361 visit_arm: |arm, _context, visitor|
3362 self.resolve_arm(arm, visitor),
3363 visit_block: |block, _context, visitor|
3364 self.resolve_block(block, visitor),
3365 visit_expr: |expr, _context, visitor|
3366 self.resolve_expr(expr, visitor),
3367 visit_local: |local, _context, visitor|
3368 self.resolve_local(local, visitor),
3369 visit_ty: |ty, _context, visitor|
3370 self.resolve_type(ty, visitor),
3371 .. *default_visitor()
3375 fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
3376 debug!("(resolving item) resolving %s",
3377 *self.session.str_of(item.ident));
3379 // Items with the !resolve_unexported attribute are X-ray contexts.
3380 // This is used to allow the test runner to run unexported tests.
3381 let orig_xray_flag = self.xray_context;
3382 if contains_name(attr_metas(item.attrs),
3383 ~"!resolve_unexported") {
3384 self.xray_context = Xray;
3389 // enum item: resolve all the variants' discrs,
3390 // then resolve the ty params
3391 item_enum(ref enum_def, ref generics) => {
3392 for (*enum_def).variants.each() |variant| {
3393 for variant.node.disr_expr.each |dis_expr| {
3394 // resolve the discriminator expr
3396 self.with_constant_rib(|| {
3397 self.resolve_expr(*dis_expr, visitor);
3402 // n.b. the discr expr gets visted twice.
3403 // but maybe it's okay since the first time will signal an
3404 // error if there is one? -- tjc
3405 do self.with_type_parameter_rib(
3407 generics, item.id, 0, NormalRibKind)) {
3408 visit_item(item, (), visitor);
3412 item_ty(_, ref generics) => {
3413 do self.with_type_parameter_rib
3414 (HasTypeParameters(generics, item.id, 0,
3418 visit_item(item, (), visitor);
3422 item_impl(ref generics,
3426 self.resolve_implementation(item.id,
3434 item_trait(ref generics, ref traits, ref methods) => {
3435 // Create a new rib for the self type.
3436 let self_type_rib = @Rib(NormalRibKind);
3437 self.type_ribs.push(self_type_rib);
3438 self_type_rib.bindings.insert(self.type_self_ident,
3439 dl_def(def_self_ty(item.id)));
3441 // Create a new rib for the trait-wide type parameters.
3442 do self.with_type_parameter_rib
3443 (HasTypeParameters(generics, item.id, 0,
3446 self.resolve_type_parameters(&generics.ty_params,
3449 // Resolve derived traits.
3450 for traits.each |trt| {
3451 match self.resolve_path(trt.path, TypeNS, true,
3454 self.session.span_err(trt.path.span,
3455 ~"attempt to derive a \
3456 nonexistent trait"),
3458 // Write a mapping from the trait ID to the
3459 // definition of the trait into the definition
3462 debug!("(resolving trait) found trait def: \
3465 self.record_def(trt.ref_id, def);
3470 for (*methods).each |method| {
3471 // Create a new rib for the method-specific type
3474 // FIXME #4951: Do we need a node ID here?
3477 required(ref ty_m) => {
3478 do self.with_type_parameter_rib
3479 (HasTypeParameters(&ty_m.generics,
3481 generics.ty_params.len(),
3482 MethodRibKind(item.id, Required))) {
3484 // Resolve the method-specific type
3486 self.resolve_type_parameters(
3487 &ty_m.generics.ty_params,
3490 for ty_m.decl.inputs.each |argument| {
3491 self.resolve_type(argument.ty, visitor);
3494 self.resolve_type(ty_m.decl.output, visitor);
3498 self.resolve_method(MethodRibKind(item.id,
3501 generics.ty_params.len(),
3508 self.type_ribs.pop();
3511 item_struct(ref struct_def, ref generics) => {
3512 self.resolve_struct(item.id,
3519 item_mod(ref module_) => {
3520 do self.with_scope(Some(item.ident)) {
3521 self.resolve_module(module_, item.span, item.ident,
3526 item_foreign_mod(ref foreign_module) => {
3527 do self.with_scope(Some(item.ident)) {
3528 for foreign_module.items.each |foreign_item| {
3529 match foreign_item.node {
3530 foreign_item_fn(_, _, ref generics) => {
3531 self.with_type_parameter_rib(
3533 generics, foreign_item.id, 0,
3535 || visit_foreign_item(*foreign_item, (),
3538 foreign_item_const(_) => {
3539 visit_foreign_item(*foreign_item, (),
3547 item_fn(ref fn_decl, _, _, ref generics, ref block) => {
3548 // If this is the main function, we must record it in the
3551 // FIXME #4404 android JNI hacks
3552 if !*self.session.building_library ||
3553 self.session.targ_cfg.os == session::os_android {
3555 if self.attr_main_fn.is_none() &&
3556 item.ident == special_idents::main {
3558 self.main_fns.push(Some((item.id, item.span)));
3561 if attrs_contains_name(item.attrs, ~"main") {
3562 if self.attr_main_fn.is_none() {
3563 self.attr_main_fn = Some((item.id, item.span));
3565 self.session.span_err(
3567 ~"multiple 'main' functions");
3571 if attrs_contains_name(item.attrs, ~"start") {
3572 if self.start_fn.is_none() {
3573 self.start_fn = Some((item.id, item.span));
3575 self.session.span_err(
3577 ~"multiple 'start' functions");
3582 self.resolve_function(OpaqueFunctionRibKind,
3588 OpaqueFunctionRibKind),
3595 self.with_constant_rib(|| {
3596 visit_item(item, (), visitor);
3601 fail!(~"item macros unimplemented")
3605 self.xray_context = orig_xray_flag;
3608 fn with_type_parameter_rib(@mut self,
3609 type_parameters: TypeParameters,
3611 match type_parameters {
3612 HasTypeParameters(generics, node_id, initial_index,
3615 let function_type_rib = @Rib(rib_kind);
3616 self.type_ribs.push(function_type_rib);
3618 for generics.ty_params.eachi |index, type_parameter| {
3619 let name = type_parameter.ident;
3620 debug!("with_type_parameter_rib: %d %d", node_id,
3622 let def_like = dl_def(def_ty_param
3623 (local_def(type_parameter.id),
3624 index + initial_index));
3625 // Associate this type parameter with
3626 // the item that bound it
3627 self.record_def(type_parameter.id,
3628 def_typaram_binder(node_id));
3629 function_type_rib.bindings.insert(name, def_like);
3633 NoTypeParameters => {
3640 match type_parameters {
3641 HasTypeParameters(*) => {
3642 self.type_ribs.pop();
3645 NoTypeParameters => {
3651 fn with_label_rib(@mut self, f: &fn()) {
3652 self.label_ribs.push(@Rib(NormalRibKind));
3654 self.label_ribs.pop();
3657 fn with_constant_rib(@mut self, f: &fn()) {
3658 self.value_ribs.push(@Rib(ConstantItemRibKind));
3660 self.value_ribs.pop();
3663 fn resolve_function(@mut self,
3665 optional_declaration: Option<&fn_decl>,
3666 type_parameters: TypeParameters,
3668 self_binding: SelfBinding,
3669 visitor: ResolveVisitor) {
3670 // Create a value rib for the function.
3671 let function_value_rib = @Rib(rib_kind);
3672 self.value_ribs.push(function_value_rib);
3674 // Create a label rib for the function.
3675 let function_label_rib = @Rib(rib_kind);
3676 self.label_ribs.push(function_label_rib);
3678 // If this function has type parameters, add them now.
3679 do self.with_type_parameter_rib(type_parameters) {
3680 // Resolve the type parameters.
3681 match type_parameters {
3682 NoTypeParameters => {
3685 HasTypeParameters(ref generics, _, _, _) => {
3686 self.resolve_type_parameters(&generics.ty_params,
3691 // Add self to the rib, if necessary.
3692 match self_binding {
3696 HasSelfBinding(self_node_id, is_implicit) => {
3697 let def_like = dl_def(def_self(self_node_id,
3699 (*function_value_rib).bindings.insert(self.self_ident,
3704 // Add each argument to the rib.
3705 match optional_declaration {
3709 Some(declaration) => {
3710 for declaration.inputs.each |argument| {
3711 let binding_mode = ArgumentIrrefutableMode;
3713 if argument.is_mutbl {Mutable} else {Immutable};
3714 self.resolve_pattern(argument.pat,
3720 self.resolve_type(argument.ty, visitor);
3722 debug!("(resolving function) recorded argument");
3725 self.resolve_type(declaration.output, visitor);
3729 // Resolve the function body.
3730 self.resolve_block(block, visitor);
3732 debug!("(resolving function) leaving function");
3735 self.label_ribs.pop();
3736 self.value_ribs.pop();
3739 fn resolve_type_parameters(@mut self,
3740 type_parameters: &OptVec<TyParam>,
3741 visitor: ResolveVisitor) {
3742 for type_parameters.each |type_parameter| {
3743 for type_parameter.bounds.each |&bound| {
3745 TraitTyParamBound(tref) => {
3746 self.resolve_trait_reference(tref, visitor)
3748 RegionTyParamBound => {}
3754 fn resolve_trait_reference(@mut self,
3755 trait_reference: &trait_ref,
3756 visitor: ResolveVisitor) {
3757 match self.resolve_path(trait_reference.path, TypeNS, true, visitor) {
3759 self.session.span_err(trait_reference.path.span,
3760 ~"attempt to implement an \
3764 self.record_def(trait_reference.ref_id, def);
3769 fn resolve_struct(@mut self,
3771 generics: &Generics,
3772 fields: &[@struct_field],
3773 optional_destructor: &Option<struct_dtor>,
3774 visitor: ResolveVisitor) {
3775 // If applicable, create a rib for the type parameters.
3776 do self.with_type_parameter_rib(HasTypeParameters
3778 OpaqueFunctionRibKind)) {
3780 // Resolve the type parameters.
3781 self.resolve_type_parameters(&generics.ty_params, visitor);
3784 for fields.each |field| {
3785 self.resolve_type(field.node.ty, visitor);
3788 // Resolve the destructor, if applicable.
3789 match *optional_destructor {
3793 Some(ref destructor) => {
3794 self.resolve_function(NormalRibKind,
3797 &destructor.node.body,
3799 ((*destructor).node.self_id,
3807 // Does this really need to take a RibKind or is it always going
3808 // to be NormalRibKind?
3809 fn resolve_method(@mut self,
3812 outer_type_parameter_count: uint,
3813 visitor: ResolveVisitor) {
3814 let method_generics = &method.generics;
3815 let type_parameters =
3816 HasTypeParameters(method_generics,
3818 outer_type_parameter_count,
3820 // we only have self ty if it is a non static method
3821 let self_binding = match method.self_ty.node {
3822 sty_static => { NoSelfBinding }
3823 _ => { HasSelfBinding(method.self_id, false) }
3826 self.resolve_function(rib_kind,
3834 fn resolve_implementation(@mut self,
3836 generics: &Generics,
3837 opt_trait_reference: Option<@trait_ref>,
3839 methods: &[@method],
3840 visitor: ResolveVisitor) {
3841 // If applicable, create a rib for the type parameters.
3842 let outer_type_parameter_count = generics.ty_params.len();
3843 do self.with_type_parameter_rib(HasTypeParameters
3846 // Resolve the type parameters.
3847 self.resolve_type_parameters(&generics.ty_params,
3850 // Resolve the trait reference, if necessary.
3851 let original_trait_refs;
3852 match opt_trait_reference {
3853 Some(trait_reference) => {
3854 self.resolve_trait_reference(trait_reference, visitor);
3856 // Record the current set of trait references.
3857 let mut new_trait_refs = ~[];
3858 for self.def_map.find(&trait_reference.ref_id).each |&def| {
3859 new_trait_refs.push(def_id_of_def(*def));
3861 original_trait_refs = Some(util::replace(
3862 &mut self.current_trait_refs,
3863 Some(new_trait_refs)));
3866 original_trait_refs = None;
3870 // Resolve the self type.
3871 self.resolve_type(self_type, visitor);
3873 for methods.each |method| {
3874 // We also need a new scope for the method-specific
3876 self.resolve_method(MethodRibKind(
3878 Provided(method.id)),
3880 outer_type_parameter_count,
3883 let borrowed_type_parameters = &method.tps;
3884 self.resolve_function(MethodRibKind(
3886 Provided(method.id)),
3889 (borrowed_type_parameters,
3891 outer_type_parameter_count,
3894 HasSelfBinding(method.self_id),
3899 // Restore the original trait references.
3900 match original_trait_refs {
3901 Some(r) => { self.current_trait_refs = r; }
3907 fn resolve_module(@mut self,
3912 visitor: ResolveVisitor) {
3913 // Write the implementations in scope into the module metadata.
3914 debug!("(resolving module) resolving module ID %d", id);
3915 visit_mod(module_, span, id, (), visitor);
3918 fn resolve_local(@mut self, local: @local, visitor: ResolveVisitor) {
3919 let mutability = if local.node.is_mutbl {Mutable} else {Immutable};
3921 // Resolve the type.
3922 self.resolve_type(local.node.ty, visitor);
3924 // Resolve the initializer, if necessary.
3925 match local.node.init {
3929 Some(initializer) => {
3930 self.resolve_expr(initializer, visitor);
3934 // Resolve the pattern.
3935 self.resolve_pattern(local.node.pat, LocalIrrefutableMode, mutability,
3939 fn binding_mode_map(@mut self, pat: @pat) -> BindingMap {
3940 let mut result = HashMap::new();
3941 do pat_bindings(self.def_map, pat) |binding_mode, _id, sp, path| {
3942 let ident = path_to_ident(path);
3943 result.insert(ident,
3944 binding_info {span: sp,
3945 binding_mode: binding_mode});
3950 fn check_consistent_bindings(@mut self, arm: &arm) {
3951 if arm.pats.len() == 0 { return; }
3952 let map_0 = self.binding_mode_map(arm.pats[0]);
3953 for arm.pats.eachi() |i, p| {
3954 let map_i = self.binding_mode_map(*p);
3956 for map_0.each |&key, &binding_0| {
3957 match map_i.find(&key) {
3959 self.session.span_err(
3961 fmt!("variable `%s` from pattern #1 is \
3962 not bound in pattern #%u",
3963 *self.session.str_of(key), i + 1));
3965 Some(binding_i) => {
3966 if binding_0.binding_mode != binding_i.binding_mode {
3967 self.session.span_err(
3969 fmt!("variable `%s` is bound with different \
3970 mode in pattern #%u than in pattern #1",
3971 *self.session.str_of(key), i + 1));
3977 for map_i.each |&key, &binding| {
3978 if !map_0.contains_key(&key) {
3979 self.session.span_err(
3981 fmt!("variable `%s` from pattern #%u is \
3982 not bound in pattern #1",
3983 *self.session.str_of(key), i + 1));
3989 fn resolve_arm(@mut self, arm: &arm, visitor: ResolveVisitor) {
3990 self.value_ribs.push(@Rib(NormalRibKind));
3992 let bindings_list = @mut HashMap::new();
3993 for arm.pats.each |pattern| {
3994 self.resolve_pattern(*pattern, RefutableMode, Immutable,
3995 Some(bindings_list), visitor);
3998 // This has to happen *after* we determine which
3999 // pat_idents are variants
4000 self.check_consistent_bindings(arm);
4002 visit_expr_opt(arm.guard, (), visitor);
4003 self.resolve_block(&arm.body, visitor);
4005 self.value_ribs.pop();
4008 fn resolve_block(@mut self, block: &blk, visitor: ResolveVisitor) {
4009 debug!("(resolving block) entering block");
4010 self.value_ribs.push(@Rib(NormalRibKind));
4012 // Move down in the graph, if there's an anonymous module rooted here.
4013 let orig_module = self.current_module;
4014 match self.current_module.anonymous_children.find(&block.node.id) {
4015 None => { /* Nothing to do. */ }
4016 Some(&anonymous_module) => {
4017 debug!("(resolving block) found anonymous module, moving \
4019 self.current_module = anonymous_module;
4023 // Descend into the block.
4024 visit_block(block, (), visitor);
4027 self.current_module = orig_module;
4029 self.value_ribs.pop();
4030 debug!("(resolving block) leaving block");
4033 fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) {
4035 // Like path expressions, the interpretation of path types depends
4036 // on whether the path has multiple elements in it or not.
4038 ty_path(path, path_id) => {
4039 // This is a path in the type namespace. Walk through scopes
4040 // scopes looking for it.
4041 let mut result_def = None;
4043 // First, check to see whether the name is a primitive type.
4044 if path.idents.len() == 1 {
4045 let name = *path.idents.last();
4047 match self.primitive_type_table
4051 Some(&primitive_type) => {
4053 Some(def_prim_ty(primitive_type));
4063 match self.resolve_path(path, TypeNS, true, visitor) {
4065 debug!("(resolving type) resolved `%s` to \
4067 *self.session.str_of(
4068 *path.idents.last()),
4070 result_def = Some(def);
4084 // Write the result into the def map.
4085 debug!("(resolving type) writing resolution for `%s` \
4087 self.idents_to_str(path.idents),
4089 self.record_def(path_id, def);
4092 self.session.span_err
4093 (ty.span, fmt!("use of undeclared type name `%s`",
4094 self.idents_to_str(path.idents)));
4100 // Just resolve embedded types.
4101 visit_ty(ty, (), visitor);
4106 fn resolve_pattern(@mut self,
4108 mode: PatternBindingMode,
4109 mutability: Mutability,
4110 // Maps idents to the node ID for the (outermost)
4111 // pattern that binds them
4112 bindings_list: Option<@mut HashMap<ident,node_id>>,
4113 visitor: ResolveVisitor) {
4114 let pat_id = pattern.id;
4115 do walk_pat(pattern) |pattern| {
4116 match pattern.node {
4117 pat_ident(binding_mode, path, _)
4118 if !path.global && path.idents.len() == 1 => {
4120 // The meaning of pat_ident with no type parameters
4121 // depends on whether an enum variant or unit-like struct
4122 // with that name is in scope. The probing lookup has to
4123 // be careful not to emit spurious errors. Only matching
4124 // patterns (match) can match nullary variants or
4125 // unit-like structs. For binding patterns (let), matching
4126 // such a value is simply disallowed (since it's rarely
4129 let ident = path.idents[0];
4131 match self.resolve_bare_identifier_pattern(ident) {
4132 FoundStructOrEnumVariant(def)
4133 if mode == RefutableMode => {
4134 debug!("(resolving pattern) resolving `%s` to \
4135 struct or enum variant",
4136 *self.session.str_of(ident));
4138 self.enforce_default_binding_mode(
4142 self.record_def(pattern.id, def);
4144 FoundStructOrEnumVariant(_) => {
4145 self.session.span_err(pattern.span,
4146 fmt!("declaration of `%s` \
4148 variant or unit-like \
4153 FoundConst(def) if mode == RefutableMode => {
4154 debug!("(resolving pattern) resolving `%s` to \
4156 *self.session.str_of(ident));
4158 self.enforce_default_binding_mode(
4162 self.record_def(pattern.id, def);
4165 self.session.span_err(pattern.span,
4166 ~"only refutable patterns \
4169 BareIdentifierPatternUnresolved => {
4170 debug!("(resolving pattern) binding `%s`",
4171 *self.session.str_of(ident));
4173 let is_mutable = mutability == Mutable;
4175 let def = match mode {
4177 // For pattern arms, we must use
4178 // `def_binding` definitions.
4180 def_binding(pattern.id, binding_mode)
4182 LocalIrrefutableMode => {
4183 // But for locals, we use `def_local`.
4184 def_local(pattern.id, is_mutable)
4186 ArgumentIrrefutableMode => {
4187 // And for function arguments, `def_arg`.
4188 def_arg(pattern.id, is_mutable)
4192 // Record the definition so that later passes
4193 // will be able to distinguish variants from
4194 // locals in patterns.
4196 self.record_def(pattern.id, def);
4198 // Add the binding to the local ribs, if it
4199 // doesn't already exist in the bindings list. (We
4200 // must not add it if it's in the bindings list
4201 // because that breaks the assumptions later
4202 // passes make about or-patterns.)
4204 match bindings_list {
4206 if !bindings_list.contains_key(&ident) => {
4207 let this = &mut *self;
4208 let last_rib = this.value_ribs[
4209 this.value_ribs.len() - 1];
4210 last_rib.bindings.insert(ident,
4212 bindings_list.insert(ident, pat_id);
4215 if b.find(&ident) == Some(&pat_id) {
4216 // Then this is a duplicate variable
4217 // in the same disjunct, which is an
4219 self.session.span_err(pattern.span,
4220 fmt!("Identifier %s is bound more \
4221 than once in the same pattern",
4222 path_to_str(path, self.session
4225 // Not bound in the same pattern: do nothing
4228 let this = &mut *self;
4229 let last_rib = this.value_ribs[
4230 this.value_ribs.len() - 1];
4231 last_rib.bindings.insert(ident,
4238 // Check the types in the path pattern.
4239 for path.types.each |ty| {
4240 self.resolve_type(*ty, visitor);
4244 pat_ident(binding_mode, path, _) => {
4245 // This must be an enum variant, struct, or constant.
4246 match self.resolve_path(path, ValueNS, false, visitor) {
4247 Some(def @ def_variant(*)) |
4248 Some(def @ def_struct(*)) => {
4249 self.record_def(pattern.id, def);
4251 Some(def @ def_const(*)) => {
4252 self.enforce_default_binding_mode(
4256 self.record_def(pattern.id, def);
4259 self.session.span_err(
4261 fmt!("not an enum variant or constant: %s",
4262 *self.session.str_of(
4263 *path.idents.last())));
4266 self.session.span_err(path.span,
4267 ~"unresolved enum variant");
4271 // Check the types in the path pattern.
4272 for path.types.each |ty| {
4273 self.resolve_type(*ty, visitor);
4277 pat_enum(path, _) => {
4278 // This must be an enum variant, struct or const.
4279 match self.resolve_path(path, ValueNS, false, visitor) {
4280 Some(def @ def_fn(*)) |
4281 Some(def @ def_variant(*)) |
4282 Some(def @ def_struct(*)) |
4283 Some(def @ def_const(*)) => {
4284 self.record_def(pattern.id, def);
4287 self.session.span_err(
4289 fmt!("not an enum variant, struct or const: %s",
4290 *self.session.str_of(
4291 *path.idents.last())));
4294 self.session.span_err(path.span,
4295 ~"unresolved enum variant, \
4300 // Check the types in the path pattern.
4301 for path.types.each |ty| {
4302 self.resolve_type(*ty, visitor);
4307 self.resolve_expr(expr, visitor);
4310 pat_range(first_expr, last_expr) => {
4311 self.resolve_expr(first_expr, visitor);
4312 self.resolve_expr(last_expr, visitor);
4315 pat_struct(path, _, _) => {
4316 let structs: &mut HashSet<def_id> = &mut self.structs;
4317 match self.resolve_path(path, TypeNS, false, visitor) {
4318 Some(def_ty(class_id))
4319 if structs.contains(&class_id) => {
4320 let class_def = def_struct(class_id);
4321 self.record_def(pattern.id, class_def);
4323 Some(definition @ def_struct(class_id))
4324 if structs.contains(&class_id) => {
4325 self.record_def(pattern.id, definition);
4327 Some(definition @ def_variant(_, variant_id))
4328 if structs.contains(&variant_id) => {
4329 self.record_def(pattern.id, definition);
4332 debug!("(resolving pattern) didn't find struct \
4334 self.session.span_err(
4336 fmt!("`%s` does not name a structure",
4337 self.idents_to_str(path.idents)));
4349 fn resolve_bare_identifier_pattern(@mut self, name: ident)
4350 -> BareIdentifierPatternResolution {
4351 match self.resolve_item_in_lexical_scope(self.current_module,
4354 SearchThroughModules) {
4355 Success(target) => {
4356 match target.bindings.value_def {
4358 fail!(~"resolved name in the value namespace to a \
4359 set of name bindings with no def?!");
4363 def @ def_variant(*) | def @ def_struct(*) => {
4364 return FoundStructOrEnumVariant(def);
4366 def @ def_const(*) => {
4367 return FoundConst(def);
4370 return BareIdentifierPatternUnresolved;
4378 fail!(~"unexpected indeterminate result");
4382 return BareIdentifierPatternUnresolved;
4387 /// If `check_ribs` is true, checks the local definitions first; i.e.
4388 /// doesn't skip straight to the containing module.
4389 fn resolve_path(@mut self,
4391 namespace: Namespace,
4393 visitor: ResolveVisitor)
4395 // First, resolve the types.
4396 for path.types.each |ty| {
4397 self.resolve_type(*ty, visitor);
4401 return self.resolve_crate_relative_path(path,
4406 if path.idents.len() > 1 {
4407 return self.resolve_module_relative_path(path,
4412 return self.resolve_identifier(*path.idents.last(),
4418 fn resolve_identifier(@mut self,
4420 namespace: Namespace,
4425 match self.resolve_identifier_in_local_ribs(identifier,
4437 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4441 // FIXME #4952: Merge me with resolve_name_in_module?
4442 fn resolve_definition_of_name_in_module(@mut self,
4443 containing_module: @mut Module,
4445 namespace: Namespace,
4448 // First, search children.
4449 match containing_module.children.find(&name) {
4450 Some(child_name_bindings) => {
4451 match (child_name_bindings.def_for_namespace(namespace),
4452 child_name_bindings.privacy_for_namespace(namespace)) {
4453 (Some(def), Some(Public)) => {
4454 // Found it. Stop the search here.
4455 return ChildNameDefinition(def);
4457 (Some(def), _) if xray == Xray => {
4458 // Found it. Stop the search here.
4459 return ChildNameDefinition(def);
4461 (Some(_), _) | (None, _) => {
4471 // Next, search import resolutions.
4472 match containing_module.import_resolutions.find(&name) {
4473 Some(import_resolution) if import_resolution.privacy == Public ||
4475 match (*import_resolution).target_for_namespace(namespace) {
4477 match (target.bindings.def_for_namespace(namespace),
4478 target.bindings.privacy_for_namespace(
4480 (Some(def), Some(Public)) => {
4482 import_resolution.state.used = true;
4483 return ImportNameDefinition(def);
4485 (Some(_), _) | (None, _) => {
4486 // This can happen with external impls, due to
4487 // the imperfect way we read the metadata.
4494 Some(_) | None => {} // Continue.
4497 // Finally, search through external children.
4498 if namespace == TypeNS {
4499 match containing_module.external_module_children.find(&name) {
4502 match module.def_id {
4503 None => {} // Continue.
4505 return ChildNameDefinition(def_mod(def_id));
4512 return NoNameDefinition;
4515 fn intern_module_part_of_path(@mut self, path: @Path) -> ~[ident] {
4516 let mut module_path_idents = ~[];
4517 for path.idents.eachi |index, ident| {
4518 if index == path.idents.len() - 1 {
4522 module_path_idents.push(*ident);
4525 return module_path_idents;
4528 fn resolve_module_relative_path(@mut self,
4531 namespace: Namespace)
4533 let module_path_idents = self.intern_module_part_of_path(path);
4535 let containing_module;
4536 match self.resolve_module_path_for_import(self.current_module,
4541 self.session.span_err(path.span,
4542 fmt!("use of undeclared module `%s`",
4544 module_path_idents)));
4549 fail!(~"indeterminate unexpected");
4552 Success(resulting_module) => {
4553 containing_module = resulting_module;
4557 let name = *path.idents.last();
4558 match self.resolve_definition_of_name_in_module(containing_module,
4562 NoNameDefinition => {
4563 // We failed to resolve the name. Report an error.
4566 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4572 /// Invariant: This must be called only during main resolution, not during
4573 /// import resolution.
4574 fn resolve_crate_relative_path(@mut self,
4577 namespace: Namespace)
4579 let module_path_idents = self.intern_module_part_of_path(path);
4581 let root_module = self.graph_root.get_module();
4583 let containing_module;
4584 match self.resolve_module_path_from_root(root_module,
4588 SearchItemsAndAllImports) {
4590 self.session.span_err(path.span,
4591 fmt!("use of undeclared module `::%s`",
4593 module_path_idents)));
4598 fail!(~"indeterminate unexpected");
4601 Success(resulting_module) => {
4602 containing_module = resulting_module;
4606 let name = *path.idents.last();
4607 match self.resolve_definition_of_name_in_module(containing_module,
4611 NoNameDefinition => {
4612 // We failed to resolve the name. Report an error.
4615 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4621 fn resolve_identifier_in_local_ribs(@mut self,
4623 namespace: Namespace,
4626 // Check the local set of ribs.
4630 search_result = self.search_ribs(&mut self.value_ribs, ident,
4632 DontAllowCapturingSelf);
4635 search_result = self.search_ribs(&mut self.type_ribs, ident,
4636 span, AllowCapturingSelf);
4640 match search_result {
4641 Some(dl_def(def)) => {
4642 debug!("(resolving path in local ribs) resolved `%s` to \
4644 *self.session.str_of(ident),
4648 Some(dl_field) | Some(dl_impl(_)) | None => {
4654 fn resolve_item_by_identifier_in_lexical_scope(@mut self,
4656 namespace: Namespace)
4659 match self.resolve_item_in_lexical_scope(self.current_module,
4662 DontSearchThroughModules) {
4663 Success(target) => {
4664 match (*target.bindings).def_for_namespace(namespace) {
4666 // This can happen if we were looking for a type and
4667 // found a module instead. Modules don't have defs.
4671 debug!("(resolving item path in lexical scope) \
4672 resolved `%s` to item",
4673 *self.session.str_of(ident));
4679 fail!(~"unexpected indeterminate result");
4687 fn find_best_match_for_name(@mut self, name: &str, max_distance: uint) -> Option<~str> {
4688 let this = &mut *self;
4690 let mut maybes: ~[~str] = ~[];
4691 let mut values: ~[uint] = ~[];
4693 let mut j = this.value_ribs.len();
4696 for this.value_ribs[j].bindings.each_key |&k| {
4697 vec::push(&mut maybes, copy *this.session.str_of(k));
4698 vec::push(&mut values, uint::max_value);
4702 let mut smallest = 0;
4703 for vec::eachi(maybes) |i, &other| {
4705 values[i] = str::levdistance(name, other);
4707 if values[i] <= values[smallest] {
4712 if vec::len(values) > 0 &&
4713 values[smallest] != uint::max_value &&
4714 values[smallest] < str::len(name) + 2 &&
4715 values[smallest] <= max_distance &&
4716 maybes[smallest] != name.to_owned() {
4718 Some(vec::swap_remove(&mut maybes, smallest))
4725 fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
4726 let this = &mut *self;
4728 let mut i = this.type_ribs.len();
4731 match this.type_ribs[i].kind {
4732 MethodRibKind(node_id, _) =>
4733 for this.crate.node.module.items.each |item| {
4734 if item.id == node_id {
4736 item_struct(class_def, _) => {
4737 for vec::each(class_def.fields) |field| {
4738 match field.node.kind {
4739 unnamed_field => {},
4740 named_field(ident, _, _) => {
4741 if str::eq_slice(*this.session.str_of(ident),
4759 fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) {
4760 // First, record candidate traits for this expression if it could
4761 // result in the invocation of a method call.
4763 self.record_candidate_traits_for_expr_if_necessary(expr);
4765 // Next, resolve the node.
4767 // The interpretation of paths depends on whether the path has
4768 // multiple elements in it or not.
4770 expr_path(path) => {
4771 // This is a local path in the value namespace. Walk through
4772 // scopes looking for it.
4774 match self.resolve_path(path, ValueNS, true, visitor) {
4776 // Write the result into the def map.
4777 debug!("(resolving expr) resolved `%s`",
4778 self.idents_to_str(path.idents));
4779 self.record_def(expr.id, def);
4782 let wrong_name = self.idents_to_str(
4784 if self.name_exists_in_scope_struct(wrong_name) {
4785 self.session.span_err(expr.span,
4786 fmt!("unresolved name: `%s`. \
4787 Did you mean: `self.%s`?",
4792 // limit search to 5 to reduce the number
4793 // of stupid suggestions
4794 match self.find_best_match_for_name(wrong_name, 5) {
4796 self.session.span_err(expr.span,
4797 fmt!("unresolved name: `%s`. \
4798 Did you mean: `%s`?",
4802 self.session.span_err(expr.span,
4803 fmt!("unresolved name: `%s`.",
4811 visit_expr(expr, (), visitor);
4814 expr_fn_block(ref fn_decl, ref block) => {
4815 self.resolve_function(FunctionRibKind(expr.id, block.node.id),
4823 expr_struct(path, _, _) => {
4824 // Resolve the path to the structure it goes to.
4825 let structs: &mut HashSet<def_id> = &mut self.structs;
4826 match self.resolve_path(path, TypeNS, false, visitor) {
4827 Some(def_ty(class_id)) | Some(def_struct(class_id))
4828 if structs.contains(&class_id) => {
4829 let class_def = def_struct(class_id);
4830 self.record_def(expr.id, class_def);
4832 Some(definition @ def_variant(_, class_id))
4833 if structs.contains(&class_id) => {
4834 self.record_def(expr.id, definition);
4837 self.session.span_err(
4839 fmt!("`%s` does not name a structure",
4840 self.idents_to_str(path.idents)));
4844 visit_expr(expr, (), visitor);
4847 expr_loop(_, Some(label)) => {
4848 do self.with_label_rib {
4849 let this = &mut *self;
4850 let def_like = dl_def(def_label(expr.id));
4851 let rib = this.label_ribs[this.label_ribs.len() - 1];
4852 rib.bindings.insert(label, def_like);
4854 visit_expr(expr, (), visitor);
4858 expr_break(Some(label)) | expr_again(Some(label)) => {
4859 match self.search_ribs(&mut self.label_ribs, label, expr.span,
4860 DontAllowCapturingSelf) {
4862 self.session.span_err(expr.span,
4863 fmt!("use of undeclared label \
4865 *self.session.str_of(
4867 Some(dl_def(def @ def_label(_))) =>
4868 self.record_def(expr.id, def),
4870 self.session.span_bug(expr.span,
4871 ~"label wasn't mapped to a \
4877 visit_expr(expr, (), visitor);
4882 fn record_candidate_traits_for_expr_if_necessary(@mut self, expr: @expr) {
4884 expr_field(_, ident, _) => {
4885 let traits = self.search_for_traits_containing_method(ident);
4886 self.trait_map.insert(expr.id, @mut traits);
4888 expr_method_call(_, ident, _, _, _) => {
4889 let traits = self.search_for_traits_containing_method(ident);
4890 self.trait_map.insert(expr.id, @mut traits);
4892 expr_binary(add, _, _) | expr_assign_op(add, _, _) => {
4893 self.add_fixed_trait_for_expr(expr.id,
4894 self.lang_items.add_trait());
4896 expr_binary(subtract, _, _) | expr_assign_op(subtract, _, _) => {
4897 self.add_fixed_trait_for_expr(expr.id,
4898 self.lang_items.sub_trait());
4900 expr_binary(mul, _, _) | expr_assign_op(mul, _, _) => {
4901 self.add_fixed_trait_for_expr(expr.id,
4902 self.lang_items.mul_trait());
4904 expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
4905 self.add_fixed_trait_for_expr(expr.id,
4906 self.lang_items.div_trait());
4908 expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
4909 self.add_fixed_trait_for_expr(expr.id,
4910 self.lang_items.rem_trait());
4912 expr_binary(bitxor, _, _) | expr_assign_op(bitxor, _, _) => {
4913 self.add_fixed_trait_for_expr(expr.id,
4914 self.lang_items.bitxor_trait());
4916 expr_binary(bitand, _, _) | expr_assign_op(bitand, _, _) => {
4917 self.add_fixed_trait_for_expr(expr.id,
4918 self.lang_items.bitand_trait());
4920 expr_binary(bitor, _, _) | expr_assign_op(bitor, _, _) => {
4921 self.add_fixed_trait_for_expr(expr.id,
4922 self.lang_items.bitor_trait());
4924 expr_binary(shl, _, _) | expr_assign_op(shl, _, _) => {
4925 self.add_fixed_trait_for_expr(expr.id,
4926 self.lang_items.shl_trait());
4928 expr_binary(shr, _, _) | expr_assign_op(shr, _, _) => {
4929 self.add_fixed_trait_for_expr(expr.id,
4930 self.lang_items.shr_trait());
4932 expr_binary(lt, _, _) | expr_binary(le, _, _) |
4933 expr_binary(ge, _, _) | expr_binary(gt, _, _) => {
4934 self.add_fixed_trait_for_expr(expr.id,
4935 self.lang_items.ord_trait());
4937 expr_binary(eq, _, _) | expr_binary(ne, _, _) => {
4938 self.add_fixed_trait_for_expr(expr.id,
4939 self.lang_items.eq_trait());
4941 expr_unary(neg, _) => {
4942 self.add_fixed_trait_for_expr(expr.id,
4943 self.lang_items.neg_trait());
4945 expr_unary(not, _) => {
4946 self.add_fixed_trait_for_expr(expr.id,
4947 self.lang_items.not_trait());
4950 self.add_fixed_trait_for_expr(expr.id,
4951 self.lang_items.index_trait());
4959 fn search_for_traits_containing_method(@mut self,
4962 debug!("(searching for traits containing method) looking for '%s'",
4963 *self.session.str_of(name));
4965 let mut found_traits = ~[];
4966 let mut search_module = self.current_module;
4968 // Look for the current trait.
4969 match /*bad*/copy self.current_trait_refs {
4970 Some(trait_def_ids) => {
4971 for trait_def_ids.each |trait_def_id| {
4972 self.add_trait_info_if_containing_method(
4973 &mut found_traits, *trait_def_id, name);
4981 // Look for trait children.
4982 for search_module.children.each_value |&child_name_bindings| {
4983 match child_name_bindings.def_for_namespace(TypeNS) {
4986 def_trait(trait_def_id) => {
4987 self.add_trait_info_if_containing_method(
4988 &mut found_traits, trait_def_id, name);
5001 // Look for imports.
5002 for search_module.import_resolutions.each_value
5003 |&import_resolution| {
5005 match import_resolution.target_for_namespace(TypeNS) {
5010 match target.bindings.def_for_namespace(TypeNS) {
5013 def_trait(trait_def_id) => {
5015 add_trait_info_if_containing_method(
5017 trait_def_id, name);
5019 import_resolution.state.used =
5036 // Move to the next parent.
5037 match search_module.parent_link {
5042 ModuleParentLink(parent_module, _) |
5043 BlockParentLink(parent_module, _) => {
5044 search_module = parent_module;
5049 return found_traits;
5052 fn add_trait_info_if_containing_method(&self,
5053 found_traits: &mut ~[def_id],
5054 trait_def_id: def_id,
5057 debug!("(adding trait info if containing method) trying trait %d:%d \
5061 *self.session.str_of(name));
5063 match self.trait_info.find(&trait_def_id) {
5064 Some(trait_info) if trait_info.contains(&name) => {
5065 debug!("(adding trait info if containing method) found trait \
5066 %d:%d for method '%s'",
5069 *self.session.str_of(name));
5070 found_traits.push(trait_def_id);
5079 fn add_fixed_trait_for_expr(@mut self,
5082 self.trait_map.insert(expr_id, @mut ~[trait_id]);
5085 fn record_def(@mut self, node_id: node_id, def: def) {
5086 debug!("(recording def) recording %? for %?", def, node_id);
5087 self.def_map.insert(node_id, def);
5090 fn enforce_default_binding_mode(@mut self,
5092 pat_binding_mode: binding_mode,
5094 match pat_binding_mode {
5097 self.session.span_err(
5099 fmt!("cannot use `copy` binding mode with %s",
5103 self.session.span_err(
5105 fmt!("cannot use `ref` binding mode with %s",
5112 // main function checking
5114 // be sure that there is only one main function
5116 fn check_duplicate_main(@mut self) {
5117 let this = &mut *self;
5118 if this.attr_main_fn.is_none() && this.start_fn.is_none() {
5119 if this.main_fns.len() >= 1u {
5121 while i < this.main_fns.len() {
5122 let (_, dup_main_span) = this.main_fns[i].unwrap();
5123 this.session.span_err(
5125 ~"multiple 'main' functions");
5128 *this.session.entry_fn = this.main_fns[0];
5129 *this.session.entry_type = Some(session::EntryMain);
5131 } else if !this.start_fn.is_none() {
5132 *this.session.entry_fn = this.start_fn;
5133 *this.session.entry_type = Some(session::EntryStart);
5135 *this.session.entry_fn = this.attr_main_fn;
5136 *this.session.entry_type = Some(session::EntryMain);
5141 // Unused import checking
5143 // Although this is a lint pass, it lives in here because it depends on
5144 // resolve data structures.
5147 fn unused_import_lint_level(@mut self, m: @mut Module) -> level {
5148 let settings = self.session.lint_settings;
5150 Some(def) => get_lint_settings_level(settings, unused_imports,
5151 def.node, def.node),
5152 None => get_lint_level(settings.default_settings, unused_imports)
5156 fn check_for_unused_imports_if_necessary(@mut self) {
5157 if self.unused_import_lint_level(self.current_module) == allow {
5161 let root_module = self.graph_root.get_module();
5162 self.check_for_unused_imports_in_module_subtree(root_module);
5165 fn check_for_unused_imports_in_module_subtree(@mut self,
5166 module_: @mut Module) {
5167 // If this isn't a local crate, then bail out. We don't need to check
5168 // for unused imports in external crates.
5170 match module_.def_id {
5171 Some(def_id) if def_id.crate == local_crate => {
5175 // Check for unused imports in the root module.
5179 debug!("(checking for unused imports in module subtree) not \
5180 checking for unused imports for `%s`",
5181 self.module_to_str(module_));
5186 self.check_for_unused_imports_in_module(module_);
5188 for module_.children.each_value |&child_name_bindings| {
5189 match (*child_name_bindings).get_module_if_available() {
5193 Some(child_module) => {
5194 self.check_for_unused_imports_in_module_subtree
5200 for module_.anonymous_children.each_value |&child_module| {
5201 self.check_for_unused_imports_in_module_subtree(child_module);
5205 fn check_for_unused_imports_in_module(@mut self, module_: @mut Module) {
5206 for module_.import_resolutions.each_value |&import_resolution| {
5207 // Ignore dummy spans for things like automatically injected
5208 // imports for the prelude, and also don't warn about the same
5209 // import statement being unused more than once. Furthermore, if
5210 // the import is public, then we can't be sure whether it's unused
5211 // or not so don't warn about it.
5212 if !import_resolution.state.used &&
5213 !import_resolution.state.warned &&
5214 import_resolution.span != dummy_sp() &&
5215 import_resolution.privacy != Public {
5216 import_resolution.state.warned = true;
5217 let span = import_resolution.span;
5218 self.session.span_lint_level(
5219 self.unused_import_lint_level(module_),
5230 // Diagnostics are not particularly efficient, because they're rarely
5234 /// A somewhat inefficient routine to obtain the name of a module.
5235 fn module_to_str(@mut self, module_: @mut Module) -> ~str {
5236 let mut idents = ~[];
5237 let mut current_module = module_;
5239 match current_module.parent_link {
5243 ModuleParentLink(module_, name) => {
5245 current_module = module_;
5247 BlockParentLink(module_, _) => {
5248 idents.push(special_idents::opaque);
5249 current_module = module_;
5254 if idents.len() == 0 {
5257 return self.idents_to_str(vec::reversed(idents));
5260 fn dump_module(@mut self, module_: @mut Module) {
5261 debug!("Dump of module `%s`:", self.module_to_str(module_));
5263 debug!("Children:");
5264 for module_.children.each_key |&name| {
5265 debug!("* %s", *self.session.str_of(name));
5268 debug!("Import resolutions:");
5269 for module_.import_resolutions.each |name, import_resolution| {
5271 match import_resolution.target_for_namespace(ValueNS) {
5272 None => { value_repr = ~""; }
5274 value_repr = ~" value:?";
5280 match import_resolution.target_for_namespace(TypeNS) {
5281 None => { type_repr = ~""; }
5283 type_repr = ~" type:?";
5288 debug!("* %s:%s%s", *self.session.str_of(*name),
5289 value_repr, type_repr);
5294 pub struct CrateMap {
5296 exp_map2: ExportMap2,
5300 /// Entry point to crate resolution.
5301 pub fn resolve_crate(session: Session,
5302 lang_items: LanguageItems,
5305 let resolver = @mut Resolver(session, lang_items, crate);
5307 let @Resolver{def_map, export_map2, trait_map, _} = resolver;
5310 exp_map2: export_map2,
5311 trait_map: trait_map