}
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);
// 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));
} 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.
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.
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;
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;
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);
}
// 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;
// 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]);
// 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;
// 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;
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) {
(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,
// 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,
// 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,
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;
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;
}
}
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));
}
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;
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);
// 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;
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;
}
// 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;
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;
// 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;
// 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;
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 =
// 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]);
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]);