about summary refs log tree commit diff
path: root/src/comp/middle/ty.rs
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-07-27 17:49:00 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-07-27 17:49:00 -0700
commit63f74f3771c20fceea294d2dc759ccde8a59a6cd (patch)
tree5504c7c6b9d0acb14f69159095bf63e84f033799 /src/comp/middle/ty.rs
parent04611a3e56b84c9d3439d1625e61d092d860a2c1 (diff)
downloadrust-63f74f3771c20fceea294d2dc759ccde8a59a6cd.tar.gz
rust-63f74f3771c20fceea294d2dc759ccde8a59a6cd.zip
Remove vestiges of "layers", insert skeletal do-nothing "kind" pass plus cached calculation of kind for each type.
Diffstat (limited to 'src/comp/middle/ty.rs')
-rw-r--r--src/comp/middle/ty.rs130
1 files changed, 128 insertions, 2 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 674e5c9b9cb..08e6447c2d0 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -152,6 +152,7 @@ export ty_fn_args;
 export type_constr;
 export type_contains_params;
 export type_contains_vars;
+export type_kind;
 export type_err;
 export type_err_to_str;
 export type_has_dynamic_size;
@@ -216,6 +217,7 @@ type ctxt =
       rcache: creader_cache,
       short_names_cache: hashmap[t, str],
       has_pointer_cache: hashmap[t, bool],
+      kind_cache: hashmap[t, ast::kind],
       owns_heap_mem_cache: hashmap[t, bool],
       ast_ty_to_ty_cache: hashmap[@ast::ty, option::t[t]]};
 
@@ -409,6 +411,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
           rcache: mk_rcache(),
           short_names_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
           has_pointer_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
+          kind_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
           owns_heap_mem_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
           ast_ty_to_ty_cache: map::mk_hashmap(ast::hash_ty, ast::eq_ty)};
     populate_type_store(cx);
@@ -981,7 +984,10 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
       ty_native(_) {/* no-op */ }
       ty_rec(flds) {
         for f: field  in flds {
-            if type_has_pointers(cx, f.mt.ty) { result = true; }
+            if type_has_pointers(cx, f.mt.ty) {
+                result = true;
+                break;
+            }
         }
       }
       ty_tag(did, tps) {
@@ -990,8 +996,12 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
             for aty: t  in variant.args {
                 // Perform any type parameter substitutions.
                 let arg_ty = substitute_type_params(cx, tps, aty);
-                if type_has_pointers(cx, arg_ty) { result = true; }
+                if type_has_pointers(cx, arg_ty) {
+                    result = true;
+                    break;
+                }
             }
+            if result { break; }
         }
       }
       ty_res(did, inner, tps) {
@@ -1005,6 +1015,122 @@ fn type_has_pointers(cx: &ctxt, ty: &t) -> bool {
     ret result;
 }
 
+fn type_kind(cx: &ctxt, ty: &t) -> ast::kind {
+    alt cx.kind_cache.find(ty) {
+      some(result) { ret result; }
+      none. {/* fall through */ }
+    }
+
+    let result = ast::kind_unique;
+
+    // Insert a default in case we loop back on self recursively.
+    cx.kind_cache.insert(ty, result);
+
+    alt struct(cx, ty) {
+
+      // Scalar types are unique-kind, no substructure.
+      ty_nil. | ty_bot. | ty_bool. | ty_int. | ty_uint. | ty_float.
+      | ty_machine(_) | ty_char. | ty_native(_) {
+        // no-op
+      }
+
+      // A handful of other built-in are unique too.
+      ty_type. | ty_istr. | ty_native_fn(_, _, _) {
+        // no-op
+      }
+
+      // Those things with refcounts-to-interior are just shared.
+      ty_str. | ty_task. {
+        result = kind_shared;
+      }
+
+      // FIXME: obj is broken for now, since we aren't asserting
+      // anything about its fields.
+      ty_obj(_) { result = kind_shared; }
+
+      // FIXME: the environment capture mode is not fully encoded
+      // here yet, leading to weirdness around closure.
+      ty_fn(proto, _, _, _, _) {
+        result = alt proto {
+          ast::proto_block. { ast::kind_pinned }
+          ast::proto_closure. { ast::kind_shared }
+          _ { ast::kind_unique }
+        }
+      }
+
+      // Those with refcounts-to-inner are the lower of their
+      // inner and shared.
+      ty_box(mt) | ty_vec(mt) {
+        result = kind::lower_kind(ast::kind_shared,
+                                  type_kind(cx, mt.ty));
+
+      }
+
+      // FIXME: remove ports. Ports currently contribute 'shared'
+      ty_port(t) {
+        result = kind::lower_kind(ast::kind_shared,
+                                  type_kind(cx, t));
+      }
+
+      // FIXME: remove chans. Chans currently contribute only
+      // their inner.
+      ty_chan(t) {
+        result = type_kind(cx, t);
+      }
+
+      // Pointers and unique boxes / vecs lower to whatever they point to.
+      ty_ptr(tm) | ty_ivec(tm) {
+        result = type_kind(cx, tm.ty);
+      }
+
+      // Records lower to the lowest of their members.
+      ty_rec(flds) {
+        for f: field  in flds {
+            result = kind::lower_kind(result, type_kind(cx, f.mt.ty));
+            if result == ast::kind_pinned { break; }
+        }
+      }
+
+      // Tags lower to the lowest of their variants.
+      ty_tag(did, tps) {
+        let variants = tag_variants(cx, did);
+        for variant: variant_info  in variants {
+            for aty: t  in variant.args {
+                // Perform any type parameter substitutions.
+                let arg_ty = substitute_type_params(cx, tps, aty);
+                result = kind::lower_kind(result, type_kind(cx, arg_ty));
+                if result == ast::kind_pinned { break; }
+            }
+            if result == ast::kind_pinned { break; }
+        }
+      }
+
+      // Resources are always pinned.
+      ty_res(did, inner, tps) {
+        result = ast::kind_pinned;
+      }
+
+      ty_var(_) { fail; }
+
+      ty_param(_) {
+        // FIXME: this should contribute the kind-bound of the typaram,
+        // when those exist.
+      }
+
+      ty_constr(t, _) {
+        result = type_kind(cx, t);
+      }
+
+        _ {
+            cx.sess.bug("missed case: " + ty_to_str(cx, ty));
+        }
+
+    }
+
+    cx.kind_cache.insert(ty, result);
+    ret result;
+}
+
 
 // FIXME: should we just return true for native types in
 // type_is_scalar?