summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2011-09-15 20:47:38 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2011-09-15 23:22:12 -0700
commit57ede5f281a406986d4167bbca137d09e6a7f565 (patch)
treebbc2917032c6875a07a4eaa95440bf02dea13dce /src/comp
parentce1877dc8ed18847024c2b199263554686f3d150 (diff)
downloadrust-57ede5f281a406986d4167bbca137d09e6a7f565.tar.gz
rust-57ede5f281a406986d4167bbca137d09e6a7f565.zip
Added non_ty_var precondition to trans::type_of_inner
This allows us to legitimately call unreachable() in the ty_var case.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs144
-rw-r--r--src/comp/middle/trans_objects.rs22
2 files changed, 109 insertions, 57 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index dafb91c25d7..4a1e7c4cd42 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -48,13 +48,20 @@ import tvec = trans_vec;
 
 fn type_of(cx: @crate_ctxt, sp: span, t: ty::t) : type_has_static_size(cx, t)
    -> TypeRef {
+    // Should follow from type_has_static_size -- argh.
+    // FIXME
+    check non_ty_var(cx, t);
     type_of_inner(cx, sp, t)
 }
 
 fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
    [TypeRef] {
     let atys = [];
-    for arg in inputs { atys += [T_ptr(type_of_inner(cx, sp, arg.ty))]; }
+    for arg in inputs {
+        let arg_ty = arg.ty;
+        check non_ty_var(cx, arg_ty);
+        atys += [T_ptr(type_of_inner(cx, sp, arg_ty))];
+    }
     ret atys;
 }
 
@@ -71,6 +78,7 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto,
     let atys: [TypeRef] = [];
 
     // Arg 0: Output pointer.
+    check non_ty_var(cx, output);
     let out_ty = T_ptr(type_of_inner(cx, sp, output));
     atys += [ret_ref ? T_ptr(out_ty) : out_ty];
 
@@ -91,7 +99,13 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto,
         // If it's an iter, the 'output' type of the iter is actually the
         // *input* type of the function we're given as our iter-block
         // argument.
-        atys += [type_of_inner(cx, sp, ty::mk_iter_body_fn(cx.tcx, output))];
+        let iter_body_ty = ty::mk_iter_body_fn(cx.tcx, output);
+        // FIXME: this check could be avoided pretty easily if we had
+        // postconditions
+        // (or better yet, just use a constraiend type that expresses
+        // non-ty-var things)
+        check non_ty_var(cx, iter_body_ty);
+        atys += [type_of_inner(cx, sp, iter_body_ty)];
     }
     // ... then explicit args.
     atys += type_of_explicit_args(cx, sp, inputs);
@@ -102,9 +116,12 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, proto: ast::proto,
 fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
                       ty_param_count: uint) -> TypeRef {
     let by_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(cx.tcx, fty));
+    // FIXME: constraint?
+    let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
+    check non_ty_var(cx, ret_ty);
     ret type_of_fn(cx, sp, ty::ty_fn_proto(cx.tcx, fty),
                    false, by_ref, ty::ty_fn_args(cx.tcx, fty),
-                   ty::ty_fn_ret(cx.tcx, fty), ty_param_count);
+                   ret_ty, ty_param_count);
 }
 
 fn type_of_native_fn(cx: @crate_ctxt, sp: span, abi: ast::native_abi,
@@ -117,83 +134,97 @@ fn type_of_native_fn(cx: @crate_ctxt, sp: span, abi: ast::native_abi,
         while i < ty_param_count { atys += [T_ptr(cx.tydesc_type)]; i += 1u; }
     }
     atys += type_of_explicit_args(cx, sp, inputs);
+    check non_ty_var(cx, output);
     ret T_fn(atys, type_of_inner(cx, sp, output));
 }
 
-/* FIXME: could add type_has_static_size as a constraint,
-   allowing us to get rid of some impossible cases. */
-fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t) -> TypeRef {
+fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
+    : non_ty_var(cx, t) -> TypeRef {
     // Check the cache.
 
     if cx.lltypes.contains_key(t) { ret cx.lltypes.get(t); }
-    let llty: TypeRef = 0 as TypeRef;
+    let llty =
     alt ty::struct(cx.tcx, t) {
-      ty::ty_native(_) { llty = T_ptr(T_i8()); }
-      ty::ty_nil. { llty = T_nil(); }
+      ty::ty_native(_) { T_ptr(T_i8()) }
+      ty::ty_nil. { T_nil() }
       ty::ty_bot. {
-        llty = T_nil(); /* ...I guess? */
-
+        T_nil() /* ...I guess? */
       }
-      ty::ty_bool. { llty = T_bool(); }
-      ty::ty_int. { llty = T_int(); }
-      ty::ty_float. { llty = T_float(); }
-      ty::ty_uint. { llty = T_int(); }
+      ty::ty_bool. { T_bool() }
+      ty::ty_int. { T_int() }
+      ty::ty_float. { T_float() }
+      ty::ty_uint. { T_int() }
       ty::ty_machine(tm) {
         alt tm {
-          ast::ty_i8. { llty = T_i8(); }
-          ast::ty_u8. { llty = T_i8(); }
-          ast::ty_i16. { llty = T_i16(); }
-          ast::ty_u16. { llty = T_i16(); }
-          ast::ty_i32. { llty = T_i32(); }
-          ast::ty_u32. { llty = T_i32(); }
-          ast::ty_i64. { llty = T_i64(); }
-          ast::ty_u64. { llty = T_i64(); }
-          ast::ty_f32. { llty = T_f32(); }
-          ast::ty_f64. { llty = T_f64(); }
+          ast::ty_i8. | ast::ty_u8. { T_i8() }
+          ast::ty_i16. | ast::ty_u16. { T_i16() }
+          ast::ty_i32. | ast::ty_u32. { T_i32() }
+          ast::ty_i64. | ast::ty_u64. { T_i64() }
+          ast::ty_f32. { T_f32() }
+          ast::ty_f64. { T_f64() }
         }
       }
-      ty::ty_char. { llty = T_char(); }
-      ty::ty_str. { llty = T_ptr(T_vec(T_i8())); }
-      ty::ty_tag(did, _) { llty = type_of_tag(cx, sp, did, t); }
-      ty::ty_box(mt) { llty = T_ptr(T_box(type_of_inner(cx, sp, mt.ty))); }
-      ty::ty_uniq(t) { llty = T_ptr(type_of_inner(cx, sp, t)); }
+      ty::ty_char. { T_char() }
+      ty::ty_str. { T_ptr(T_vec(T_i8())) }
+      ty::ty_tag(did, _) { type_of_tag(cx, sp, did, t) }
+      ty::ty_box(mt) {
+        let mt_ty = mt.ty;
+        check non_ty_var(cx, mt_ty);
+        T_ptr(T_box(type_of_inner(cx, sp, mt_ty))) }
+      ty::ty_uniq(t) {
+        check non_ty_var(cx, t);
+        T_ptr(type_of_inner(cx, sp, t)) }
       ty::ty_vec(mt) {
-        if ty::type_has_dynamic_size(cx.tcx, mt.ty) {
-            llty = T_ptr(T_opaque_vec());
-        } else { llty = T_ptr(T_vec(type_of_inner(cx, sp, mt.ty))); }
-      }
-      ty::ty_ptr(mt) { llty = T_ptr(type_of_inner(cx, sp, mt.ty)); }
+        let mt_ty = mt.ty;
+        if ty::type_has_dynamic_size(cx.tcx, mt_ty) {
+            T_ptr(T_opaque_vec())
+        } else {
+            // should be unnecessary
+            check non_ty_var(cx, mt_ty);
+            T_ptr(T_vec(type_of_inner(cx, sp, mt_ty))) }
+      }
+      ty::ty_ptr(mt) {
+        let mt_ty = mt.ty;
+        check non_ty_var(cx, mt_ty);
+        T_ptr(type_of_inner(cx, sp, mt_ty)) }
       ty::ty_rec(fields) {
         let tys: [TypeRef] = [];
         for f: ty::field in fields {
-            tys += [type_of_inner(cx, sp, f.mt.ty)];
+            let mt_ty = f.mt.ty;
+            check non_ty_var(cx, mt_ty);
+            tys += [type_of_inner(cx, sp, mt_ty)];
         }
-        llty = T_struct(tys);
+        T_struct(tys)
       }
       ty::ty_fn(_, _, _, _, _) {
-        llty = T_fn_pair(*cx, type_of_fn_from_ty(cx, sp, t, 0u));
+        T_fn_pair(*cx, type_of_fn_from_ty(cx, sp, t, 0u))
       }
       ty::ty_native_fn(abi, args, out) {
         let nft = native_fn_wrapper_type(cx, sp, 0u, t);
-        llty = T_fn_pair(*cx, nft);
+        T_fn_pair(*cx, nft)
       }
-      ty::ty_obj(meths) { llty = cx.rust_object_type; }
+      ty::ty_obj(meths) { cx.rust_object_type }
       ty::ty_res(_, sub, tps) {
         let sub1 = ty::substitute_type_params(cx.tcx, tps, sub);
+        check non_ty_var(cx, sub1);
         ret T_struct([T_i32(), type_of_inner(cx, sp, sub1)]);
       }
       ty::ty_var(_) {
+        // FIXME should be a constraint that makes this impossible
+        // (use unreachable())
         cx.tcx.sess.span_fatal(sp, "trans::type_of called on ty_var");
       }
-      ty::ty_param(_, _) { llty = T_typaram(cx.tn); }
-      ty::ty_type. { llty = T_ptr(cx.tydesc_type); }
+      ty::ty_param(_, _) { T_typaram(cx.tn) }
+      ty::ty_type. { T_ptr(cx.tydesc_type) }
       ty::ty_tup(elts) {
         let tys = [];
-        for elt in elts { tys += [type_of_inner(cx, sp, elt)]; }
-        llty = T_struct(tys);
+        for elt in elts {
+            check non_ty_var(cx, elt);
+            tys += [type_of_inner(cx, sp, elt)];
+        }
+        T_struct(tys)
       }
-    }
-    assert (llty as int != 0);
+    };
     cx.lltypes.insert(t, llty);
     ret llty;
 }
@@ -1131,6 +1162,7 @@ fn declare_generic_glue(cx: @local_ctxt, t: ty::t, llfnty: TypeRef, name: str)
     ret llfn;
 }
 
+// FIXME: was this causing the leak?
 fn make_generic_glue_inner(cx: @local_ctxt, sp: span, t: ty::t,
                            llfn: ValueRef, helper: glue_helper,
                            ty_params: [uint]) -> ValueRef {
@@ -3296,8 +3328,10 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
     // The 'llretptr' that will arrive in the thunk we're creating also needs
     // to be the correct type.  Cast it to f's return type, if necessary.
     let llretptr = fcx.llretptr;
-    if ty::type_contains_params(cx.ccx.tcx, outgoing_ret_ty) {
-        let llretty = type_of_inner(cx.ccx, sp, outgoing_ret_ty);
+    let ccx = cx.ccx;
+    if ty::type_contains_params(ccx.tcx, outgoing_ret_ty) {
+        check non_ty_var(ccx, outgoing_ret_ty);
+        let llretty = type_of_inner(ccx, sp, outgoing_ret_ty);
         llretptr = PointerCast(bcx, llretptr, T_ptr(llretty));
     }
 
@@ -3573,6 +3607,7 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
         // type deep in a structure -- which the caller has a concrete view
         // of. If so, cast the caller's view of the restlot to the callee's
         // view, for the sake of making a type-compatible call.
+        check non_ty_var(ccx, retty);
         let llretty = T_ptr(type_of_inner(ccx, bcx.sp, retty));
         if by_ref { llretty = T_ptr(llretty); }
         llargs += [PointerCast(cx, llretslot, llretty)];
@@ -3594,6 +3629,7 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t<generic_info>,
         let lli =
             if ty::type_contains_params(tcx, retty) {
                 let body_ty = ty::mk_iter_body_fn(tcx, retty);
+                check non_ty_var(ccx, body_ty);
                 let body_llty = type_of_inner(ccx, cx.sp, body_ty);
                 PointerCast(bcx, lli, T_ptr(body_llty))
             } else { lli };
@@ -3884,7 +3920,7 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
 }
 
 fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
-    ret trans_expr_out(cx, e, return);
+    trans_expr_out(cx, e, return)
 }
 
 fn trans_expr_out(cx: @block_ctxt, e: @ast::expr, output: out_method) ->
@@ -4531,7 +4567,7 @@ fn zero_alloca(cx: @block_ctxt, llptr: ValueRef, t: ty::t) -> result {
         // let llalign = align_of(llsz.bcx, t);
         bcx = call_bzero(llsz.bcx, llptr, llsz.val, C_int(0)).bcx;
     }
-    ret rslt(bcx, llptr);
+    rslt(bcx, llptr)
 }
 
 fn trans_stmt(cx: @block_ctxt, s: ast::stmt) -> result {
@@ -5372,6 +5408,7 @@ fn decl_fn_and_pair_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
         type_of_fn_from_ty(ccx, sp, node_type, std::vec::len(ty_params));
     alt ty::struct(ccx.tcx, node_type) {
       ty::ty_fn(proto, inputs, output, rs, _) {
+        check non_ty_var(ccx, output);
         llfty = type_of_fn(ccx, sp, proto, false,
                            ast_util::ret_by_ref(rs), inputs, output,
                            vec::len(ty_params));
@@ -5412,8 +5449,12 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
         let vecarg_ty: ty::arg =
             {mode: ast::by_ref,
              ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mut: ast::imm})};
+        // FIXME: mk_nil should have a post condition
+        let nt = ty::mk_nil(ccx.tcx);
+        check non_ty_var(ccx, nt);
+
         let llfty = type_of_fn(ccx, sp, ast::proto_fn, false, false,
-                               [vecarg_ty], ty::mk_nil(ccx.tcx), 0u);
+                               [vecarg_ty], nt, 0u);
         let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty);
 
         let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl);
@@ -5514,6 +5555,7 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
                           x: ty::t) -> TypeRef {
     alt ty::struct(cx.tcx, x) {
       ty::ty_native_fn(abi, args, out) {
+        check non_ty_var(cx, out);
         ret type_of_fn(cx, sp, ast::proto_fn, false, false, args, out,
                        ty_param_count);
       }
diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs
index a74ee6ba9ed..4f6dbfaa5f9 100644
--- a/src/comp/middle/trans_objects.rs
+++ b/src/comp/middle/trans_objects.rs
@@ -627,8 +627,11 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
     // creating also needs to be the correct type.  Cast it to the method's
     // return type, if necessary.
     let llretptr = fcx.llretptr;
-    if ty::type_contains_params(cx.ccx.tcx, m.output) {
-        let llretty = type_of_inner(cx.ccx, sp, m.output);
+    let ccx = cx.ccx;
+    if ty::type_contains_params(ccx.tcx, m.output) {
+        let m_output = m.output;
+        check non_ty_var(ccx, m_output);
+        let llretty = type_of_inner(ccx, sp, m_output);
         llretptr = PointerCast(bcx, llretptr, T_ptr(llretty));
     }
 
@@ -732,8 +735,11 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
     // creating also needs to be the correct type.  Cast it to the method's
     // return type, if necessary.
     let llretptr = fcx.llretptr;
-    if ty::type_contains_params(cx.ccx.tcx, m.output) {
-        let llretty = type_of_inner(cx.ccx, sp, m.output);
+    let ccx = cx.ccx;
+    if ty::type_contains_params(ccx.tcx, m.output) {
+        let m_output = m.output;
+        check non_ty_var(ccx, m_output);
+        let llretty = type_of_inner(ccx, sp, m_output);
         llretptr = PointerCast(bcx, llretptr, T_ptr(llretty));
     }
 
@@ -881,7 +887,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
     let llfnty = T_nil();
     alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.node.id)) {
       ty::ty_fn(proto, inputs, output, rs, _) {
-        llfnty = type_of_fn(cx.ccx, m.span, proto, true,
+        let ccx = cx.ccx;
+        check non_ty_var(ccx, output);
+        llfnty = type_of_fn(ccx, m.span, proto, true,
                             ast_util::ret_by_ref(rs), inputs, output,
                             vec::len(ty_params));
       }
@@ -933,8 +941,10 @@ fn populate_self_stack(bcx: @block_ctxt, self_stack: ValueRef,
 
 fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method,
                 tps: [ast::ty_param]) -> TypeRef {
+    let out_ty = m.output;
+    check non_ty_var(ccx, out_ty);
     type_of_fn(ccx, sp, m.proto, true, ast_util::ret_by_ref(m.cf),
-               m.inputs, m.output, vec::len(tps))
+               m.inputs, out_ty, vec::len(tps))
 }
 
 //