Start on in-crate monomorphizing
Adds a --monomorpize flag to rustc to turn it on. You probably don't want to use it yet, since it's broken in a whole bunch of ways, but it successfully monomorphizes simple generic functions called from within the crate. Issue #1736
This commit is contained in:
parent
a02f332602
commit
3bcd4fe6fa
12 changed files with 169 additions and 125 deletions
|
|
@ -357,6 +357,7 @@ fn build_session_options(match: getopts::match,
|
|||
if opt_present(match, "no-lint-ctypes") {
|
||||
lint_opts += [(lint::ctypes, false)];
|
||||
}
|
||||
let monomorphize = opt_present(match, "monomorphize");
|
||||
|
||||
let output_type =
|
||||
if parse_only || no_trans {
|
||||
|
|
@ -434,6 +435,7 @@ fn build_session_options(match: getopts::match,
|
|||
parse_only: parse_only,
|
||||
no_trans: no_trans,
|
||||
no_asm_comments: no_asm_comments,
|
||||
monomorphize: monomorphize,
|
||||
warn_unused_imports: warn_unused_imports};
|
||||
ret sopts;
|
||||
}
|
||||
|
|
@ -493,6 +495,7 @@ fn opts() -> [getopts::opt] {
|
|||
optflag("time-passes"), optflag("time-llvm-passes"),
|
||||
optflag("no-verify"),
|
||||
optflag("no-lint-ctypes"),
|
||||
optflag("monomorphize"),
|
||||
optmulti("cfg"), optflag("test"),
|
||||
optflag("lib"), optflag("bin"), optflag("static"), optflag("gc"),
|
||||
optflag("no-asm-comments"),
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type options =
|
|||
parse_only: bool,
|
||||
no_trans: bool,
|
||||
no_asm_comments: bool,
|
||||
monomorphize: bool,
|
||||
warn_unused_imports: bool};
|
||||
|
||||
type crate_metadata = {name: str, data: [u8]};
|
||||
|
|
|
|||
|
|
@ -668,7 +668,7 @@ fn create_local_var(bcx: @block_ctxt, local: @ast::local)
|
|||
});
|
||||
let loc = codemap::lookup_char_pos(cx.sess.codemap,
|
||||
local.span.lo);
|
||||
let ty = base::node_id_type(cx, local.node.id);
|
||||
let ty = node_id_type(bcx, local.node.id);
|
||||
let tymd = create_ty(cx, ty, local.node.ty);
|
||||
let filemd = create_file(cx, loc.filename);
|
||||
let context = alt bcx.parent {
|
||||
|
|
@ -717,7 +717,7 @@ fn create_arg(bcx: @block_ctxt, arg: ast::arg, sp: span)
|
|||
};*/
|
||||
let loc = codemap::lookup_char_pos(cx.sess.codemap,
|
||||
sp.lo);
|
||||
let ty = base::node_id_type(cx, arg.id);
|
||||
let ty = node_id_type(bcx, arg.id);
|
||||
let tymd = create_ty(cx, ty, arg.ty);
|
||||
let filemd = create_file(cx, loc.filename);
|
||||
let context = create_function(bcx.fcx);
|
||||
|
|
|
|||
|
|
@ -692,7 +692,7 @@ fn trans_alt(cx: @block_ctxt, expr: @ast::expr, arms_: [ast::arm],
|
|||
}
|
||||
|
||||
let exit_map = [];
|
||||
let t = base::node_id_type(cx.fcx.ccx, expr.id);
|
||||
let t = node_id_type(cx, expr.id);
|
||||
let vr = base::spill_if_immediate(er.bcx, er.val, t);
|
||||
compile_submatch(vr.bcx, match, [vr.val],
|
||||
bind mk_fail(alt_cx, expr.span, fail_cx), exit_map);
|
||||
|
|
@ -725,7 +725,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
alt normalize_pat(bcx_tcx(bcx), pat).node {
|
||||
ast::pat_ident(_,inner) {
|
||||
if make_copy || ccx.copy_map.contains_key(pat.id) {
|
||||
let ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
let ty = node_id_type(bcx, pat.id);
|
||||
// FIXME: Could constrain pat_bind to make this
|
||||
// check unnecessary.
|
||||
check (type_has_static_size(ccx, ty));
|
||||
|
|
@ -753,7 +753,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
}
|
||||
}
|
||||
ast::pat_rec(fields, _) {
|
||||
let rec_ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
let rec_ty = node_id_type(bcx, pat.id);
|
||||
let rec_fields = ty::get_fields(ccx.tcx, rec_ty);
|
||||
for f: ast::field_pat in fields {
|
||||
let ix = option::get(ty::field_idx(f.ident, rec_fields));
|
||||
|
|
@ -764,7 +764,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
}
|
||||
}
|
||||
ast::pat_tup(elems) {
|
||||
let tup_ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
let tup_ty = node_id_type(bcx, pat.id);
|
||||
let i = 0u;
|
||||
for elem in elems {
|
||||
// how to get rid of this check?
|
||||
|
|
|
|||
|
|
@ -112,9 +112,6 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg],
|
|||
// Given a function type and a count of ty params, construct an llvm type
|
||||
fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t,
|
||||
param_bounds: [ty::param_bounds]) -> TypeRef {
|
||||
// FIXME: Check should be unnecessary, b/c it's implied
|
||||
// by returns_non_ty_var(t). Make that a postcondition
|
||||
// (see Issue #586)
|
||||
let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
|
||||
ret type_of_fn(cx, ty::ty_fn_args(cx.tcx, fty),
|
||||
ret_ty, param_bounds);
|
||||
|
|
@ -371,13 +368,6 @@ fn umin(cx: @block_ctxt, a: ValueRef, b: ValueRef) -> ValueRef {
|
|||
ret Select(cx, cond, a, b);
|
||||
}
|
||||
|
||||
fn align_to(cx: @block_ctxt, off: ValueRef, align: ValueRef) -> ValueRef {
|
||||
let mask = Sub(cx, align, C_int(bcx_ccx(cx), 1));
|
||||
let bumped = Add(cx, off, mask);
|
||||
ret And(cx, bumped, Not(cx, mask));
|
||||
}
|
||||
|
||||
|
||||
// Returns the real size of the given type for the current target.
|
||||
fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint {
|
||||
ret llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint;
|
||||
|
|
@ -2008,12 +1998,6 @@ fn trans_lit(cx: @block_ctxt, lit: ast::lit, dest: dest) -> @block_ctxt {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Converts an annotation to a type
|
||||
fn node_id_type(cx: @crate_ctxt, id: ast::node_id) -> ty::t {
|
||||
ret ty::node_id_to_type(cx.tcx, id);
|
||||
}
|
||||
|
||||
fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
|
||||
un_expr: @ast::expr, dest: dest) -> @block_ctxt {
|
||||
// Check for user-defined method call
|
||||
|
|
@ -2029,7 +2013,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
|
|||
}
|
||||
|
||||
if dest == ignore { ret trans_expr(bcx, e, ignore); }
|
||||
let e_ty = ty::expr_ty(bcx_tcx(bcx), e);
|
||||
let e_ty = expr_ty(bcx, e);
|
||||
alt op {
|
||||
ast::not {
|
||||
let {bcx, val} = trans_temp_expr(bcx, e);
|
||||
|
|
@ -2155,7 +2139,7 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
|
|||
fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
|
||||
dst: @ast::expr, src: @ast::expr) -> @block_ctxt {
|
||||
let tcx = bcx_tcx(bcx);
|
||||
let t = ty::expr_ty(tcx, src);
|
||||
let t = expr_ty(bcx, src);
|
||||
let lhs_res = trans_lval(bcx, dst);
|
||||
assert (lhs_res.kind == owned);
|
||||
|
||||
|
|
@ -2163,7 +2147,7 @@ fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
|
|||
alt bcx_ccx(bcx).method_map.find(ex.id) {
|
||||
some(origin) {
|
||||
let callee_id = ast_util::op_expr_callee_id(ex);
|
||||
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
|
||||
let fty = ty::node_id_to_type(tcx, callee_id);
|
||||
ret trans_call_inner(bcx, fty, {|bcx|
|
||||
// FIXME provide the already-computed address, not the expr
|
||||
impl::trans_method_callee(bcx, callee_id, dst, origin)
|
||||
|
|
@ -2309,8 +2293,8 @@ fn trans_binary(bcx: @block_ctxt, op: ast::binop, lhs: @ast::expr,
|
|||
let lhs_res = trans_temp_expr(bcx, lhs);
|
||||
let rhs_res = trans_temp_expr(lhs_res.bcx, rhs);
|
||||
ret trans_eager_binop(rhs_res.bcx, op, lhs_res.val,
|
||||
ty::expr_ty(bcx_tcx(bcx), lhs), rhs_res.val,
|
||||
ty::expr_ty(bcx_tcx(bcx), rhs), dest);
|
||||
expr_ty(bcx, lhs), rhs_res.val,
|
||||
expr_ty(bcx, rhs), dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2438,7 +2422,7 @@ fn trans_for(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
|
|||
}
|
||||
let ccx = bcx_ccx(cx);
|
||||
let next_cx = new_sub_block_ctxt(cx, "next");
|
||||
let seq_ty = ty::expr_ty(bcx_tcx(cx), seq);
|
||||
let seq_ty = expr_ty(cx, seq);
|
||||
let {bcx: bcx, val: seq} = trans_temp_expr(cx, seq);
|
||||
let seq = PointerCast(bcx, seq, T_ptr(ccx.opaque_vec_type));
|
||||
let fill = tvec::get_fill(bcx, seq);
|
||||
|
|
@ -2538,10 +2522,52 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
|
|||
type_of_ty_param_bounds_and_ty(ccx, tpt));
|
||||
}
|
||||
|
||||
fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
|
||||
dicts: option<typeck::dict_res>) -> ValueRef {
|
||||
let hash_id = @{def: fn_id, substs: substs, dicts: alt dicts {
|
||||
some(os) { vec::map(*os, {|o| impl::dict_id(ccx.tcx, o)}) }
|
||||
none { [] }
|
||||
}};
|
||||
alt ccx.monomorphized.find(hash_id) {
|
||||
some(val) { ret val; }
|
||||
none {}
|
||||
}
|
||||
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
|
||||
let mono_ty = ty::substitute_type_params(ccx.tcx, substs, tpt.ty);
|
||||
let (item, pt) = alt ccx.tcx.items.get(fn_id.node) {
|
||||
ast_map::node_item(i, p) { (i, p) } _ { fail; }
|
||||
};
|
||||
let pt = *pt + [path_name(item.ident)];
|
||||
let result = alt item.node {
|
||||
ast::item_fn(decl, _, body) {
|
||||
let llfty = type_of_fn_from_ty(ccx, mono_ty, []);
|
||||
let s = mangle_exported_name(ccx, pt, mono_ty);
|
||||
let lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
|
||||
trans_fn(ccx, pt, decl, body, lldecl, no_self, [],
|
||||
some(substs), fn_id.node);
|
||||
lldecl
|
||||
}
|
||||
_ { fail "FIXME[mono] handle other constructs"; }
|
||||
};
|
||||
ccx.monomorphized.insert(hash_id, result);
|
||||
result
|
||||
}
|
||||
|
||||
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
|
||||
-> lval_maybe_callee {
|
||||
let ccx = bcx_ccx(bcx);
|
||||
let tys = ty::node_id_to_type_params(ccx.tcx, id);
|
||||
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
|
||||
if ccx.sess.opts.monomorphize && vec::len(tys) > 0u &&
|
||||
fn_id.crate == ast::local_crate &&
|
||||
!vec::any(tys, {|t| ty::type_contains_params(ccx.tcx, t)}) &&
|
||||
vec::all(*tpt.bounds, {|bs| vec::all(*bs, {|b|
|
||||
alt b { ty::bound_iface(_) { false } _ { true } }
|
||||
})}) {
|
||||
let dicts = ccx.dict_map.find(id);
|
||||
ret {bcx: bcx, val: monomorphic_fn(ccx, fn_id, tys, dicts),
|
||||
kind: owned, env: null_env, generic: none};
|
||||
}
|
||||
let val = if fn_id.crate == ast::local_crate {
|
||||
// Internal reference.
|
||||
assert (ccx.item_ids.contains_key(fn_id.node));
|
||||
|
|
@ -2550,9 +2576,8 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
|
|||
// External reference.
|
||||
trans_external_path(bcx, fn_id, tpt)
|
||||
};
|
||||
let tys = ty::node_id_to_type_params(ccx.tcx, id);
|
||||
let gen = none, bcx = bcx;
|
||||
if vec::len(tys) != 0u {
|
||||
if vec::len(tys) > 0u {
|
||||
let tydescs = [], tis = [];
|
||||
for t in tys {
|
||||
// TODO: Doesn't always escape.
|
||||
|
|
@ -2640,7 +2665,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
|
|||
ret lval_static_fn(cx, vid, id);
|
||||
} else {
|
||||
// Nullary variant.
|
||||
let enum_ty = node_id_type(ccx, id);
|
||||
let enum_ty = ty::node_id_to_type(ccx.tcx, id);
|
||||
let alloc_result = alloc_ty(cx, enum_ty);
|
||||
let llenumblob = alloc_result.val;
|
||||
let llenumty = type_of_enum(ccx, tid, enum_ty);
|
||||
|
|
@ -2673,7 +2698,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
|
|||
fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr,
|
||||
field: ast::ident) -> lval_result {
|
||||
let {bcx, val} = trans_temp_expr(bcx, base);
|
||||
let {bcx, val, ty} = autoderef(bcx, val, ty::expr_ty(bcx_tcx(bcx), base));
|
||||
let {bcx, val, ty} = autoderef(bcx, val, expr_ty(bcx, base));
|
||||
let fields = alt ty::struct(bcx_tcx(bcx), ty) {
|
||||
ty::ty_rec(fs) { fs }
|
||||
// Constraint?
|
||||
|
|
@ -2689,7 +2714,7 @@ fn trans_rec_field(bcx: @block_ctxt, base: @ast::expr,
|
|||
|
||||
fn trans_index(cx: @block_ctxt, ex: @ast::expr, base: @ast::expr,
|
||||
idx: @ast::expr) -> lval_result {
|
||||
let base_ty = ty::expr_ty(bcx_tcx(cx), base);
|
||||
let base_ty = expr_ty(cx, base);
|
||||
let exp = trans_temp_expr(cx, base);
|
||||
let lv = autoderef(exp.bcx, exp.val, base_ty);
|
||||
let ix = trans_temp_expr(lv.bcx, idx);
|
||||
|
|
@ -2707,7 +2732,7 @@ fn trans_index(cx: @block_ctxt, ex: @ast::expr, base: @ast::expr,
|
|||
ix_val = Trunc(bcx, ix.val, ccx.int_type);
|
||||
} else { ix_val = ix.val; }
|
||||
|
||||
let unit_ty = node_id_type(bcx_ccx(cx), ex.id);
|
||||
let unit_ty = node_id_type(cx, ex.id);
|
||||
let unit_sz = size_of(bcx, unit_ty);
|
||||
bcx = unit_sz.bcx;
|
||||
maybe_name_value(bcx_ccx(cx), unit_sz.val, "unit_sz");
|
||||
|
|
@ -2771,7 +2796,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
alt e.node {
|
||||
ast::expr_path(_) {
|
||||
let v = trans_path(cx, e.id);
|
||||
ret lval_maybe_callee_to_lval(v, ty::expr_ty(bcx_tcx(cx), e));
|
||||
ret lval_maybe_callee_to_lval(v, expr_ty(cx, e));
|
||||
}
|
||||
ast::expr_field(base, ident, _) {
|
||||
ret trans_rec_field(cx, base, ident);
|
||||
|
|
@ -2782,7 +2807,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
ast::expr_unary(ast::deref, base) {
|
||||
let ccx = bcx_ccx(cx);
|
||||
let sub = trans_temp_expr(cx, base);
|
||||
let t = ty::expr_ty(ccx.tcx, base);
|
||||
let t = expr_ty(cx, base);
|
||||
let val =
|
||||
alt ty::struct(ccx.tcx, t) {
|
||||
ty::ty_box(_) {
|
||||
|
|
@ -2792,7 +2817,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
GEPi(sub.bcx, sub.val, [0, 1])
|
||||
}
|
||||
ty::ty_enum(_, _) {
|
||||
let ety = ty::expr_ty(ccx.tcx, e);
|
||||
let ety = expr_ty(cx, e);
|
||||
let ellty =
|
||||
if check type_has_static_size(ccx, ety) {
|
||||
T_ptr(type_of(ccx, ety))
|
||||
|
|
@ -2808,12 +2833,6 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
};
|
||||
ret lval_owned(sub.bcx, val);
|
||||
}
|
||||
// This is a by-ref returning call. Regular calls are not lval
|
||||
ast::expr_call(f, args, _) {
|
||||
let cell = empty_dest_cell();
|
||||
let bcx = trans_call(cx, f, args, e.id, by_val(cell));
|
||||
ret lval_owned(bcx, *cell);
|
||||
}
|
||||
_ { bcx_ccx(cx).sess.span_bug(e.span, "non-lval in trans_lval"); }
|
||||
}
|
||||
}
|
||||
|
|
@ -2878,14 +2897,14 @@ fn float_cast(bcx: @block_ctxt, lldsttype: TypeRef, llsrctype: TypeRef,
|
|||
fn trans_cast(cx: @block_ctxt, e: @ast::expr, id: ast::node_id,
|
||||
dest: dest) -> @block_ctxt {
|
||||
let ccx = bcx_ccx(cx);
|
||||
let t_out = node_id_type(ccx, id);
|
||||
alt ty::struct(ccx.tcx, t_out) {
|
||||
let t_out = node_id_type(cx, id);
|
||||
alt ty::struct(bcx_tcx(cx), t_out) {
|
||||
ty::ty_iface(_, _) { ret impl::trans_cast(cx, e, id, dest); }
|
||||
_ {}
|
||||
}
|
||||
let e_res = trans_temp_expr(cx, e);
|
||||
let ll_t_in = val_ty(e_res.val);
|
||||
let t_in = ty::expr_ty(ccx.tcx, e);
|
||||
let t_in = expr_ty(cx, e);
|
||||
// Check should be avoidable because it's a cast.
|
||||
// FIXME: Constrain types so as to avoid this check.
|
||||
check (type_has_static_size(ccx, t_out));
|
||||
|
|
@ -2957,7 +2976,7 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef,
|
|||
&to_revoke: [{v: ValueRef, t: ty::t}], e: @ast::expr) ->
|
||||
result {
|
||||
let ccx = bcx_ccx(cx);
|
||||
let e_ty = ty::expr_ty(ccx.tcx, e);
|
||||
let e_ty = expr_ty(cx, e);
|
||||
let is_bot = ty::type_is_bot(ccx.tcx, e_ty);
|
||||
let lv = trans_temp_lval(cx, e);
|
||||
let bcx = lv.bcx;
|
||||
|
|
@ -3134,7 +3153,7 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef,
|
|||
fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
|
||||
args: [@ast::expr], id: ast::node_id, dest: dest)
|
||||
-> @block_ctxt {
|
||||
trans_call_inner(in_cx, ty::expr_ty(bcx_tcx(in_cx), f),
|
||||
trans_call_inner(in_cx, expr_ty(in_cx, f),
|
||||
{|cx| trans_callee(cx, f)}, args, id, dest)
|
||||
}
|
||||
|
||||
|
|
@ -3329,7 +3348,7 @@ fn trans_landing_pad(bcx: @block_ctxt,
|
|||
|
||||
fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
|
||||
dest: dest) -> @block_ctxt {
|
||||
let t = node_id_type(bcx.fcx.ccx, id);
|
||||
let t = node_id_type(bcx, id);
|
||||
let bcx = bcx;
|
||||
let addr = alt dest {
|
||||
ignore {
|
||||
|
|
@ -3342,7 +3361,7 @@ fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
|
|||
let temp_cleanups = [], i = 0;
|
||||
for e in elts {
|
||||
let dst = GEP_tup_like_1(bcx, t, addr, [0, i]);
|
||||
let e_ty = ty::expr_ty(bcx_tcx(bcx), e);
|
||||
let e_ty = expr_ty(bcx, e);
|
||||
bcx = trans_expr_save_in(dst.bcx, e, dst.val);
|
||||
add_clean_temp_mem(bcx, dst.val, e_ty);
|
||||
temp_cleanups += [dst.val];
|
||||
|
|
@ -3355,7 +3374,7 @@ fn trans_tup(bcx: @block_ctxt, elts: [@ast::expr], id: ast::node_id,
|
|||
fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
|
||||
base: option<@ast::expr>, id: ast::node_id,
|
||||
dest: dest) -> @block_ctxt {
|
||||
let t = node_id_type(bcx_ccx(bcx), id);
|
||||
let t = node_id_type(bcx, id);
|
||||
let bcx = bcx;
|
||||
let addr = alt dest {
|
||||
ignore {
|
||||
|
|
@ -3409,7 +3428,7 @@ fn trans_rec(bcx: @block_ctxt, fields: [ast::field],
|
|||
// that nil or bot expressions get ignore rather than save_in as destination.
|
||||
fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef)
|
||||
-> @block_ctxt {
|
||||
let tcx = bcx_tcx(bcx), t = ty::expr_ty(tcx, e);
|
||||
let tcx = bcx_tcx(bcx), t = expr_ty(bcx, e);
|
||||
let do_ignore = ty::type_is_bot(tcx, t) || ty::type_is_nil(tcx, t);
|
||||
ret trans_expr(bcx, e, if do_ignore { ignore } else { save_in(dest) });
|
||||
}
|
||||
|
|
@ -3425,7 +3444,7 @@ fn trans_temp_lval(bcx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
ret trans_lval(bcx, e);
|
||||
} else {
|
||||
let tcx = bcx_tcx(bcx);
|
||||
let ty = ty::expr_ty(tcx, e);
|
||||
let ty = expr_ty(bcx, e);
|
||||
if ty::type_is_nil(tcx, ty) || ty::type_is_bot(tcx, ty) {
|
||||
bcx = trans_expr(bcx, e, ignore);
|
||||
ret {bcx: bcx, val: C_nil(), kind: temporary};
|
||||
|
|
@ -3448,7 +3467,7 @@ fn trans_temp_lval(bcx: @block_ctxt, e: @ast::expr) -> lval_result {
|
|||
fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result {
|
||||
let {bcx, val, kind} = trans_temp_lval(bcx, e);
|
||||
if kind == owned {
|
||||
val = load_if_immediate(bcx, val, ty::expr_ty(bcx_tcx(bcx), e));
|
||||
val = load_if_immediate(bcx, val, expr_ty(bcx, e));
|
||||
}
|
||||
ret {bcx: bcx, val: val};
|
||||
}
|
||||
|
|
@ -3503,10 +3522,10 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
|||
bcx, proto, decl, body, e.span, e.id, *cap_clause, dest);
|
||||
}
|
||||
ast::expr_fn_block(decl, body) {
|
||||
alt ty::struct(tcx, ty::expr_ty(tcx, e)) {
|
||||
alt ty::struct(tcx, expr_ty(bcx, e)) {
|
||||
ty::ty_fn({proto, _}) {
|
||||
#debug("translating fn_block %s with type %s",
|
||||
expr_to_str(e), ty_to_str(tcx, ty::expr_ty(tcx, e)));
|
||||
expr_to_str(e), ty_to_str(tcx, expr_ty(bcx, e)));
|
||||
let cap_clause = { copies: [], moves: [] };
|
||||
ret closure::trans_expr_fn(
|
||||
bcx, proto, decl, body, e.span, e.id, cap_clause, dest);
|
||||
|
|
@ -3618,7 +3637,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
|||
let {bcx, val: addr, kind} = trans_lval(src_r.bcx, dst);
|
||||
assert kind == owned;
|
||||
ret store_temp_expr(bcx, DROP_EXISTING, addr, src_r,
|
||||
ty::expr_ty(bcx_tcx(bcx), src),
|
||||
expr_ty(bcx, src),
|
||||
bcx_ccx(bcx).last_uses.contains_key(src.id));
|
||||
}
|
||||
ast::expr_move(dst, src) {
|
||||
|
|
@ -3628,14 +3647,14 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
|||
let {bcx, val: addr, kind} = trans_lval(src_r.bcx, dst);
|
||||
assert kind == owned;
|
||||
ret move_val(bcx, DROP_EXISTING, addr, src_r,
|
||||
ty::expr_ty(bcx_tcx(bcx), src));
|
||||
expr_ty(bcx, src));
|
||||
}
|
||||
ast::expr_swap(dst, src) {
|
||||
assert dest == ignore;
|
||||
let lhs_res = trans_lval(bcx, dst);
|
||||
assert lhs_res.kind == owned;
|
||||
let rhs_res = trans_lval(lhs_res.bcx, src);
|
||||
let t = ty::expr_ty(tcx, src);
|
||||
let t = expr_ty(bcx, src);
|
||||
let {bcx: bcx, val: tmp_alloc} = alloc_ty(rhs_res.bcx, t);
|
||||
// Swap through a temporary.
|
||||
bcx = move_val(bcx, INIT, tmp_alloc, lhs_res, t);
|
||||
|
|
@ -3656,7 +3675,7 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
|||
let lv = trans_lval(bcx, e), ccx = bcx_ccx(bcx);
|
||||
let {bcx, val, kind} = lv;
|
||||
let last_use = kind == owned && ccx.last_uses.contains_key(e.id);
|
||||
let ty = ty::expr_ty(ccx.tcx, e);
|
||||
let ty = expr_ty(bcx, e);
|
||||
alt dest {
|
||||
by_val(cell) {
|
||||
if kind == temporary {
|
||||
|
|
@ -3719,7 +3738,7 @@ fn load_if_immediate(cx: @block_ctxt, v: ValueRef, t: ty::t) -> ValueRef {
|
|||
|
||||
fn trans_log(lvl: @ast::expr, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt {
|
||||
let ccx = bcx_ccx(cx), tcx = ccx.tcx;
|
||||
if ty::type_is_bot(tcx, ty::expr_ty(tcx, lvl)) {
|
||||
if ty::type_is_bot(tcx, expr_ty(cx, lvl)) {
|
||||
ret trans_expr(cx, lvl, ignore);
|
||||
}
|
||||
|
||||
|
|
@ -3754,7 +3773,7 @@ fn trans_log(lvl: @ast::expr, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt {
|
|||
|
||||
CondBr(level_res.bcx, test, log_cx.llbb, after_cx.llbb);
|
||||
let sub = trans_temp_expr(log_cx, e);
|
||||
let e_ty = ty::expr_ty(bcx_tcx(cx), e);
|
||||
let e_ty = expr_ty(cx, e);
|
||||
let log_bcx = sub.bcx;
|
||||
|
||||
let ti = none::<@tydesc_info>;
|
||||
|
|
@ -3793,7 +3812,7 @@ fn trans_fail_expr(bcx: @block_ctxt, sp_opt: option<span>,
|
|||
some(expr) {
|
||||
let tcx = bcx_tcx(bcx);
|
||||
let expr_res = trans_temp_expr(bcx, expr);
|
||||
let e_ty = ty::expr_ty(tcx, expr);
|
||||
let e_ty = expr_ty(bcx, expr);
|
||||
bcx = expr_res.bcx;
|
||||
|
||||
if ty::type_is_str(tcx, e_ty) {
|
||||
|
|
@ -3916,7 +3935,7 @@ fn trans_be(cx: @block_ctxt, e: @ast::expr) : ast_util::is_call_expr(e) ->
|
|||
}
|
||||
|
||||
fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
|
||||
let ty = node_id_type(bcx_ccx(bcx), local.node.id);
|
||||
let ty = node_id_type(bcx, local.node.id);
|
||||
let llptr = alt bcx.fcx.lllocals.find(local.node.id) {
|
||||
some(local_mem(v)) { v }
|
||||
some(_) { bcx_tcx(bcx).sess.span_bug(local.span,
|
||||
|
|
@ -4214,7 +4233,7 @@ fn alloc_ty(cx: @block_ctxt, t: ty::t) -> result {
|
|||
}
|
||||
|
||||
fn alloc_local(cx: @block_ctxt, local: @ast::local) -> @block_ctxt {
|
||||
let t = node_id_type(bcx_ccx(cx), local.node.id);
|
||||
let t = node_id_type(cx, local.node.id);
|
||||
let p = normalize_pat(bcx_tcx(cx), local.node.pat);
|
||||
let is_simple = alt p.node {
|
||||
ast::pat_ident(_, none) { true } _ { false }
|
||||
|
|
@ -4258,7 +4277,7 @@ fn trans_block_dps(bcx: @block_ctxt, b: ast::blk, dest: dest)
|
|||
}
|
||||
alt b.node.expr {
|
||||
some(e) {
|
||||
let bt = ty::type_is_bot(bcx_tcx(bcx), ty::expr_ty(bcx_tcx(bcx), e));
|
||||
let bt = ty::type_is_bot(bcx_tcx(bcx), expr_ty(bcx, e));
|
||||
debuginfo::update_source_pos(bcx, e.span);
|
||||
bcx = trans_expr(bcx, e, if bt { ignore } else { dest });
|
||||
}
|
||||
|
|
@ -4302,6 +4321,7 @@ fn mk_standard_basic_blocks(llfn: ValueRef) ->
|
|||
// - trans_args
|
||||
fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path,
|
||||
llfndecl: ValueRef, id: ast::node_id,
|
||||
param_substs: option<[ty::t]>,
|
||||
sp: option<span>) -> @fn_ctxt {
|
||||
let llbbs = mk_standard_basic_blocks(llfndecl);
|
||||
ret @{llfn: llfndecl,
|
||||
|
|
@ -4321,6 +4341,7 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path,
|
|||
mutable lltyparams: [],
|
||||
derived_tydescs: ty::new_ty_hash(),
|
||||
id: id,
|
||||
param_substs: param_substs,
|
||||
span: sp,
|
||||
path: path,
|
||||
ccx: ccx};
|
||||
|
|
@ -4328,7 +4349,7 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path,
|
|||
|
||||
fn new_fn_ctxt(ccx: @crate_ctxt, path: path, llfndecl: ValueRef,
|
||||
sp: option<span>) -> @fn_ctxt {
|
||||
ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, sp);
|
||||
ret new_fn_ctxt_w_id(ccx, path, llfndecl, -1, none, sp);
|
||||
}
|
||||
|
||||
// NB: must keep 4 fns in sync:
|
||||
|
|
@ -4457,18 +4478,20 @@ enum self_arg { impl_self(ty::t), no_self, }
|
|||
fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
||||
body: ast::blk, llfndecl: ValueRef,
|
||||
ty_self: self_arg, ty_params: [ast::ty_param],
|
||||
param_substs: option<[ty::t]>,
|
||||
id: ast::node_id, maybe_load_env: fn(@fn_ctxt)) {
|
||||
set_uwtable(llfndecl);
|
||||
|
||||
// Set up arguments to the function.
|
||||
let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, some(body.span));
|
||||
let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, id, param_substs,
|
||||
some(body.span));
|
||||
create_llargs_for_fn_args(fcx, ty_self, decl.inputs, ty_params);
|
||||
|
||||
// Create the first basic block in the function and keep a handle on it to
|
||||
// pass to finish_fn later.
|
||||
let bcx = new_top_block_ctxt(fcx, some(body.span));
|
||||
let lltop = bcx.llbb;
|
||||
let block_ty = node_id_type(ccx, body.node.id);
|
||||
let block_ty = node_id_type(bcx, body.node.id);
|
||||
|
||||
let arg_tys = arg_tys_of_fn(fcx.ccx, id);
|
||||
bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, arg_tys);
|
||||
|
|
@ -4487,8 +4510,6 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
|||
bcx = trans_block_dps(bcx, body, save_in(fcx.llretptr));
|
||||
}
|
||||
|
||||
// FIXME: until LLVM has a unit type, we are moving around
|
||||
// C_nil values rather than their void type.
|
||||
if !bcx.unreachable { build_return(bcx); }
|
||||
// Insert the mandatory first few basic blocks before lltop.
|
||||
finish_fn(fcx, lltop);
|
||||
|
|
@ -4498,19 +4519,17 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
|||
// function.
|
||||
fn trans_fn(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
||||
body: ast::blk, llfndecl: ValueRef, ty_self: self_arg,
|
||||
ty_params: [ast::ty_param], id: ast::node_id) {
|
||||
ty_params: [ast::ty_param], param_substs: option<[ty::t]>,
|
||||
id: ast::node_id) {
|
||||
let do_time = ccx.sess.opts.stats;
|
||||
let start = if do_time {
|
||||
time::get_time()
|
||||
} else {
|
||||
{sec: 0u32, usec: 0u32}
|
||||
};
|
||||
let fcx = option::none;
|
||||
trans_closure(ccx, path, decl, body, llfndecl, ty_self, ty_params, id,
|
||||
{|new_fcx| fcx = option::some(new_fcx);});
|
||||
if ccx.sess.opts.extra_debuginfo {
|
||||
debuginfo::create_function(option::get(fcx));
|
||||
}
|
||||
let start = if do_time { time::get_time() }
|
||||
else { {sec: 0u32, usec: 0u32} };
|
||||
trans_closure(ccx, path, decl, body, llfndecl, ty_self,
|
||||
ty_params, param_substs, id, {|fcx|
|
||||
if ccx.sess.opts.extra_debuginfo {
|
||||
debuginfo::create_function(fcx);
|
||||
}
|
||||
});
|
||||
if do_time {
|
||||
let end = time::get_time();
|
||||
log_fn_time(ccx, path_str(path), start, end);
|
||||
|
|
@ -4521,7 +4540,7 @@ fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
|
|||
ctor_id: ast::node_id, ty_params: [ast::ty_param]) {
|
||||
// Create a function for the constructor
|
||||
let llctor_decl = ccx.item_ids.get(ctor_id);
|
||||
let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, none);
|
||||
let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id, none, none);
|
||||
let ret_t = ty::ret_ty_of_fn(ccx.tcx, ctor_id);
|
||||
create_llargs_for_fn_args(fcx, no_self, dtor.inputs, ty_params);
|
||||
let bcx = new_top_block_ctxt(fcx, none);
|
||||
|
|
@ -4579,7 +4598,8 @@ fn trans_enum_variant(ccx: @crate_ctxt,
|
|||
"unbound variant id in trans_enum_variant");
|
||||
}
|
||||
}
|
||||
let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, none);
|
||||
let fcx = new_fn_ctxt_w_id(ccx, [], llfndecl, variant.node.id, none,
|
||||
none);
|
||||
create_llargs_for_fn_args(fcx, no_self, fn_args, ty_params);
|
||||
let ty_param_substs = [], i = 0u;
|
||||
for tp: ast::ty_param in ty_params {
|
||||
|
|
@ -4639,7 +4659,7 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
|||
let te2 = trans_const_expr(cx, e2);
|
||||
/* Neither type is bottom, and we expect them to be unified already,
|
||||
* so the following is safe. */
|
||||
let ty = ty::expr_ty(ccx_tcx(cx), e1);
|
||||
let ty = ty::expr_ty(cx.tcx, e1);
|
||||
let is_float = ty::type_is_fp(ccx_tcx(cx), ty);
|
||||
let signed = ty::type_is_signed(ccx_tcx(cx), ty);
|
||||
ret alt b {
|
||||
|
|
@ -4683,7 +4703,7 @@ fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
|||
}
|
||||
ast::expr_unary(u, e) {
|
||||
let te = trans_const_expr(cx, e);
|
||||
let ty = ty::expr_ty(ccx_tcx(cx), e);
|
||||
let ty = ty::expr_ty(cx.tcx, e);
|
||||
let is_float = ty::type_is_fp(ccx_tcx(cx), ty);
|
||||
ret alt u {
|
||||
ast::box(_) |
|
||||
|
|
@ -4904,7 +4924,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
|||
alt ccx.item_ids.find(item.id) {
|
||||
some(llfndecl) {
|
||||
trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
|
||||
llfndecl, no_self, tps, item.id);
|
||||
llfndecl, no_self, tps, none, item.id);
|
||||
}
|
||||
_ {
|
||||
ccx.sess.span_fatal(item.span,
|
||||
|
|
@ -4922,7 +4942,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
|||
alt ccx.item_ids.find(item.id) {
|
||||
some(lldtor_decl) {
|
||||
trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
|
||||
lldtor_decl, no_self, tps, dtor_id);
|
||||
lldtor_decl, no_self, tps, none, dtor_id);
|
||||
}
|
||||
_ {
|
||||
ccx.sess.span_fatal(item.span, "unbound dtor in trans_item");
|
||||
|
|
@ -4972,8 +4992,7 @@ fn get_pair_fn_ty(llpairty: TypeRef) -> TypeRef {
|
|||
fn register_fn(ccx: @crate_ctxt, sp: span, path: path, flav: str,
|
||||
ty_params: [ast::ty_param], node_id: ast::node_id) {
|
||||
// FIXME: pull this out
|
||||
let t = node_id_type(ccx, node_id);
|
||||
check returns_non_ty_var(ccx, t);
|
||||
let t = ty::node_id_to_type(ccx.tcx, node_id);
|
||||
register_fn_full(ccx, sp, path, flav, ty_params, node_id, t);
|
||||
}
|
||||
|
||||
|
|
@ -4983,8 +5002,7 @@ fn param_bounds(ccx: @crate_ctxt, tp: ast::ty_param) -> ty::param_bounds {
|
|||
|
||||
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path, _flav: str,
|
||||
tps: [ast::ty_param], node_id: ast::node_id,
|
||||
node_type: ty::t)
|
||||
: returns_non_ty_var(ccx, node_type) {
|
||||
node_type: ty::t) {
|
||||
let llfty = type_of_fn_from_ty(ccx, node_type,
|
||||
vec::map(tps, {|p| param_bounds(ccx, p)}));
|
||||
let ps: str = mangle_exported_name(ccx, path, node_type);
|
||||
|
|
@ -5147,7 +5165,7 @@ fn collect_native_item(ccx: @crate_ctxt,
|
|||
alt i.node {
|
||||
ast::native_item_fn(_, tps) {
|
||||
let id = i.id;
|
||||
let node_type = node_id_type(ccx, id);
|
||||
let node_type = ty::node_id_to_type(ccx.tcx, id);
|
||||
let fn_abi =
|
||||
alt attr::get_meta_item_value_str_by_name(i.attrs, "abi") {
|
||||
option::none {
|
||||
|
|
@ -5203,9 +5221,8 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>,
|
|||
let my_path = item_path(ccx, i);
|
||||
alt i.node {
|
||||
ast::item_const(_, _) {
|
||||
let typ = node_id_type(ccx, i.id);
|
||||
let s = mangle_exported_name(ccx, my_path,
|
||||
node_id_type(ccx, i.id));
|
||||
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
||||
let s = mangle_exported_name(ccx, my_path, typ);
|
||||
// FIXME: Could follow from a constraint on types of const
|
||||
// items
|
||||
let g = str::as_buf(s, {|buf|
|
||||
|
|
@ -5240,9 +5257,8 @@ fn collect_item(ccx: @crate_ctxt, abi: @mutable option<ast::native_abi>,
|
|||
// the dtor_id. This is a bit counter-intuitive, but simplifies
|
||||
// ty_res, which would have to carry around two def_ids otherwise
|
||||
// -- one to identify the type, and one to find the dtor symbol.
|
||||
let t = node_id_type(ccx, dtor_id);
|
||||
let t = ty::node_id_to_type(ccx.tcx, dtor_id);
|
||||
// FIXME: how to get rid of this check?
|
||||
check returns_non_ty_var(ccx, t);
|
||||
register_fn_full(ccx, i.span, my_path + [path_name("dtor")],
|
||||
"res_dtor", tps, i.id, t);
|
||||
}
|
||||
|
|
@ -5534,6 +5550,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
|
|||
consts: new_int_hash::<ValueRef>(),
|
||||
tydescs: ty::new_ty_hash(),
|
||||
dicts: map::mk_hashmap(hash_dict_id, {|a, b| a == b}),
|
||||
monomorphized: map::mk_hashmap(hash_mono_id, {|a, b| a == b}),
|
||||
module_data: new_str_hash::<ValueRef>(),
|
||||
lltypes: ty::new_ty_hash(),
|
||||
names: new_namegen(),
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ import ast_map::{path, path_mod, path_name};
|
|||
|
||||
enum environment_value {
|
||||
// Evaluate expr and store result in env (used for bind).
|
||||
env_expr(@ast::expr),
|
||||
env_expr(@ast::expr, ty::t),
|
||||
|
||||
// Copy the value from this llvm ValueRef into the environment.
|
||||
env_copy(ValueRef, ty::t, lval_kind),
|
||||
|
|
@ -103,7 +103,7 @@ enum environment_value {
|
|||
|
||||
fn ev_to_str(ccx: @crate_ctxt, ev: environment_value) -> str {
|
||||
alt ev {
|
||||
env_expr(ex) { expr_to_str(ex) }
|
||||
env_expr(ex, _) { expr_to_str(ex) }
|
||||
env_copy(v, t, lk) { #fmt("copy(%s,%s)", val_str(ccx.tn, v),
|
||||
ty_to_str(ccx.tcx, t)) }
|
||||
env_move(v, t, lk) { #fmt("move(%s,%s)", val_str(ccx.tn, v),
|
||||
|
|
@ -151,7 +151,7 @@ fn mk_closure_tys(tcx: ty::ctxt,
|
|||
env_copy(_, t, _) { t }
|
||||
env_move(_, t, _) { t }
|
||||
env_ref(_, t, _) { t }
|
||||
env_expr(e) { ty::expr_ty(tcx, e) }
|
||||
env_expr(_, t) { t }
|
||||
}];
|
||||
}
|
||||
let bound_data_ty = ty::mk_tup(tcx, bound_tys);
|
||||
|
|
@ -316,7 +316,7 @@ fn store_environment(
|
|||
bcx = bound_data.bcx;
|
||||
let bound_data = bound_data.val;
|
||||
alt bv {
|
||||
env_expr(e) {
|
||||
env_expr(e, _) {
|
||||
bcx = base::trans_expr_save_in(bcx, e, bound_data);
|
||||
add_clean_temp_mem(bcx, bound_data, bound_tys[i]);
|
||||
temp_cleanups += [bound_data];
|
||||
|
|
@ -457,7 +457,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
|||
dest: dest) -> @block_ctxt {
|
||||
if dest == ignore { ret bcx; }
|
||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||
let fty = node_id_type(ccx, id);
|
||||
let fty = node_id_type(bcx, id);
|
||||
let llfnty = type_of_fn_from_ty(ccx, fty, []);
|
||||
let sub_path = bcx.fcx.path + [path_name("anon")];
|
||||
let s = mangle_internal_name_by_path(ccx, sub_path);
|
||||
|
|
@ -468,7 +468,8 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
|||
let cap_vars = capture::compute_capture_vars(
|
||||
ccx.tcx, id, proto, cap_clause);
|
||||
let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck);
|
||||
trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], id, {|fcx|
|
||||
trans_closure(ccx, sub_path, decl, body, llfn, no_self, [],
|
||||
bcx.fcx.param_substs, id, {|fcx|
|
||||
load_environment(bcx, fcx, cdata_ty, cap_vars, ck);
|
||||
});
|
||||
llbox
|
||||
|
|
@ -479,10 +480,9 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
|||
ast::proto_box { trans_closure_env(ty::ck_box) }
|
||||
ast::proto_uniq { trans_closure_env(ty::ck_uniq) }
|
||||
ast::proto_bare {
|
||||
let closure = C_null(T_opaque_box_ptr(ccx));
|
||||
trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], id,
|
||||
{|_fcx|});
|
||||
closure
|
||||
trans_closure(ccx, sub_path, decl, body, llfn, no_self, [], none,
|
||||
id, {|_fcx|});
|
||||
C_null(T_opaque_box_ptr(ccx))
|
||||
}
|
||||
};
|
||||
fill_fn_pair(bcx, get_dest_addr(dest), llfn, closure);
|
||||
|
|
@ -492,7 +492,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
|||
fn trans_bind(cx: @block_ctxt, f: @ast::expr, args: [option<@ast::expr>],
|
||||
id: ast::node_id, dest: dest) -> @block_ctxt {
|
||||
let f_res = trans_callee(cx, f);
|
||||
ret trans_bind_1(cx, ty::expr_ty(bcx_tcx(cx), f), f_res, args,
|
||||
ret trans_bind_1(cx, expr_ty(cx, f), f_res, args,
|
||||
ty::node_id_to_type(bcx_tcx(cx), id), dest);
|
||||
}
|
||||
|
||||
|
|
@ -567,7 +567,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
|||
// Actually construct the closure
|
||||
let {llbox, cdata_ty, bcx} = store_environment(
|
||||
bcx, vec::map(lltydescs, {|d| {desc: d, dicts: none}}),
|
||||
env_vals + vec::map(bound, {|x| env_expr(x)}),
|
||||
env_vals + vec::map(bound, {|x| env_expr(x, expr_ty(bcx, x))}),
|
||||
ty::ck_box);
|
||||
|
||||
// Make thunk
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ type crate_ctxt =
|
|||
consts: hashmap<ast::node_id, ValueRef>,
|
||||
tydescs: hashmap<ty::t, @tydesc_info>,
|
||||
dicts: hashmap<dict_id, ValueRef>,
|
||||
monomorphized: hashmap<mono_id, ValueRef>,
|
||||
module_data: hashmap<str, ValueRef>,
|
||||
lltypes: hashmap<ty::t, TypeRef>,
|
||||
names: namegen,
|
||||
|
|
@ -235,6 +236,7 @@ type fn_ctxt =
|
|||
mutable lltyparams: [fn_ty_param],
|
||||
derived_tydescs: hashmap<ty::t, derived_tydesc_info>,
|
||||
id: ast::node_id,
|
||||
param_substs: option<[ty::t]>,
|
||||
span: option<span>,
|
||||
path: path,
|
||||
ccx: @crate_ctxt};
|
||||
|
|
@ -917,6 +919,16 @@ fn hash_dict_id(&&dp: dict_id) -> uint {
|
|||
h
|
||||
}
|
||||
|
||||
// Used to identify cached monomorphized functions
|
||||
// FIXME[mono] don't count different boxes as different types
|
||||
type mono_id = @{def: ast::def_id, substs: [ty::t], dicts: [dict_id]};
|
||||
fn hash_mono_id(&&mi: mono_id) -> uint {
|
||||
let h = syntax::ast_util::hash_def_id(mi.def);
|
||||
for ty in mi.substs { h = (h << 2u) + ty; }
|
||||
for dict in mi.dicts { h = (h << 2u) + hash_dict_id(dict); }
|
||||
h
|
||||
}
|
||||
|
||||
fn umax(cx: @block_ctxt, a: ValueRef, b: ValueRef) -> ValueRef {
|
||||
let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
|
||||
ret build::Select(cx, cond, b, a);
|
||||
|
|
@ -945,6 +957,18 @@ fn path_str(p: path) -> str {
|
|||
r
|
||||
}
|
||||
|
||||
fn node_id_type(bcx: @block_ctxt, id: ast::node_id) -> ty::t {
|
||||
let tcx = bcx_tcx(bcx);
|
||||
let t = ty::node_id_to_type(tcx, id);
|
||||
alt bcx.fcx.param_substs {
|
||||
some(s) { ty::substitute_type_params(tcx, s, t) }
|
||||
_ { t }
|
||||
}
|
||||
}
|
||||
fn expr_ty(bcx: @block_ctxt, ex: @ast::expr) -> ty::t {
|
||||
node_id_type(bcx, ex.id)
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
|
|||
some(llfn) {
|
||||
trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body,
|
||||
llfn, impl_self(ty::node_id_to_type(ccx.tcx, id)),
|
||||
tps + m.tps, m.id);
|
||||
tps + m.tps, none, m.id);
|
||||
}
|
||||
_ {
|
||||
ccx.tcx.sess.bug("Unbound id in trans_impl");
|
||||
|
|
@ -62,7 +62,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
|
|||
|
||||
fn trans_self_arg(bcx: @block_ctxt, base: @ast::expr) -> result {
|
||||
let tz = [], tr = [];
|
||||
let basety = ty::expr_ty(bcx_tcx(bcx), base);
|
||||
let basety = expr_ty(bcx, base);
|
||||
let {bcx, val} = trans_arg_expr(bcx, {mode: ast::by_ref, ty: basety},
|
||||
T_ptr(type_of_or_i8(bcx, basety)), tz,
|
||||
tr, base);
|
||||
|
|
@ -153,7 +153,7 @@ fn trans_iface_callee(bcx: @block_ctxt, callee_id: ast::node_id,
|
|||
// FIXME[impl] I doubt this is alignment-safe
|
||||
let self = PointerCast(bcx, GEPi(bcx, box_body, [0, 2]),
|
||||
T_opaque_cbox_ptr(bcx_ccx(bcx)));
|
||||
let iface_id = alt ty::struct(tcx, ty::expr_ty(tcx, base)) {
|
||||
let iface_id = alt ty::struct(tcx, expr_ty(bcx, base)) {
|
||||
ty::ty_iface(did, _) { did }
|
||||
// precondition
|
||||
_ { bcx_tcx(bcx).sess.span_bug(base.span, "base has non-iface type \
|
||||
|
|
@ -442,7 +442,7 @@ fn get_dict_ptrs(bcx: @block_ctxt, origin: typeck::dict_origin)
|
|||
fn trans_cast(bcx: @block_ctxt, val: @ast::expr, id: ast::node_id, dest: dest)
|
||||
-> @block_ctxt {
|
||||
let ccx = bcx_ccx(bcx), tcx = ccx.tcx;
|
||||
let val_ty = ty::expr_ty(tcx, val);
|
||||
let val_ty = expr_ty(bcx, val);
|
||||
let {bcx, val: dict} = get_dict(bcx, ccx.dict_map.get(id)[0]);
|
||||
let body_ty = ty::mk_tup(tcx, [ty::mk_type(tcx), ty::mk_type(tcx),
|
||||
val_ty]);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import lib::llvm::{ValueRef, TypeRef};
|
|||
import back::abi;
|
||||
import base::{call_memmove, trans_shared_malloc, type_of_or_i8,
|
||||
INIT, copy_val, load_if_immediate, get_tydesc,
|
||||
node_id_type, new_sub_block_ctxt, do_spill_noroot,
|
||||
new_sub_block_ctxt, do_spill_noroot,
|
||||
dest};
|
||||
import shape::{llsize_of, size_of};
|
||||
import build::*;
|
||||
|
|
@ -106,7 +106,7 @@ fn trans_vec(bcx: @block_ctxt, args: [@ast::expr], id: ast::node_id,
|
|||
}
|
||||
ret bcx;
|
||||
}
|
||||
let vec_ty = node_id_type(bcx_ccx(bcx), id);
|
||||
let vec_ty = node_id_type(bcx, id);
|
||||
let {bcx: bcx,
|
||||
val: vptr,
|
||||
llunitsz: llunitsz,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import build::*;
|
|||
import base::{
|
||||
trans_shared_malloc,
|
||||
type_of_inner,
|
||||
node_id_type,
|
||||
INIT,
|
||||
trans_shared_free,
|
||||
drop_ty,
|
||||
|
|
@ -24,7 +23,7 @@ pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
|
|||
|
||||
fn trans_uniq(bcx: @block_ctxt, contents: @ast::expr,
|
||||
node_id: ast::node_id, dest: dest) -> @block_ctxt {
|
||||
let uniq_ty = node_id_type(bcx_ccx(bcx), node_id);
|
||||
let uniq_ty = node_id_type(bcx, node_id);
|
||||
check type_is_unique_box(bcx, uniq_ty);
|
||||
let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);
|
||||
add_clean_free(bcx, llptr, true);
|
||||
|
|
|
|||
|
|
@ -2581,15 +2581,12 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id,
|
|||
// If the given item is in an external crate, looks up its type and adds it to
|
||||
// the type cache. Returns the type parameters and type.
|
||||
fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
|
||||
if did.crate == ast::local_crate {
|
||||
// The item is in this crate. The caller should have added it to the
|
||||
// type cache already; we simply return it.
|
||||
|
||||
ret cx.tcache.get(did);
|
||||
}
|
||||
alt cx.tcache.find(did) {
|
||||
some(tpt) { ret tpt; }
|
||||
none {
|
||||
// The item is in this crate. The caller should have added it to the
|
||||
// type cache already
|
||||
assert did.crate != ast::local_crate;
|
||||
let tyt = csearch::get_type(cx, did);
|
||||
cx.tcache.insert(did, tyt);
|
||||
ret tyt;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ fn build_ctxt(sess: session::session, ast: @ast::crate) -> ctxt {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: this whole structure should not be duplicated here. makes it
|
||||
// painful to add or remove options.
|
||||
fn build_session() -> session::session {
|
||||
let sopts: @session::options = @{
|
||||
crate_type: session::lib_crate,
|
||||
|
|
@ -84,6 +86,7 @@ fn build_session() -> session::session {
|
|||
parse_only: false,
|
||||
no_trans: false,
|
||||
no_asm_comments: false,
|
||||
monomorphize: false,
|
||||
warn_unused_imports: false
|
||||
};
|
||||
driver::build_session(sopts, ".", diagnostic::emit)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue