]> git.lizzy.rs Git - rust.git/commitdiff
Add a precondition to GEP_tup_like
authorTim Chevalier <chevalier@alum.wellesley.edu>
Sat, 17 Sep 2011 17:18:30 +0000 (10:18 -0700)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Sat, 17 Sep 2011 17:18:30 +0000 (10:18 -0700)
src/comp/middle/trans.rs
src/comp/middle/trans_alt.rs
src/comp/middle/trans_objects.rs

index 61040ba44a8f305565df5aff347f41b267f4ad3a..887c8e6a230b51190f534496ce1552c8e893b5b5 100644 (file)
@@ -610,6 +610,8 @@ fn align_elements(cx: @block_ctxt, elts: [ty::t]) -> result {
 }
 
 fn dynamic_align_of(cx: @block_ctxt, t: ty::t) -> result {
+// FIXME: Typestate constraint that shows this alt is
+// exhaustive
     alt ty::struct(bcx_tcx(cx), t) {
       ty::ty_param(p, _) {
         let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align);
@@ -668,9 +670,8 @@ fn bump_ptr(bcx: @block_ctxt, t: ty::t, base: ValueRef, sz: ValueRef) ->
 // ty::struct and knows what to do when it runs into a ty_param stuck in the
 // middle of the thing it's GEP'ing into. Much like size_of and align_of,
 // above.
-fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int]) ->
-   result {
-    assert (ty::type_is_tup_like(bcx_tcx(cx), t));
+fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
+    : type_is_tup_like(cx, t) -> result {
     // It might be a static-known type. Handle this.
     if !ty::type_has_dynamic_size(bcx_tcx(cx), t) {
         ret rslt(cx, GEPi(cx, base, ixs));
@@ -785,6 +786,8 @@ fn GEP_tag(cx: @block_ctxt, llblobptr: ValueRef, tag_id: ast::def_id,
     } else { llunionptr = llblobptr; }
 
     // Do the GEP_tup_like().
+    // Silly check -- postcondition on mk_tup?
+    check type_is_tup_like(cx, tup_ty);
     let rs = GEP_tup_like(cx, tup_ty, llunionptr, [0, ix as int]);
     // Cast the result to the appropriate type, if necessary.
 
@@ -1403,12 +1406,15 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
     let drop_cx = new_sub_block_ctxt(cx, "drop res");
     let next_cx = new_sub_block_ctxt(cx, "next");
 
+    // Silly check
+    check type_is_tup_like(cx, tup_ty);
     let drop_flag = GEP_tup_like(cx, tup_ty, rs, [0, 0]);
     cx = drop_flag.bcx;
     let null_test = IsNull(cx, Load(cx, drop_flag.val));
     CondBr(cx, null_test, next_cx.llbb, drop_cx.llbb);
     cx = drop_cx;
 
+    check type_is_tup_like(cx, tup_ty);
     let val = GEP_tup_like(cx, tup_ty, rs, [0, 1]);
     cx = val.bcx;
     // Find and call the actual destructor.
@@ -1641,10 +1647,15 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
         ret cx;
     }
 
+    /*
+    Typestate constraint that shows the unimpl case doesn't happen?
+    */
     alt ty::struct(bcx_tcx(cx), t) {
       ty::ty_rec(fields) {
         let i: int = 0;
         for fld: ty::field in fields {
+            // Silly check
+            check type_is_tup_like(cx, t);
             let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
             cx = f(bcx, llfld_a, fld.mt.ty);
             i += 1;
@@ -1653,6 +1664,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
       ty::ty_tup(args) {
         let i = 0;
         for arg in args {
+            // Silly check
+            check type_is_tup_like(cx, t);
             let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
             cx = f(bcx, llfld_a, arg);
             i += 1;
@@ -1663,6 +1676,8 @@ fn iter_variant(cx: @block_ctxt, a_tup: ValueRef,
         let inner1 = ty::substitute_type_params(tcx, tps, inner);
         let inner_t_s = ty::substitute_type_params(tcx, tps, inner);
         let tup_t = ty::mk_tup(tcx, [ty::mk_int(tcx), inner_t_s]);
+        // Silly check
+        check type_is_tup_like(cx, tup_t);
         let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, tup_t, av, [0, 1]);
         ret f(bcx, llfld_a, inner1);
       }
@@ -2543,11 +2558,15 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
 
     // Copy expr values into boxed bindings.
     let i = 0u;
+    // Silly check
+    check type_is_tup_like(bcx, closure_ty);
     let bindings =
         GEP_tup_like(bcx, closure_ty, closure,
                      [0, abi::closure_elt_bindings]);
     bcx = bindings.bcx;
     for lv: lval_result in bound_vals {
+        // Also a silly check
+        check type_is_tup_like(bcx, bindings_ty);
         let bound =
             GEP_tup_like(bcx, bindings_ty, bindings.val, [0, i as int]);
         bcx = bound.bcx;
@@ -2559,6 +2578,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
 
     // If necessary, copy tydescs describing type parameters into the
     // appropriate slot in the closure.
+    // Silly check as well
+    check type_is_tup_like(bcx, closure_ty);
     let ty_params_slot =
         GEP_tup_like(bcx, closure_ty, closure,
                      [0, abi::closure_elt_ty_params]);
@@ -2663,6 +2684,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
     // If this is an aliasing closure/for-each body, we need to load
     // the iterbody.
     if !copying && !option::is_none(enclosing_cx.fcx.lliterbody) {
+        // Silly check
+        check type_is_tup_like(bcx, ty);
         let iterbodyptr = GEP_tup_like(bcx, ty, llclosure, path + [0]);
         fcx.lliterbody = some(Load(bcx, iterbodyptr.val));
         bcx = iterbodyptr.bcx;
@@ -2671,6 +2694,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
 
     // Load the actual upvars.
     for upvar_def in *upvars {
+        // Silly check
+        check type_is_tup_like(bcx, ty);
         let upvarptr = GEP_tup_like(bcx, ty, llclosure, path + [i as int]);
         bcx = upvarptr.bcx;
         let llupvarptr = upvarptr.val;
@@ -2984,7 +3009,10 @@ fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
     alt ty::struct(bcx_tcx(cx), t) {
       ty::ty_rec(fields) {
         let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields);
-        let v = GEP_tup_like(r.bcx, t, r.val, [0, ix as int]);
+        let r_bcx = r.bcx;
+        // Silly check
+        check type_is_tup_like(r_bcx, t);
+        let v = GEP_tup_like(r_bcx, t, r.val, [0, ix as int]);
         ret lval_no_env(v.bcx, v.val, true);
       }
       ty::ty_obj(methods) {
@@ -3329,6 +3357,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
         (fptr, C_null(T_opaque_closure_ptr(*bcx_ccx(bcx))), 0)
       }
       none. {
+        // Silly check
+        check type_is_tup_like(bcx, closure_ty);
         let {bcx: cx, val: pair} =
             GEP_tup_like(bcx, closure_ty, llclosure,
                          [0, abi::box_rc_field_body,
@@ -3368,6 +3398,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
     // Copy in the type parameters.
     let i: uint = 0u;
     while i < ty_param_count {
+        // Silly check
+        check type_is_tup_like(copy_args_bcx, closure_ty);
         let lltyparam_ptr =
             GEP_tup_like(copy_args_bcx, closure_ty, llclosure,
                          [0, abi::box_rc_field_body,
@@ -3391,6 +3423,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
           // Arg provided at binding time; thunk copies it from
           // closure.
           some(e) {
+            // Silly check
+            check type_is_tup_like(bcx, closure_ty);
             let bound_arg =
                 GEP_tup_like(bcx, closure_ty, llclosure,
                              [0, abi::box_rc_field_body,
@@ -3914,6 +3948,8 @@ fn trans_tup(cx: @block_ctxt, elts: [@ast::expr], id: ast::node_id) ->
         let e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e);
         let src = trans_lval(bcx, e);
         bcx = src.bcx;
+        // FIXME: constraint on argument?
+        check type_is_tup_like(bcx, t);
         let dst_res = GEP_tup_like(bcx, t, tup_val, [0, i]);
         bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty);
         i += 1;
@@ -3943,6 +3979,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
     alt ty::struct(bcx_tcx(cx), t) { ty::ty_rec(flds) { ty_fields = flds; } }
     for tf: ty::field in ty_fields {
         let e_ty = tf.mt.ty;
+        // FIXME: constraint on argument?
+        check type_is_tup_like(bcx, t);
         let dst_res = GEP_tup_like(bcx, t, rec_val, [0, i]);
         bcx = dst_res.bcx;
         let expr_provided = false;
@@ -3956,6 +3994,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
             }
         }
         if !expr_provided {
+            // FIXME: constraint on argument?
+            check type_is_tup_like(bcx, t);
             let src_res = GEP_tup_like(bcx, t, base_val, [0, i]);
             src_res =
                 rslt(src_res.bcx, load_if_immediate(bcx, src_res.val, e_ty));
@@ -5100,6 +5140,8 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) {
     }
     i = 0;
     for f: ast::obj_field in fcx.lcx.obj_fields {
+        // FIXME: silly check
+        check type_is_tup_like(bcx, fields_tup_ty);
         let rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, [0, i]);
         bcx = llstaticallocas_block_ctxt(fcx);
         let llfield = rslt.val;
@@ -5248,9 +5290,12 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
         llretptr = BitCast(bcx, llretptr, llret_t);
     }
 
+    // FIXME: silly checks
+    check type_is_tup_like(bcx, tup_t);
     let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
     bcx = dst.bcx;
     bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
+    check type_is_tup_like(bcx, tup_t);
     let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
     bcx = flag.bcx;
     Store(bcx, C_int(1), flag.val);
index 066f969ba60bf53f7bbbd9aa92dc286e615ec536..eea4704c3d080aef1f25b046b0b9b5c7f33cb9e8 100644 (file)
@@ -342,6 +342,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
         for field_name: ast::ident in rec_fields {
             let ix: uint =
                 ty::field_idx(ccx.sess, dummy_sp(), field_name, fields);
+            // not sure how to get rid of this check
+            check type_is_tup_like(bcx, rec_ty);
             let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
             rec_vals += [r.val];
             bcx = r.bcx;
@@ -359,6 +361,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
             };
         let tup_vals = [], i = 0u;
         while i < n_tup_elts {
+            // how to get rid of this check?
+            check type_is_tup_like(bcx, tup_ty);
             let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
             tup_vals += [r.val];
             bcx = r.bcx;
@@ -603,6 +607,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
         for f: ast::field_pat in fields {
             let ix: uint =
                 ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields);
+            // how to get rid of this check?
+            check type_is_tup_like(bcx, rec_ty);
             let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
             bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy);
         }
@@ -611,6 +617,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
         let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
         let i = 0u;
         for elem in elems {
+            // how to get rid of this check?
+            check type_is_tup_like(bcx, tup_ty);
             let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
             bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy);
             i += 1u;
index 1b36cbdee742596a633c92b1ca8b5d4df59dfbb7..99eacedaf3b389e6ae6806002d087487a58559b1 100644 (file)
@@ -121,11 +121,14 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         // the types of the object's fields, so that the fields can be freed
         // later.
 
+        // postcondition on create_object_body_type?
+        check type_is_tup_like(bcx, body_ty);
         let body_tydesc =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
         bcx = body_tydesc.bcx;
         let ti = none;
 
+        check type_is_tup_like(bcx, body_ty);
         let r =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]);
         bcx = r.bcx;
@@ -151,6 +154,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         let i: int = 0;
         for tp: ast::ty_param in ty_params {
             let typaram = bcx.fcx.lltydescs[i];
+            // Silly check
+            check type_is_tup_like(bcx, typarams_ty);
             let capture =
                 GEP_tup_like(bcx, typarams_ty, body_typarams, [0, i]);
             bcx = capture.bcx;
@@ -159,6 +164,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
         }
 
         // Copy args into body fields.
+        // how to get rid of this check?
+        check type_is_tup_like(bcx, body_ty);
         let body_fields =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
         bcx = body_fields.bcx;
@@ -169,6 +176,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
                 let arg = load_if_immediate(bcx, arg1, arg_tys[i].ty);
                 // TODO: can we just get fields_ty out of body_ty instead?
                 let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields);
+                // Silly check
+                check type_is_tup_like(bcx, fields_ty);
                 let field =
                     GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
                 bcx = field.bcx;
@@ -314,6 +323,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
         // the user of the object.  So the tydesc is needed to keep track of
         // the types of the object's fields, so that the fields can be freed
         // later.
+        // postcondition on create_object_body_type?
+        check type_is_tup_like(bcx, body_ty);
         let body_tydesc =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
         bcx = body_tydesc.bcx;
@@ -328,6 +339,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
         // body.  (This is something like saving the lexical environment of a
         // function in its closure: the fields were passed to the object
         // constructor and are now available to the object's methods.
+        check type_is_tup_like(bcx, body_ty);
         let body_fields =
             GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
         bcx = body_fields.bcx;
@@ -338,6 +350,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
             load_if_immediate(bcx, additional_field_vals[i].val,
                               additional_field_tys[i]);
             let fields_ty: ty::t = ty::mk_tup(ccx.tcx, additional_field_tys);
+            // Silly check
+            check type_is_tup_like(bcx, fields_ty);
             let field = GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
             bcx = field.bcx;
             bcx =
@@ -356,6 +370,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
             // value) wrapped in a result.
             let inner_obj_val: result = trans_expr(bcx, e);
 
+            check type_is_tup_like(bcx, body_ty);
             let body_inner_obj =
                 GEP_tup_like(bcx, body_ty, body,
                              [0, abi::obj_body_elt_inner_obj]);
@@ -776,6 +791,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
                     T_ptr(type_of(cx_ccx, sp, body_ty)));
 
     // Now, reach into the body and grab the inner_obj.
+    check type_is_tup_like(bcx, body_ty);
     let llinner_obj =
         GEP_tup_like(bcx, body_ty, llself_obj_body,
                      [0, abi::obj_body_elt_inner_obj]);