Pass bounds to trans::type_of_fn
This commit is contained in:
parent
664a0443ad
commit
270b4273e7
@ -83,7 +83,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
|
||||
// - trans_args
|
||||
fn type_of_fn(cx: @crate_ctxt, sp: span,
|
||||
is_method: bool, inputs: [ty::arg],
|
||||
output: ty::t, ty_param_count: uint)
|
||||
output: ty::t, params: [ty::param_bounds])
|
||||
: non_ty_var(cx, output) -> TypeRef {
|
||||
let atys: [TypeRef] = [];
|
||||
|
||||
@ -100,8 +100,10 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
|
||||
|
||||
// Args >2: ty params, if not acquired via capture...
|
||||
if !is_method {
|
||||
let i = 0u;
|
||||
while i < ty_param_count { atys += [T_ptr(cx.tydesc_type)]; i += 1u; }
|
||||
// FIXME[impl] Also add args for the dicts
|
||||
for _param in params {
|
||||
atys += [T_ptr(cx.tydesc_type)];
|
||||
}
|
||||
}
|
||||
// ... then explicit args.
|
||||
atys += type_of_explicit_args(cx, sp, inputs);
|
||||
@ -110,7 +112,7 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
|
||||
|
||||
// Given a function type and a count of ty params, construct an llvm type
|
||||
fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
|
||||
ty_param_count: uint)
|
||||
param_bounds: [ty::param_bounds])
|
||||
: returns_non_ty_var(cx, fty) -> TypeRef {
|
||||
// FIXME: Check should be unnecessary, b/c it's implied
|
||||
// by returns_non_ty_var(t). Make that a postcondition
|
||||
@ -118,7 +120,7 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
|
||||
let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
|
||||
check non_ty_var(cx, ret_ty);
|
||||
ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty),
|
||||
ret_ty, ty_param_count);
|
||||
ret_ty, param_bounds);
|
||||
}
|
||||
|
||||
fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
|
||||
@ -171,10 +173,10 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
|
||||
ty::ty_fn(_) {
|
||||
// FIXME: could be a constraint on ty_fn
|
||||
check returns_non_ty_var(cx, t);
|
||||
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, []))
|
||||
}
|
||||
ty::ty_native_fn(args, out) {
|
||||
let nft = native_fn_wrapper_type(cx, sp, 0u, t);
|
||||
let nft = native_fn_wrapper_type(cx, sp, [], t);
|
||||
T_fn_pair(cx, nft)
|
||||
}
|
||||
ty::ty_obj(meths) { cx.rust_object_type }
|
||||
@ -234,7 +236,7 @@ fn type_of_ty_param_bounds_and_ty(lcx: @local_ctxt, sp: span,
|
||||
alt ty::struct(cx.tcx, t) {
|
||||
ty::ty_fn(_) | ty::ty_native_fn(_, _) {
|
||||
check returns_non_ty_var(cx, t);
|
||||
ret type_of_fn_from_ty(cx, sp, t, vec::len(tpt.bounds));
|
||||
ret type_of_fn_from_ty(cx, sp, t, tpt.bounds);
|
||||
}
|
||||
_ {
|
||||
// fall through
|
||||
@ -2562,7 +2564,8 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
|
||||
type generic_info =
|
||||
{item_type: ty::t,
|
||||
static_tis: [option::t<@tydesc_info>],
|
||||
tydescs: [ValueRef]};
|
||||
tydescs: [ValueRef],
|
||||
param_bounds: [ty::param_bounds]};
|
||||
|
||||
tag lval_kind {
|
||||
temporary; //< Temporary value passed by value if of immediate type
|
||||
@ -2608,18 +2611,19 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
|
||||
|
||||
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
|
||||
-> lval_maybe_callee {
|
||||
let tpt = ty::lookup_item_type(bcx_tcx(bcx), fn_id);
|
||||
let ccx = bcx_ccx(bcx);
|
||||
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
|
||||
let val = if fn_id.crate == ast::local_crate {
|
||||
// Internal reference.
|
||||
assert (bcx_ccx(bcx).item_ids.contains_key(fn_id.node));
|
||||
bcx_ccx(bcx).item_ids.get(fn_id.node)
|
||||
assert (ccx.item_ids.contains_key(fn_id.node));
|
||||
ccx.item_ids.get(fn_id.node)
|
||||
} else {
|
||||
// External reference.
|
||||
trans_external_path(bcx, fn_id, tpt)
|
||||
};
|
||||
let tys = ty::node_id_to_type_params(bcx_tcx(bcx), id);
|
||||
let tys = ty::node_id_to_type_params(ccx.tcx, id);
|
||||
let gen = none, bcx = bcx;
|
||||
if vec::len::<ty::t>(tys) != 0u {
|
||||
if vec::len(tys) != 0u {
|
||||
let tydescs = [], tis = [];
|
||||
for t in tys {
|
||||
// TODO: Doesn't always escape.
|
||||
@ -2629,7 +2633,11 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
|
||||
bcx = td.bcx;
|
||||
tydescs += [td.val];
|
||||
}
|
||||
gen = some({item_type: tpt.ty, static_tis: tis, tydescs: tydescs});
|
||||
let bounds = ty::lookup_item_type(ccx.tcx, fn_id).bounds;
|
||||
gen = some({item_type: tpt.ty,
|
||||
static_tis: tis,
|
||||
tydescs: tydescs,
|
||||
param_bounds: bounds});
|
||||
}
|
||||
ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen};
|
||||
}
|
||||
@ -2767,7 +2775,7 @@ fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
|
||||
check non_ty_var(ccx, ret_ty);
|
||||
|
||||
let ll_fn_ty = type_of_fn(ccx, bcx.sp, true,
|
||||
ty::ty_fn_args(tcx, fn_ty), ret_ty, 0u);
|
||||
ty::ty_fn_args(tcx, fn_ty), ret_ty, []);
|
||||
v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
|
||||
ret {bcx: bcx, mthptr: v, objptr: o};
|
||||
}
|
||||
@ -5084,13 +5092,17 @@ fn register_fn(ccx: @crate_ctxt, sp: span, path: [str], flav: str,
|
||||
register_fn_full(ccx, sp, path, flav, ty_params, node_id, t);
|
||||
}
|
||||
|
||||
fn param_bounds(ccx: @crate_ctxt, tp: ast::ty_param) -> ty::param_bounds {
|
||||
ccx.tcx.ty_param_bounds.get(ast_util::local_def(tp.id))
|
||||
}
|
||||
|
||||
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
|
||||
ty_params: [ast::ty_param], node_id: ast::node_id,
|
||||
tps: [ast::ty_param], node_id: ast::node_id,
|
||||
node_type: ty::t)
|
||||
: returns_non_ty_var(ccx, node_type) {
|
||||
let path = path;
|
||||
let llfty =
|
||||
type_of_fn_from_ty(ccx, sp, node_type, vec::len(ty_params));
|
||||
let llfty = type_of_fn_from_ty(ccx, sp, node_type,
|
||||
vec::map(tps, {|p| param_bounds(ccx, p)}));
|
||||
let ps: str = mangle_exported_name(ccx, path, node_type);
|
||||
let llfn: ValueRef = decl_cdecl_fn(ccx.llmod, ps, llfty);
|
||||
ccx.item_ids.insert(node_id, llfn);
|
||||
@ -5128,7 +5140,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
||||
let nt = ty::mk_nil(ccx.tcx);
|
||||
check non_ty_var(ccx, nt);
|
||||
|
||||
let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, 0u);
|
||||
let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, []);
|
||||
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
|
||||
lib::llvm::LLVMCCallConv, llfty);
|
||||
|
||||
@ -5221,12 +5233,13 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
|
||||
ret count;
|
||||
}
|
||||
|
||||
fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
|
||||
fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span,
|
||||
param_bounds: [ty::param_bounds],
|
||||
x: ty::t) -> TypeRef {
|
||||
alt ty::struct(cx.tcx, x) {
|
||||
ty::ty_native_fn(args, out) {
|
||||
check non_ty_var(cx, out);
|
||||
ret type_of_fn(cx, sp, false, args, out, ty_param_count);
|
||||
ret type_of_fn(cx, sp, false, args, out, param_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5273,10 +5286,10 @@ fn collect_native_item(ccx: @crate_ctxt,
|
||||
ast::native_abi_rust_intrinsic. {
|
||||
// For intrinsics: link the function directly to the intrinsic
|
||||
// function itself.
|
||||
let num_ty_param = vec::len(tps);
|
||||
check returns_non_ty_var(ccx, node_type);
|
||||
let fn_type = type_of_fn_from_ty(ccx, sp, node_type,
|
||||
num_ty_param);
|
||||
let fn_type = type_of_fn_from_ty(
|
||||
ccx, sp, node_type,
|
||||
vec::map(tps, {|p| param_bounds(ccx, p)}));
|
||||
let ri_name = "rust_intrinsic_" + link_name(i);
|
||||
let llnativefn = get_extern_fn(
|
||||
ccx.externs, ccx.llmod, ri_name,
|
||||
|
@ -383,7 +383,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
||||
let ccx = bcx_ccx(bcx), bcx = bcx;
|
||||
let fty = node_id_type(ccx, id);
|
||||
check returns_non_ty_var(ccx, fty);
|
||||
let llfnty = type_of_fn_from_ty(ccx, sp, fty, 0u);
|
||||
let llfnty = type_of_fn_from_ty(ccx, sp, fty, []);
|
||||
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names.next("anon"));
|
||||
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||
@ -436,16 +436,13 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
||||
}
|
||||
|
||||
// Figure out which tydescs we need to pass, if any.
|
||||
let outgoing_fty_real; // the type with typarams still in it
|
||||
let lltydescs: [ValueRef];
|
||||
alt f_res.generic {
|
||||
none. { outgoing_fty_real = outgoing_fty; lltydescs = []; }
|
||||
let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic {
|
||||
none. { (outgoing_fty, [], []) }
|
||||
some(ginfo) {
|
||||
lazily_emit_all_generic_info_tydesc_glues(cx, ginfo);
|
||||
outgoing_fty_real = ginfo.item_type;
|
||||
lltydescs = ginfo.tydescs;
|
||||
(ginfo.item_type, ginfo.tydescs, ginfo.param_bounds)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let ty_param_count = vec::len(lltydescs);
|
||||
if vec::len(bound) == 0u && ty_param_count == 0u {
|
||||
@ -487,7 +484,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
|
||||
// Make thunk
|
||||
let llthunk =
|
||||
trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty_real, args,
|
||||
box_ty, ty_param_count, target_res);
|
||||
box_ty, param_bounds, target_res);
|
||||
|
||||
// Fill the function pair
|
||||
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
|
||||
@ -558,7 +555,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
|
||||
outgoing_fty: ty::t,
|
||||
args: [option::t<@ast::expr>],
|
||||
boxed_closure_ty: ty::t,
|
||||
ty_param_count: uint,
|
||||
param_bounds: [ty::param_bounds],
|
||||
target_fn: option::t<ValueRef>)
|
||||
-> {val: ValueRef, ty: TypeRef} {
|
||||
// If we supported constraints on record fields, we could make the
|
||||
@ -667,7 +664,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
|
||||
let llargs: [ValueRef] = [llretptr, lltargetenv];
|
||||
|
||||
// Copy in the type parameters.
|
||||
let i: uint = 0u;
|
||||
// FIXME[impl] This will also have to copy the dicts
|
||||
let i = 0u, ty_param_count = vec::len(param_bounds);
|
||||
while i < ty_param_count {
|
||||
// Silly check
|
||||
check type_is_tup_like(load_env_bcx, boxed_closure_ty);
|
||||
@ -739,11 +737,10 @@ fn trans_bind_thunk(cx: @local_ctxt,
|
||||
|
||||
check returns_non_ty_var(ccx, outgoing_fty);
|
||||
let lltargetty =
|
||||
type_of_fn_from_ty(ccx, sp, outgoing_fty, ty_param_count);
|
||||
type_of_fn_from_ty(ccx, sp, outgoing_fty, param_bounds);
|
||||
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
|
||||
Call(bcx, lltargetfn, llargs);
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
ret {val: llthunk, ty: llthunk_ty};
|
||||
}
|
||||
|
||||
|
@ -320,13 +320,13 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t)
|
||||
}
|
||||
}
|
||||
|
||||
let params = csearch::get_type_param_count(ccx.sess.get_cstore(), did);
|
||||
let param_bounds = ty::lookup_item_type(ccx.tcx, did).bounds;
|
||||
let nil_res = ty::mk_nil(ccx.tcx);
|
||||
// FIXME: Silly check -- mk_nil should have a postcondition
|
||||
check non_ty_var(ccx, nil_res);
|
||||
let f_t = type_of_fn(ccx, sp, false,
|
||||
[{mode: ast::by_ref, ty: inner_t}],
|
||||
nil_res, params);
|
||||
nil_res, param_bounds);
|
||||
ret trans::get_extern_const(ccx.externs, ccx.llmod,
|
||||
csearch::get_symbol(ccx.sess.get_cstore(),
|
||||
did), f_t);
|
||||
|
@ -880,8 +880,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
|
||||
ty::ty_fn(f) {
|
||||
let out = f.output;
|
||||
check non_ty_var(ccx, out);
|
||||
llfnty = type_of_fn(ccx, m.span, true, f.inputs, out,
|
||||
vec::len(ty_params));
|
||||
llfnty = type_of_fn(
|
||||
ccx, m.span, true, f.inputs, out,
|
||||
vec::map(ty_params, {|p| param_bounds(ccx, p)}));
|
||||
}
|
||||
}
|
||||
let mcx: @local_ctxt =
|
||||
@ -933,7 +934,8 @@ fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method,
|
||||
tps: [ast::ty_param]) -> TypeRef {
|
||||
let out_ty = m.fty.output;
|
||||
check non_ty_var(ccx, out_ty);
|
||||
type_of_fn(ccx, sp, true, m.fty.inputs, out_ty, vec::len(tps))
|
||||
type_of_fn(ccx, sp, true, m.fty.inputs, out_ty,
|
||||
vec::map(tps, {|p| param_bounds(ccx, p)}))
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -185,7 +185,7 @@ export closure_kind;
|
||||
export closure_block;
|
||||
export closure_shared;
|
||||
export closure_send;
|
||||
export param_bound, bound_copy, bound_send, bound_iface;
|
||||
export param_bound, param_bounds, bound_copy, bound_send, bound_iface;
|
||||
export param_bounds_to_kind;
|
||||
|
||||
// Data types
|
||||
@ -194,7 +194,9 @@ type arg = {mode: mode, ty: t};
|
||||
|
||||
type field = {ident: ast::ident, mt: mt};
|
||||
|
||||
type method = {ident: ast::ident, tps: [@[param_bound]], fty: fn_ty};
|
||||
type param_bounds = @[param_bound];
|
||||
|
||||
type method = {ident: ast::ident, tps: [param_bounds], fty: fn_ty};
|
||||
|
||||
type constr_table = hashmap<ast::node_id, [constr]>;
|
||||
|
||||
@ -220,7 +222,7 @@ type ctxt =
|
||||
ast_ty_to_ty_cache: hashmap<@ast::ty, option::t<t>>,
|
||||
tag_var_cache: hashmap<def_id, @[variant_info]>,
|
||||
iface_method_cache: hashmap<def_id, @[method]>,
|
||||
ty_param_bounds: hashmap<def_id, @[param_bound]>};
|
||||
ty_param_bounds: hashmap<def_id, param_bounds>};
|
||||
|
||||
type ty_ctxt = ctxt;
|
||||
|
||||
@ -308,7 +310,7 @@ tag param_bound {
|
||||
bound_iface(t);
|
||||
}
|
||||
|
||||
fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
|
||||
fn param_bounds_to_kind(bounds: param_bounds) -> kind {
|
||||
let kind = kind_noncopyable;
|
||||
for bound in *bounds {
|
||||
alt bound {
|
||||
@ -322,7 +324,7 @@ fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
|
||||
kind
|
||||
}
|
||||
|
||||
type ty_param_bounds_and_ty = @{bounds: [@[param_bound]], ty: t};
|
||||
type ty_param_bounds_and_ty = @{bounds: [param_bounds], ty: t};
|
||||
|
||||
type type_cache = hashmap<ast::def_id, ty_param_bounds_and_ty>;
|
||||
|
||||
|
@ -504,7 +504,7 @@ fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
|
||||
ret tpt;
|
||||
}
|
||||
fn ty_param_bounds(tcx: ty::ctxt, mode: mode, params: [ast::ty_param])
|
||||
-> [@[ty::param_bound]] {
|
||||
-> [ty::param_bounds] {
|
||||
let result = [];
|
||||
for param in params {
|
||||
result += [alt tcx.ty_param_bounds.find(local_def(param.id)) {
|
||||
@ -626,7 +626,7 @@ mod write {
|
||||
}
|
||||
|
||||
fn mk_ty_params(tcx: ty::ctxt, atps: [ast::ty_param])
|
||||
-> {bounds: [@[ty::param_bound]], params: [ty::t]} {
|
||||
-> {bounds: [ty::param_bounds], params: [ty::t]} {
|
||||
let i = 0u, bounds = ty_param_bounds(tcx, m_collect, atps);
|
||||
{bounds: bounds,
|
||||
params: vec::map(atps, {|atp|
|
||||
@ -2896,6 +2896,7 @@ fn resolve_vtables(tcx: ty::ctxt, impl_map: resolve::impl_map,
|
||||
ty::ty_iface(did, _) { did }
|
||||
_ { ret; }
|
||||
};
|
||||
// FIXME check against bounded param types
|
||||
let found = false;
|
||||
std::list::iter(isc) {|impls|
|
||||
if found { ret; }
|
||||
|
Loading…
Reference in New Issue
Block a user