Remove a large part of the tydesc-passing code
This commit is contained in:
parent
83c9f58534
commit
8f84d4c8b6
src/rustc
@ -429,7 +429,9 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_family(ebml_w, 'f');
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, fn_ty);
|
||||
encode_symbol(ecx, ebml_w, ctor_id);
|
||||
if tps.len() == 0u {
|
||||
encode_symbol(ecx, ebml_w, ctor_id);
|
||||
}
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
@ -447,7 +449,6 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
}
|
||||
alt ifce {
|
||||
some(t) {
|
||||
encode_symbol(ecx, ebml_w, item.id);
|
||||
let i_ty = alt check t.node {
|
||||
ty_path(_, id) { ty::node_id_to_type(tcx, id) }
|
||||
};
|
||||
|
@ -270,7 +270,7 @@ fn dynastack_alloca(cx: block, t: TypeRef, n: ValueRef, ty: ty::t) ->
|
||||
C_uint(bcx.ccx(), llsize_of_real(bcx.ccx(), t)),
|
||||
n);
|
||||
|
||||
let lltydesc = get_tydesc_simple(cx, ty, false).val;
|
||||
let lltydesc = get_tydesc_simple(cx, ty).val;
|
||||
|
||||
let llresult = Call(dy_cx, dynastack_alloc, [llsz, lltydesc]);
|
||||
ret PointerCast(dy_cx, llresult, T_ptr(t));
|
||||
@ -450,7 +450,7 @@ fn trans_malloc_boxed_raw(bcx: block, t: ty::t,
|
||||
let llty = type_of(ccx, box_ptr);
|
||||
|
||||
// Get the tydesc for the body:
|
||||
let {bcx, val: lltydesc} = get_tydesc(bcx, t, true, static_ti);
|
||||
let {bcx, val: lltydesc} = get_tydesc(bcx, t, static_ti);
|
||||
lazily_emit_all_tydesc_glue(ccx, static_ti);
|
||||
|
||||
// Allocate space:
|
||||
@ -470,37 +470,6 @@ fn trans_malloc_boxed(bcx: block, t: ty::t) ->
|
||||
|
||||
// Type descriptor and type glue stuff
|
||||
|
||||
// Given a type and a field index into its corresponding type descriptor,
|
||||
// returns an LLVM ValueRef of that field from the tydesc, generating the
|
||||
// tydesc if necessary.
|
||||
fn field_of_tydesc(cx: block, t: ty::t, escapes: bool, field: int) ->
|
||||
result {
|
||||
let tydesc = get_tydesc_simple(cx, t, escapes);
|
||||
ret rslt(tydesc.bcx,
|
||||
GEPi(tydesc.bcx, tydesc.val, [0, field]));
|
||||
}
|
||||
|
||||
// Given a type containing ty params, build a vector containing a ValueRef for
|
||||
// each of the ty params it uses (from the current frame) and a vector of the
|
||||
// indices of the ty params present in the type. This is used solely for
|
||||
// constructing derived tydescs.
|
||||
fn linearize_ty_params(cx: block, t: ty::t) ->
|
||||
{params: [uint], descs: [ValueRef]} {
|
||||
let param_vals = [], param_defs = [];
|
||||
ty::walk_ty(cx.tcx(), t) {|t|
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_param(pid, _) {
|
||||
if !vec::any(param_defs, {|d| d == pid}) {
|
||||
param_vals += [cx.fcx.lltyparams[pid].desc];
|
||||
param_defs += [pid];
|
||||
}
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
ret {params: param_defs, descs: param_vals};
|
||||
}
|
||||
|
||||
fn trans_stack_local_derived_tydesc(cx: block, llsz: ValueRef,
|
||||
llalign: ValueRef, llroottydesc: ValueRef,
|
||||
llfirstparam: ValueRef, n_params: uint)
|
||||
@ -527,93 +496,16 @@ fn trans_stack_local_derived_tydesc(cx: block, llsz: ValueRef,
|
||||
ret llmyroottydesc;
|
||||
}
|
||||
|
||||
fn get_derived_tydesc(cx: block, t: ty::t, escapes: bool,
|
||||
&static_ti: option<@tydesc_info>) -> result {
|
||||
alt cx.fcx.derived_tydescs.find(t) {
|
||||
some(info) {
|
||||
// If the tydesc escapes in this context, the cached derived
|
||||
// tydesc also has to be one that was marked as escaping.
|
||||
if !(escapes && !info.escapes) {
|
||||
ret rslt(cx, info.lltydesc);
|
||||
}
|
||||
}
|
||||
none {/* fall through */ }
|
||||
}
|
||||
|
||||
cx.ccx().stats.n_derived_tydescs += 1u;
|
||||
let bcx = raw_block(cx.fcx, cx.fcx.llderivedtydescs);
|
||||
let tys = linearize_ty_params(bcx, t);
|
||||
let root_ti = get_static_tydesc(bcx.ccx(), t, tys.params);
|
||||
static_ti = some(root_ti);
|
||||
lazily_emit_all_tydesc_glue(cx.ccx(), static_ti);
|
||||
let root = root_ti.tydesc;
|
||||
let sz = size_of(bcx, t);
|
||||
bcx = sz.bcx;
|
||||
let align = align_of(bcx, t);
|
||||
bcx = align.bcx;
|
||||
|
||||
// Store the captured type descriptors in an alloca if the caller isn't
|
||||
// promising to do so itself.
|
||||
let n_params = ty::count_ty_params(bcx.tcx(), t);
|
||||
|
||||
assert n_params == tys.params.len();
|
||||
assert n_params == tys.descs.len();
|
||||
|
||||
let llparamtydescs =
|
||||
alloca(bcx, T_array(T_ptr(bcx.ccx().tydesc_type), n_params + 1u));
|
||||
let i = 0;
|
||||
|
||||
// If the type descriptor escapes, we need to add in the root as
|
||||
// the first parameter, because upcall_get_type_desc() expects it.
|
||||
if escapes {
|
||||
Store(bcx, root, GEPi(bcx, llparamtydescs, [0, 0]));
|
||||
i += 1;
|
||||
}
|
||||
|
||||
for td: ValueRef in tys.descs {
|
||||
Store(bcx, td, GEPi(bcx, llparamtydescs, [0, i]));
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let llfirstparam =
|
||||
PointerCast(bcx, llparamtydescs,
|
||||
T_ptr(T_ptr(bcx.ccx().tydesc_type)));
|
||||
|
||||
let v;
|
||||
if escapes {
|
||||
let ccx = bcx.ccx();
|
||||
let td_val =
|
||||
Call(bcx, ccx.upcalls.get_type_desc,
|
||||
[C_null(T_ptr(T_nil())), sz.val,
|
||||
align.val, C_uint(ccx, 1u + n_params), llfirstparam,
|
||||
C_uint(ccx, 0u)]);
|
||||
v = td_val;
|
||||
} else {
|
||||
v = trans_stack_local_derived_tydesc(bcx, sz.val, align.val, root,
|
||||
llfirstparam, n_params);
|
||||
}
|
||||
bcx.fcx.derived_tydescs.insert(t, {lltydesc: v, escapes: escapes});
|
||||
ret rslt(cx, v);
|
||||
}
|
||||
|
||||
fn get_tydesc_simple(bcx: block, t: ty::t, escapes: bool) -> result {
|
||||
fn get_tydesc_simple(bcx: block, t: ty::t) -> result {
|
||||
let ti = none;
|
||||
get_tydesc(bcx, t, escapes, ti)
|
||||
get_tydesc(bcx, t, ti)
|
||||
}
|
||||
|
||||
fn get_tydesc(cx: block, t: ty::t, escapes: bool,
|
||||
fn get_tydesc(cx: block, t: ty::t,
|
||||
&static_ti: option<@tydesc_info>) -> result {
|
||||
|
||||
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
||||
alt ty::type_param(t) {
|
||||
some(id) { ret rslt(cx, cx.fcx.lltyparams[id].desc); }
|
||||
none {/* fall through */ }
|
||||
}
|
||||
|
||||
// Does it contain a type param? If so, generate a derived tydesc.
|
||||
if ty::type_has_params(t) {
|
||||
ret get_derived_tydesc(cx, t, escapes, static_ti);
|
||||
}
|
||||
// FIXME[mono]
|
||||
assert !ty::type_has_params(t);
|
||||
// Otherwise, generate a tydesc if necessary, and return it.
|
||||
let info = get_static_tydesc(cx.ccx(), t, []);
|
||||
static_ti = some(info);
|
||||
@ -980,7 +872,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
|
||||
let dtor_addr = common::get_res_dtor(ccx, did, inner_t);
|
||||
let args = [bcx.fcx.llretptr, null_env_ptr(bcx)];
|
||||
for tp in tps {
|
||||
let td = get_tydesc_simple(bcx, tp, false);
|
||||
let td = get_tydesc_simple(bcx, tp);
|
||||
args += [td.val];
|
||||
bcx = td.bcx;
|
||||
}
|
||||
@ -1244,13 +1136,6 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
|
||||
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti);
|
||||
}
|
||||
|
||||
fn lazily_emit_all_generic_info_tydesc_glues(ccx: @crate_ctxt,
|
||||
gi: generic_info) {
|
||||
for ti: option<@tydesc_info> in gi.static_tis {
|
||||
lazily_emit_all_tydesc_glue(ccx, ti);
|
||||
}
|
||||
}
|
||||
|
||||
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: int,
|
||||
static_ti: option<@tydesc_info>) {
|
||||
alt static_ti {
|
||||
@ -1349,7 +1234,7 @@ fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef,
|
||||
fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: int) ->
|
||||
block {
|
||||
let ti: option<@tydesc_info> = none::<@tydesc_info>;
|
||||
let {bcx: bcx, val: td} = get_tydesc(cx, t, false, ti);
|
||||
let {bcx: bcx, val: td} = get_tydesc(cx, t, ti);
|
||||
call_tydesc_glue_full(bcx, v, td, field, ti);
|
||||
ret bcx;
|
||||
}
|
||||
@ -1370,7 +1255,7 @@ fn call_cmp_glue(cx: block, lhs: ValueRef, rhs: ValueRef, t: ty::t,
|
||||
|
||||
let llrawlhsptr = BitCast(bcx, lllhs, T_ptr(T_i8()));
|
||||
let llrawrhsptr = BitCast(bcx, llrhs, T_ptr(T_i8()));
|
||||
r = get_tydesc_simple(bcx, t, false);
|
||||
r = get_tydesc_simple(bcx, t);
|
||||
let lltydesc = r.val;
|
||||
bcx = r.bcx;
|
||||
let lltydescs =
|
||||
@ -2047,18 +1932,6 @@ fn trans_loop(cx:block, body: ast::blk) -> block {
|
||||
ret next_cx;
|
||||
}
|
||||
|
||||
type generic_info = {item_type: ty::t,
|
||||
static_tis: [option<@tydesc_info>],
|
||||
tydescs: [ValueRef],
|
||||
param_bounds: @[ty::param_bounds],
|
||||
origins: option<typeck::vtable_res>};
|
||||
|
||||
enum generic_callee {
|
||||
generic_full(generic_info),
|
||||
generic_mono(ty::t),
|
||||
generic_none,
|
||||
}
|
||||
|
||||
enum lval_kind {
|
||||
temporary, //< Temporary value passed by value if of immediate type
|
||||
owned, //< Non-temporary value passed by pointer
|
||||
@ -2075,7 +1948,7 @@ type lval_maybe_callee = {bcx: block,
|
||||
val: ValueRef,
|
||||
kind: lval_kind,
|
||||
env: callee_env,
|
||||
generic: generic_callee};
|
||||
tds: option<[ValueRef]>};
|
||||
|
||||
fn null_env_ptr(bcx: block) -> ValueRef {
|
||||
C_null(T_opaque_box_ptr(bcx.ccx()))
|
||||
@ -2094,8 +1967,7 @@ fn lval_temp(bcx: block, val: ValueRef) -> lval_result {
|
||||
|
||||
fn lval_no_env(bcx: block, val: ValueRef, kind: lval_kind)
|
||||
-> lval_maybe_callee {
|
||||
ret {bcx: bcx, val: val, kind: kind, env: is_closure,
|
||||
generic: generic_none};
|
||||
ret {bcx: bcx, val: val, kind: kind, env: is_closure, tds: none};
|
||||
}
|
||||
|
||||
fn trans_external_path(cx: block, did: ast::def_id,
|
||||
@ -2108,7 +1980,7 @@ fn trans_external_path(cx: block, did: ast::def_id,
|
||||
|
||||
fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
|
||||
vtables: option<typeck::vtable_res>)
|
||||
-> option<{llfn: ValueRef, fty: ty::t}> {
|
||||
-> option<ValueRef> {
|
||||
let substs = vec::map(substs, {|t|
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_box(mt) { ty::mk_opaque_box(ccx.tcx) }
|
||||
@ -2126,7 +1998,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
|
||||
|
||||
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
|
||||
let mono_ty = ty::substitute_type_params(ccx.tcx, substs, tpt.ty);
|
||||
let llfty = type_of_fn_from_ty(ccx, mono_ty, []);
|
||||
let llfty = type_of_fn_from_ty(ccx, mono_ty, 0u);
|
||||
|
||||
let map_node = ccx.tcx.items.get(fn_id.node);
|
||||
// Get the path so that we can create a symbol
|
||||
@ -2146,7 +2018,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
|
||||
let pt = *pt + [path_name(ccx.names(name))];
|
||||
let s = mangle_exported_name(ccx, pt, mono_ty);
|
||||
let lldecl = decl_cdecl_fn(ccx.llmod, s, llfty);
|
||||
ccx.monomorphized.insert(hash_id, {llfn: lldecl, fty: mono_ty});
|
||||
ccx.monomorphized.insert(hash_id, lldecl);
|
||||
|
||||
let psubsts = some({tys: substs, vtables: vtables, bounds: tpt.bounds});
|
||||
alt check map_node {
|
||||
@ -2182,10 +2054,9 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
|
||||
}
|
||||
}
|
||||
}
|
||||
some({llfn: lldecl, fty: mono_ty})
|
||||
some(lldecl)
|
||||
}
|
||||
|
||||
// FIXME[mono] Only actually translate things that are not generic
|
||||
fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||
-> ast::def_id {
|
||||
alt ccx.external.find(fn_id) {
|
||||
@ -2266,10 +2137,12 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
|
||||
}
|
||||
};
|
||||
alt mono {
|
||||
some({llfn, fty}) {
|
||||
ret {bcx: bcx, val: llfn,
|
||||
some(llfn) {
|
||||
let cast = PointerCast(bcx, llfn, T_ptr(type_of_fn_from_ty(
|
||||
ccx, node_id_type(bcx, id), 0u)));
|
||||
ret {bcx: bcx, val: cast,
|
||||
kind: owned, env: null_env,
|
||||
generic: generic_mono(fty)};
|
||||
tds: none};
|
||||
}
|
||||
none {}
|
||||
}
|
||||
@ -2295,23 +2168,22 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
|
||||
}
|
||||
}
|
||||
|
||||
let gen = generic_none, bcx = bcx;
|
||||
let tds = none, bcx = bcx;
|
||||
// FIXME[mono] ensure this is a native function
|
||||
if tys.len() > 0u {
|
||||
let tydescs = [], tis = [];
|
||||
val = PointerCast(bcx, val, T_ptr(type_of_fn_from_ty(
|
||||
ccx, node_id_type(bcx, id), tys.len())));
|
||||
let tydescs = [];
|
||||
for t in tys {
|
||||
let ti = none;
|
||||
let td = get_tydesc(bcx, t, true, ti);
|
||||
tis += [ti];
|
||||
let td = get_tydesc(bcx, t, ti);
|
||||
lazily_emit_all_tydesc_glue(ccx, ti);
|
||||
bcx = td.bcx;
|
||||
tydescs += [td.val];
|
||||
}
|
||||
gen = generic_full({item_type: tpt.ty,
|
||||
static_tis: tis,
|
||||
tydescs: tydescs,
|
||||
param_bounds: tpt.bounds,
|
||||
origins: ccx.maps.vtable_map.find(id)});
|
||||
tds = some(tydescs);
|
||||
}
|
||||
ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen};
|
||||
ret {bcx: bcx, val: val, kind: owned, env: null_env, tds: tds};
|
||||
}
|
||||
|
||||
fn lookup_discriminant(ccx: @crate_ctxt, vid: ast::def_id) -> ValueRef {
|
||||
@ -2564,7 +2436,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
||||
}
|
||||
|
||||
fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result {
|
||||
let must_bind = alt c.generic { generic_full(_) { true } _ { false } } ||
|
||||
let must_bind = option::is_some(c.tds) ||
|
||||
alt c.env { self_env(_, _) { true } _ { false } };
|
||||
if must_bind {
|
||||
let n_args = ty::ty_fn_args(ty).len();
|
||||
@ -2761,7 +2633,7 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
|
||||
// - new_fn_ctxt
|
||||
// - trans_args
|
||||
fn trans_args(cx: block, llenv: ValueRef,
|
||||
gen: generic_callee, es: [@ast::expr], fn_ty: ty::t,
|
||||
tds: option<[ValueRef]>, es: [@ast::expr], fn_ty: ty::t,
|
||||
dest: dest)
|
||||
-> {bcx: block,
|
||||
args: [ValueRef],
|
||||
@ -2770,54 +2642,40 @@ fn trans_args(cx: block, llenv: ValueRef,
|
||||
let temp_cleanups = [];
|
||||
let args = ty::ty_fn_args(fn_ty);
|
||||
let llargs: [ValueRef] = [];
|
||||
let lltydescs: [ValueRef] = [];
|
||||
|
||||
let ccx = cx.ccx();
|
||||
let bcx = cx;
|
||||
|
||||
let retty = ty::ty_fn_ret(fn_ty), full_retty = retty;
|
||||
alt gen {
|
||||
generic_full(g) { fail; }
|
||||
generic_mono(t) {
|
||||
args = ty::ty_fn_args(t);
|
||||
retty = ty::ty_fn_ret(t);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
let retty = ty::ty_fn_ret(fn_ty);
|
||||
// Arg 0: Output pointer.
|
||||
let llretslot = alt dest {
|
||||
ignore {
|
||||
if ty::type_is_nil(retty) {
|
||||
llvm::LLVMGetUndef(T_ptr(T_nil()))
|
||||
} else {
|
||||
let {bcx: cx, val} = alloc_ty(bcx, full_retty);
|
||||
let {bcx: cx, val} = alloc_ty(bcx, retty);
|
||||
bcx = cx;
|
||||
val
|
||||
}
|
||||
}
|
||||
save_in(dst) { dst }
|
||||
by_val(_) {
|
||||
let {bcx: cx, val} = alloc_ty(bcx, full_retty);
|
||||
let {bcx: cx, val} = alloc_ty(bcx, retty);
|
||||
bcx = cx;
|
||||
val
|
||||
}
|
||||
};
|
||||
|
||||
if retty != full_retty || ty::type_has_params(retty) {
|
||||
// It's possible that the callee has some generic-ness somewhere in
|
||||
// its return value -- say a method signature within an obj or a fn
|
||||
// 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.
|
||||
let llretty = T_ptr(type_of(ccx, retty));
|
||||
llargs += [PointerCast(cx, llretslot, llretty)];
|
||||
} else { llargs += [llretslot]; }
|
||||
llargs += [llretslot];
|
||||
|
||||
// Arg 1: Env (closure-bindings / self value)
|
||||
llargs += [llenv];
|
||||
|
||||
// Args >2: ty_params ...
|
||||
llargs += lltydescs;
|
||||
alt tds {
|
||||
some(tds) { llargs += tds; }
|
||||
none {}
|
||||
}
|
||||
|
||||
// ... then explicit args.
|
||||
|
||||
@ -2883,7 +2741,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
|
||||
|
||||
let ret_ty = node_id_type(bcx, id);
|
||||
let args_res =
|
||||
trans_args(bcx, llenv, f_res.generic, args, fn_expr_ty, dest);
|
||||
trans_args(bcx, llenv, f_res.tds, args, fn_expr_ty, dest);
|
||||
bcx = args_res.bcx;
|
||||
let llargs = args_res.args;
|
||||
let llretslot = args_res.retslot;
|
||||
@ -3418,7 +3276,7 @@ fn trans_log(lvl: @ast::expr, bcx: block, e: @ast::expr) -> block {
|
||||
with_scope(bcx, "log") {|bcx|
|
||||
let {bcx, val, _} = trans_temp_expr(bcx, e);
|
||||
let e_ty = expr_ty(bcx, e);
|
||||
let {bcx, val: tydesc} = get_tydesc_simple(bcx, e_ty, false);
|
||||
let {bcx, val: tydesc} = get_tydesc_simple(bcx, e_ty);
|
||||
// Call the polymorphic log function.
|
||||
let {bcx, val} = spill_if_immediate(bcx, val, e_ty);
|
||||
let val = PointerCast(bcx, val, T_ptr(T_i8()));
|
||||
@ -4376,6 +4234,15 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
let llfndecl = get_item_val(ccx, item.id);
|
||||
trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
|
||||
llfndecl, no_self, none, item.id, none);
|
||||
} else {
|
||||
for stmt in body.node.stmts {
|
||||
alt stmt.node {
|
||||
ast::stmt_decl(@{node: ast::decl_item(i), _}, _) {
|
||||
trans_item(ccx, *i);
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::item_impl(tps, _, _, ms) {
|
||||
@ -4400,8 +4267,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
|
||||
let i = 0;
|
||||
for variant: ast::variant in variants {
|
||||
let llfn = get_item_val(ccx, variant.node.id);
|
||||
if variant.node.args.len() > 0u {
|
||||
let llfn = get_item_val(ccx, variant.node.id);
|
||||
trans_enum_variant(ccx, item.id, variant,
|
||||
vi[i].disr_val, degen,
|
||||
none, llfn);
|
||||
@ -4535,7 +4402,7 @@ fn param_bounds(ccx: @crate_ctxt, tps: [ast::ty_param])
|
||||
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: path, flav: str,
|
||||
bnds: [ty::param_bounds], node_id: ast::node_id,
|
||||
node_type: ty::t) -> ValueRef {
|
||||
let llfty = type_of_fn_from_ty(ccx, node_type, bnds);
|
||||
let llfty = type_of_fn_from_ty(ccx, node_type, bnds.len());
|
||||
register_fn_fuller(ccx, sp, path, flav, node_id, node_type,
|
||||
lib::llvm::CCallConv, llfty)
|
||||
}
|
||||
@ -4582,7 +4449,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
||||
{mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_vec(ccx.tcx, {ty: unit_ty, mutbl: ast::m_imm})};
|
||||
let nt = ty::mk_nil(ccx.tcx);
|
||||
let llfty = type_of_fn(ccx, [vecarg_ty], nt, []);
|
||||
let llfty = type_of_fn(ccx, [vecarg_ty], nt, 0u);
|
||||
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
|
||||
lib::llvm::CCallConv, llfty);
|
||||
|
||||
|
@ -131,21 +131,15 @@ fn mk_tuplified_uniq_cbox_ty(tcx: ty::ctxt, cdata_ty: ty::t) -> ty::t {
|
||||
// Given a closure ty, emits a corresponding tuple ty
|
||||
fn mk_closure_tys(tcx: ty::ctxt,
|
||||
ck: ty::closure_kind,
|
||||
ty_params: [fn_ty_param],
|
||||
ty_params: option<[ValueRef]>,
|
||||
bound_values: [environment_value])
|
||||
-> (ty::t, [ty::t]) {
|
||||
let bound_tys = [];
|
||||
|
||||
let tydesc_ty = mk_tydesc_ty(tcx, ck);
|
||||
|
||||
// Compute the closed over tydescs
|
||||
let param_ptrs = [];
|
||||
for tp in ty_params {
|
||||
param_ptrs += [tydesc_ty];
|
||||
option::may(tp.vtables) {|vtables|
|
||||
for vtable in vtables { param_ptrs += [tydesc_ty]; }
|
||||
}
|
||||
}
|
||||
let n_param_ptrs = alt ty_params {
|
||||
some(tds) { tds.len() } none { 0u }
|
||||
};
|
||||
|
||||
// Compute the closed over data
|
||||
for bv in bound_values {
|
||||
@ -158,7 +152,8 @@ fn mk_closure_tys(tcx: ty::ctxt,
|
||||
}
|
||||
let bound_data_ty = ty::mk_tup(tcx, bound_tys);
|
||||
|
||||
let cdata_ty = ty::mk_tup(tcx, [ty::mk_tup(tcx, param_ptrs),
|
||||
let typtrs = vec::from_elem(n_param_ptrs, mk_tydesc_ty(tcx, ck));
|
||||
let cdata_ty = ty::mk_tup(tcx, [ty::mk_tup(tcx, typtrs),
|
||||
bound_data_ty]);
|
||||
#debug["cdata_ty=%s", ty_to_str(tcx, cdata_ty)];
|
||||
ret (cdata_ty, bound_tys);
|
||||
@ -186,7 +181,7 @@ fn allocate_cbox(bcx: block,
|
||||
&ti: option<@tydesc_info>) -> block {
|
||||
let ccx = bcx.ccx();
|
||||
let bound_tydesc = GEPi(bcx, box, [0, abi::box_field_tydesc]);
|
||||
let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, true, ti);
|
||||
let {bcx, val: td} = base::get_tydesc(bcx, cdata_ty, ti);
|
||||
let td = Call(bcx, ccx.upcalls.create_shared_type_desc, [td]);
|
||||
Store(bcx, td, bound_tydesc);
|
||||
bcx
|
||||
@ -243,7 +238,7 @@ fn cast_if_we_can(bcx: block, llbox: ValueRef, t: ty::t) -> ValueRef {
|
||||
// heap allocated closure that copies the upvars into environment.
|
||||
// Otherwise, it is stack allocated and copies pointers to the upvars.
|
||||
fn store_environment(
|
||||
bcx: block, lltyparams: [fn_ty_param],
|
||||
bcx: block, lltyparams: option<[ValueRef]>,
|
||||
bound_values: [environment_value],
|
||||
ck: ty::closure_kind)
|
||||
-> closure_result {
|
||||
@ -284,18 +279,11 @@ fn store_environment(
|
||||
let {bcx:bcx, val:ty_params_slot} =
|
||||
GEP_tup_like(bcx, cbox_ty, llbox,
|
||||
[0, abi::box_field_body, abi::closure_body_ty_params]);
|
||||
let off = 0;
|
||||
for tp in lltyparams {
|
||||
let cloned_td = maybe_clone_tydesc(bcx, ck, tp.desc);
|
||||
Store(bcx, cloned_td, GEPi(bcx, ty_params_slot, [0, off]));
|
||||
off += 1;
|
||||
option::may(tp.vtables, {|vtables|
|
||||
for vtable in vtables {
|
||||
let cast = PointerCast(bcx, vtable, val_ty(cloned_td));
|
||||
Store(bcx, cast, GEPi(bcx, ty_params_slot, [0, off]));
|
||||
off += 1;
|
||||
}
|
||||
});
|
||||
option::may(lltyparams) {|tds|
|
||||
vec::iteri(tds) {|i, td|
|
||||
let cloned_td = maybe_clone_tydesc(bcx, ck, td);
|
||||
Store(bcx, cloned_td, GEPi(bcx, ty_params_slot, [0, i as int]));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy expr values into boxed bindings.
|
||||
@ -389,14 +377,13 @@ fn build_closure(bcx0: block,
|
||||
}
|
||||
}
|
||||
}
|
||||
ret store_environment(bcx, copy bcx.fcx.lltyparams, env_vals, ck);
|
||||
ret store_environment(bcx, none, env_vals, ck);
|
||||
}
|
||||
|
||||
// Given an enclosing block context, a new function context, a closure type,
|
||||
// and a list of upvars, generate code to load and populate the environment
|
||||
// with the upvars and type descriptors.
|
||||
fn load_environment(enclosing_cx: block,
|
||||
fcx: fn_ctxt,
|
||||
fn load_environment(fcx: fn_ctxt,
|
||||
cdata_ty: ty::t,
|
||||
cap_vars: [capture::capture_var],
|
||||
ck: ty::closure_kind) {
|
||||
@ -405,27 +392,6 @@ fn load_environment(enclosing_cx: block,
|
||||
// Load a pointer to the closure data, skipping over the box header:
|
||||
let llcdata = base::opaque_box_body(bcx, cdata_ty, fcx.llenv);
|
||||
|
||||
// Populate the type parameters from the environment. We need to
|
||||
// do this first because the tydescs are needed to index into
|
||||
// the bindings if they are dynamically sized.
|
||||
let {bcx, val: lltydescs} = GEP_tup_like(bcx, cdata_ty, llcdata,
|
||||
[0, abi::closure_body_ty_params]);
|
||||
let off = 0;
|
||||
for tp in copy enclosing_cx.fcx.lltyparams {
|
||||
let tydesc = Load(bcx, GEPi(bcx, lltydescs, [0, off]));
|
||||
off += 1;
|
||||
let vtables = option::map(tp.vtables, {|vtables|
|
||||
let rslt = [];
|
||||
for vtable in vtables {
|
||||
let vtable = Load(bcx, GEPi(bcx, lltydescs, [0, off]));
|
||||
rslt += [PointerCast(bcx, vtable, T_ptr(T_vtable()))];
|
||||
off += 1;
|
||||
}
|
||||
rslt
|
||||
});
|
||||
fcx.lltyparams += [{desc: tydesc, vtables: vtables}];
|
||||
}
|
||||
|
||||
// Populate the upvars from the environment.
|
||||
let i = 0u;
|
||||
vec::iter(cap_vars) { |cap_var|
|
||||
@ -460,7 +426,7 @@ fn trans_expr_fn(bcx: block,
|
||||
if dest == ignore { ret bcx; }
|
||||
let ccx = bcx.ccx(), bcx = bcx;
|
||||
let fty = node_id_type(bcx, id);
|
||||
let llfnty = type_of_fn_from_ty(ccx, fty, []);
|
||||
let llfnty = type_of_fn_from_ty(ccx, fty, 0u);
|
||||
let sub_path = bcx.fcx.path + [path_name("anon")];
|
||||
let s = mangle_internal_name_by_path(ccx, sub_path);
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||
@ -472,7 +438,7 @@ fn trans_expr_fn(bcx: block,
|
||||
let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck, id);
|
||||
trans_closure(ccx, sub_path, decl, body, llfn, no_self,
|
||||
bcx.fcx.param_substs, id, none, {|fcx|
|
||||
load_environment(bcx, fcx, cdata_ty, cap_vars, ck);
|
||||
load_environment(fcx, cdata_ty, cap_vars, ck);
|
||||
});
|
||||
llbox
|
||||
};
|
||||
@ -513,13 +479,7 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t,
|
||||
ret bcx;
|
||||
}
|
||||
|
||||
// Figure out which tydescs we need to pass, if any.
|
||||
let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic {
|
||||
generic_full(ginfo) { fail; }
|
||||
_ { (outgoing_fty, [], @[]) }
|
||||
};
|
||||
|
||||
if bound.len() == 0u && lltydescs.len() == 0u &&
|
||||
if bound.len() == 0u && option::is_none(f_res.tds) &&
|
||||
(f_res.env == null_env || f_res.env == is_closure) {
|
||||
// Trivial 'binding': just return the closure
|
||||
let lv = lval_maybe_callee_to_lval(f_res, pair_ty);
|
||||
@ -545,14 +505,15 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t,
|
||||
|
||||
// Actually construct the closure
|
||||
let {llbox, cdata_ty, bcx} = store_environment(
|
||||
bcx, vec::map(lltydescs, {|d| {desc: d, vtables: none}}),
|
||||
bcx, f_res.tds,
|
||||
env_vals + vec::map(bound, {|x| env_expr(x, expr_ty(bcx, x))}),
|
||||
ty::ck_box);
|
||||
|
||||
// Make thunk
|
||||
let llthunk = trans_bind_thunk(
|
||||
cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty_real, args,
|
||||
cdata_ty, *param_bounds, target_info);
|
||||
cx.fcx.ccx, cx.fcx.path, pair_ty, outgoing_fty, args,
|
||||
cdata_ty, target_info,
|
||||
alt f_res.tds { some(x) { x.len() } _ { 0u } });
|
||||
|
||||
// Fill the function pair
|
||||
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
|
||||
@ -704,16 +665,15 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
|
||||
outgoing_fty: ty::t,
|
||||
args: [option<@ast::expr>],
|
||||
cdata_ty: ty::t,
|
||||
param_bounds: [ty::param_bounds],
|
||||
target_info: target_info)
|
||||
target_info: target_info,
|
||||
n_tps: uint)
|
||||
-> {val: ValueRef, ty: TypeRef} {
|
||||
let tcx = ccx.tcx;
|
||||
#debug["trans_bind_thunk[incoming_fty=%s,outgoing_fty=%s,\
|
||||
cdata_ty=%s,param_bounds=%?]",
|
||||
cdata_ty=%s]",
|
||||
ty_to_str(tcx, incoming_fty),
|
||||
ty_to_str(tcx, outgoing_fty),
|
||||
ty_to_str(tcx, cdata_ty),
|
||||
param_bounds];
|
||||
ty_to_str(tcx, cdata_ty)];
|
||||
|
||||
// Here we're not necessarily constructing a thunk in the sense of
|
||||
// "function with no arguments". The result of compiling 'bind f(foo,
|
||||
@ -813,28 +773,11 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
|
||||
let {bcx: l_bcx, val: param_record} =
|
||||
GEP_tup_like(l_bcx, cdata_ty, llcdata,
|
||||
[0, abi::closure_body_ty_params]);
|
||||
let off = 0;
|
||||
for param in param_bounds {
|
||||
let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, off])),
|
||||
vtables = none;
|
||||
let i = 0u;
|
||||
while i < n_tps {
|
||||
let dsc = Load(l_bcx, GEPi(l_bcx, param_record, [0, i as int]));
|
||||
llargs += [dsc];
|
||||
off += 1;
|
||||
for bound in *param {
|
||||
alt bound {
|
||||
ty::bound_iface(_) {
|
||||
let vtable = Load(l_bcx, GEPi(l_bcx, param_record, [0, off]));
|
||||
vtable = PointerCast(l_bcx, vtable, T_ptr(T_vtable()));
|
||||
llargs += [vtable];
|
||||
off += 1;
|
||||
vtables = some(alt vtables {
|
||||
none { [vtable] }
|
||||
some(ds) { ds + [vtable] }
|
||||
});
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
fcx.lltyparams += [{desc: dsc, vtables: vtables}];
|
||||
fcx.lltyparams += [{desc: dsc, vtables: none}];
|
||||
}
|
||||
|
||||
let a: uint = first_tp_arg; // retptr, env come first
|
||||
@ -895,7 +838,7 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
|
||||
// in the closure does not know how many type descriptors the function
|
||||
// needs to take.
|
||||
let lltargetty =
|
||||
type_of_fn_from_ty(ccx, outgoing_fty, param_bounds);
|
||||
type_of_fn_from_ty(ccx, outgoing_fty, 0u);
|
||||
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
|
||||
Call(bcx, lltargetfn, llargs);
|
||||
build_return(bcx);
|
||||
|
@ -93,7 +93,7 @@ type crate_ctxt = {
|
||||
// Track mapping of external ids to local items imported for inlining
|
||||
external: hashmap<ast::def_id, option<ast::node_id>>,
|
||||
// Cache instances of monomorphized functions
|
||||
monomorphized: hashmap<mono_id, {llfn: ValueRef, fty: ty::t}>,
|
||||
monomorphized: hashmap<mono_id, ValueRef>,
|
||||
// Cache generated vtables
|
||||
vtables: hashmap<mono_id, ValueRef>,
|
||||
module_data: hashmap<str, ValueRef>,
|
||||
@ -180,6 +180,7 @@ type fn_ctxt = @{
|
||||
llupvars: hashmap<ast::node_id, ValueRef>,
|
||||
|
||||
// A vector of incoming type descriptors and their associated vtables.
|
||||
// Currently only used by glue functions
|
||||
mutable lltyparams: [fn_ty_param],
|
||||
|
||||
// Derived tydescs are tydescs created at runtime, for types that
|
||||
@ -307,7 +308,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, inner_t: ty::t)
|
||||
let nil_res = ty::mk_nil(ccx.tcx);
|
||||
let fn_mode = ast::expl(ast::by_ref);
|
||||
let f_t = type_of::type_of_fn(ccx, [{mode: fn_mode, ty: inner_t}],
|
||||
nil_res, *param_bounds);
|
||||
nil_res, (*param_bounds).len());
|
||||
ret base::get_extern_const(ccx.externs, ccx.llmod,
|
||||
csearch::get_symbol(ccx.sess.cstore,
|
||||
did), f_t);
|
||||
@ -542,9 +543,9 @@ fn set_struct_body(t: TypeRef, elts: [TypeRef]) unsafe {
|
||||
fn T_empty_struct() -> TypeRef { ret T_struct([]); }
|
||||
|
||||
// A vtable is, in reality, a vtable pointer followed by zero or more pointers
|
||||
// to tydescs and other vtables that it closes over. But the types and number
|
||||
// of those are rarely known to the code that needs to manipulate them, so
|
||||
// they are described by this opaque type.
|
||||
// to tydescs and other vtables that it closes over. But the types and number of
|
||||
// those are rarely known to the code that needs to manipulate them, so they
|
||||
// are described by this opaque type.
|
||||
fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) }
|
||||
|
||||
fn T_task(targ_cfg: @session::config) -> TypeRef {
|
||||
|
@ -76,7 +76,7 @@ fn trans_static_callee(bcx: block, callee_id: ast::node_id,
|
||||
|
||||
fn wrapper_fn_ty(ccx: @crate_ctxt, vtable_ty: TypeRef, fty: ty::t,
|
||||
tps: @[ty::param_bounds]) -> {ty: ty::t, llty: TypeRef} {
|
||||
let bare_fn_ty = type_of_fn_from_ty(ccx, fty, *tps);
|
||||
let bare_fn_ty = type_of_fn_from_ty(ccx, fty, (*tps).len());
|
||||
let {inputs, output} = llfn_arg_tys(bare_fn_ty);
|
||||
{ty: fty, llty: T_fn([vtable_ty] + inputs, output)}
|
||||
}
|
||||
@ -86,13 +86,11 @@ fn trans_vtable_callee(bcx: block, env: callee_env, vtable: ValueRef,
|
||||
-> lval_maybe_callee {
|
||||
let bcx = bcx, ccx = bcx.ccx();
|
||||
let fty = node_id_type(bcx, callee_id);
|
||||
let llfty = type_of::type_of_fn_from_ty(ccx, fty, []);
|
||||
let llfty = type_of::type_of_fn_from_ty(ccx, fty, 0u);
|
||||
let vtable = PointerCast(bcx, vtable,
|
||||
T_ptr(T_array(T_ptr(llfty), n_method + 1u)));
|
||||
let mptr = Load(bcx, GEPi(bcx, vtable, [0, n_method as int]));
|
||||
{bcx: bcx, val: mptr, kind: owned,
|
||||
env: env,
|
||||
generic: generic_none}
|
||||
{bcx: bcx, val: mptr, kind: owned, env: env, tds: none}
|
||||
}
|
||||
|
||||
fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
||||
@ -243,10 +241,10 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t],
|
||||
let fty = ty::substitute_type_params(tcx, substs,
|
||||
ty::mk_fn(tcx, im.fty));
|
||||
if (*im.tps).len() > 0u || ty::type_has_vars(fty) {
|
||||
C_null(type_of_fn_from_ty(ccx, fty, []))
|
||||
C_null(type_of_fn_from_ty(ccx, fty, 0u))
|
||||
} else {
|
||||
let m_id = method_with_name(ccx, impl_id, im.ident);
|
||||
option::get(monomorphic_fn(ccx, m_id, substs, some(vtables))).llfn
|
||||
option::get(monomorphic_fn(ccx, m_id, substs, some(vtables)))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||
let t = ty::node_id_to_type(ccx.tcx, id);
|
||||
let ps = link::mangle_internal_name_by_path(
|
||||
ccx, path + [ast_map::path_name("__rust_abi")]);
|
||||
let llty = type_of_fn_from_ty(ccx, t, []);
|
||||
let llty = type_of_fn_from_ty(ccx, t, 0u);
|
||||
let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
|
||||
trans_fn(ccx, path, decl, body, llfndecl, no_self, none, id,
|
||||
none);
|
||||
@ -383,8 +383,7 @@ fn decl_native_fn(ccx: @crate_ctxt, i: @ast::native_item,
|
||||
ast::native_abi_rust_intrinsic {
|
||||
// For intrinsics: link the function directly to the intrinsic
|
||||
// function itself.
|
||||
let fn_type = type_of_fn_from_ty(
|
||||
ccx, node_type, param_bounds(ccx, tps));
|
||||
let fn_type = type_of_fn_from_ty(ccx, node_type, tps.len());
|
||||
let ri_name = "rust_intrinsic_" + native::link_name(i);
|
||||
ccx.item_symbols.insert(i.id, ri_name);
|
||||
get_extern_fn(ccx.externs, ccx.llmod, ri_name,
|
||||
|
@ -701,7 +701,7 @@ fn dynamic_metrics(cx: block, t: ty::t) -> metrics {
|
||||
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_param(p, _) {
|
||||
let {bcx, val: tydesc} = base::get_tydesc_simple(cx, t, false);
|
||||
let {bcx, val: tydesc} = base::get_tydesc_simple(cx, t);
|
||||
let szptr = GEPi(bcx, tydesc, [0, abi::tydesc_field_size]);
|
||||
let aptr = GEPi(bcx, tydesc, [0, abi::tydesc_field_align]);
|
||||
{bcx: bcx, sz: Load(bcx, szptr), align: Load(bcx, aptr)}
|
||||
|
@ -202,7 +202,7 @@ fn trans_append_literal(bcx: block, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
let ccx = bcx.ccx();
|
||||
let elt_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
let ti = none;
|
||||
let {bcx: bcx, val: td} = get_tydesc(bcx, elt_ty, false, ti);
|
||||
let {bcx: bcx, val: td} = get_tydesc(bcx, elt_ty, ti);
|
||||
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, ti);
|
||||
let opaque_v = PointerCast(bcx, vptrptr,
|
||||
T_ptr(T_ptr(ccx.opaque_vec_type)));
|
||||
|
@ -19,7 +19,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, inputs: [ty::arg]) -> [TypeRef] {
|
||||
}
|
||||
|
||||
fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg],
|
||||
output: ty::t, params: [ty::param_bounds]) -> TypeRef {
|
||||
output: ty::t, n_ty_params: uint) -> TypeRef {
|
||||
let atys: [TypeRef] = [];
|
||||
|
||||
// Arg 0: Output pointer.
|
||||
@ -29,14 +29,10 @@ fn type_of_fn(cx: @crate_ctxt, inputs: [ty::arg],
|
||||
atys += [T_opaque_box_ptr(cx)];
|
||||
|
||||
// Args >2: ty params, if not acquired via capture...
|
||||
for bounds in params {
|
||||
let i = 0u;
|
||||
while i < n_ty_params {
|
||||
atys += [T_ptr(cx.tydesc_type)];
|
||||
for bound in *bounds {
|
||||
alt bound {
|
||||
ty::bound_iface(_) { atys += [T_ptr(T_vtable())]; }
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
// ... then explicit args.
|
||||
atys += type_of_explicit_args(cx, inputs);
|
||||
@ -44,9 +40,9 @@ 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 {
|
||||
type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), param_bounds)
|
||||
fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t, n_ty_params: uint)
|
||||
-> TypeRef {
|
||||
type_of_fn(cx, ty::ty_fn_args(fty), ty::ty_fn_ret(fty), n_ty_params)
|
||||
}
|
||||
|
||||
fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
@ -93,7 +89,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
T_struct(tys)
|
||||
}
|
||||
ty::ty_fn(_) {
|
||||
T_fn_pair(cx, type_of_fn_from_ty(cx, t, []))
|
||||
T_fn_pair(cx, type_of_fn_from_ty(cx, t, 0u))
|
||||
}
|
||||
ty::ty_iface(_, _) { T_opaque_iface(cx) }
|
||||
ty::ty_res(_, sub, tps) {
|
||||
@ -155,7 +151,7 @@ fn type_of_ty_param_bounds_and_ty
|
||||
let t = tpt.ty;
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_fn(_) {
|
||||
ret type_of_fn_from_ty(ccx, t, *tpt.bounds);
|
||||
ret type_of_fn_from_ty(ccx, t, (*tpt.bounds).len());
|
||||
}
|
||||
_ {
|
||||
// fall through
|
||||
|
Loading…
x
Reference in New Issue
Block a user