diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index dafb91c25d73..4a1e7c4cd425 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))); } + 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) { llty = T_ptr(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, // 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, 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 a74ee6ba9ed6..4f6dbfaa5f9a 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)) } //