1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use driver::session::Session;
15 use metadata::csearch::{each_path, get_method_names_if_trait};
16 use metadata::csearch::{get_static_methods_if_impl, get_struct_fields};
17 use metadata::csearch::{get_type_name_if_impl};
18 use metadata::cstore::find_extern_mod_stmt_cnum;
19 use metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
20 use middle::lang_items::LanguageItems;
21 use middle::lint::{deny, allow, forbid, level, unused_imports, warn};
22 use middle::lint::{get_lint_level, get_lint_settings_level};
23 use middle::pat_util::{pat_bindings};
28 use syntax::ast::{RegionTyParamBound, TraitTyParamBound, _mod, add, arm};
29 use syntax::ast::{binding_mode, bitand, bitor, bitxor, blk};
30 use syntax::ast::{bind_infer, bind_by_ref, bind_by_copy};
31 use syntax::ast::{crate, crate_num, decl_item, def, def_arg, def_binding};
32 use syntax::ast::{def_const, def_foreign_mod, def_fn, def_id, def_label};
33 use syntax::ast::{def_local, def_mod, def_prim_ty, def_region, def_self};
34 use syntax::ast::{def_self_ty, def_static_method, def_struct, def_ty};
35 use syntax::ast::{def_ty_param, def_typaram_binder};
36 use syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
37 use syntax::ast::{expr_binary, expr_break, expr_cast, expr_field, expr_fn};
38 use syntax::ast::{expr_fn_block, expr_index, expr_method_call, expr_path};
39 use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
40 use syntax::ast::{def_upvar, def_use, def_variant, div, eq};
41 use syntax::ast::{enum_variant_kind, expr, expr_again, expr_assign_op};
42 use syntax::ast::{expr_fn_block, expr_index, expr_loop};
43 use syntax::ast::{expr_path, expr_struct, expr_unary, fn_decl};
44 use syntax::ast::{foreign_item, foreign_item_const, foreign_item_fn, ge};
45 use syntax::ast::{gt, ident, impure_fn, inherited, item, item_struct};
46 use syntax::ast::{item_const, item_enum, item_fn, item_foreign_mod};
47 use syntax::ast::{item_impl, item_mac, item_mod, item_trait, item_ty, le};
48 use syntax::ast::{local, local_crate, lt, method, mode, module_ns, mul};
49 use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident};
50 use syntax::ast::{path, pat_box, pat_lit, pat_range, pat_rec, pat_struct};
51 use syntax::ast::{pat_tup, pat_uniq, pat_wild, prim_ty, private, provided};
52 use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl};
53 use syntax::ast::{struct_dtor, struct_field, struct_variant_kind, sty_by_ref};
54 use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty};
55 use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i};
56 use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path};
57 use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
58 use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
59 use syntax::ast::{variant, view_item, view_item_extern_mod};
60 use syntax::ast::{view_item_use, view_path_glob, view_path_list};
61 use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
62 use syntax::ast::{unsafe_fn};
63 use syntax::ast_util::{def_id_of_def, local_def};
64 use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
65 use syntax::ast_util::{Privacy, Public, Private};
66 use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy};
67 use syntax::attr::{attr_metas, contains_name, attrs_contains_name};
68 use syntax::parse::token::ident_interner;
69 use syntax::parse::token::special_idents;
70 use syntax::print::pprust::{pat_to_str, path_to_str};
71 use syntax::codemap::{span, dummy_sp};
72 use syntax::visit::{default_visitor, fk_method, mk_vt, Visitor, visit_block};
73 use syntax::visit::{visit_crate, visit_expr, visit_expr_opt, visit_fn};
74 use syntax::visit::{visit_foreign_item, visit_item, visit_method_helper};
75 use syntax::visit::{visit_mod, visit_ty, vt};
79 use option::{Some, get, is_some, is_none};
80 use str::{connect, split_str};
83 use std::list::{Cons, List, Nil};
84 use std::oldmap::HashMap;
88 pub type DefMap = HashMap<node_id,def>;
90 pub struct binding_info {
92 binding_mode: binding_mode,
95 // Map from the name in a pattern to its binding mode.
96 pub type BindingMap = HashMap<ident,binding_info>;
98 // Implementation resolution
100 // FIXME #4946: This kind of duplicates information kept in
101 // ty::method. Maybe it should go away.
103 pub struct MethodInfo {
113 methods: ~[@MethodInfo]
116 // Trait method resolution
117 pub type TraitMap = @HashMap<node_id,@DVec<def_id>>;
119 // This is the replacement export map. It maps a module to all of the exports
121 pub type ExportMap2 = HashMap<node_id, ~[Export2]>;
124 name: @~str, // The name of the target.
125 def_id: def_id, // The definition of the target.
126 reexport: bool, // Whether this is a reexport.
130 pub enum PatternBindingMode {
132 LocalIrrefutableMode,
133 ArgumentIrrefutableMode(mode)
141 /// A NamespaceResult represents the result of resolving an import in
142 /// a particular namespace. The result is either definitely-resolved,
143 /// definitely- unresolved, or unknown.
144 pub enum NamespaceResult {
145 /// Means that resolve hasn't gathered enough information yet to determine
146 /// whether the name is bound in this namespace. (That is, it hasn't
147 /// resolved all `use` directives yet.)
149 /// Means that resolve has determined that the name is definitely
150 /// not bound in the namespace.
152 /// Means that resolve has determined that the name is bound in the Module
153 /// argument, and specified by the NameBindings argument.
154 BoundResult(@mut Module, @mut NameBindings)
157 pub impl NamespaceResult {
158 pure fn is_unknown(&self) -> bool {
160 UnknownResult => true,
166 pub enum NameDefinition {
167 NoNameDefinition, //< The name was unbound.
168 ChildNameDefinition(def), //< The name identifies an immediate child.
169 ImportNameDefinition(def) //< The name identifies an import.
174 pub enum Mutability {
179 pub enum SelfBinding {
181 HasSelfBinding(node_id, bool /* is implicit */)
184 pub type ResolveVisitor = vt<()>;
187 pub enum ImportDirectiveNS {
192 /// Contains data for specific types of import directives.
193 pub enum ImportDirectiveSubclass {
194 SingleImport(ident /* target */, ident /* source */, ImportDirectiveNS),
198 /// The context that we thread through while building the reduced graph.
199 pub enum ReducedGraphParent {
200 ModuleReducedGraphParent(@mut Module)
203 pub enum ResolveResult<T> {
204 Failed, // Failed to resolve the name.
205 Indeterminate, // Couldn't determine due to unresolved globs.
206 Success(T) // Successfully resolved the import.
209 pub impl<T> ResolveResult<T> {
210 fn failed(&self) -> bool {
211 match *self { Failed => true, _ => false }
213 fn indeterminate(&self) -> bool {
214 match *self { Indeterminate => true, _ => false }
218 pub enum TypeParameters/& {
219 NoTypeParameters, //< No type parameters.
220 HasTypeParameters(&~[ty_param], //< Type parameters.
221 node_id, //< ID of the enclosing item
223 // The index to start numbering the type parameters at.
224 // This is zero if this is the outermost set of type
225 // parameters, or equal to the number of outer type
226 // parameters. For example, if we have:
229 // fn method<U>() { ... }
232 // The index at the method site will be 1, because the
233 // outer T had index 0.
237 // The kind of the rib used for type parameters.
241 // The rib kind controls the translation of argument or local definitions
242 // (`def_arg` or `def_local`) to upvars (`def_upvar`).
245 // No translation needs to be applied.
248 // We passed through a function scope at the given node ID. Translate
249 // upvars as appropriate.
250 FunctionRibKind(node_id /* func id */, node_id /* body id */),
252 // We passed through an impl or trait and are now in one of its
253 // methods. Allow references to ty params that that impl or trait
254 // binds. Disallow any other upvars (including other ty params that are
256 // parent; method itself
257 MethodRibKind(node_id, MethodSort),
259 // We passed through a function *item* scope. Disallow upvars.
260 OpaqueFunctionRibKind,
262 // We're in a constant item. Can't refer to dynamic stuff.
266 // Methods can be required or provided. Required methods only occur in traits.
267 pub enum MethodSort {
272 // The X-ray flag indicates that a context has the X-ray privilege, which
273 // allows it to reference private names. Currently, this is used for the test
276 // FIXME #4947: The X-ray flag is kind of questionable in the first
277 // place. It might be better to introduce an expr_xray_path instead.
281 NoXray, //< Private items cannot be accessed.
282 Xray //< Private items can be accessed.
285 pub enum UseLexicalScopeFlag {
290 pub enum SearchThroughModulesFlag {
291 DontSearchThroughModules,
295 pub enum ModulePrefixResult {
297 PrefixFound(@mut Module, uint)
301 pub enum AllowCapturingSelfFlag {
302 AllowCapturingSelf, //< The "self" definition can be captured.
303 DontAllowCapturingSelf, //< The "self" definition cannot be captured.
306 pub enum BareIdentifierPatternResolution {
307 FoundStructOrEnumVariant(def),
309 BareIdentifierPatternUnresolved
312 // Specifies how duplicates should be handled when adding a child item if
313 // another item exists with the same name in some namespace.
315 pub enum DuplicateCheckingMode {
316 ForbidDuplicateModules,
317 ForbidDuplicateTypes,
318 ForbidDuplicateValues,
319 ForbidDuplicateTypesAndValues,
323 // Returns the namespace associated with the given duplicate checking mode,
324 // or fails for OverwriteDuplicates. This is used for error messages.
325 pub fn namespace_for_duplicate_checking_mode(mode: DuplicateCheckingMode)
328 ForbidDuplicateModules | ForbidDuplicateTypes |
329 ForbidDuplicateTypesAndValues => TypeNS,
330 ForbidDuplicateValues => ValueNS,
331 OverwriteDuplicates => fail!(~"OverwriteDuplicates has no namespace")
337 bindings: HashMap<ident,def_like>,
341 pub fn Rib(kind: RibKind) -> Rib {
349 /// One import directive.
350 pub struct ImportDirective {
352 module_path: @DVec<ident>,
353 subclass: @ImportDirectiveSubclass,
357 pub fn ImportDirective(privacy: Privacy,
358 module_path: @DVec<ident>,
359 subclass: @ImportDirectiveSubclass,
364 module_path: module_path,
370 /// The item that an import resolves to.
372 target_module: @mut Module,
373 bindings: @mut NameBindings,
376 pub fn Target(target_module: @mut Module,
377 bindings: @mut NameBindings)
380 target_module: target_module,
385 /// An ImportResolution represents a particular `use` directive.
386 pub struct ImportResolution {
387 /// The privacy of this `use` directive (whether it's `use` or
392 // The number of outstanding references to this name. When this reaches
393 // zero, outside modules can count on the targets being correct. Before
394 // then, all bets are off; future imports could override this name.
396 outstanding_references: uint,
398 /// The value that this `use` directive names, if there is one.
399 value_target: Option<Target>,
400 /// The type that this `use` directive names, if there is one.
401 type_target: Option<Target>,
403 /// There exists one state per import statement
404 state: @mut ImportState,
407 pub fn ImportResolution(privacy: Privacy,
409 state: @mut ImportState) -> ImportResolution {
413 outstanding_references: 0,
420 pub impl ImportResolution {
421 fn target_for_namespace(&self, namespace: Namespace) -> Option<Target> {
423 TypeNS => return copy self.type_target,
424 ValueNS => return copy self.value_target
429 pub struct ImportState {
434 pub fn ImportState() -> ImportState {
435 ImportState{ used: false, warned: false }
438 /// The link from a module up to its nearest parent node.
439 pub enum ParentLink {
441 ModuleParentLink(@mut Module, ident),
442 BlockParentLink(@mut Module, node_id)
445 /// The type of module this is.
446 pub enum ModuleKind {
453 /// One node in the tree of modules.
455 parent_link: ParentLink,
456 def_id: Option<def_id>,
459 children: @HashMap<ident,@mut NameBindings>,
460 imports: @DVec<@ImportDirective>,
462 // The anonymous children of this node. Anonymous children are pseudo-
463 // modules that are implicitly created around items contained within
466 // For example, if we have this:
474 // There will be an anonymous module created around `g` with the ID of the
475 // entry block for `f`.
477 anonymous_children: @HashMap<node_id,@mut Module>,
479 // The status of resolving each import in this module.
480 import_resolutions: @HashMap<ident,@mut ImportResolution>,
482 // The number of unresolved globs that this module exports.
485 // The index of the import we're resolving.
486 resolved_import_count: uint,
489 pub fn Module(parent_link: ParentLink,
490 def_id: Option<def_id>,
494 parent_link: parent_link,
497 children: @HashMap(),
499 anonymous_children: @HashMap(),
500 import_resolutions: @HashMap(),
502 resolved_import_count: 0
507 fn all_imports_resolved(&self) -> bool {
508 return self.imports.len() == self.resolved_import_count;
512 // Records a possibly-private type definition.
513 pub struct TypeNsDef {
515 module_def: Option<@mut Module>,
516 type_def: Option<def>
519 // Records a possibly-private value definition.
520 pub struct ValueNsDef {
525 // Records the definitions (at most one for each namespace) that a name is
527 pub struct NameBindings {
528 type_def: Option<TypeNsDef>, //< Meaning in type namespace.
529 value_def: Option<ValueNsDef>, //< Meaning in value namespace.
531 // For error reporting
532 // FIXME (#3783): Merge me into TypeNsDef and ValueNsDef.
533 type_span: Option<span>,
534 value_span: Option<span>,
537 pub impl NameBindings {
538 /// Creates a new module in this set of name bindings.
539 fn define_module(@mut self,
541 parent_link: ParentLink,
542 def_id: Option<def_id>,
545 // Merges the module with the existing type def or creates a new one.
546 let module_ = @mut Module(parent_link, def_id, kind);
547 match self.type_def {
549 self.type_def = Some(TypeNsDef {
551 module_def: Some(module_),
555 Some(copy type_def) => {
556 self.type_def = Some(TypeNsDef {
558 module_def: Some(module_),
563 self.type_span = Some(sp);
566 /// Records a type definition.
567 fn define_type(@mut self, privacy: Privacy, def: def, sp: span) {
568 // Merges the type with the existing type def or creates a new one.
569 match self.type_def {
571 self.type_def = Some(TypeNsDef {
577 Some(copy type_def) => {
578 self.type_def = Some(TypeNsDef {
585 self.type_span = Some(sp);
588 /// Records a value definition.
589 fn define_value(@mut self, privacy: Privacy, def: def, sp: span) {
590 self.value_def = Some(ValueNsDef { privacy: privacy, def: def });
591 self.value_span = Some(sp);
594 /// Returns the module node if applicable.
595 fn get_module_if_available() -> Option<@mut Module> {
596 match self.type_def {
597 Some(ref type_def) => (*type_def).module_def,
603 * Returns the module node. Fails if this node does not have a module
606 fn get_module(@mut self) -> @mut Module {
607 match self.get_module_if_available() {
609 fail!(~"get_module called on a node with no module \
612 Some(module_def) => module_def
616 fn defined_in_namespace(namespace: Namespace) -> bool {
618 TypeNS => return self.type_def.is_some(),
619 ValueNS => return self.value_def.is_some()
623 fn def_for_namespace(namespace: Namespace) -> Option<def> {
626 match self.type_def {
628 Some(ref type_def) => {
629 // FIXME (#3784): This is reallllly questionable.
630 // Perhaps the right thing to do is to merge def_mod
632 match (*type_def).type_def {
633 Some(type_def) => Some(type_def),
635 match (*type_def).module_def {
636 Some(module_def) => {
637 module_def.def_id.map(|def_id|
648 match self.value_def {
650 Some(value_def) => Some(value_def.def)
656 fn privacy_for_namespace(namespace: Namespace) -> Option<Privacy> {
659 match self.type_def {
661 Some(ref type_def) => Some((*type_def).privacy)
665 match self.value_def {
667 Some(value_def) => Some(value_def.privacy)
673 fn span_for_namespace(namespace: Namespace) -> Option<span> {
674 if self.defined_in_namespace(namespace) {
676 TypeNS => self.type_span,
677 ValueNS => self.value_span,
685 pub fn NameBindings() -> NameBindings {
694 /// Interns the names of the primitive types.
695 pub struct PrimitiveTypeTable {
696 primitive_types: HashMap<ident,prim_ty>,
699 pub impl PrimitiveTypeTable {
700 fn intern(&self, intr: @ident_interner, string: @~str,
701 primitive_type: prim_ty) {
702 let ident = intr.intern(string);
703 self.primitive_types.insert(ident, primitive_type);
707 pub fn PrimitiveTypeTable(intr: @ident_interner) -> PrimitiveTypeTable {
708 let table = PrimitiveTypeTable {
709 primitive_types: HashMap()
712 table.intern(intr, @~"bool", ty_bool);
713 table.intern(intr, @~"char", ty_int(ty_char));
714 table.intern(intr, @~"float", ty_float(ty_f));
715 table.intern(intr, @~"f32", ty_float(ty_f32));
716 table.intern(intr, @~"f64", ty_float(ty_f64));
717 table.intern(intr, @~"int", ty_int(ty_i));
718 table.intern(intr, @~"i8", ty_int(ty_i8));
719 table.intern(intr, @~"i16", ty_int(ty_i16));
720 table.intern(intr, @~"i32", ty_int(ty_i32));
721 table.intern(intr, @~"i64", ty_int(ty_i64));
722 table.intern(intr, @~"str", ty_str);
723 table.intern(intr, @~"uint", ty_uint(ty_u));
724 table.intern(intr, @~"u8", ty_uint(ty_u8));
725 table.intern(intr, @~"u16", ty_uint(ty_u16));
726 table.intern(intr, @~"u32", ty_uint(ty_u32));
727 table.intern(intr, @~"u64", ty_uint(ty_u64));
733 pub fn namespace_to_str(ns: Namespace) -> ~str {
740 pub fn Resolver(session: Session,
741 lang_items: LanguageItems,
744 let graph_root = @mut NameBindings();
746 graph_root.define_module(Public,
748 Some(def_id { crate: 0, node: 0 }),
752 let current_module = graph_root.get_module();
754 let self = Resolver {
756 lang_items: copy lang_items,
759 // The outermost module has def ID 0; this is not reflected in the
762 graph_root: graph_root,
764 trait_info: @HashMap(),
767 unresolved_imports: 0,
769 current_module: current_module,
774 xray_context: NoXray,
775 current_trait_refs: None,
777 self_ident: special_idents::self_,
778 type_self_ident: special_idents::type_self,
780 primitive_type_table: @PrimitiveTypeTable(session.
781 parse_sess.interner),
783 namespaces: ~[ TypeNS, ValueNS ],
789 export_map2: @HashMap(),
790 trait_map: @HashMap(),
798 /// The main resolver class.
799 pub struct Resolver {
801 lang_items: LanguageItems,
804 intr: @ident_interner,
806 graph_root: @mut NameBindings,
808 trait_info: @HashMap<def_id,@HashMap<ident,()>>,
809 structs: @HashMap<def_id,()>,
811 // The number of imports that are currently unresolved.
812 unresolved_imports: uint,
814 // The module that represents the current item scope.
815 current_module: @mut Module,
817 // The current set of local scopes, for values.
818 // FIXME #4948: Reuse ribs to avoid allocation.
819 value_ribs: @DVec<@Rib>,
821 // The current set of local scopes, for types.
822 type_ribs: @DVec<@Rib>,
824 // The current set of local scopes, for labels.
825 label_ribs: @DVec<@Rib>,
827 // Whether the current context is an X-ray context. An X-ray context is
828 // allowed to access private names of any module.
829 xray_context: XrayFlag,
831 // The trait that the current context can refer to.
832 current_trait_refs: Option<@DVec<def_id>>,
834 // The ident for the keyword "self".
836 // The ident for the non-keyword "Self".
837 type_self_ident: ident,
839 // The idents for the primitive types.
840 primitive_type_table: @PrimitiveTypeTable,
842 // The four namespaces.
843 namespaces: ~[Namespace],
845 // The function that has attribute named 'main'
846 attr_main_fn: Option<(node_id, span)>,
847 // The functions named 'main'
848 main_fns: ~[Option<(node_id, span)>],
851 export_map2: @ExportMap2,
856 /// The main name resolution procedure.
857 fn resolve(@mut self) {
858 self.build_reduced_graph();
859 self.session.abort_if_errors();
861 self.resolve_imports();
862 self.session.abort_if_errors();
864 self.record_exports();
865 self.session.abort_if_errors();
867 self.resolve_crate();
868 self.session.abort_if_errors();
870 self.check_duplicate_main();
871 self.check_for_unused_imports_if_necessary();
875 // Reduced graph building
877 // Here we build the "reduced graph": the graph of the module tree without
878 // any imports resolved.
881 /// Constructs the reduced graph for the entire crate.
882 fn build_reduced_graph(@mut self) {
884 ModuleReducedGraphParent(self.graph_root.get_module());
885 visit_crate(*self.crate, initial_parent, mk_vt(@Visitor {
886 visit_item: |item, context, visitor|
887 self.build_reduced_graph_for_item(item, context, visitor),
889 visit_foreign_item: |foreign_item, context, visitor|
890 self.build_reduced_graph_for_foreign_item(foreign_item,
894 visit_view_item: |view_item, context, visitor|
895 self.build_reduced_graph_for_view_item(view_item,
899 visit_block: |block, context, visitor|
900 self.build_reduced_graph_for_block(block,
904 .. *default_visitor()
908 /// Returns the current module tracked by the reduced graph parent.
909 fn get_module_from_parent(@mut self,
910 reduced_graph_parent: ReducedGraphParent)
912 match reduced_graph_parent {
913 ModuleReducedGraphParent(module_) => {
920 * Adds a new child item to the module definition of the parent node and
921 * returns its corresponding name bindings as well as the current parent.
922 * Or, if we're inside a block, creates (or reuses) an anonymous module
923 * corresponding to the innermost block ID and returns the name bindings
924 * as well as the newly-created parent.
926 * If this node does not have a module definition and we are not inside
929 fn add_child(@mut self,
931 reduced_graph_parent: ReducedGraphParent,
932 duplicate_checking_mode: DuplicateCheckingMode,
933 // For printing errors
935 -> (@mut NameBindings, ReducedGraphParent) {
937 // If this is the immediate descendant of a module, then we add the
938 // child name directly. Otherwise, we create or reuse an anonymous
939 // module and add the child to that.
942 match reduced_graph_parent {
943 ModuleReducedGraphParent(parent_module) => {
944 module_ = parent_module;
948 // Add or reuse the child.
949 let new_parent = ModuleReducedGraphParent(module_);
950 match module_.children.find(&name) {
952 let child = @mut NameBindings();
953 module_.children.insert(name, child);
954 return (child, new_parent);
957 // Enforce the duplicate checking mode. If we're requesting
958 // duplicate module checking, check that there isn't a module
959 // in the module with the same name. If we're requesting
960 // duplicate type checking, check that there isn't a type in
961 // the module with the same name. If we're requesting
962 // duplicate value checking, check that there isn't a value in
963 // the module with the same name. If we're requesting
964 // duplicate type checking and duplicate value checking, check
965 // that there isn't a duplicate type and a duplicate value
966 // with the same name. If no duplicate checking was requested
967 // at all, do nothing.
969 let mut is_duplicate = false;
970 match duplicate_checking_mode {
971 ForbidDuplicateModules => {
973 child.get_module_if_available().is_some();
975 ForbidDuplicateTypes => {
976 match child.def_for_namespace(TypeNS) {
977 Some(def_mod(_)) | None => {}
978 Some(_) => is_duplicate = true
981 ForbidDuplicateValues => {
982 is_duplicate = child.defined_in_namespace(ValueNS);
984 ForbidDuplicateTypesAndValues => {
985 match child.def_for_namespace(TypeNS) {
986 Some(def_mod(_)) | None => {}
987 Some(_) => is_duplicate = true
989 if child.defined_in_namespace(ValueNS) {
993 OverwriteDuplicates => {}
995 if duplicate_checking_mode != OverwriteDuplicates &&
997 // Return an error here by looking up the namespace that
998 // had the duplicate.
999 let ns = namespace_for_duplicate_checking_mode(
1000 duplicate_checking_mode);
1001 self.session.span_err(sp,
1002 fmt!("duplicate definition of %s %s",
1003 namespace_to_str(ns),
1004 *self.session.str_of(name)));
1005 do child.span_for_namespace(ns).iter() |sp| {
1006 self.session.span_note(*sp,
1007 fmt!("first definition of %s %s here:",
1008 namespace_to_str(ns),
1009 *self.session.str_of(name)));
1012 return (child, new_parent);
1017 fn block_needs_anonymous_module(@mut self, block: blk) -> bool {
1018 // If the block has view items, we need an anonymous module.
1019 if block.node.view_items.len() > 0 {
1023 // Check each statement.
1024 for block.node.stmts.each |statement| {
1025 match statement.node {
1026 stmt_decl(declaration, _) => {
1027 match declaration.node {
1042 // If we found neither view items nor items, we don't need to create
1043 // an anonymous module.
1048 fn get_parent_link(@mut self,
1049 parent: ReducedGraphParent,
1053 ModuleReducedGraphParent(module_) => {
1054 return ModuleParentLink(module_, name);
1059 /// Constructs the reduced graph for one item.
1060 fn build_reduced_graph_for_item(@mut self,
1062 parent: ReducedGraphParent,
1063 &&visitor: vt<ReducedGraphParent>) {
1064 let ident = item.ident;
1066 let privacy = visibility_to_privacy(item.vis);
1068 match /*bad*/copy item.node {
1069 item_mod(module_) => {
1070 let (name_bindings, new_parent) =
1071 self.add_child(ident, parent, ForbidDuplicateModules, sp);
1073 let parent_link = self.get_parent_link(new_parent, ident);
1074 let def_id = def_id { crate: 0, node: item.id };
1075 name_bindings.define_module(privacy,
1082 ModuleReducedGraphParent(name_bindings.get_module());
1084 visit_mod(module_, sp, item.id, new_parent, visitor);
1087 item_foreign_mod(fm) => {
1088 let new_parent = match fm.sort {
1090 let (name_bindings, new_parent) =
1091 self.add_child(ident, parent,
1092 ForbidDuplicateModules, sp);
1094 let parent_link = self.get_parent_link(new_parent,
1096 let def_id = def_id { crate: 0, node: item.id };
1097 name_bindings.define_module(privacy,
1103 ModuleReducedGraphParent(name_bindings.get_module())
1106 // For anon foreign mods, the contents just go in the
1111 visit_item(item, new_parent, visitor);
1114 // These items live in the value namespace.
1116 let (name_bindings, _) =
1117 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1119 name_bindings.define_value
1120 (privacy, def_const(local_def(item.id)), sp);
1122 item_fn(_, purity, _, _) => {
1123 let (name_bindings, new_parent) =
1124 self.add_child(ident, parent, ForbidDuplicateValues, sp);
1126 let def = def_fn(local_def(item.id), purity);
1127 name_bindings.define_value(privacy, def, sp);
1128 visit_item(item, new_parent, visitor);
1131 // These items live in the type namespace.
1133 let (name_bindings, _) =
1134 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1136 name_bindings.define_type
1137 (privacy, def_ty(local_def(item.id)), sp);
1140 item_enum(ref enum_definition, _) => {
1141 let (name_bindings, new_parent) =
1142 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1144 name_bindings.define_type
1145 (privacy, def_ty(local_def(item.id)), sp);
1147 for (*enum_definition).variants.each |variant| {
1148 self.build_reduced_graph_for_variant(*variant,
1150 // inherited => privacy of the enum item
1151 variant_visibility_to_privacy(variant.node.vis,
1158 // These items live in both the type and value namespaces.
1159 item_struct(struct_def, _) => {
1160 let (name_bindings, new_parent) =
1161 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1163 name_bindings.define_type(
1164 privacy, def_ty(local_def(item.id)), sp);
1166 // If this struct is tuple-like or enum-like, define a name
1167 // in the value namespace.
1168 match struct_def.ctor_id {
1171 name_bindings.define_value(
1173 def_struct(local_def(ctor_id)),
1178 // Record the def ID of this struct.
1179 self.structs.insert(local_def(item.id), ());
1181 visit_item(item, new_parent, visitor);
1184 item_impl(_, trait_ref_opt, ty, methods) => {
1185 // If this implements an anonymous trait and it has static
1186 // methods, then add all the static methods within to a new
1187 // module, if the type was defined within this module.
1189 // FIXME (#3785): This is quite unsatisfactory. Perhaps we
1190 // should modify anonymous traits to only be implementable in
1191 // the same module that declared the type.
1193 // Bail out early if there are no static methods.
1194 let mut has_static_methods = false;
1195 for methods.each |method| {
1196 match method.self_ty.node {
1197 sty_static => has_static_methods = true,
1202 // If there are static methods, then create the module
1204 match (trait_ref_opt, ty) {
1205 (None, @Ty { node: ty_path(path, _), _ }) if
1206 has_static_methods && path.idents.len() == 1 => {
1207 // Create the module.
1208 let name = path_to_ident(path);
1209 let (name_bindings, new_parent) =
1210 self.add_child(name,
1212 ForbidDuplicateModules,
1215 let parent_link = self.get_parent_link(new_parent,
1217 let def_id = local_def(item.id);
1218 name_bindings.define_module(Public,
1224 let new_parent = ModuleReducedGraphParent(
1225 name_bindings.get_module());
1227 // For each static method...
1228 for methods.each |method| {
1229 match method.self_ty.node {
1231 // Add the static method to the
1233 let ident = method.ident;
1234 let (method_name_bindings, _) =
1238 ForbidDuplicateValues,
1240 let def = def_fn(local_def(method.id),
1242 method_name_bindings.define_value(
1243 Public, def, method.span);
1252 visit_item(item, parent, visitor);
1255 item_trait(_, _, ref methods) => {
1256 let (name_bindings, new_parent) =
1257 self.add_child(ident, parent, ForbidDuplicateTypes, sp);
1259 // If the trait has static methods, then add all the static
1260 // methods within to a new module.
1262 // We only need to create the module if the trait has static
1263 // methods, so check that first.
1264 let mut has_static_methods = false;
1265 for (*methods).each |method| {
1266 let ty_m = trait_method_to_ty_method(*method);
1267 match ty_m.self_ty.node {
1269 has_static_methods = true;
1276 // Create the module if necessary.
1277 let module_parent_opt;
1278 if has_static_methods {
1279 let parent_link = self.get_parent_link(parent, ident);
1280 name_bindings.define_module(privacy,
1282 Some(local_def(item.id)),
1285 module_parent_opt = Some(ModuleReducedGraphParent(
1286 name_bindings.get_module()));
1288 module_parent_opt = None;
1291 // Add the names of all the methods to the trait info.
1292 let method_names = @HashMap();
1293 for (*methods).each |method| {
1294 let ty_m = trait_method_to_ty_method(*method);
1296 let ident = ty_m.ident;
1297 // Add it to the trait info if not static,
1298 // add it as a name in the trait module otherwise.
1299 match ty_m.self_ty.node {
1301 let def = def_static_method(
1303 Some(local_def(item.id)),
1306 let (method_name_bindings, _) =
1307 self.add_child(ident,
1308 module_parent_opt.get(),
1309 ForbidDuplicateValues,
1311 method_name_bindings.define_value(Public,
1316 method_names.insert(ident, ());
1321 let def_id = local_def(item.id);
1322 self.trait_info.insert(def_id, method_names);
1324 name_bindings.define_type(privacy, def_ty(def_id), sp);
1325 visit_item(item, new_parent, visitor);
1329 fail!(~"item macros unimplemented")
1334 // Constructs the reduced graph for one variant. Variants exist in the
1335 // type and/or value namespaces.
1336 fn build_reduced_graph_for_variant(@mut self,
1339 +parent_privacy: Privacy,
1340 parent: ReducedGraphParent,
1341 &&visitor: vt<ReducedGraphParent>) {
1342 let ident = variant.node.name;
1343 let (child, _) = self.add_child(ident, parent, ForbidDuplicateValues,
1347 match variant.node.vis {
1348 public => privacy = Public,
1349 private => privacy = Private,
1350 inherited => privacy = parent_privacy
1353 match variant.node.kind {
1354 tuple_variant_kind(_) => {
1355 child.define_value(privacy,
1356 def_variant(item_id,
1357 local_def(variant.node.id)),
1360 struct_variant_kind(_) => {
1361 child.define_type(privacy,
1362 def_variant(item_id,
1363 local_def(variant.node.id)),
1365 self.structs.insert(local_def(variant.node.id), ());
1367 enum_variant_kind(ref enum_definition) => {
1368 child.define_type(privacy,
1369 def_ty(local_def(variant.node.id)),
1371 for (*enum_definition).variants.each |variant| {
1372 self.build_reduced_graph_for_variant(*variant, item_id,
1381 * Constructs the reduced graph for one 'view item'. View items consist
1382 * of imports and use directives.
1384 fn build_reduced_graph_for_view_item(@mut self,
1385 view_item: @view_item,
1386 parent: ReducedGraphParent,
1387 &&_visitor: vt<ReducedGraphParent>) {
1388 let privacy = visibility_to_privacy(view_item.vis);
1389 match /*bad*/copy view_item.node {
1390 view_item_use(view_paths) => {
1391 for view_paths.each |view_path| {
1392 // Extract and intern the module part of the path. For
1393 // globs and lists, the path is found directly in the AST;
1394 // for simple paths we have to munge the path a little.
1396 let module_path = @DVec();
1397 match view_path.node {
1398 view_path_simple(_, full_path, _, _) => {
1399 let path_len = full_path.idents.len();
1400 assert path_len != 0;
1402 for full_path.idents.eachi |i, ident| {
1403 if i != path_len - 1 {
1404 (*module_path).push(*ident);
1409 view_path_glob(module_ident_path, _) |
1410 view_path_list(module_ident_path, _, _) => {
1411 for module_ident_path.idents.each |ident| {
1412 (*module_path).push(*ident);
1417 // Build up the import directives.
1418 let module_ = self.get_module_from_parent(parent);
1419 let state = @mut ImportState();
1420 match view_path.node {
1421 view_path_simple(binding, full_path, ns, _) => {
1423 module_ns => TypeNSOnly,
1424 type_value_ns => AnyNS
1427 let source_ident = full_path.idents.last();
1428 let subclass = @SingleImport(binding,
1431 self.build_import_directive(privacy,
1438 view_path_list(_, ref source_idents, _) => {
1439 for (*source_idents).each |source_ident| {
1440 let name = source_ident.node.name;
1441 let subclass = @SingleImport(name,
1444 self.build_import_directive(privacy,
1452 view_path_glob(_, _) => {
1453 self.build_import_directive(privacy,
1464 view_item_extern_mod(name, _, node_id) => {
1465 match find_extern_mod_stmt_cnum(self.session.cstore,
1468 let (child_name_bindings, new_parent) =
1469 self.add_child(name, parent, ForbidDuplicateTypes,
1472 let def_id = def_id { crate: crate_id, node: 0 };
1473 let parent_link = ModuleParentLink
1474 (self.get_module_from_parent(new_parent), name);
1476 child_name_bindings.define_module(privacy,
1481 self.build_reduced_graph_for_external_crate
1482 (child_name_bindings.get_module());
1492 /// Constructs the reduced graph for one foreign item.
1493 fn build_reduced_graph_for_foreign_item(@mut self,
1494 foreign_item: @foreign_item,
1495 parent: ReducedGraphParent,
1497 vt<ReducedGraphParent>) {
1498 let name = foreign_item.ident;
1499 let (name_bindings, new_parent) =
1500 self.add_child(name, parent, ForbidDuplicateValues,
1503 match /*bad*/copy foreign_item.node {
1504 foreign_item_fn(_, _, type_parameters) => {
1505 let def = def_fn(local_def(foreign_item.id), unsafe_fn);
1506 name_bindings.define_value(Public, def, foreign_item.span);
1508 do self.with_type_parameter_rib
1509 (HasTypeParameters(&type_parameters, foreign_item.id,
1510 0, NormalRibKind)) {
1511 visit_foreign_item(foreign_item, new_parent, visitor);
1514 foreign_item_const(*) => {
1515 let def = def_const(local_def(foreign_item.id));
1516 name_bindings.define_value(Public, def, foreign_item.span);
1518 visit_foreign_item(foreign_item, new_parent, visitor);
1523 fn build_reduced_graph_for_block(@mut self,
1525 parent: ReducedGraphParent,
1526 &&visitor: vt<ReducedGraphParent>) {
1528 if self.block_needs_anonymous_module(block) {
1529 let block_id = block.node.id;
1531 debug!("(building reduced graph for block) creating a new \
1532 anonymous module for block %d",
1535 let parent_module = self.get_module_from_parent(parent);
1536 let new_module = @mut Module(
1537 BlockParentLink(parent_module, block_id),
1539 AnonymousModuleKind);
1540 parent_module.anonymous_children.insert(block_id, new_module);
1541 new_parent = ModuleReducedGraphParent(new_module);
1543 new_parent = parent;
1546 visit_block(block, new_parent, visitor);
1549 fn handle_external_def(@mut self,
1551 modules: HashMap<def_id, @mut Module>,
1552 child_name_bindings: @mut NameBindings,
1555 new_parent: ReducedGraphParent) {
1557 def_mod(def_id) | def_foreign_mod(def_id) => {
1558 match copy child_name_bindings.type_def {
1559 Some(TypeNsDef { module_def: Some(copy module_def), _ }) => {
1560 debug!("(building reduced graph for external crate) \
1561 already created module");
1562 module_def.def_id = Some(def_id);
1563 modules.insert(def_id, module_def);
1566 debug!("(building reduced graph for \
1567 external crate) building module \
1569 let parent_link = self.get_parent_link(new_parent, ident);
1571 match modules.find(&def_id) {
1573 child_name_bindings.define_module(Public,
1578 modules.insert(def_id,
1579 child_name_bindings.get_module());
1581 Some(existing_module) => {
1582 // Create an import resolution to
1583 // avoid creating cycles in the
1587 @mut ImportResolution(Public,
1589 @mut ImportState());
1590 resolution.outstanding_references = 0;
1592 match existing_module.parent_link {
1594 BlockParentLink(*) => {
1595 fail!(~"can't happen");
1597 ModuleParentLink(parent_module, ident) => {
1598 let name_bindings = parent_module.children.get(
1600 resolution.type_target =
1601 Some(Target(parent_module, name_bindings));
1605 debug!("(building reduced graph for external crate) \
1606 ... creating import resolution");
1608 new_parent.import_resolutions.insert(ident, resolution);
1614 def_fn(*) | def_static_method(*) | def_const(*) |
1616 debug!("(building reduced graph for external \
1617 crate) building value %s", final_ident);
1618 child_name_bindings.define_value(Public, def, dummy_sp());
1621 debug!("(building reduced graph for external \
1622 crate) building type %s", final_ident);
1624 // If this is a trait, add all the method names
1625 // to the trait info.
1627 match get_method_names_if_trait(self.session.cstore, def_id) {
1631 Some(method_names) => {
1632 let interned_method_names = @HashMap();
1633 for method_names.each |method_data| {
1634 let (method_name, self_ty) = *method_data;
1635 debug!("(building reduced graph for \
1636 external crate) ... adding \
1638 *self.session.str_of(method_name));
1640 // Add it to the trait info if not static.
1641 if self_ty != sty_static {
1642 interned_method_names.insert(method_name, ());
1645 self.trait_info.insert(def_id, interned_method_names);
1649 child_name_bindings.define_type(Public, def, dummy_sp());
1651 def_struct(def_id) => {
1652 debug!("(building reduced graph for external \
1653 crate) building type %s",
1655 child_name_bindings.define_type(Public, def, dummy_sp());
1656 self.structs.insert(def_id, ());
1658 def_self(*) | def_arg(*) | def_local(*) |
1659 def_prim_ty(*) | def_ty_param(*) | def_binding(*) |
1660 def_use(*) | def_upvar(*) | def_region(*) |
1661 def_typaram_binder(*) | def_label(*) | def_self_ty(*) => {
1662 fail!(fmt!("didn't expect `%?`", def));
1668 * Builds the reduced graph rooted at the 'use' directive for an external
1671 fn build_reduced_graph_for_external_crate(@mut self, root: @mut Module) {
1672 let modules = HashMap();
1674 // Create all the items reachable by paths.
1675 for each_path(self.session.cstore, root.def_id.get().crate)
1676 |path_string, def_like| {
1678 debug!("(building reduced graph for external crate) found path \
1680 path_string, def_like);
1682 let mut pieces = split_str(path_string, ~"::");
1683 let final_ident_str = pieces.pop();
1684 let final_ident = self.session.ident_of(final_ident_str);
1686 // Find the module we need, creating modules along the way if we
1689 let mut current_module = root;
1690 for pieces.each |ident_str| {
1691 let ident = self.session.ident_of(/*bad*/copy *ident_str);
1692 // Create or reuse a graph node for the child.
1693 let (child_name_bindings, new_parent) =
1694 self.add_child(ident,
1695 ModuleReducedGraphParent(current_module),
1696 OverwriteDuplicates,
1699 // Define or reuse the module node.
1700 match child_name_bindings.type_def {
1702 debug!("(building reduced graph for external crate) \
1703 autovivifying missing type def %s",
1705 let parent_link = self.get_parent_link(new_parent,
1707 child_name_bindings.define_module(Public,
1713 Some(copy type_ns_def)
1714 if type_ns_def.module_def.is_none() => {
1715 debug!("(building reduced graph for external crate) \
1716 autovivifying missing module def %s",
1718 let parent_link = self.get_parent_link(new_parent,
1720 child_name_bindings.define_module(Public,
1726 _ => {} // Fall through.
1729 current_module = child_name_bindings.get_module();
1734 // Add the new child item.
1735 let (child_name_bindings, new_parent) =
1736 self.add_child(final_ident,
1737 ModuleReducedGraphParent(
1739 OverwriteDuplicates,
1742 self.handle_external_def(def,
1744 child_name_bindings,
1745 *self.session.str_of(
1751 // We only process static methods of impls here.
1752 match get_type_name_if_impl(self.session.cstore, def) {
1754 Some(final_ident) => {
1755 let static_methods_opt =
1756 get_static_methods_if_impl(
1757 self.session.cstore, def);
1758 match static_methods_opt {
1759 Some(ref static_methods) if
1760 static_methods.len() >= 1 => {
1761 debug!("(building reduced graph for \
1762 external crate) processing \
1763 static methods for type name %s",
1764 *self.session.str_of(
1767 let (child_name_bindings, new_parent) =
1768 self.add_child(final_ident,
1769 ModuleReducedGraphParent(
1771 OverwriteDuplicates,
1774 // Process the static methods. First,
1775 // create the module.
1777 match copy child_name_bindings.type_def {
1779 module_def: Some(copy module_def),
1782 // We already have a module. This
1784 type_module = module_def;
1788 self.get_parent_link(
1789 new_parent, final_ident);
1790 child_name_bindings.define_module(
1797 child_name_bindings.
1802 // Add each static method to the module.
1803 let new_parent = ModuleReducedGraphParent(
1805 for static_methods.each
1806 |static_method_info| {
1807 let ident = static_method_info.ident;
1808 debug!("(building reduced graph for \
1809 external crate) creating \
1810 static method '%s'",
1811 *self.session.str_of(ident));
1813 let (method_name_bindings, _) =
1817 OverwriteDuplicates,
1820 static_method_info.def_id,
1821 static_method_info.purity);
1822 method_name_bindings.define_value(
1823 Public, def, dummy_sp());
1827 // Otherwise, do nothing.
1828 Some(_) | None => {}
1834 debug!("(building reduced graph for external crate) \
1841 /// Creates and adds an import directive to the given module.
1842 fn build_import_directive(@mut self,
1844 module_: @mut Module,
1845 module_path: @DVec<ident>,
1846 subclass: @ImportDirectiveSubclass,
1848 state: @mut ImportState) {
1849 let directive = @ImportDirective(privacy, module_path,
1851 module_.imports.push(directive);
1853 // Bump the reference count on the name. Or, if this is a glob, set
1854 // the appropriate flag.
1857 SingleImport(target, _, _) => {
1858 debug!("(building import directive) building import \
1859 directive: privacy %? %s::%s",
1861 self.idents_to_str(module_path.get()),
1862 *self.session.str_of(target));
1864 match module_.import_resolutions.find(&target) {
1865 Some(resolution) => {
1866 debug!("(building import directive) bumping \
1868 resolution.outstanding_references += 1;
1871 debug!("(building import directive) creating new");
1872 let resolution = @mut ImportResolution(privacy,
1875 let name = self.idents_to_str(module_path.get());
1876 // Don't warn about unused intrinsics because they're
1877 // automatically appended to all files
1878 if name == ~"intrinsic::rusti" {
1879 resolution.state.warned = true;
1881 resolution.outstanding_references = 1;
1882 module_.import_resolutions.insert(target, resolution);
1887 // Set the glob flag. This tells us that we don't know the
1888 // module's exports ahead of time.
1890 module_.glob_count += 1;
1894 self.unresolved_imports += 1;
1897 // Import resolution
1899 // This is a fixed-point algorithm. We resolve imports until our efforts
1900 // are stymied by an unresolved import; then we bail out of the current
1901 // module and continue. We terminate successfully once no more imports
1902 // remain or unsuccessfully when no forward progress in resolving imports
1906 * Resolves all imports for the crate. This method performs the fixed-
1909 fn resolve_imports(@mut self) {
1911 let mut prev_unresolved_imports = 0;
1913 debug!("(resolving imports) iteration %u, %u imports left",
1914 i, self.unresolved_imports);
1916 let module_root = self.graph_root.get_module();
1917 self.resolve_imports_for_module_subtree(module_root);
1919 if self.unresolved_imports == 0 {
1920 debug!("(resolving imports) success");
1924 if self.unresolved_imports == prev_unresolved_imports {
1925 self.session.err(~"failed to resolve imports");
1926 self.report_unresolved_imports(module_root);
1931 prev_unresolved_imports = self.unresolved_imports;
1936 * Attempts to resolve imports for the given module and all of its
1939 fn resolve_imports_for_module_subtree(@mut self, module_: @mut Module) {
1940 debug!("(resolving imports for module subtree) resolving %s",
1941 self.module_to_str(module_));
1942 self.resolve_imports_for_module(module_);
1944 for module_.children.each_value |&child_node| {
1945 match child_node.get_module_if_available() {
1949 Some(child_module) => {
1950 self.resolve_imports_for_module_subtree(child_module);
1955 for module_.anonymous_children.each_value |&child_module| {
1956 self.resolve_imports_for_module_subtree(child_module);
1960 /// Attempts to resolve imports for the given module only.
1961 fn resolve_imports_for_module(@mut self, module_: @mut Module) {
1962 if (*module_).all_imports_resolved() {
1963 debug!("(resolving imports for module) all imports resolved for \
1965 self.module_to_str(module_));
1969 let import_count = module_.imports.len();
1970 while module_.resolved_import_count < import_count {
1971 let import_index = module_.resolved_import_count;
1972 let import_directive = module_.imports.get_elt(import_index);
1973 match self.resolve_import_for_module(module_, import_directive) {
1975 // We presumably emitted an error. Continue.
1976 let idents = import_directive.module_path.get();
1977 let msg = fmt!("failed to resolve import: %s",
1978 *self.import_path_to_str(idents,
1979 *import_directive.subclass));
1980 self.session.span_err(import_directive.span, msg);
1983 // Bail out. We'll come around next time.
1991 module_.resolved_import_count += 1;
1995 fn idents_to_str(@mut self, idents: ~[ident]) -> ~str {
1996 let ident_strs = do idents.map |ident| {
1997 /*bad*/ copy *self.session.str_of(*ident)
1999 str::connect(ident_strs, "::")
2002 fn import_directive_subclass_to_str(@mut self,
2003 subclass: ImportDirectiveSubclass)
2006 SingleImport(_target, source, _ns) => self.session.str_of(source),
2011 fn import_path_to_str(@mut self,
2013 subclass: ImportDirectiveSubclass)
2015 if idents.is_empty() {
2016 self.import_directive_subclass_to_str(subclass)
2019 self.idents_to_str(idents),
2020 *self.import_directive_subclass_to_str(subclass))
2025 * Attempts to resolve the given import. The return value indicates
2026 * failure if we're certain the name does not exist, indeterminate if we
2027 * don't know whether the name exists at the moment due to other
2028 * currently-unresolved imports, or success if we know the name exists.
2029 * If successful, the resolved bindings are written into the module.
2031 fn resolve_import_for_module(@mut self,
2032 module_: @mut Module,
2033 import_directive: @ImportDirective)
2034 -> ResolveResult<()> {
2035 let mut resolution_result;
2036 let module_path = import_directive.module_path;
2038 debug!("(resolving import for module) resolving import `%s::...` in \
2040 self.idents_to_str((*module_path).get()),
2041 self.module_to_str(module_));
2043 // One-level renaming imports of the form `import foo = bar;` are
2044 // handled specially.
2046 if (*module_path).len() == 0 {
2048 self.resolve_one_level_renaming_import(module_,
2051 // First, resolve the module path for the directive, if necessary.
2052 match self.resolve_module_path_for_import(module_,
2054 DontUseLexicalScope,
2055 import_directive.span) {
2058 resolution_result = Failed;
2061 resolution_result = Indeterminate;
2063 Success(containing_module) => {
2064 // We found the module that the target is contained
2065 // within. Attempt to resolve the import within it.
2067 match *import_directive.subclass {
2068 SingleImport(target, source, AnyNS) => {
2070 self.resolve_single_import(module_,
2075 SingleImport(target, source, TypeNSOnly) => {
2077 self.resolve_single_module_import
2078 (module_, containing_module, target,
2082 let span = import_directive.span;
2083 let p = import_directive.privacy;
2085 self.resolve_glob_import(p,
2095 // Decrement the count of unresolved imports.
2096 match resolution_result {
2098 assert self.unresolved_imports >= 1;
2099 self.unresolved_imports -= 1;
2102 // Nothing to do here; just return the error.
2106 // Decrement the count of unresolved globs if necessary. But only if
2107 // the resolution result is indeterminate -- otherwise we'll stop
2108 // processing imports here. (See the loop in
2109 // resolve_imports_for_module.)
2111 if !resolution_result.indeterminate() {
2112 match *import_directive.subclass {
2114 assert module_.glob_count >= 1;
2115 module_.glob_count -= 1;
2117 SingleImport(*) => {
2123 return resolution_result;
2126 fn resolve_single_import(@mut self,
2127 module_: @mut Module,
2128 containing_module: @mut Module,
2131 -> ResolveResult<()> {
2132 debug!("(resolving single import) resolving `%s` = `%s::%s` from \
2134 *self.session.str_of(target),
2135 self.module_to_str(containing_module),
2136 *self.session.str_of(source),
2137 self.module_to_str(module_));
2139 // We need to resolve both namespaces for this to succeed.
2141 // FIXME #4949: See if there's some way of handling namespaces in
2142 // a more generic way. We have two of them; it seems worth
2145 let mut value_result = UnknownResult;
2146 let mut type_result = UnknownResult;
2148 // Search for direct children of the containing module.
2149 match containing_module.children.find(&source) {
2153 Some(child_name_bindings) => {
2154 if (*child_name_bindings).defined_in_namespace(ValueNS) {
2155 value_result = BoundResult(containing_module,
2156 child_name_bindings);
2158 if (*child_name_bindings).defined_in_namespace(TypeNS) {
2159 type_result = BoundResult(containing_module,
2160 child_name_bindings);
2165 // Unless we managed to find a result in both namespaces (unlikely),
2166 // search imports as well.
2167 match (value_result, type_result) {
2168 (BoundResult(*), BoundResult(*)) => {
2172 // If there is an unresolved glob at this point in the
2173 // containing module, bail out. We don't know enough to be
2174 // able to resolve this import.
2176 if containing_module.glob_count > 0 {
2177 debug!("(resolving single import) unresolved glob; \
2179 return Indeterminate;
2182 // Now search the exported imports within the containing
2185 match containing_module.import_resolutions.find(&source) {
2187 // The containing module definitely doesn't have an
2188 // exported import with the name in question. We can
2189 // therefore accurately report that the names are
2192 if value_result.is_unknown() {
2193 value_result = UnboundResult;
2195 if type_result.is_unknown() {
2196 type_result = UnboundResult;
2199 Some(import_resolution)
2200 if import_resolution.outstanding_references
2203 fn get_binding(import_resolution:
2204 @mut ImportResolution,
2205 namespace: Namespace)
2206 -> NamespaceResult {
2208 // Import resolutions must be declared with "pub"
2209 // in order to be exported.
2210 if import_resolution.privacy == Private {
2211 return UnboundResult;
2214 match (*import_resolution).
2215 target_for_namespace(namespace) {
2217 return UnboundResult;
2220 import_resolution.state.used = true;
2221 return BoundResult(target.target_module,
2227 // The name is an import which has been fully
2228 // resolved. We can, therefore, just follow it.
2229 if value_result.is_unknown() {
2230 value_result = get_binding(import_resolution,
2233 if type_result.is_unknown() {
2234 type_result = get_binding(import_resolution,
2239 // The import is unresolved. Bail out.
2240 debug!("(resolving single import) unresolved import; \
2242 return Indeterminate;
2248 // We've successfully resolved the import. Write the results in.
2249 assert module_.import_resolutions.contains_key(&target);
2250 let import_resolution = module_.import_resolutions.get(&target);
2252 match value_result {
2253 BoundResult(target_module, name_bindings) => {
2254 import_resolution.value_target =
2255 Some(Target(target_module, name_bindings));
2257 UnboundResult => { /* Continue. */ }
2259 fail!(~"value result should be known at this point");
2263 BoundResult(target_module, name_bindings) => {
2264 import_resolution.type_target =
2265 Some(Target(target_module, name_bindings));
2267 UnboundResult => { /* Continue. */ }
2269 fail!(~"type result should be known at this point");
2273 let i = import_resolution;
2274 match (i.value_target, i.type_target) {
2275 // If this name wasn't found in either namespace, it's definitely
2277 (None, None) => { return Failed; }
2278 // If it's private, it's also unresolved.
2279 (Some(t), None) | (None, Some(t)) => {
2280 match t.bindings.type_def {
2281 Some(ref type_def) => {
2282 if type_def.privacy == Private {
2288 match t.bindings.value_def {
2289 Some(ref value_def) => {
2290 if value_def.privacy == Private {
2297 // It's also an error if there's both a type and a value with this
2298 // name, but both are private
2299 (Some(val), Some(ty)) => {
2300 match (val.bindings.value_def, ty.bindings.value_def) {
2301 (Some(ref value_def), Some(ref type_def)) =>
2302 if value_def.privacy == Private
2303 && type_def.privacy == Private {
2311 assert import_resolution.outstanding_references >= 1;
2312 import_resolution.outstanding_references -= 1;
2314 debug!("(resolving single import) successfully resolved import");
2318 fn resolve_single_module_import(@mut self,
2319 module_: @mut Module,
2320 containing_module: @mut Module,
2323 -> ResolveResult<()> {
2324 debug!("(resolving single module import) resolving `%s` = `%s::%s` \
2326 *self.session.str_of(target),
2327 self.module_to_str(containing_module),
2328 *self.session.str_of(source),
2329 self.module_to_str(module_));
2331 // We need to resolve the module namespace for this to succeed.
2332 let mut module_result = UnknownResult;
2334 // Search for direct children of the containing module.
2335 match containing_module.children.find(&source) {
2339 Some(child_name_bindings) => {
2340 if (*child_name_bindings).defined_in_namespace(TypeNS) {
2341 module_result = BoundResult(containing_module,
2342 child_name_bindings);
2347 // Unless we managed to find a result, search imports as well.
2348 match module_result {
2353 // If there is an unresolved glob at this point in the
2354 // containing module, bail out. We don't know enough to be
2355 // able to resolve this import.
2357 if containing_module.glob_count > 0 {
2358 debug!("(resolving single module import) unresolved \
2359 glob; bailing out");
2360 return Indeterminate;
2363 // Now search the exported imports within the containing
2365 match containing_module.import_resolutions.find(&source) {
2367 // The containing module definitely doesn't have an
2368 // exported import with the name in question. We can
2369 // therefore accurately report that the names are
2372 if module_result.is_unknown() {
2373 module_result = UnboundResult;
2376 Some(import_resolution)
2377 if import_resolution.outstanding_references
2379 // The name is an import which has been fully
2380 // resolved. We can, therefore, just follow it.
2382 if module_result.is_unknown() {
2383 match (*import_resolution).target_for_namespace(
2386 module_result = UnboundResult;
2389 import_resolution.state.used = true;
2390 module_result = BoundResult
2391 (target.target_module,
2398 // The import is unresolved. Bail out.
2399 debug!("(resolving single module import) unresolved \
2400 import; bailing out");
2401 return Indeterminate;
2407 // We've successfully resolved the import. Write the results in.
2408 assert module_.import_resolutions.contains_key(&target);
2409 let import_resolution = module_.import_resolutions.get(&target);
2411 match module_result {
2412 BoundResult(target_module, name_bindings) => {
2413 debug!("(resolving single import) found module binding");
2414 import_resolution.type_target =
2415 Some(Target(target_module, name_bindings));
2418 debug!("(resolving single import) didn't find module \
2422 fail!(~"module result should be known at this point");
2426 let i = import_resolution;
2427 if i.type_target.is_none() {
2428 // If this name wasn't found in the type namespace, it's
2429 // definitely unresolved.
2433 assert import_resolution.outstanding_references >= 1;
2434 import_resolution.outstanding_references -= 1;
2436 debug!("(resolving single module import) successfully resolved \
2443 * Resolves a glob import. Note that this function cannot fail; it either
2444 * succeeds or bails out (as importing * from an empty module or a module
2445 * that exports nothing is valid).
2447 fn resolve_glob_import(@mut self,
2449 module_: @mut Module,
2450 containing_module: @mut Module,
2452 -> ResolveResult<()> {
2453 // This function works in a highly imperative manner; it eagerly adds
2454 // everything it can to the list of import resolutions of the module
2456 debug!("(resolving glob import) resolving %? glob import", privacy);
2457 let state = @mut ImportState();
2459 // We must bail out if the node has unresolved imports of any kind
2460 // (including globs).
2461 if !(*containing_module).all_imports_resolved() {
2462 debug!("(resolving glob import) target module has unresolved \
2463 imports; bailing out");
2464 return Indeterminate;
2467 assert containing_module.glob_count == 0;
2469 // Add all resolved imports from the containing module.
2470 for containing_module.import_resolutions.each
2471 |&ident, &target_import_resolution| {
2473 debug!("(resolving glob import) writing module resolution \
2475 is_none(&target_import_resolution.type_target),
2476 self.module_to_str(module_));
2478 // Here we merge two import resolutions.
2479 match module_.import_resolutions.find(&ident) {
2481 // Simple: just copy the old import resolution.
2482 let new_import_resolution =
2483 @mut ImportResolution(privacy,
2484 target_import_resolution.span,
2486 new_import_resolution.value_target =
2487 copy target_import_resolution.value_target;
2488 new_import_resolution.type_target =
2489 copy target_import_resolution.type_target;
2491 module_.import_resolutions.insert
2492 (ident, new_import_resolution);
2494 Some(dest_import_resolution) => {
2495 // Merge the two import resolutions at a finer-grained
2498 match copy target_import_resolution.value_target {
2502 Some(value_target) => {
2503 dest_import_resolution.value_target =
2504 Some(copy value_target);
2507 match copy target_import_resolution.type_target {
2511 Some(type_target) => {
2512 dest_import_resolution.type_target =
2513 Some(copy type_target);
2520 // Add all children from the containing module.
2521 for containing_module.children.each |&ident, &name_bindings| {
2522 let mut dest_import_resolution;
2523 match module_.import_resolutions.find(&ident) {
2525 // Create a new import resolution from this child.
2526 dest_import_resolution = @mut ImportResolution(privacy,
2529 module_.import_resolutions.insert
2530 (ident, dest_import_resolution);
2532 Some(existing_import_resolution) => {
2533 dest_import_resolution = existing_import_resolution;
2538 debug!("(resolving glob import) writing resolution `%s` in `%s` \
2539 to `%s`, privacy=%?",
2540 *self.session.str_of(ident),
2541 self.module_to_str(containing_module),
2542 self.module_to_str(module_),
2543 dest_import_resolution.privacy);
2545 // Merge the child item into the import resolution.
2546 if (*name_bindings).defined_in_namespace(ValueNS) {
2547 debug!("(resolving glob import) ... for value target");
2548 dest_import_resolution.value_target =
2549 Some(Target(containing_module, name_bindings));
2551 if (*name_bindings).defined_in_namespace(TypeNS) {
2552 debug!("(resolving glob import) ... for type target");
2553 dest_import_resolution.type_target =
2554 Some(Target(containing_module, name_bindings));
2558 debug!("(resolving glob import) successfully resolved import");
2562 fn resolve_module_path_from_root(@mut self,
2563 module_: @mut Module,
2564 module_path: @DVec<ident>,
2567 -> ResolveResult<@mut Module> {
2568 let mut search_module = module_;
2569 let mut index = index;
2570 let module_path_len = (*module_path).len();
2572 // Resolve the module part of the path. This does not involve looking
2573 // upward though scope chains; we simply resolve names directly in
2574 // modules as we go.
2576 while index < module_path_len {
2577 let name = (*module_path).get_elt(index);
2578 match self.resolve_name_in_module(search_module,
2583 self.session.span_err(span, ~"unresolved name");
2587 debug!("(resolving module path for import) module \
2588 resolution is indeterminate: %s",
2589 *self.session.str_of(name));
2590 return Indeterminate;
2592 Success(target) => {
2593 // Check to see whether there are type bindings, and, if
2594 // so, whether there is a module within.
2595 match target.bindings.type_def {
2596 Some(copy type_def) => {
2597 match type_def.module_def {
2600 self.session.span_err(span,
2608 Some(copy module_def) => {
2609 search_module = module_def;
2614 // There are no type bindings at all.
2615 self.session.span_err(span,
2616 fmt!("not a module: %s",
2617 *self.session.str_of(
2628 return Success(search_module);
2632 * Attempts to resolve the module part of an import directive or path
2633 * rooted at the given module.
2635 fn resolve_module_path_for_import(@mut self,
2636 module_: @mut Module,
2637 module_path: @DVec<ident>,
2638 use_lexical_scope: UseLexicalScopeFlag,
2640 -> ResolveResult<@mut Module> {
2641 let module_path_len = (*module_path).len();
2642 assert module_path_len > 0;
2644 debug!("(resolving module path for import) processing `%s` rooted at \
2646 self.idents_to_str((*module_path).get()),
2647 self.module_to_str(module_));
2649 // Resolve the module prefix, if any.
2650 let module_prefix_result = self.resolve_module_prefix(module_,
2653 let mut search_module;
2654 let mut start_index;
2655 match module_prefix_result {
2657 self.session.span_err(span, ~"unresolved name");
2661 debug!("(resolving module path for import) indeterminate; \
2663 return Indeterminate;
2665 Success(NoPrefixFound) => {
2666 // There was no prefix, so we're considering the first element
2667 // of the path. How we handle this depends on whether we were
2668 // instructed to use lexical scope or not.
2669 match use_lexical_scope {
2670 DontUseLexicalScope => {
2671 // This is a crate-relative path. We will start the
2672 // resolution process at index zero.
2673 search_module = self.graph_root.get_module();
2676 UseLexicalScope => {
2677 // This is not a crate-relative path. We resolve the
2678 // first component of the path in the current lexical
2679 // scope and then proceed to resolve below that.
2680 let result = self.resolve_module_in_lexical_scope(
2682 module_path.get_elt(0));
2685 self.session.span_err(span,
2686 ~"unresolved name");
2690 debug!("(resolving module path for import) \
2691 indeterminate; bailing");
2692 return Indeterminate;
2694 Success(containing_module) => {
2695 search_module = containing_module;
2702 Success(PrefixFound(containing_module, index)) => {
2703 search_module = containing_module;
2704 start_index = index;
2708 return self.resolve_module_path_from_root(search_module,
2714 fn resolve_item_in_lexical_scope(@mut self,
2715 module_: @mut Module,
2717 namespace: Namespace,
2718 search_through_modules:
2719 SearchThroughModulesFlag)
2720 -> ResolveResult<Target> {
2721 debug!("(resolving item in lexical scope) resolving `%s` in \
2722 namespace %? in `%s`",
2723 *self.session.str_of(name),
2725 self.module_to_str(module_));
2727 // The current module node is handled specially. First, check for
2728 // its immediate children.
2730 match module_.children.find(&name) {
2732 if (*name_bindings).defined_in_namespace(namespace) => {
2733 return Success(Target(module_, name_bindings));
2735 Some(_) | None => { /* Not found; continue. */ }
2738 // Now check for its import directives. We don't have to have resolved
2739 // all its imports in the usual way; this is because chains of
2740 // adjacent import statements are processed as though they mutated the
2743 match module_.import_resolutions.find(&name) {
2745 // Not found; continue.
2747 Some(import_resolution) => {
2748 match (*import_resolution).target_for_namespace(namespace) {
2750 // Not found; continue.
2751 debug!("(resolving item in lexical scope) found \
2752 import resolution, but not in namespace %?",
2756 import_resolution.state.used = true;
2757 return Success(copy target);
2763 // Finally, proceed up the scope chain looking for parent modules.
2764 let mut search_module = module_;
2766 // Go to the next parent.
2767 match search_module.parent_link {
2769 // No more parents. This module was unresolved.
2770 debug!("(resolving item in lexical scope) unresolved \
2774 ModuleParentLink(parent_module_node, _) => {
2775 match search_through_modules {
2776 DontSearchThroughModules => {
2777 match search_module.kind {
2778 NormalModuleKind => {
2779 // We stop the search here.
2780 debug!("(resolving item in lexical \
2781 scope) unresolved module: not \
2782 searching through module \
2788 AnonymousModuleKind => {
2789 search_module = parent_module_node;
2793 SearchThroughModules => {
2794 search_module = parent_module_node;
2798 BlockParentLink(parent_module_node, _) => {
2799 search_module = parent_module_node;
2803 // Resolve the name in the parent module.
2804 match self.resolve_name_in_module(search_module,
2809 // Continue up the search chain.
2812 // We couldn't see through the higher scope because of an
2813 // unresolved import higher up. Bail.
2815 debug!("(resolving item in lexical scope) indeterminate \
2816 higher scope; bailing");
2817 return Indeterminate;
2819 Success(target) => {
2820 // We found the module.
2821 return Success(copy target);
2827 /** Resolves a module name in the current lexical scope. */
2828 fn resolve_module_in_lexical_scope(@mut self,
2829 module_: @mut Module,
2831 -> ResolveResult<@mut Module> {
2832 // If this module is an anonymous module, resolve the item in the
2833 // lexical scope. Otherwise, resolve the item from the crate root.
2834 let resolve_result = self.resolve_item_in_lexical_scope(
2835 module_, name, TypeNS, DontSearchThroughModules);
2836 match resolve_result {
2837 Success(target) => {
2838 match target.bindings.type_def {
2839 Some(ref type_def) => {
2840 match (*type_def).module_def {
2842 error!("!!! (resolving module in lexical \
2843 scope) module wasn't actually a \
2847 Some(module_def) => {
2848 return Success(module_def);
2853 error!("!!! (resolving module in lexical scope) module
2854 wasn't actually a module!");
2860 debug!("(resolving module in lexical scope) indeterminate; \
2862 return Indeterminate;
2865 debug!("(resolving module in lexical scope) failed to \
2873 * Returns the nearest normal module parent of the given module.
2875 fn get_nearest_normal_module_parent(@mut self, module_: @mut Module)
2876 -> Option<@mut Module> {
2877 let mut module_ = module_;
2879 match module_.parent_link {
2880 NoParentLink => return None,
2881 ModuleParentLink(new_module, _) |
2882 BlockParentLink(new_module, _) => {
2883 match new_module.kind {
2884 NormalModuleKind => return Some(new_module),
2887 AnonymousModuleKind => module_ = new_module,
2895 * Returns the nearest normal module parent of the given module, or the
2896 * module itself if it is a normal module.
2898 fn get_nearest_normal_module_parent_or_self(@mut self,
2899 module_: @mut Module)
2901 match module_.kind {
2902 NormalModuleKind => return module_,
2903 ExternModuleKind | TraitModuleKind | AnonymousModuleKind => {
2904 match self.get_nearest_normal_module_parent(module_) {
2906 Some(new_module) => new_module
2913 * Resolves a "module prefix". A module prefix is one of (a) `self::`;
2914 * (b) some chain of `super::`.
2916 fn resolve_module_prefix(@mut self,
2917 module_: @mut Module,
2918 module_path: @DVec<ident>)
2919 -> ResolveResult<ModulePrefixResult> {
2920 let interner = self.session.parse_sess.interner;
2922 // Start at the current module if we see `self` or `super`, or at the
2923 // top of the crate otherwise.
2924 let mut containing_module;
2926 if *interner.get(module_path.get_elt(0)) == ~"self" {
2928 self.get_nearest_normal_module_parent_or_self(module_);
2930 } else if *interner.get(module_path.get_elt(0)) == ~"super" {
2932 self.get_nearest_normal_module_parent_or_self(module_);
2933 i = 0; // We'll handle `super` below.
2935 return Success(NoPrefixFound);
2938 // Now loop through all the `super`s we find.
2939 while i < module_path.len() &&
2940 *interner.get(module_path.get_elt(i)) == ~"super" {
2941 debug!("(resolving module prefix) resolving `super` at %s",
2942 self.module_to_str(containing_module));
2943 match self.get_nearest_normal_module_parent(containing_module) {
2944 None => return Failed,
2945 Some(new_module) => {
2946 containing_module = new_module;
2952 debug!("(resolving module prefix) finished resolving prefix at %s",
2953 self.module_to_str(containing_module));
2955 return Success(PrefixFound(containing_module, i));
2959 * Attempts to resolve the supplied name in the given module for the
2960 * given namespace. If successful, returns the target corresponding to
2963 fn resolve_name_in_module(@mut self,
2964 module_: @mut Module,
2966 namespace: Namespace,
2968 -> ResolveResult<Target> {
2969 debug!("(resolving name in module) resolving `%s` in `%s`",
2970 *self.session.str_of(name),
2971 self.module_to_str(module_));
2973 // First, check the direct children of the module.
2974 match module_.children.find(&name) {
2976 if (*name_bindings).defined_in_namespace(namespace) => {
2978 debug!("(resolving name in module) found node as child");
2979 return Success(Target(module_, name_bindings));
2986 // Next, check the module's imports. If the module has a glob and
2987 // globs were not allowed, then we bail out; we don't know its imports
2989 if !allow_globs && module_.glob_count > 0 {
2990 debug!("(resolving name in module) module has glob; bailing out");
2991 return Indeterminate;
2994 // Otherwise, we check the list of resolved imports.
2995 match module_.import_resolutions.find(&name) {
2996 Some(import_resolution) => {
2997 if import_resolution.outstanding_references != 0 {
2998 debug!("(resolving name in module) import unresolved; \
3000 return Indeterminate;
3003 match (*import_resolution).target_for_namespace(namespace) {
3005 debug!("(resolving name in module) name found, but \
3006 not in namespace %?",
3010 debug!("(resolving name in module) resolved to \
3012 import_resolution.state.used = true;
3013 return Success(copy target);
3022 // We're out of luck.
3023 debug!("(resolving name in module) failed to resolve %s",
3024 *self.session.str_of(name));
3029 * Resolves a one-level renaming import of the kind `import foo = bar;`
3030 * This needs special handling, as, unlike all of the other imports, it
3031 * needs to look in the scope chain for modules and non-modules alike.
3033 fn resolve_one_level_renaming_import(@mut self,
3034 module_: @mut Module,
3035 import_directive: @ImportDirective)
3036 -> ResolveResult<()> {
3037 let mut target_name;
3038 let mut source_name;
3039 let allowable_namespaces;
3040 match *import_directive.subclass {
3041 SingleImport(target, source, namespaces) => {
3042 target_name = target;
3043 source_name = source;
3044 allowable_namespaces = namespaces;
3047 fail!(~"found `import *`, which is invalid");
3051 debug!("(resolving one-level naming result) resolving import `%s` = \
3053 *self.session.str_of(target_name),
3054 *self.session.str_of(source_name),
3055 self.module_to_str(module_));
3057 // Find the matching items in the lexical scope chain for every
3058 // namespace. If any of them come back indeterminate, this entire
3059 // import is indeterminate.
3061 let mut module_result;
3062 debug!("(resolving one-level naming result) searching for module");
3063 match self.resolve_item_in_lexical_scope(module_,
3066 SearchThroughModules) {
3068 debug!("(resolving one-level renaming import) didn't find \
3070 module_result = None;
3073 debug!("(resolving one-level renaming import) module result \
3074 is indeterminate; bailing");
3075 return Indeterminate;
3077 Success(name_bindings) => {
3078 debug!("(resolving one-level renaming import) module result \
3080 module_result = Some(copy name_bindings);
3084 let mut value_result;
3085 let mut type_result;
3086 if allowable_namespaces == TypeNSOnly {
3087 value_result = None;
3090 debug!("(resolving one-level naming result) searching for value");
3091 match self.resolve_item_in_lexical_scope(module_,
3094 SearchThroughModules) {
3097 debug!("(resolving one-level renaming import) didn't \
3098 find value result");
3099 value_result = None;
3102 debug!("(resolving one-level renaming import) value \
3103 result is indeterminate; bailing");
3104 return Indeterminate;
3106 Success(name_bindings) => {
3107 debug!("(resolving one-level renaming import) value \
3109 value_result = Some(copy name_bindings);
3113 debug!("(resolving one-level naming result) searching for type");
3114 match self.resolve_item_in_lexical_scope(module_,
3117 SearchThroughModules) {
3120 debug!("(resolving one-level renaming import) didn't \
3125 debug!("(resolving one-level renaming import) type \
3126 result is indeterminate; bailing");
3127 return Indeterminate;
3129 Success(name_bindings) => {
3130 debug!("(resolving one-level renaming import) type \
3132 type_result = Some(copy name_bindings);
3138 // NB: This one results in effects that may be somewhat surprising. It
3142 // impl foo for ... { ... }
3144 // impl foo for ... { ... }
3145 // import bar = foo;
3150 // results in only A::B::foo being aliased to A::B::bar, not A::foo
3151 // *and* A::B::foo being aliased to A::B::bar.
3154 // If nothing at all was found, that's an error.
3155 if is_none(&module_result) &&
3156 is_none(&value_result) &&
3157 is_none(&type_result) {
3159 self.session.span_err(import_directive.span,
3160 ~"unresolved import");
3164 // Otherwise, proceed and write in the bindings.
3165 match module_.import_resolutions.find(&target_name) {
3167 fail!(~"(resolving one-level renaming import) reduced graph \
3168 construction or glob importing should have created the \
3169 import resolution name by now");
3171 Some(import_resolution) => {
3172 debug!("(resolving one-level renaming import) writing module \
3173 result %? for `%s` into `%s`",
3174 is_none(&module_result),
3175 *self.session.str_of(target_name),
3176 self.module_to_str(module_));
3178 import_resolution.value_target = value_result;
3179 import_resolution.type_target = type_result;
3181 assert import_resolution.outstanding_references >= 1;
3182 import_resolution.outstanding_references -= 1;
3186 debug!("(resolving one-level renaming import) successfully resolved");
3190 fn report_unresolved_imports(@mut self, module_: @mut Module) {
3191 let index = module_.resolved_import_count;
3192 let import_count = module_.imports.len();
3193 if index != import_count {
3194 self.session.span_err(module_.imports.get_elt(index).span,
3195 ~"unresolved import");
3198 // Descend into children and anonymous children.
3199 for module_.children.each_value |&child_node| {
3200 match child_node.get_module_if_available() {
3204 Some(child_module) => {
3205 self.report_unresolved_imports(child_module);
3210 for module_.anonymous_children.each_value |&module_| {
3211 self.report_unresolved_imports(module_);
3217 // This pass simply determines what all "export" keywords refer to and
3218 // writes the results into the export map.
3220 // FIXME #4953 This pass will be removed once exports change to per-item.
3221 // Then this operation can simply be performed as part of item (or import)
3224 fn record_exports(@mut self) {
3225 let root_module = self.graph_root.get_module();
3226 self.record_exports_for_module_subtree(root_module);
3229 fn record_exports_for_module_subtree(@mut self, module_: @mut Module) {
3230 // If this isn't a local crate, then bail out. We don't need to record
3231 // exports for nonlocal crates.
3233 match module_.def_id {
3234 Some(def_id) if def_id.crate == local_crate => {
3236 debug!("(recording exports for module subtree) recording \
3237 exports for local module");
3240 // Record exports for the root module.
3241 debug!("(recording exports for module subtree) recording \
3242 exports for root module");
3246 debug!("(recording exports for module subtree) not recording \
3248 self.module_to_str(module_));
3253 self.record_exports_for_module(module_);
3255 for module_.children.each_value |&child_name_bindings| {
3256 match child_name_bindings.get_module_if_available() {
3260 Some(child_module) => {
3261 self.record_exports_for_module_subtree(child_module);
3266 for module_.anonymous_children.each_value |&child_module| {
3267 self.record_exports_for_module_subtree(child_module);
3271 fn record_exports_for_module(@mut self, module_: @mut Module) {
3272 let mut exports2 = ~[];
3274 self.add_exports_for_module(&mut exports2, module_);
3275 match copy module_.def_id {
3277 self.export_map2.insert(def_id.node, exports2);
3278 debug!("(computing exports) writing exports for %d (some)",
3285 fn add_exports_of_namebindings(@mut self,
3286 exports2: &mut ~[Export2],
3288 namebindings: @mut NameBindings,
3291 match (namebindings.def_for_namespace(ns),
3292 namebindings.privacy_for_namespace(ns)) {
3293 (Some(d), Some(Public)) => {
3294 debug!("(computing exports) YES: %s '%s' => %?",
3295 if reexport { ~"reexport" } else { ~"export"},
3296 *self.session.str_of(ident),
3298 exports2.push(Export2 {
3300 name: self.session.str_of(ident),
3301 def_id: def_id_of_def(d)
3304 (Some(_), Some(privacy)) => {
3305 debug!("(computing reexports) NO: privacy %?", privacy);
3308 debug!("(computing reexports) NO: %?, %?", d_opt, p_opt);
3313 fn add_exports_for_module(@mut self,
3314 exports2: &mut ~[Export2],
3315 module_: @mut Module) {
3316 for module_.children.each |ident, namebindings| {
3317 debug!("(computing exports) maybe export '%s'",
3318 *self.session.str_of(*ident));
3319 self.add_exports_of_namebindings(&mut *exports2,
3324 self.add_exports_of_namebindings(&mut *exports2,
3331 for module_.import_resolutions.each |ident, importresolution| {
3332 if importresolution.privacy != Public {
3333 debug!("(computing exports) not reexporting private `%s`",
3334 *self.session.str_of(*ident));
3337 for [ TypeNS, ValueNS ].each |ns| {
3338 match importresolution.target_for_namespace(*ns) {
3340 debug!("(computing exports) maybe reexport '%s'",
3341 *self.session.str_of(*ident));
3342 self.add_exports_of_namebindings(&mut *exports2,
3356 // We maintain a list of value ribs and type ribs.
3358 // Simultaneously, we keep track of the current position in the module
3359 // graph in the `current_module` pointer. When we go to resolve a name in
3360 // the value or type namespaces, we first look through all the ribs and
3361 // then query the module graph. When we resolve a name in the module
3362 // namespace, we can skip all the ribs (since nested modules are not
3363 // allowed within blocks in Rust) and jump straight to the current module
3366 // Named implementations are handled separately. When we find a method
3367 // call, we consult the module node to find all of the implementations in
3368 // scope. This information is lazily cached in the module node. We then
3369 // generate a fake "implementation scope" containing all the
3370 // implementations thus found, for compatibility with old resolve pass.
3372 fn with_scope(@mut self, name: Option<ident>, f: fn()) {
3373 let orig_module = self.current_module;
3375 // Move down in the graph.
3381 match orig_module.children.find(&name) {
3383 debug!("!!! (with scope) didn't find `%s` in `%s`",
3384 *self.session.str_of(name),
3385 self.module_to_str(orig_module));
3387 Some(name_bindings) => {
3388 match (*name_bindings).get_module_if_available() {
3390 debug!("!!! (with scope) didn't find module \
3392 *self.session.str_of(name),
3393 self.module_to_str(orig_module));
3396 self.current_module = module_;
3406 self.current_module = orig_module;
3409 // Wraps the given definition in the appropriate number of `def_upvar`
3412 fn upvarify(@mut self,
3417 allow_capturing_self: AllowCapturingSelfFlag)
3418 -> Option<def_like> {
3420 let mut is_ty_param;
3423 dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
3424 dl_def(d @ def_arg(*)) | dl_def(d @ def_binding(*)) => {
3426 is_ty_param = false;
3428 dl_def(d @ def_ty_param(*)) => {
3432 dl_def(d @ def_self(*))
3433 if allow_capturing_self == DontAllowCapturingSelf => {
3435 is_ty_param = false;
3438 return Some(def_like);
3442 let mut rib_index = rib_index + 1;
3443 while rib_index < (*ribs).len() {
3444 let rib = (*ribs).get_elt(rib_index);
3447 // Nothing to do. Continue.
3449 FunctionRibKind(function_id, body_id) => {
3451 def = def_upvar(def_id_of_def(def).node,
3457 MethodRibKind(item_id, _) => {
3458 // If the def is a ty param, and came from the parent
3461 def_ty_param(did, _) if self.def_map.find(&did.node)
3462 == Some(def_typaram_binder(item_id)) => {
3467 // This was an attempt to access an upvar inside a
3468 // named function item. This is not allowed, so we
3471 self.session.span_err(
3473 ~"attempted dynamic environment-capture");
3475 // This was an attempt to use a type parameter outside
3478 self.session.span_err(span,
3479 ~"attempt to use a type \
3480 argument out of scope");
3487 OpaqueFunctionRibKind => {
3489 // This was an attempt to access an upvar inside a
3490 // named function item. This is not allowed, so we
3493 self.session.span_err(
3495 ~"attempted dynamic environment-capture");
3497 // This was an attempt to use a type parameter outside
3500 self.session.span_err(span,
3501 ~"attempt to use a type \
3502 argument out of scope");
3507 ConstantItemRibKind => {
3508 // Still doesn't deal with upvars
3509 self.session.span_err(span,
3510 ~"attempt to use a non-constant \
3511 value in a constant");
3519 return Some(dl_def(def));
3522 fn search_ribs(@mut self,
3526 allow_capturing_self: AllowCapturingSelfFlag)
3527 -> Option<def_like> {
3528 // FIXME #4950: This should not use a while loop.
3529 // FIXME #4950: Try caching?
3531 let mut i = (*ribs).len();
3534 let rib = (*ribs).get_elt(i);
3535 match rib.bindings.find(&name) {
3537 return self.upvarify(ribs, i, def_like, span,
3538 allow_capturing_self);
3549 fn resolve_crate(@mut self) {
3550 debug!("(resolving crate) starting");
3552 visit_crate(*self.crate, (), mk_vt(@Visitor {
3553 visit_item: |item, _context, visitor|
3554 self.resolve_item(item, visitor),
3555 visit_arm: |arm, _context, visitor|
3556 self.resolve_arm(arm, visitor),
3557 visit_block: |block, _context, visitor|
3558 self.resolve_block(block, visitor),
3559 visit_expr: |expr, _context, visitor|
3560 self.resolve_expr(expr, visitor),
3561 visit_local: |local, _context, visitor|
3562 self.resolve_local(local, visitor),
3563 visit_ty: |ty, _context, visitor|
3564 self.resolve_type(ty, visitor),
3565 .. *default_visitor()
3569 fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
3570 debug!("(resolving item) resolving %s",
3571 *self.session.str_of(item.ident));
3573 // Items with the !resolve_unexported attribute are X-ray contexts.
3574 // This is used to allow the test runner to run unexported tests.
3575 let orig_xray_flag = self.xray_context;
3576 if contains_name(attr_metas(/*bad*/copy item.attrs),
3577 ~"!resolve_unexported") {
3578 self.xray_context = Xray;
3581 match /*bad*/copy item.node {
3583 // enum item: resolve all the variants' discrs,
3584 // then resolve the ty params
3585 item_enum(ref enum_def, ref type_parameters) => {
3587 for (*enum_def).variants.each() |variant| {
3588 do variant.node.disr_expr.iter() |dis_expr| {
3589 // resolve the discriminator expr
3591 self.with_constant_rib(|| {
3592 self.resolve_expr(*dis_expr, visitor);
3597 // n.b. the discr expr gets visted twice.
3598 // but maybe it's okay since the first time will signal an
3599 // error if there is one? -- tjc
3600 do self.with_type_parameter_rib(
3602 type_parameters, item.id, 0, NormalRibKind)) {
3603 visit_item(item, (), visitor);
3607 item_ty(_, type_parameters) => {
3608 do self.with_type_parameter_rib
3609 (HasTypeParameters(&type_parameters, item.id, 0,
3613 visit_item(item, (), visitor);
3617 item_impl(type_parameters,
3621 self.resolve_implementation(item.id,
3630 item_trait(ref type_parameters, ref traits, ref methods) => {
3631 // Create a new rib for the self type.
3632 let self_type_rib = @Rib(NormalRibKind);
3633 (*self.type_ribs).push(self_type_rib);
3634 self_type_rib.bindings.insert(self.type_self_ident,
3635 dl_def(def_self_ty(item.id)));
3637 // Create a new rib for the trait-wide type parameters.
3638 do self.with_type_parameter_rib
3639 (HasTypeParameters(type_parameters, item.id, 0,
3642 self.resolve_type_parameters(/*bad*/copy *type_parameters,
3645 // Resolve derived traits.
3646 for traits.each |trt| {
3647 match self.resolve_path(trt.path, TypeNS, true,
3650 self.session.span_err(trt.path.span,
3651 ~"attempt to derive a \
3652 nonexistent trait"),
3654 // Write a mapping from the trait ID to the
3655 // definition of the trait into the definition
3658 debug!("(resolving trait) found trait def: \
3661 self.record_def(trt.ref_id, def);
3666 for (*methods).each |method| {
3667 // Create a new rib for the method-specific type
3670 // FIXME #4951: Do we need a node ID here?
3673 required(ref ty_m) => {
3674 do self.with_type_parameter_rib
3675 (HasTypeParameters(&(*ty_m).tps,
3677 type_parameters.len(),
3678 MethodRibKind(item.id, Required))) {
3680 // Resolve the method-specific type
3682 self.resolve_type_parameters(
3683 /*bad*/copy (*ty_m).tps,
3686 for (*ty_m).decl.inputs.each |argument| {
3687 self.resolve_type(argument.ty, visitor);
3690 self.resolve_type(ty_m.decl.output, visitor);
3694 self.resolve_method(MethodRibKind(item.id,
3697 type_parameters.len(),
3704 (*self.type_ribs).pop();
3707 item_struct(struct_def, ty_params) => {
3708 self.resolve_struct(item.id,
3710 /*bad*/copy struct_def.fields,
3715 item_mod(module_) => {
3716 do self.with_scope(Some(item.ident)) {
3717 self.resolve_module(module_, item.span, item.ident,
3722 item_foreign_mod(foreign_module) => {
3723 do self.with_scope(Some(item.ident)) {
3724 for foreign_module.items.each |foreign_item| {
3725 match /*bad*/copy foreign_item.node {
3726 foreign_item_fn(_, _, type_parameters) => {
3727 do self.with_type_parameter_rib
3728 (HasTypeParameters(&type_parameters,
3731 OpaqueFunctionRibKind))
3734 visit_foreign_item(*foreign_item, (),
3738 foreign_item_const(_) => {
3739 visit_foreign_item(*foreign_item, (),
3747 item_fn(ref fn_decl, _, ref ty_params, ref block) => {
3748 // If this is the main function, we must record it in the
3750 // FIXME #4404 android JNI hacks
3751 if !*self.session.building_library ||
3752 self.session.targ_cfg.os == session::os_android {
3754 if self.attr_main_fn.is_none() &&
3755 item.ident == special_idents::main {
3757 self.main_fns.push(Some((item.id, item.span)));
3760 if attrs_contains_name(item.attrs, ~"main") {
3761 if self.attr_main_fn.is_none() {
3762 self.attr_main_fn = Some((item.id, item.span));
3764 self.session.span_err(
3766 ~"multiple 'main' functions");
3771 self.resolve_function(OpaqueFunctionRibKind,
3772 Some(@/*bad*/copy *fn_decl),
3777 OpaqueFunctionRibKind),
3784 self.with_constant_rib(|| {
3785 visit_item(item, (), visitor);
3790 fail!(~"item macros unimplemented")
3794 self.xray_context = orig_xray_flag;
3797 fn with_type_parameter_rib(@mut self,
3798 type_parameters: TypeParameters,
3800 match type_parameters {
3801 HasTypeParameters(type_parameters, node_id, initial_index,
3804 let function_type_rib = @Rib(rib_kind);
3805 (*self.type_ribs).push(function_type_rib);
3807 for (*type_parameters).eachi |index, type_parameter| {
3808 let name = type_parameter.ident;
3809 debug!("with_type_parameter_rib: %d %d", node_id,
3811 let def_like = dl_def(def_ty_param
3812 (local_def(type_parameter.id),
3813 index + initial_index));
3814 // Associate this type parameter with
3815 // the item that bound it
3816 self.record_def(type_parameter.id,
3817 def_typaram_binder(node_id));
3818 (*function_type_rib).bindings.insert(name, def_like);
3822 NoTypeParameters => {
3829 match type_parameters {
3830 HasTypeParameters(*) => {
3831 (*self.type_ribs).pop();
3834 NoTypeParameters => {
3840 fn with_label_rib(@mut self, f: fn()) {
3841 (*self.label_ribs).push(@Rib(NormalRibKind));
3843 (*self.label_ribs).pop();
3846 fn with_constant_rib(@mut self, f: fn()) {
3847 (*self.value_ribs).push(@Rib(ConstantItemRibKind));
3849 (*self.value_ribs).pop();
3852 fn resolve_function(@mut self,
3854 optional_declaration: Option<@fn_decl>,
3855 type_parameters: TypeParameters,
3857 self_binding: SelfBinding,
3858 visitor: ResolveVisitor) {
3859 // Create a value rib for the function.
3860 let function_value_rib = @Rib(rib_kind);
3861 (*self.value_ribs).push(function_value_rib);
3863 // Create a label rib for the function.
3864 let function_label_rib = @Rib(rib_kind);
3865 (*self.label_ribs).push(function_label_rib);
3867 // If this function has type parameters, add them now.
3868 do self.with_type_parameter_rib(type_parameters) {
3869 // Resolve the type parameters.
3870 match type_parameters {
3871 NoTypeParameters => {
3874 HasTypeParameters(type_parameters, _, _, _) => {
3875 self.resolve_type_parameters(/*bad*/copy *type_parameters,
3880 // Add self to the rib, if necessary.
3881 match self_binding {
3885 HasSelfBinding(self_node_id, is_implicit) => {
3886 let def_like = dl_def(def_self(self_node_id,
3888 (*function_value_rib).bindings.insert(self.self_ident,
3893 // Add each argument to the rib.
3894 match optional_declaration {
3898 Some(declaration) => {
3899 for declaration.inputs.each |argument| {
3901 ArgumentIrrefutableMode(argument.mode);
3903 if argument.is_mutbl {Mutable} else {Immutable};
3904 self.resolve_pattern(argument.pat,
3910 self.resolve_type(argument.ty, visitor);
3912 debug!("(resolving function) recorded argument");
3915 self.resolve_type(declaration.output, visitor);
3919 // Resolve the function body.
3920 self.resolve_block(block, visitor);
3922 debug!("(resolving function) leaving function");
3925 (*self.label_ribs).pop();
3926 (*self.value_ribs).pop();
3929 fn resolve_type_parameters(@mut self,
3930 type_parameters: ~[ty_param],
3931 visitor: ResolveVisitor) {
3932 for type_parameters.each |type_parameter| {
3933 for type_parameter.bounds.each |&bound| {
3935 TraitTyParamBound(ty) => self.resolve_type(ty, visitor),
3936 RegionTyParamBound => {}
3942 fn resolve_struct(@mut self,
3944 type_parameters: @~[ty_param],
3945 fields: ~[@struct_field],
3946 optional_destructor: Option<struct_dtor>,
3947 visitor: ResolveVisitor) {
3948 // If applicable, create a rib for the type parameters.
3949 let borrowed_type_parameters: &~[ty_param] = &*type_parameters;
3950 do self.with_type_parameter_rib(HasTypeParameters
3951 (borrowed_type_parameters, id, 0,
3952 OpaqueFunctionRibKind)) {
3954 // Resolve the type parameters.
3955 self.resolve_type_parameters(/*bad*/copy *type_parameters,
3959 for fields.each |field| {
3960 self.resolve_type(field.node.ty, visitor);
3963 // Resolve the destructor, if applicable.
3964 match optional_destructor {
3968 Some(ref destructor) => {
3969 self.resolve_function(NormalRibKind,
3972 (*destructor).node.body,
3974 ((*destructor).node.self_id,
3982 // Does this really need to take a RibKind or is it always going
3983 // to be NormalRibKind?
3984 fn resolve_method(@mut self,
3987 outer_type_parameter_count: uint,
3988 visitor: ResolveVisitor) {
3989 let borrowed_method_type_parameters = &method.tps;
3990 let type_parameters =
3991 HasTypeParameters(borrowed_method_type_parameters,
3993 outer_type_parameter_count,
3995 // we only have self ty if it is a non static method
3996 let self_binding = match method.self_ty.node {
3997 sty_static => { NoSelfBinding }
3998 sty_by_ref => { HasSelfBinding(method.self_id, true) }
3999 _ => { HasSelfBinding(method.self_id, false) }
4002 self.resolve_function(rib_kind,
4003 Some(@/*bad*/copy method.decl),
4010 fn resolve_implementation(@mut self,
4013 type_parameters: ~[ty_param],
4014 opt_trait_reference: Option<@trait_ref>,
4016 methods: ~[@method],
4017 visitor: ResolveVisitor) {
4018 // If applicable, create a rib for the type parameters.
4019 let outer_type_parameter_count = type_parameters.len();
4020 let borrowed_type_parameters: &~[ty_param] = &type_parameters;
4021 do self.with_type_parameter_rib(HasTypeParameters
4022 (borrowed_type_parameters, id, 0,
4024 // Resolve the type parameters.
4025 self.resolve_type_parameters(/*bad*/copy type_parameters,
4028 // Resolve the trait reference, if necessary.
4029 let original_trait_refs = self.current_trait_refs;
4030 match opt_trait_reference {
4031 Some(trait_reference) => {
4032 let new_trait_refs = @DVec();
4033 match self.resolve_path(
4034 trait_reference.path, TypeNS, true, visitor) {
4036 self.session.span_err(span,
4037 ~"attempt to implement an \
4041 self.record_def(trait_reference.ref_id, def);
4043 // Record the current trait reference.
4044 (*new_trait_refs).push(def_id_of_def(def));
4047 // Record the current set of trait references.
4048 self.current_trait_refs = Some(new_trait_refs);
4053 // Resolve the self type.
4054 self.resolve_type(self_type, visitor);
4056 for methods.each |method| {
4057 // We also need a new scope for the method-specific
4059 self.resolve_method(MethodRibKind(
4061 Provided(method.id)),
4063 outer_type_parameter_count,
4066 let borrowed_type_parameters = &method.tps;
4067 self.resolve_function(MethodRibKind(
4069 Provided(method.id)),
4072 (borrowed_type_parameters,
4074 outer_type_parameter_count,
4077 HasSelfBinding(method.self_id),
4082 // Restore the original trait references.
4083 self.current_trait_refs = original_trait_refs;
4087 fn resolve_module(@mut self,
4092 visitor: ResolveVisitor) {
4093 // Write the implementations in scope into the module metadata.
4094 debug!("(resolving module) resolving module ID %d", id);
4095 visit_mod(module_, span, id, (), visitor);
4098 fn resolve_local(@mut self, local: @local, visitor: ResolveVisitor) {
4099 let mutability = if local.node.is_mutbl {Mutable} else {Immutable};
4101 // Resolve the type.
4102 self.resolve_type(local.node.ty, visitor);
4104 // Resolve the initializer, if necessary.
4105 match local.node.init {
4109 Some(initializer) => {
4110 self.resolve_expr(initializer, visitor);
4114 // Resolve the pattern.
4115 self.resolve_pattern(local.node.pat, LocalIrrefutableMode, mutability,
4119 fn binding_mode_map(@mut self, pat: @pat) -> BindingMap {
4120 let result = HashMap();
4121 do pat_bindings(*self.def_map, pat) |binding_mode, _id, sp, path| {
4122 let ident = path_to_ident(path);
4123 result.insert(ident,
4124 binding_info {span: sp,
4125 binding_mode: binding_mode});
4130 fn check_consistent_bindings(@mut self, arm: arm) {
4131 if arm.pats.len() == 0 { return; }
4132 let map_0 = self.binding_mode_map(arm.pats[0]);
4133 for arm.pats.eachi() |i, p| {
4134 let map_i = self.binding_mode_map(*p);
4136 for map_0.each |&key, &binding_0| {
4137 match map_i.find(&key) {
4139 self.session.span_err(
4141 fmt!("variable `%s` from pattern #1 is \
4142 not bound in pattern #%u",
4143 *self.session.str_of(key), i + 1));
4145 Some(binding_i) => {
4146 if binding_0.binding_mode != binding_i.binding_mode {
4147 self.session.span_err(
4149 fmt!("variable `%s` is bound with different \
4150 mode in pattern #%u than in pattern #1",
4151 *self.session.str_of(key), i + 1));
4157 for map_i.each |&key, &binding| {
4158 if !map_0.contains_key(&key) {
4159 self.session.span_err(
4161 fmt!("variable `%s` from pattern #%u is \
4162 not bound in pattern #1",
4163 *self.session.str_of(key), i + 1));
4169 fn resolve_arm(@mut self, arm: arm, visitor: ResolveVisitor) {
4170 (*self.value_ribs).push(@Rib(NormalRibKind));
4172 let bindings_list = HashMap();
4173 for arm.pats.each |pattern| {
4174 self.resolve_pattern(*pattern, RefutableMode, Immutable,
4175 Some(bindings_list), visitor);
4178 // This has to happen *after* we determine which
4179 // pat_idents are variants
4180 self.check_consistent_bindings(arm);
4182 visit_expr_opt(arm.guard, (), visitor);
4183 self.resolve_block(arm.body, visitor);
4185 (*self.value_ribs).pop();
4188 fn resolve_block(@mut self, block: blk, visitor: ResolveVisitor) {
4189 debug!("(resolving block) entering block");
4190 (*self.value_ribs).push(@Rib(NormalRibKind));
4192 // Move down in the graph, if there's an anonymous module rooted here.
4193 let orig_module = self.current_module;
4194 match self.current_module.anonymous_children.find(&block.node.id) {
4195 None => { /* Nothing to do. */ }
4196 Some(anonymous_module) => {
4197 debug!("(resolving block) found anonymous module, moving \
4199 self.current_module = anonymous_module;
4203 // Descend into the block.
4204 visit_block(block, (), visitor);
4207 self.current_module = orig_module;
4209 (*self.value_ribs).pop();
4210 debug!("(resolving block) leaving block");
4213 fn resolve_type(@mut self, ty: @Ty, visitor: ResolveVisitor) {
4215 // Like path expressions, the interpretation of path types depends
4216 // on whether the path has multiple elements in it or not.
4218 ty_path(path, path_id) => {
4219 // This is a path in the type namespace. Walk through scopes
4220 // scopes looking for it.
4221 let mut result_def = None;
4223 // First, check to see whether the name is a primitive type.
4224 if path.idents.len() == 1 {
4225 let name = path.idents.last();
4227 match self.primitive_type_table
4231 Some(primitive_type) => {
4233 Some(def_prim_ty(primitive_type));
4243 match self.resolve_path(path, TypeNS, true, visitor) {
4245 debug!("(resolving type) resolved `%s` to \
4247 *self.session.str_of(
4248 path.idents.last()),
4250 result_def = Some(def);
4262 match copy result_def {
4264 // Write the result into the def map.
4265 debug!("(resolving type) writing resolution for `%s` \
4267 self.idents_to_str(path.idents),
4269 self.record_def(path_id, def);
4272 self.session.span_err
4273 (ty.span, fmt!("use of undeclared type name `%s`",
4274 self.idents_to_str(path.idents)));
4280 // Just resolve embedded types.
4281 visit_ty(ty, (), visitor);
4286 fn resolve_pattern(@mut self,
4288 mode: PatternBindingMode,
4289 mutability: Mutability,
4290 // Maps idents to the node ID for the (outermost)
4291 // pattern that binds them
4292 bindings_list: Option<HashMap<ident,node_id>>,
4293 visitor: ResolveVisitor) {
4294 let pat_id = pattern.id;
4295 do walk_pat(pattern) |pattern| {
4296 match pattern.node {
4297 pat_ident(binding_mode, path, _)
4298 if !path.global && path.idents.len() == 1 => {
4300 // The meaning of pat_ident with no type parameters
4301 // depends on whether an enum variant or unit-like struct
4302 // with that name is in scope. The probing lookup has to
4303 // be careful not to emit spurious errors. Only matching
4304 // patterns (match) can match nullary variants or
4305 // unit-like structs. For binding patterns (let), matching
4306 // such a value is simply disallowed (since it's rarely
4309 let ident = path.idents[0];
4311 match self.resolve_bare_identifier_pattern(ident) {
4312 FoundStructOrEnumVariant(def)
4313 if mode == RefutableMode => {
4314 debug!("(resolving pattern) resolving `%s` to \
4315 struct or enum variant",
4316 *self.session.str_of(ident));
4318 self.enforce_default_binding_mode(
4322 self.record_def(pattern.id, def);
4324 FoundStructOrEnumVariant(_) => {
4325 self.session.span_err(pattern.span,
4326 fmt!("declaration of `%s` \
4328 variant or unit-like \
4333 FoundConst(def) if mode == RefutableMode => {
4334 debug!("(resolving pattern) resolving `%s` to \
4336 *self.session.str_of(ident));
4338 self.enforce_default_binding_mode(
4342 self.record_def(pattern.id, def);
4345 self.session.span_err(pattern.span,
4346 ~"only refutable patterns \
4349 BareIdentifierPatternUnresolved => {
4350 debug!("(resolving pattern) binding `%s`",
4351 *self.session.str_of(ident));
4353 let is_mutable = mutability == Mutable;
4355 let def = match mode {
4357 // For pattern arms, we must use
4358 // `def_binding` definitions.
4360 def_binding(pattern.id, binding_mode)
4362 LocalIrrefutableMode => {
4363 // But for locals, we use `def_local`.
4364 def_local(pattern.id, is_mutable)
4366 ArgumentIrrefutableMode(argument_mode) => {
4367 // And for function arguments, `def_arg`.
4368 def_arg(pattern.id, argument_mode,
4373 // Record the definition so that later passes
4374 // will be able to distinguish variants from
4375 // locals in patterns.
4377 self.record_def(pattern.id, def);
4379 // Add the binding to the local ribs, if it
4380 // doesn't already exist in the bindings list. (We
4381 // must not add it if it's in the bindings list
4382 // because that breaks the assumptions later
4383 // passes make about or-patterns.)
4385 match bindings_list {
4387 if !bindings_list.contains_key(&ident)
4389 let last_rib = (*self.value_ribs).last();
4390 last_rib.bindings.insert(ident,
4392 bindings_list.insert(ident, pat_id);
4395 if b.find(&ident) == Some(pat_id) {
4396 // Then this is a duplicate variable
4397 // in the same disjunct, which is an
4399 self.session.span_err(pattern.span,
4400 fmt!("Identifier %s is bound more \
4401 than once in the same pattern",
4402 path_to_str(path, self.session
4405 // Not bound in the same pattern: do nothing
4408 let last_rib = (*self.value_ribs).last();
4409 last_rib.bindings.insert(ident,
4416 // Check the types in the path pattern.
4417 for path.types.each |ty| {
4418 self.resolve_type(*ty, visitor);
4422 pat_ident(_, path, _) | pat_enum(path, _) => {
4423 // These two must be enum variants or structs.
4424 match self.resolve_path(path, ValueNS, false, visitor) {
4425 Some(def @ def_variant(*)) |
4426 Some(def @ def_struct(*)) => {
4427 self.record_def(pattern.id, def);
4430 self.session.span_err(
4432 fmt!("not an enum variant: %s",
4433 *self.session.str_of(
4434 path.idents.last())));
4437 self.session.span_err(path.span,
4438 ~"unresolved enum variant");
4442 // Check the types in the path pattern.
4443 for path.types.each |ty| {
4444 self.resolve_type(*ty, visitor);
4449 self.resolve_expr(expr, visitor);
4452 pat_range(first_expr, last_expr) => {
4453 self.resolve_expr(first_expr, visitor);
4454 self.resolve_expr(last_expr, visitor);
4457 pat_struct(path, _, _) => {
4458 match self.resolve_path(path, TypeNS, false, visitor) {
4459 Some(def_ty(class_id))
4460 if self.structs.contains_key(&class_id)
4462 let class_def = def_struct(class_id);
4463 self.record_def(pattern.id, class_def);
4465 Some(definition @ def_struct(class_id))
4466 if self.structs.contains_key(&class_id)
4468 self.record_def(pattern.id, definition);
4470 Some(definition @ def_variant(_, variant_id))
4471 if self.structs.contains_key(&variant_id)
4473 self.record_def(pattern.id, definition);
4476 debug!("(resolving pattern) didn't find struct \
4478 self.session.span_err(
4480 fmt!("`%s` does not name a structure",
4481 self.idents_to_str(path.idents)));
4493 fn resolve_bare_identifier_pattern(@mut self, name: ident)
4494 -> BareIdentifierPatternResolution {
4495 match self.resolve_item_in_lexical_scope(self.current_module,
4498 SearchThroughModules) {
4499 Success(target) => {
4500 match target.bindings.value_def {
4502 fail!(~"resolved name in the value namespace to a \
4503 set of name bindings with no def?!");
4507 def @ def_variant(*) | def @ def_struct(*) => {
4508 return FoundStructOrEnumVariant(def);
4510 def @ def_const(*) => {
4511 return FoundConst(def);
4514 return BareIdentifierPatternUnresolved;
4522 fail!(~"unexpected indeterminate result");
4526 return BareIdentifierPatternUnresolved;
4532 * If `check_ribs` is true, checks the local definitions first; i.e.
4533 * doesn't skip straight to the containing module.
4535 fn resolve_path(@mut self,
4537 namespace: Namespace,
4539 visitor: ResolveVisitor)
4541 // First, resolve the types.
4542 for path.types.each |ty| {
4543 self.resolve_type(*ty, visitor);
4547 return self.resolve_crate_relative_path(path,
4552 if path.idents.len() > 1 {
4553 return self.resolve_module_relative_path(path,
4558 return self.resolve_identifier(path.idents.last(),
4564 fn resolve_identifier(@mut self,
4566 namespace: Namespace,
4571 match self.resolve_identifier_in_local_ribs(identifier,
4583 return self.resolve_item_by_identifier_in_lexical_scope(identifier,
4587 // FIXME #4952: Merge me with resolve_name_in_module?
4588 fn resolve_definition_of_name_in_module(@mut self,
4589 containing_module: @mut Module,
4591 namespace: Namespace,
4594 // First, search children.
4595 match containing_module.children.find(&name) {
4596 Some(child_name_bindings) => {
4597 match (child_name_bindings.def_for_namespace(namespace),
4598 child_name_bindings.privacy_for_namespace(namespace)) {
4599 (Some(def), Some(Public)) => {
4600 // Found it. Stop the search here.
4601 return ChildNameDefinition(def);
4603 (Some(def), _) if xray == Xray => {
4604 // Found it. Stop the search here.
4605 return ChildNameDefinition(def);
4607 (Some(_), _) | (None, _) => {
4617 // Next, search import resolutions.
4618 match containing_module.import_resolutions.find(&name) {
4619 Some(import_resolution) if import_resolution.privacy == Public ||
4621 match (*import_resolution).target_for_namespace(namespace) {
4623 match (target.bindings.def_for_namespace(namespace),
4624 target.bindings.privacy_for_namespace(
4626 (Some(def), Some(Public)) => {
4628 import_resolution.state.used = true;
4629 return ImportNameDefinition(def);
4631 (Some(_), _) | (None, _) => {
4632 // This can happen with external impls, due to
4633 // the imperfect way we read the metadata.
4635 return NoNameDefinition;
4640 return NoNameDefinition;
4645 return NoNameDefinition;
4650 fn intern_module_part_of_path(@mut self, path: @path) -> @DVec<ident> {
4651 let module_path_idents = @DVec();
4652 for path.idents.eachi |index, ident| {
4653 if index == path.idents.len() - 1 {
4657 (*module_path_idents).push(*ident);
4660 return module_path_idents;
4663 fn resolve_module_relative_path(@mut self,
4666 namespace: Namespace)
4668 let module_path_idents = self.intern_module_part_of_path(path);
4670 let mut containing_module;
4671 match self.resolve_module_path_for_import(self.current_module,
4676 self.session.span_err(path.span,
4677 fmt!("use of undeclared module `%s`",
4679 (*module_path_idents).get())));
4684 fail!(~"indeterminate unexpected");
4687 Success(resulting_module) => {
4688 containing_module = resulting_module;
4692 let name = path.idents.last();
4693 match self.resolve_definition_of_name_in_module(containing_module,
4697 NoNameDefinition => {
4698 // We failed to resolve the name. Report an error.
4701 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4707 fn resolve_crate_relative_path(@mut self,
4710 namespace: Namespace)
4712 let module_path_idents = self.intern_module_part_of_path(path);
4714 let root_module = self.graph_root.get_module();
4716 let mut containing_module;
4717 match self.resolve_module_path_from_root(root_module,
4723 self.session.span_err(path.span,
4724 fmt!("use of undeclared module `::%s`",
4726 ((*module_path_idents).get())));
4731 fail!(~"indeterminate unexpected");
4734 Success(resulting_module) => {
4735 containing_module = resulting_module;
4739 let name = path.idents.last();
4740 match self.resolve_definition_of_name_in_module(containing_module,
4744 NoNameDefinition => {
4745 // We failed to resolve the name. Report an error.
4748 ChildNameDefinition(def) | ImportNameDefinition(def) => {
4754 fn resolve_identifier_in_local_ribs(@mut self,
4756 namespace: Namespace,
4759 // Check the local set of ribs.
4760 let mut search_result;
4763 search_result = self.search_ribs(self.value_ribs, ident, span,
4764 DontAllowCapturingSelf);
4767 search_result = self.search_ribs(self.type_ribs, ident, span,
4768 AllowCapturingSelf);
4772 match copy search_result {
4773 Some(dl_def(def)) => {
4774 debug!("(resolving path in local ribs) resolved `%s` to \
4776 *self.session.str_of(ident),
4780 Some(dl_field) | Some(dl_impl(_)) | None => {
4786 fn resolve_item_by_identifier_in_lexical_scope(@mut self,
4788 namespace: Namespace)
4791 match self.resolve_item_in_lexical_scope(self.current_module,
4794 DontSearchThroughModules) {
4795 Success(target) => {
4796 match (*target.bindings).def_for_namespace(namespace) {
4798 // This can happen if we were looking for a type and
4799 // found a module instead. Modules don't have defs.
4803 debug!("(resolving item path in lexical scope) \
4804 resolved `%s` to item",
4805 *self.session.str_of(ident));
4811 fail!(~"unexpected indeterminate result");
4819 fn find_best_match_for_name(@mut self, name: &str) -> Option<~str> {
4820 let mut maybes: ~[~str] = ~[];
4821 let mut values: ~[uint] = ~[];
4823 let mut j = self.value_ribs.len();
4826 let rib = self.value_ribs.get_elt(j);
4827 for rib.bindings.each_entry |e| {
4828 vec::push(&mut maybes, copy *self.session.str_of(e.key));
4829 vec::push(&mut values, uint::max_value);
4833 // Levenshtein Distance between two strings
4834 fn distance(s: &str, t: &str) -> uint {
4836 let slen = str::len(s);
4837 let tlen = str::len(t);
4839 if slen == 0 { return tlen; }
4840 if tlen == 0 { return slen; }
4842 let mut dcol = vec::from_fn(tlen + 1, |x| x);
4844 for str::each_chari(s) |i, sc| {
4846 let mut current = i;
4847 dcol[0] = current + 1;
4849 for str::each_chari(t) |j, tc| {
4851 let mut next = dcol[j + 1];
4854 dcol[j + 1] = current;
4856 dcol[j + 1] = cmp::min(current, next);
4857 dcol[j + 1] = cmp::min(dcol[j + 1], dcol[j]) + 1;
4867 let mut smallest = 0;
4868 for vec::eachi(maybes) |i, &other| {
4870 values[i] = distance(name, other);
4872 if values[i] <= values[smallest] {
4877 if vec::len(values) > 0 &&
4878 values[smallest] != uint::max_value &&
4879 values[smallest] < str::len(name) + 2 {
4881 Some(vec::swap_remove(&mut maybes, smallest))
4888 fn name_exists_in_scope_struct(@mut self, name: &str) -> bool {
4889 let mut i = self.type_ribs.len();
4892 let rib = self.type_ribs.get_elt(i);
4894 MethodRibKind(node_id, _) =>
4895 for self.crate.node.module.items.each |item| {
4896 if item.id == node_id {
4898 item_struct(class_def, _) => {
4899 for vec::each(class_def.fields) |field| {
4900 match field.node.kind {
4901 unnamed_field => {},
4902 named_field(ident, _, _) => {
4903 if str::eq_slice(*self.session.str_of(ident),
4921 fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) {
4922 // First, record candidate traits for this expression if it could
4923 // result in the invocation of a method call.
4925 self.record_candidate_traits_for_expr_if_necessary(expr);
4927 // Next, resolve the node.
4929 // The interpretation of paths depends on whether the path has
4930 // multiple elements in it or not.
4932 expr_path(path) => {
4933 // This is a local path in the value namespace. Walk through
4934 // scopes looking for it.
4936 match self.resolve_path(path, ValueNS, true, visitor) {
4938 // Write the result into the def map.
4939 debug!("(resolving expr) resolved `%s`",
4940 self.idents_to_str(path.idents));
4941 self.record_def(expr.id, def);
4944 let wrong_name = self.idents_to_str(
4945 /*bad*/copy path.idents);
4946 if self.name_exists_in_scope_struct(wrong_name) {
4947 self.session.span_err(expr.span,
4948 fmt!("unresolved name: `%s`. \
4949 Did you mean: `self.%s`?",
4954 match self.find_best_match_for_name(wrong_name) {
4957 self.session.span_err(expr.span,
4958 fmt!("unresolved name: `%s`. \
4959 Did you mean: `%s`?",
4963 self.session.span_err(expr.span,
4964 fmt!("unresolved name: `%s`.",
4972 visit_expr(expr, (), visitor);
4975 expr_fn(_, ref fn_decl, ref block, _) |
4976 expr_fn_block(ref fn_decl, ref block) => {
4977 self.resolve_function(FunctionRibKind(expr.id, block.node.id),
4978 Some(@/*bad*/copy *fn_decl),
4985 expr_struct(path, _, _) => {
4986 // Resolve the path to the structure it goes to.
4987 match self.resolve_path(path, TypeNS, false, visitor) {
4988 Some(def_ty(class_id)) | Some(def_struct(class_id))
4989 if self.structs.contains_key(&class_id) => {
4990 let class_def = def_struct(class_id);
4991 self.record_def(expr.id, class_def);
4993 Some(definition @ def_variant(_, class_id))
4994 if self.structs.contains_key(&class_id) => {
4995 self.record_def(expr.id, definition);
4998 self.session.span_err(
5000 fmt!("`%s` does not name a structure",
5001 self.idents_to_str(path.idents)));
5005 visit_expr(expr, (), visitor);
5008 expr_loop(_, Some(label)) => {
5009 do self.with_label_rib {
5010 let def_like = dl_def(def_label(expr.id));
5011 self.label_ribs.last().bindings.insert(label, def_like);
5013 visit_expr(expr, (), visitor);
5017 expr_break(Some(label)) | expr_again(Some(label)) => {
5018 match self.search_ribs(self.label_ribs, label, expr.span,
5019 DontAllowCapturingSelf) {
5021 self.session.span_err(expr.span,
5022 fmt!("use of undeclared label \
5024 *self.session.str_of(
5026 Some(dl_def(def @ def_label(_))) =>
5027 self.record_def(expr.id, def),
5029 self.session.span_bug(expr.span,
5030 ~"label wasn't mapped to a \
5036 visit_expr(expr, (), visitor);
5041 fn record_candidate_traits_for_expr_if_necessary(@mut self, expr: @expr) {
5043 expr_field(_, ident, _) => {
5044 let traits = self.search_for_traits_containing_method(ident);
5045 self.trait_map.insert(expr.id, traits);
5047 expr_method_call(_, ident, _, _, _) => {
5048 let traits = self.search_for_traits_containing_method(ident);
5049 self.trait_map.insert(expr.id, traits);
5051 expr_binary(add, _, _) | expr_assign_op(add, _, _) => {
5052 self.add_fixed_trait_for_expr(expr.id,
5053 self.lang_items.add_trait());
5055 expr_binary(subtract, _, _) | expr_assign_op(subtract, _, _) => {
5056 self.add_fixed_trait_for_expr(expr.id,
5057 self.lang_items.sub_trait());
5059 expr_binary(mul, _, _) | expr_assign_op(mul, _, _) => {
5060 self.add_fixed_trait_for_expr(expr.id,
5061 self.lang_items.mul_trait());
5063 expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
5064 self.add_fixed_trait_for_expr(expr.id,
5065 self.lang_items.div_trait());
5067 expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
5068 self.add_fixed_trait_for_expr(expr.id,
5069 self.lang_items.modulo_trait());
5071 expr_binary(bitxor, _, _) | expr_assign_op(bitxor, _, _) => {
5072 self.add_fixed_trait_for_expr(expr.id,
5073 self.lang_items.bitxor_trait());
5075 expr_binary(bitand, _, _) | expr_assign_op(bitand, _, _) => {
5076 self.add_fixed_trait_for_expr(expr.id,
5077 self.lang_items.bitand_trait());
5079 expr_binary(bitor, _, _) | expr_assign_op(bitor, _, _) => {
5080 self.add_fixed_trait_for_expr(expr.id,
5081 self.lang_items.bitor_trait());
5083 expr_binary(shl, _, _) | expr_assign_op(shl, _, _) => {
5084 self.add_fixed_trait_for_expr(expr.id,
5085 self.lang_items.shl_trait());
5087 expr_binary(shr, _, _) | expr_assign_op(shr, _, _) => {
5088 self.add_fixed_trait_for_expr(expr.id,
5089 self.lang_items.shr_trait());
5091 expr_binary(lt, _, _) | expr_binary(le, _, _) |
5092 expr_binary(ge, _, _) | expr_binary(gt, _, _) => {
5093 self.add_fixed_trait_for_expr(expr.id,
5094 self.lang_items.ord_trait());
5096 expr_binary(eq, _, _) | expr_binary(ne, _, _) => {
5097 self.add_fixed_trait_for_expr(expr.id,
5098 self.lang_items.eq_trait());
5100 expr_unary(neg, _) => {
5101 self.add_fixed_trait_for_expr(expr.id,
5102 self.lang_items.neg_trait());
5104 expr_unary(not, _) => {
5105 self.add_fixed_trait_for_expr(expr.id,
5106 self.lang_items.not_trait());
5109 self.add_fixed_trait_for_expr(expr.id,
5110 self.lang_items.index_trait());
5118 fn search_for_traits_containing_method(@mut self,
5121 debug!("(searching for traits containing method) looking for '%s'",
5122 *self.session.str_of(name));
5124 let found_traits = @DVec();
5125 let mut search_module = self.current_module;
5127 // Look for the current trait.
5128 match copy self.current_trait_refs {
5129 Some(trait_def_ids) => {
5130 for trait_def_ids.each |trait_def_id| {
5131 self.add_trait_info_if_containing_method(
5132 found_traits, *trait_def_id, name);
5140 // Look for trait children.
5141 for search_module.children.each_value |&child_name_bindings| {
5142 match child_name_bindings.def_for_namespace(TypeNS) {
5145 def_ty(trait_def_id) => {
5146 self.add_trait_info_if_containing_method(
5147 found_traits, trait_def_id, name);
5160 // Look for imports.
5161 for search_module.import_resolutions.each_value
5162 |&import_resolution| {
5164 match import_resolution.target_for_namespace(TypeNS) {
5169 match target.bindings.def_for_namespace(TypeNS) {
5172 def_ty(trait_def_id) => {
5174 add_trait_info_if_containing_method(
5175 found_traits, trait_def_id, name);
5177 import_resolution.state.used =
5194 // Move to the next parent.
5195 match search_module.parent_link {
5200 ModuleParentLink(parent_module, _) |
5201 BlockParentLink(parent_module, _) => {
5202 search_module = parent_module;
5207 return found_traits;
5210 fn add_trait_info_if_containing_method(@mut self,
5211 found_traits: @DVec<def_id>,
5212 trait_def_id: def_id,
5215 debug!("(adding trait info if containing method) trying trait %d:%d \
5219 *self.session.str_of(name));
5221 match self.trait_info.find(&trait_def_id) {
5222 Some(trait_info) if trait_info.contains_key(&name) => {
5223 debug!("(adding trait info if containing method) found trait \
5224 %d:%d for method '%s'",
5227 *self.session.str_of(name));
5228 (*found_traits).push(trait_def_id);
5237 fn add_fixed_trait_for_expr(@mut self,
5239 +trait_id: def_id) {
5240 let traits = @DVec();
5241 traits.push(trait_id);
5242 self.trait_map.insert(expr_id, traits);
5245 fn record_def(@mut self, node_id: node_id, def: def) {
5246 debug!("(recording def) recording %? for %?", def, node_id);
5247 self.def_map.insert(node_id, def);
5250 fn enforce_default_binding_mode(@mut self,
5252 pat_binding_mode: binding_mode,
5254 match pat_binding_mode {
5257 self.session.span_err(
5259 fmt!("cannot use `copy` binding mode with %s",
5263 self.session.span_err(
5265 fmt!("cannot use `ref` binding mode with %s",
5272 // main function checking
5274 // be sure that there is only one main function
5276 fn check_duplicate_main(@mut self) {
5277 if self.attr_main_fn.is_none() {
5278 if self.main_fns.len() >= 1u {
5280 while i < self.main_fns.len() {
5281 let (_, dup_main_span) =
5282 option::unwrap(self.main_fns[i]);
5283 self.session.span_err(
5285 ~"multiple 'main' functions");
5288 *self.session.main_fn = self.main_fns[0];
5291 *self.session.main_fn = self.attr_main_fn;
5296 // Unused import checking
5298 // Although this is a lint pass, it lives in here because it depends on
5299 // resolve data structures.
5302 fn unused_import_lint_level(@mut self, m: @mut Module) -> level {
5303 let settings = self.session.lint_settings;
5305 Some(def) => get_lint_settings_level(settings, unused_imports,
5306 def.node, def.node),
5307 None => get_lint_level(settings.default_settings, unused_imports)
5311 fn check_for_unused_imports_if_necessary(@mut self) {
5312 if self.unused_import_lint_level(self.current_module) == allow {
5316 let root_module = self.graph_root.get_module();
5317 self.check_for_unused_imports_in_module_subtree(root_module);
5320 fn check_for_unused_imports_in_module_subtree(@mut self,
5321 module_: @mut Module) {
5322 // If this isn't a local crate, then bail out. We don't need to check
5323 // for unused imports in external crates.
5325 match module_.def_id {
5326 Some(def_id) if def_id.crate == local_crate => {
5330 // Check for unused imports in the root module.
5334 debug!("(checking for unused imports in module subtree) not \
5335 checking for unused imports for `%s`",
5336 self.module_to_str(module_));
5341 self.check_for_unused_imports_in_module(module_);
5343 for module_.children.each_value |&child_name_bindings| {
5344 match (*child_name_bindings).get_module_if_available() {
5348 Some(child_module) => {
5349 self.check_for_unused_imports_in_module_subtree
5355 for module_.anonymous_children.each_value |&child_module| {
5356 self.check_for_unused_imports_in_module_subtree(child_module);
5360 fn check_for_unused_imports_in_module(@mut self, module_: @mut Module) {
5361 for module_.import_resolutions.each_value |&import_resolution| {
5362 // Ignore dummy spans for things like automatically injected
5363 // imports for the prelude, and also don't warn about the same
5364 // import statement being unused more than once. Furthermore, if
5365 // the import is public, then we can't be sure whether it's unused
5366 // or not so don't warn about it.
5367 if !import_resolution.state.used &&
5368 !import_resolution.state.warned &&
5369 import_resolution.span != dummy_sp() &&
5370 import_resolution.privacy != Public {
5371 import_resolution.state.warned = true;
5372 match self.unused_import_lint_level(module_) {
5374 self.session.span_warn(copy import_resolution.span,
5378 self.session.span_err(copy import_resolution.span,
5391 // Diagnostics are not particularly efficient, because they're rarely
5395 /// A somewhat inefficient routine to obtain the name of a module.
5396 fn module_to_str(@mut self, module_: @mut Module) -> ~str {
5397 let idents = DVec();
5398 let mut current_module = module_;
5400 match current_module.parent_link {
5404 ModuleParentLink(module_, name) => {
5406 current_module = module_;
5408 BlockParentLink(module_, _) => {
5409 idents.push(special_idents::opaque);
5410 current_module = module_;
5415 if idents.len() == 0 {
5418 return self.idents_to_str(vec::reversed(idents.get()));
5421 fn dump_module(@mut self, module_: @mut Module) {
5422 debug!("Dump of module `%s`:", self.module_to_str(module_));
5424 debug!("Children:");
5425 for module_.children.each_key |&name| {
5426 debug!("* %s", *self.session.str_of(name));
5429 debug!("Import resolutions:");
5430 for module_.import_resolutions.each |&name, &import_resolution| {
5432 match (*import_resolution).target_for_namespace(ValueNS) {
5433 None => { value_repr = ~""; }
5435 value_repr = ~" value:?";
5441 match (*import_resolution).target_for_namespace(TypeNS) {
5442 None => { type_repr = ~""; }
5444 type_repr = ~" type:?";
5449 debug!("* %s:%s%s", *self.session.str_of(name),
5450 value_repr, type_repr);
5455 pub struct CrateMap {
5457 exp_map2: ExportMap2,
5461 /// Entry point to crate resolution.
5462 pub fn resolve_crate(session: Session,
5463 lang_items: LanguageItems,
5466 let resolver = @mut Resolver(session, lang_items, crate);
5469 def_map: *resolver.def_map,
5470 exp_map2: *resolver.export_map2,
5471 trait_map: resolver.trait_map