about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-05-13 16:46:20 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-05-13 17:20:46 +0200
commitae26b775b4ae4a1405effefb015ec44f0311c29f (patch)
tree33b7104df2b9fcebca3b74a6b319a8a695a3c907 /src/comp
parenteb419fd8c78f907f1a5cd20f5e71009ba37ef7e9 (diff)
downloadrust-ae26b775b4ae4a1405effefb015ec44f0311c29f.tar.gz
rust-ae26b775b4ae4a1405effefb015ec44f0311c29f.zip
Implement module namespaces
Module names no longer clash with type and value names. The
tokenizer/parser still needs to be taught to be more careful in
identifying keywords, so that we can use 'str' and 'vec' and so as
module names.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/resolve.rs142
1 files changed, 72 insertions, 70 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index ad1a5fe926a..f530d3f412f 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -44,7 +44,9 @@ tag scope {
 tag import_state {
     todo(@ast::view_item, list[scope]);
     resolving(span);
-    resolved(option::t[def] /* value */, option::t[def] /* type */);
+    resolved(option::t[def] /* value */,
+             option::t[def] /* type */,
+             option::t[def] /* module */);
 }
 
 type ext_hash = hashmap[tup(def_id,str,namespace),def];
@@ -97,6 +99,7 @@ tag dir { inside; outside; }
 tag namespace {
     ns_value;
     ns_type;
+    ns_module;
 }
 
 fn resolve_crate(session sess, @ast::crate crate) -> def_map {
@@ -159,7 +162,7 @@ fn resolve_imports(&env e) {
             case (todo(?item, ?sc)) {
                 resolve_import(e, item, sc);
             }
-            case (resolved(_, _)) {}
+            case (resolved(_, _, _)) {}
         }
     }
 }
@@ -324,51 +327,45 @@ fn resolve_import(&env e, &@ast::view_item it, &list[scope] sc) {
     if (n_idents == 1u) {
         register(e, defid, it.span, end_id,
                  lookup_in_scope(e, sc, it.span, end_id, ns_value),
-                 lookup_in_scope(e, sc, it.span, end_id, ns_type));
+                 lookup_in_scope(e, sc, it.span, end_id, ns_type),
+                 lookup_in_scope(e, sc, it.span, end_id, ns_module));
     } else {
-        auto dcur = lookup_in_scope_strict(e, sc, it.span, ids.(0), ns_value);
+        auto dcur = lookup_in_scope_strict(e, sc, it.span, ids.(0),
+                                           ns_module);
         auto i = 1u;
         while (true) {
-            if (!is_module(dcur)) {
-                e.sess.span_err(it.span, ids.(i-1u) +
-                                " is not a module or crate");
-            }
             if (i == n_idents - 1u) {
                 register(e, defid, it.span, end_id,
                          lookup_in_mod(e, dcur, end_id, ns_value, outside),
-                         lookup_in_mod(e, dcur, end_id, ns_type, outside));
+                         lookup_in_mod(e, dcur, end_id, ns_type, outside),
+                         lookup_in_mod(e, dcur, end_id, ns_module, outside));
                 break;
             } else {
                 dcur = lookup_in_mod_strict(e, dcur, it.span, ids.(i),
-                                            ns_value, outside);
+                                            ns_module, outside);
                 i += 1u;
             }
         }
     }
 
     fn register(&env e, def_id defid, &span sp, &ident id,
-                &option::t[def] val, &option::t[def] typ) {
-        if (option::is_none(val) && option::is_none(typ)) {
+                &option::t[def] val, &option::t[def] typ,
+                &option::t[def] md) {
+        if (option::is_none(val) && option::is_none(typ) &&
+            option::is_none(md)) {
             unresolved(e, sp, id, "import");
         }
-        e.imports.insert(defid._1, resolved(val, typ));
+        e.imports.insert(defid._1, resolved(val, typ, md));
     }
 }
 
 // Utilities
 
-fn is_module(def d) -> bool {
-    alt (d) {
-        case (ast::def_mod(_)) { ret true; }
-        case (ast::def_native_mod(_)) { ret true; }
-        case (_) { ret false; }
-    }
-}
-
 fn ns_name(namespace ns) -> str {
     alt (ns) {
         case (ns_type) { ret "typename"; }
         case (ns_value) { ret "name"; }
+        case (ns_module) { ret "modulename"; }
     }
 }
 
@@ -381,20 +378,14 @@ fn unresolved(&env e, &span sp, &ident id, &str kind) {
 fn lookup_path_strict(&env e, &list[scope] sc, &span sp, vec[ident] idents,
                       namespace ns) -> def {
     auto n_idents = _vec::len(idents);
-    auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), ns);
+    auto headns = if (n_idents == 1u) { ns } else { ns_module };
+    auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns);
     auto i = 1u;
     while (i < n_idents) {
-        if (!is_module(dcur)) {
-            e.sess.span_err(sp, idents.(i-1u) +
-                            " can't be dereferenced as a module");
-        }
-        dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), ns, outside);
+        auto curns = if (n_idents == i + 1u) { ns } else { ns_module };
+        dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), curns, outside);
         i += 1u;
     }
-    if (is_module(dcur)) {
-        e.sess.span_err(sp, _str::connect(idents, "::") +
-                        " is a module, not a " + ns_name(ns));
-    }
     ret dcur;
 }
                       
@@ -566,29 +557,37 @@ fn lookup_in_pat(&ident id, &ast::pat pat) -> option::t[def] {
 
 fn lookup_in_fn(&ident id, &ast::fn_decl decl, &vec[ast::ty_param] ty_params,
                 namespace ns) -> option::t[def] {
-    if (ns == ns_value) {
-        for (ast::arg a in decl.inputs) {
-            if (_str::eq(a.ident, id)) {
-                ret some(ast::def_arg(a.id));
+    alt (ns) {
+        case (ns_value) {
+            for (ast::arg a in decl.inputs) {
+                if (_str::eq(a.ident, id)) {
+                    ret some(ast::def_arg(a.id));
+                }
             }
+            ret none[def];
         }
-        ret none[def];
-    } else {
-        ret lookup_in_ty_params(id, ty_params);
+        case (ns_type) {
+            ret lookup_in_ty_params(id, ty_params);
+        }
+        case (_) { ret none[def]; }
     }
 }
 
 fn lookup_in_obj(&ident id, &ast::_obj ob, &vec[ast::ty_param] ty_params,
                  namespace ns) -> option::t[def] {
-    if (ns == ns_value) {
-        for (ast::obj_field f in ob.fields) {
-            if (_str::eq(f.ident, id)) {
-                ret some(ast::def_obj_field(f.id));
+    alt (ns) {
+        case (ns_value) {
+            for (ast::obj_field f in ob.fields) {
+                if (_str::eq(f.ident, id)) {
+                    ret some(ast::def_obj_field(f.id));
+                }
             }
+            ret none[def];
         }
-        ret none[def];
-    } else {
-        ret lookup_in_ty_params(id, ty_params);
+        case (ns_type) {
+            ret lookup_in_ty_params(id, ty_params);
+        }
+        case (_) { ret none[def]; }
     }
 }
 
@@ -611,7 +610,7 @@ fn lookup_in_block(&ident id, &ast::block_ b, namespace ns)
                                     if (_str::eq(name, id)) {
                                         ret some(ast::def_ty(defid));
                                     }
-                                } else {
+                                } else if (ns == ns_value) {
                                     for (ast::variant v in variants) {
                                         if (_str::eq(v.node.name, id)) {
                                             ret some(ast::def_variant(
@@ -623,7 +622,7 @@ fn lookup_in_block(&ident id, &ast::block_ b, namespace ns)
                             case (_) {
                                 if (_str::eq(ast::item_ident(it), id)) {
                                     auto found = found_def_item(it, ns);
-                                    if (!option::is_none(found)) { ret found; }
+                                    if (!option::is_none(found)) {ret found;}
                                 }
                             }
                         }
@@ -645,10 +644,10 @@ fn found_def_item(@ast::item i, namespace ns) -> option::t[def] {
             if (ns == ns_value) { ret some(ast::def_fn(defid)); }
         }
         case (ast::item_mod(_, _, ?defid)) {
-            ret some(ast::def_mod(defid));
+            if (ns == ns_module) { ret some(ast::def_mod(defid)); }
         }
         case (ast::item_native_mod(_, _, ?defid)) {
-            ret some(ast::def_native_mod(defid));
+            if (ns == ns_module) { ret some(ast::def_native_mod(defid)); }
         }
         case (ast::item_ty(_, _, _, ?defid, _)) {
             if (ns == ns_type) { ret some(ast::def_ty(defid)); }
@@ -657,8 +656,11 @@ fn found_def_item(@ast::item i, namespace ns) -> option::t[def] {
             if (ns == ns_type) { ret some(ast::def_ty(defid)); }
         }
         case (ast::item_obj(_, _, _, ?odid, _)) {
-            if (ns == ns_value) { ret some(ast::def_obj(odid.ctor)); }
-            else { ret some(ast::def_obj(odid.ty)); }
+            alt (ns) {
+                case (ns_value) { ret some(ast::def_obj(odid.ctor)); }
+                case (ns_type) { ret some(ast::def_obj(odid.ty)); }
+                case (_) { }
+            }
         }
         case (_) { }
     }
@@ -725,9 +727,10 @@ fn lookup_import(&env e, def_id defid, namespace ns) -> option::t[def] {
         case (resolving(?sp)) {
             e.sess.span_err(sp, "cyclic import");
         }
-        case (resolved(?val, ?typ)) {
+        case (resolved(?val, ?typ, ?md)) {
             ret alt (ns) { case (ns_value) { val }
-                           case (ns_type) { typ } };
+                           case (ns_type) { typ }
+                           case (ns_module) { md } };
         }
     }
 }
@@ -917,23 +920,22 @@ fn index_nmod(&ast::native_mod md) -> nmod_index {
 
 // External lookups
 
-// FIXME creader should handle multiple namespaces
-fn check_def_by_ns(def d, namespace ns) -> bool {
+fn ns_for_def(def d) -> namespace {
     ret alt (d) {
-        case (ast::def_fn(?id)) { ns == ns_value }
-        case (ast::def_obj(?id)) { ns == ns_value }
-        case (ast::def_obj_field(?id)) { ns == ns_value }
-        case (ast::def_mod(?id)) { true }
-        case (ast::def_native_mod(?id)) { true }
-        case (ast::def_const(?id)) { ns == ns_value }
-        case (ast::def_arg(?id)) { ns == ns_value }
-        case (ast::def_local(?id)) { ns == ns_value }
-        case (ast::def_variant(_, ?id)) { ns == ns_value }
-        case (ast::def_ty(?id)) { ns == ns_type }
-        case (ast::def_binding(?id)) { ns == ns_type }
-        case (ast::def_use(?id)) { true }
-        case (ast::def_native_ty(?id)) { ns == ns_type }
-        case (ast::def_native_fn(?id)) { ns == ns_value }
+        case (ast::def_fn(?id)) { ns_value }
+        case (ast::def_obj(?id)) { ns_value }
+        case (ast::def_obj_field(?id)) { ns_value }
+        case (ast::def_mod(?id)) { ns_module }
+        case (ast::def_native_mod(?id)) { ns_module }
+        case (ast::def_const(?id)) { ns_value }
+        case (ast::def_arg(?id)) { ns_value }
+        case (ast::def_local(?id)) { ns_value }
+        case (ast::def_variant(_, ?id)) { ns_value }
+        case (ast::def_ty(?id)) { ns_type }
+        case (ast::def_binding(?id)) { ns_type }
+        case (ast::def_use(?id)) { ns_module }
+        case (ast::def_native_ty(?id)) { ns_type }
+        case (ast::def_native_fn(?id)) { ns_value }
     };
 }
 
@@ -941,7 +943,7 @@ fn lookup_external(&env e, int cnum, vec[ident] ids, namespace ns)
     -> option::t[def] {
     for (def d in creader::lookup_defs(e.sess, cnum, ids)) {
         e.ext_map.insert(ast::def_id_of_def(d), ids);
-        if (check_def_by_ns(d, ns)) { ret some(d); }
+        if (ns == ns_for_def(d)) { ret some(d); }
     }
     ret none[def];
 }