Skip to content

Commit 270b427

Browse files
committed
Pass bounds to trans::type_of_fn
1 parent 664a044 commit 270b427

File tree

6 files changed

+65
-50
lines changed

6 files changed

+65
-50
lines changed

src/comp/middle/trans.rs

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) ->
8383
// - trans_args
8484
fn type_of_fn(cx: @crate_ctxt, sp: span,
8585
is_method: bool, inputs: [ty::arg],
86-
output: ty::t, ty_param_count: uint)
86+
output: ty::t, params: [ty::param_bounds])
8787
: non_ty_var(cx, output) -> TypeRef {
8888
let atys: [TypeRef] = [];
8989

@@ -100,8 +100,10 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
100100

101101
// Args >2: ty params, if not acquired via capture...
102102
if !is_method {
103-
let i = 0u;
104-
while i < ty_param_count { atys += [T_ptr(cx.tydesc_type)]; i += 1u; }
103+
// FIXME[impl] Also add args for the dicts
104+
for _param in params {
105+
atys += [T_ptr(cx.tydesc_type)];
106+
}
105107
}
106108
// ... then explicit args.
107109
atys += type_of_explicit_args(cx, sp, inputs);
@@ -110,15 +112,15 @@ fn type_of_fn(cx: @crate_ctxt, sp: span,
110112

111113
// Given a function type and a count of ty params, construct an llvm type
112114
fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t,
113-
ty_param_count: uint)
115+
param_bounds: [ty::param_bounds])
114116
: returns_non_ty_var(cx, fty) -> TypeRef {
115117
// FIXME: Check should be unnecessary, b/c it's implied
116118
// by returns_non_ty_var(t). Make that a postcondition
117119
// (see Issue #586)
118120
let ret_ty = ty::ty_fn_ret(cx.tcx, fty);
119121
check non_ty_var(cx, ret_ty);
120122
ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty),
121-
ret_ty, ty_param_count);
123+
ret_ty, param_bounds);
122124
}
123125

124126
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)
171173
ty::ty_fn(_) {
172174
// FIXME: could be a constraint on ty_fn
173175
check returns_non_ty_var(cx, t);
174-
T_fn_pair(cx, type_of_fn_from_ty(cx, sp, t, 0u))
176+
T_fn_pair(cx, type_of_fn_from_ty(cx, sp, t, []))
175177
}
176178
ty::ty_native_fn(args, out) {
177-
let nft = native_fn_wrapper_type(cx, sp, 0u, t);
179+
let nft = native_fn_wrapper_type(cx, sp, [], t);
178180
T_fn_pair(cx, nft)
179181
}
180182
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,
234236
alt ty::struct(cx.tcx, t) {
235237
ty::ty_fn(_) | ty::ty_native_fn(_, _) {
236238
check returns_non_ty_var(cx, t);
237-
ret type_of_fn_from_ty(cx, sp, t, vec::len(tpt.bounds));
239+
ret type_of_fn_from_ty(cx, sp, t, tpt.bounds);
238240
}
239241
_ {
240242
// fall through
@@ -2562,7 +2564,8 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
25622564
type generic_info =
25632565
{item_type: ty::t,
25642566
static_tis: [option::t<@tydesc_info>],
2565-
tydescs: [ValueRef]};
2567+
tydescs: [ValueRef],
2568+
param_bounds: [ty::param_bounds]};
25662569

25672570
tag lval_kind {
25682571
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,
26082611

26092612
fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
26102613
-> lval_maybe_callee {
2611-
let tpt = ty::lookup_item_type(bcx_tcx(bcx), fn_id);
2614+
let ccx = bcx_ccx(bcx);
2615+
let tpt = ty::lookup_item_type(ccx.tcx, fn_id);
26122616
let val = if fn_id.crate == ast::local_crate {
26132617
// Internal reference.
2614-
assert (bcx_ccx(bcx).item_ids.contains_key(fn_id.node));
2615-
bcx_ccx(bcx).item_ids.get(fn_id.node)
2618+
assert (ccx.item_ids.contains_key(fn_id.node));
2619+
ccx.item_ids.get(fn_id.node)
26162620
} else {
26172621
// External reference.
26182622
trans_external_path(bcx, fn_id, tpt)
26192623
};
2620-
let tys = ty::node_id_to_type_params(bcx_tcx(bcx), id);
2624+
let tys = ty::node_id_to_type_params(ccx.tcx, id);
26212625
let gen = none, bcx = bcx;
2622-
if vec::len::<ty::t>(tys) != 0u {
2626+
if vec::len(tys) != 0u {
26232627
let tydescs = [], tis = [];
26242628
for t in tys {
26252629
// 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)
26292633
bcx = td.bcx;
26302634
tydescs += [td.val];
26312635
}
2632-
gen = some({item_type: tpt.ty, static_tis: tis, tydescs: tydescs});
2636+
let bounds = ty::lookup_item_type(ccx.tcx, fn_id).bounds;
2637+
gen = some({item_type: tpt.ty,
2638+
static_tis: tis,
2639+
tydescs: tydescs,
2640+
param_bounds: bounds});
26332641
}
26342642
ret {bcx: bcx, val: val, kind: owned, env: null_env, generic: gen};
26352643
}
@@ -2767,7 +2775,7 @@ fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef,
27672775
check non_ty_var(ccx, ret_ty);
27682776

27692777
let ll_fn_ty = type_of_fn(ccx, bcx.sp, true,
2770-
ty::ty_fn_args(tcx, fn_ty), ret_ty, 0u);
2778+
ty::ty_fn_args(tcx, fn_ty), ret_ty, []);
27712779
v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty))));
27722780
ret {bcx: bcx, mthptr: v, objptr: o};
27732781
}
@@ -5084,13 +5092,17 @@ fn register_fn(ccx: @crate_ctxt, sp: span, path: [str], flav: str,
50845092
register_fn_full(ccx, sp, path, flav, ty_params, node_id, t);
50855093
}
50865094

5095+
fn param_bounds(ccx: @crate_ctxt, tp: ast::ty_param) -> ty::param_bounds {
5096+
ccx.tcx.ty_param_bounds.get(ast_util::local_def(tp.id))
5097+
}
5098+
50875099
fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
5088-
ty_params: [ast::ty_param], node_id: ast::node_id,
5100+
tps: [ast::ty_param], node_id: ast::node_id,
50895101
node_type: ty::t)
50905102
: returns_non_ty_var(ccx, node_type) {
50915103
let path = path;
5092-
let llfty =
5093-
type_of_fn_from_ty(ccx, sp, node_type, vec::len(ty_params));
5104+
let llfty = type_of_fn_from_ty(ccx, sp, node_type,
5105+
vec::map(tps, {|p| param_bounds(ccx, p)}));
50945106
let ps: str = mangle_exported_name(ccx, path, node_type);
50955107
let llfn: ValueRef = decl_cdecl_fn(ccx.llmod, ps, llfty);
50965108
ccx.item_ids.insert(node_id, llfn);
@@ -5128,7 +5140,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
51285140
let nt = ty::mk_nil(ccx.tcx);
51295141
check non_ty_var(ccx, nt);
51305142

5131-
let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, 0u);
5143+
let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, []);
51325144
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
51335145
lib::llvm::LLVMCCallConv, llfty);
51345146

@@ -5221,12 +5233,13 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
52215233
ret count;
52225234
}
52235235

5224-
fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint,
5236+
fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span,
5237+
param_bounds: [ty::param_bounds],
52255238
x: ty::t) -> TypeRef {
52265239
alt ty::struct(cx.tcx, x) {
52275240
ty::ty_native_fn(args, out) {
52285241
check non_ty_var(cx, out);
5229-
ret type_of_fn(cx, sp, false, args, out, ty_param_count);
5242+
ret type_of_fn(cx, sp, false, args, out, param_bounds);
52305243
}
52315244
}
52325245
}
@@ -5273,10 +5286,10 @@ fn collect_native_item(ccx: @crate_ctxt,
52735286
ast::native_abi_rust_intrinsic. {
52745287
// For intrinsics: link the function directly to the intrinsic
52755288
// function itself.
5276-
let num_ty_param = vec::len(tps);
52775289
check returns_non_ty_var(ccx, node_type);
5278-
let fn_type = type_of_fn_from_ty(ccx, sp, node_type,
5279-
num_ty_param);
5290+
let fn_type = type_of_fn_from_ty(
5291+
ccx, sp, node_type,
5292+
vec::map(tps, {|p| param_bounds(ccx, p)}));
52805293
let ri_name = "rust_intrinsic_" + link_name(i);
52815294
let llnativefn = get_extern_fn(
52825295
ccx.externs, ccx.llmod, ri_name,

src/comp/middle/trans_closure.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
383383
let ccx = bcx_ccx(bcx), bcx = bcx;
384384
let fty = node_id_type(ccx, id);
385385
check returns_non_ty_var(ccx, fty);
386-
let llfnty = type_of_fn_from_ty(ccx, sp, fty, 0u);
386+
let llfnty = type_of_fn_from_ty(ccx, sp, fty, []);
387387
let sub_cx = extend_path(bcx.fcx.lcx, ccx.names.next("anon"));
388388
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
389389
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,
436436
}
437437

438438
// Figure out which tydescs we need to pass, if any.
439-
let outgoing_fty_real; // the type with typarams still in it
440-
let lltydescs: [ValueRef];
441-
alt f_res.generic {
442-
none. { outgoing_fty_real = outgoing_fty; lltydescs = []; }
439+
let (outgoing_fty_real, lltydescs, param_bounds) = alt f_res.generic {
440+
none. { (outgoing_fty, [], []) }
443441
some(ginfo) {
444442
lazily_emit_all_generic_info_tydesc_glues(cx, ginfo);
445-
outgoing_fty_real = ginfo.item_type;
446-
lltydescs = ginfo.tydescs;
443+
(ginfo.item_type, ginfo.tydescs, ginfo.param_bounds)
447444
}
448-
}
445+
};
449446

450447
let ty_param_count = vec::len(lltydescs);
451448
if vec::len(bound) == 0u && ty_param_count == 0u {
@@ -487,7 +484,7 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
487484
// Make thunk
488485
let llthunk =
489486
trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty_real, args,
490-
box_ty, ty_param_count, target_res);
487+
box_ty, param_bounds, target_res);
491488

492489
// Fill the function pair
493490
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
@@ -558,7 +555,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
558555
outgoing_fty: ty::t,
559556
args: [option::t<@ast::expr>],
560557
boxed_closure_ty: ty::t,
561-
ty_param_count: uint,
558+
param_bounds: [ty::param_bounds],
562559
target_fn: option::t<ValueRef>)
563560
-> {val: ValueRef, ty: TypeRef} {
564561
// If we supported constraints on record fields, we could make the
@@ -667,7 +664,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
667664
let llargs: [ValueRef] = [llretptr, lltargetenv];
668665

669666
// Copy in the type parameters.
670-
let i: uint = 0u;
667+
// FIXME[impl] This will also have to copy the dicts
668+
let i = 0u, ty_param_count = vec::len(param_bounds);
671669
while i < ty_param_count {
672670
// Silly check
673671
check type_is_tup_like(load_env_bcx, boxed_closure_ty);
@@ -739,11 +737,10 @@ fn trans_bind_thunk(cx: @local_ctxt,
739737

740738
check returns_non_ty_var(ccx, outgoing_fty);
741739
let lltargetty =
742-
type_of_fn_from_ty(ccx, sp, outgoing_fty, ty_param_count);
740+
type_of_fn_from_ty(ccx, sp, outgoing_fty, param_bounds);
743741
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
744742
Call(bcx, lltargetfn, llargs);
745743
build_return(bcx);
746744
finish_fn(fcx, lltop);
747745
ret {val: llthunk, ty: llthunk_ty};
748746
}
749-

src/comp/middle/trans_common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,13 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t)
320320
}
321321
}
322322

323-
let params = csearch::get_type_param_count(ccx.sess.get_cstore(), did);
323+
let param_bounds = ty::lookup_item_type(ccx.tcx, did).bounds;
324324
let nil_res = ty::mk_nil(ccx.tcx);
325325
// FIXME: Silly check -- mk_nil should have a postcondition
326326
check non_ty_var(ccx, nil_res);
327327
let f_t = type_of_fn(ccx, sp, false,
328328
[{mode: ast::by_ref, ty: inner_t}],
329-
nil_res, params);
329+
nil_res, param_bounds);
330330
ret trans::get_extern_const(ccx.externs, ccx.llmod,
331331
csearch::get_symbol(ccx.sess.get_cstore(),
332332
did), f_t);

src/comp/middle/trans_objects.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
880880
ty::ty_fn(f) {
881881
let out = f.output;
882882
check non_ty_var(ccx, out);
883-
llfnty = type_of_fn(ccx, m.span, true, f.inputs, out,
884-
vec::len(ty_params));
883+
llfnty = type_of_fn(
884+
ccx, m.span, true, f.inputs, out,
885+
vec::map(ty_params, {|p| param_bounds(ccx, p)}));
885886
}
886887
}
887888
let mcx: @local_ctxt =
@@ -933,7 +934,8 @@ fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method,
933934
tps: [ast::ty_param]) -> TypeRef {
934935
let out_ty = m.fty.output;
935936
check non_ty_var(ccx, out_ty);
936-
type_of_fn(ccx, sp, true, m.fty.inputs, out_ty, vec::len(tps))
937+
type_of_fn(ccx, sp, true, m.fty.inputs, out_ty,
938+
vec::map(tps, {|p| param_bounds(ccx, p)}))
937939
}
938940

939941
//

src/comp/middle/ty.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export closure_kind;
185185
export closure_block;
186186
export closure_shared;
187187
export closure_send;
188-
export param_bound, bound_copy, bound_send, bound_iface;
188+
export param_bound, param_bounds, bound_copy, bound_send, bound_iface;
189189
export param_bounds_to_kind;
190190

191191
// Data types
@@ -194,7 +194,9 @@ type arg = {mode: mode, ty: t};
194194

195195
type field = {ident: ast::ident, mt: mt};
196196

197-
type method = {ident: ast::ident, tps: [@[param_bound]], fty: fn_ty};
197+
type param_bounds = @[param_bound];
198+
199+
type method = {ident: ast::ident, tps: [param_bounds], fty: fn_ty};
198200

199201
type constr_table = hashmap<ast::node_id, [constr]>;
200202

@@ -220,7 +222,7 @@ type ctxt =
220222
ast_ty_to_ty_cache: hashmap<@ast::ty, option::t<t>>,
221223
tag_var_cache: hashmap<def_id, @[variant_info]>,
222224
iface_method_cache: hashmap<def_id, @[method]>,
223-
ty_param_bounds: hashmap<def_id, @[param_bound]>};
225+
ty_param_bounds: hashmap<def_id, param_bounds>};
224226

225227
type ty_ctxt = ctxt;
226228

@@ -308,7 +310,7 @@ tag param_bound {
308310
bound_iface(t);
309311
}
310312

311-
fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
313+
fn param_bounds_to_kind(bounds: param_bounds) -> kind {
312314
let kind = kind_noncopyable;
313315
for bound in *bounds {
314316
alt bound {
@@ -322,7 +324,7 @@ fn param_bounds_to_kind(bounds: @[param_bound]) -> kind {
322324
kind
323325
}
324326

325-
type ty_param_bounds_and_ty = @{bounds: [@[param_bound]], ty: t};
327+
type ty_param_bounds_and_ty = @{bounds: [param_bounds], ty: t};
326328

327329
type type_cache = hashmap<ast::def_id, ty_param_bounds_and_ty>;
328330

src/comp/middle/typeck.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
504504
ret tpt;
505505
}
506506
fn ty_param_bounds(tcx: ty::ctxt, mode: mode, params: [ast::ty_param])
507-
-> [@[ty::param_bound]] {
507+
-> [ty::param_bounds] {
508508
let result = [];
509509
for param in params {
510510
result += [alt tcx.ty_param_bounds.find(local_def(param.id)) {
@@ -626,7 +626,7 @@ mod write {
626626
}
627627

628628
fn mk_ty_params(tcx: ty::ctxt, atps: [ast::ty_param])
629-
-> {bounds: [@[ty::param_bound]], params: [ty::t]} {
629+
-> {bounds: [ty::param_bounds], params: [ty::t]} {
630630
let i = 0u, bounds = ty_param_bounds(tcx, m_collect, atps);
631631
{bounds: bounds,
632632
params: vec::map(atps, {|atp|
@@ -2896,6 +2896,7 @@ fn resolve_vtables(tcx: ty::ctxt, impl_map: resolve::impl_map,
28962896
ty::ty_iface(did, _) { did }
28972897
_ { ret; }
28982898
};
2899+
// FIXME check against bounded param types
28992900
let found = false;
29002901
std::list::iter(isc) {|impls|
29012902
if found { ret; }

0 commit comments

Comments
 (0)