@@ -98,9 +98,14 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, is_method: bool, inputs: [ty::arg],
98
98
99
99
// Args >2: ty params, if not acquired via capture...
100
100
if !is_method {
101
- // FIXME[impl] Also add args for the dicts
102
- for _param in params {
101
+ for bounds in params {
103
102
atys += [ T_ptr ( cx. tydesc_type ) ] ;
103
+ for bound in * bounds {
104
+ alt bound {
105
+ ty : : bound_iface ( _) { atys += [ T_ptr ( T_dict ( ) ) ] ; }
106
+ _ { }
107
+ }
108
+ }
104
109
}
105
110
}
106
111
// ... then explicit args.
@@ -905,7 +910,10 @@ fn linearize_ty_params(cx: @block_ctxt, t: ty::t) ->
905
910
ty:: ty_param ( pid, _) {
906
911
let seen: bool = false ;
907
912
for d: uint in r. defs { if d == pid { seen = true ; } }
908
- if !seen { r. vals += [ r. cx . fcx . lltydescs [ pid] ] ; r. defs += [ pid] ; }
913
+ if !seen {
914
+ r. vals += [ r. cx . fcx . lltyparams [ pid] . desc ] ;
915
+ r. defs += [ pid] ;
916
+ }
909
917
}
910
918
_ { }
911
919
}
@@ -1041,8 +1049,9 @@ fn get_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
1041
1049
// Is the supplied type a type param? If so, return the passed-in tydesc.
1042
1050
alt ty:: type_param ( bcx_tcx ( cx) , t) {
1043
1051
some ( id) {
1044
- if id < vec:: len ( cx. fcx . lltydescs ) {
1045
- ret { kind : tk_param, result : rslt ( cx, cx. fcx . lltydescs [ id] ) } ;
1052
+ if id < vec:: len ( cx. fcx . lltyparams ) {
1053
+ ret { kind : tk_param,
1054
+ result : rslt ( cx, cx. fcx . lltyparams [ id] . desc ) } ;
1046
1055
} else {
1047
1056
bcx_tcx ( cx) . sess . span_bug ( cx. sp ,
1048
1057
"Unbound typaram in get_tydesc: " +
@@ -1205,10 +1214,7 @@ fn make_generic_glue_inner(cx: @local_ctxt, sp: span, t: ty::t,
1205
1214
p += 1 u;
1206
1215
}
1207
1216
1208
- // FIXME: Implement some kind of freeze operation in the standard library.
1209
- let lltydescs_frozen = [ ] ;
1210
- for lltydesc: ValueRef in lltydescs { lltydescs_frozen += [ lltydesc] ; }
1211
- fcx. lltydescs = lltydescs_frozen;
1217
+ fcx. lltyparams = vec:: map_mut ( lltydescs, { |d| { desc: d, dicts: none} } ) ;
1212
1218
1213
1219
let bcx = new_top_block_ctxt ( fcx) ;
1214
1220
let lltop = bcx. llbb ;
@@ -2558,11 +2564,13 @@ fn trans_do_while(cx: @block_ctxt, body: ast::blk, cond: @ast::expr) ->
2558
2564
ret next_cx;
2559
2565
}
2560
2566
2561
- type generic_info =
2562
- { item_type : ty:: t ,
2563
- static_tis : [ option:: t < @tydesc_info > ] ,
2564
- tydescs : [ ValueRef ] ,
2565
- param_bounds : @[ ty:: param_bounds ] } ;
2567
+ type generic_info = {
2568
+ item_type : ty:: t ,
2569
+ static_tis : [ option:: t < @tydesc_info > ] ,
2570
+ tydescs : [ ValueRef ] ,
2571
+ param_bounds : @[ ty:: param_bounds ] ,
2572
+ origins : option:: t < typeck:: dict_res >
2573
+ } ;
2566
2574
2567
2575
tag lval_kind {
2568
2576
temporary; //< Temporary value passed by value if of immediate type
@@ -2571,7 +2579,12 @@ tag lval_kind {
2571
2579
}
2572
2580
type local_var_result = { val: ValueRef , kind: lval_kind} ;
2573
2581
type lval_result = { bcx : @block_ctxt , val : ValueRef , kind : lval_kind } ;
2574
- tag callee_env { obj_env( ValueRef ) ; null_env; is_closure; }
2582
+ tag callee_env {
2583
+ null_env;
2584
+ is_closure;
2585
+ obj_env ( ValueRef ) ;
2586
+ dict_env ( ValueRef , ValueRef ) ;
2587
+ }
2575
2588
type lval_maybe_callee = { bcx: @block_ctxt,
2576
2589
val: ValueRef ,
2577
2590
kind: lval_kind,
@@ -2630,11 +2643,11 @@ fn lval_static_fn(bcx: @block_ctxt, fn_id: ast::def_id, id: ast::node_id)
2630
2643
bcx = td. bcx ;
2631
2644
tydescs += [ td. val ] ;
2632
2645
}
2633
- let bounds = ty:: lookup_item_type ( ccx. tcx , fn_id) . bounds ;
2634
2646
gen = some ( { item_type: tpt. ty ,
2635
2647
static_tis: tis,
2636
2648
tydescs: tydescs,
2637
- param_bounds: bounds} ) ;
2649
+ param_bounds: tpt. bounds ,
2650
+ origins: ccx. dict_map . find ( id) } ) ;
2638
2651
}
2639
2652
ret { bcx : bcx, val : val, kind : owned, env : null_env, generic : gen} ;
2640
2653
}
@@ -2843,17 +2856,6 @@ fn expr_is_lval(bcx: @block_ctxt, e: @ast::expr) -> bool {
2843
2856
ty:: expr_is_lval ( ccx. method_map , ccx. tcx , e)
2844
2857
}
2845
2858
2846
- // This is for impl methods, not obj methods.
2847
- fn trans_method_callee ( bcx : @block_ctxt , e : @ast:: expr , base : @ast:: expr ,
2848
- did : ast:: def_id ) -> lval_maybe_callee {
2849
- let tz = [ ] , tr = [ ] ;
2850
- let basety = ty:: expr_ty ( bcx_tcx ( bcx) , base) ;
2851
- let { bcx, val} = trans_arg_expr ( bcx, { mode: ast:: by_ref, ty: basety} ,
2852
- type_of_or_i8 ( bcx, basety) , tz, tr, base) ;
2853
- let val = PointerCast ( bcx, val, T_opaque_boxed_closure_ptr ( bcx_ccx ( bcx) ) ) ;
2854
- { env: obj_env ( val) with lval_static_fn ( bcx, did, e. id ) }
2855
- }
2856
-
2857
2859
fn trans_callee ( bcx : @block_ctxt , e : @ast:: expr ) -> lval_maybe_callee {
2858
2860
alt e. node {
2859
2861
ast:: expr_path ( p) { ret trans_path ( bcx, p, e. id ) ; }
@@ -2862,10 +2864,11 @@ fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
2862
2864
if !expr_is_lval ( bcx, e) {
2863
2865
alt bcx_ccx ( bcx) . method_map . find ( e. id ) {
2864
2866
some ( typeck:: method_static ( did) ) { // An impl method
2865
- ret trans_method_callee ( bcx, e, base, did) ;
2867
+ ret trans_impl :: trans_static_callee ( bcx, e, base, did) ;
2866
2868
}
2867
- some ( typeck:: method_param ( _) ) {
2868
- fail "not implemented" ; // FIXME[impl]
2869
+ some ( typeck:: method_param ( iid, off, p, b) ) {
2870
+ ret trans_impl:: trans_dict_callee (
2871
+ bcx, e, base, iid, off, p, b) ;
2869
2872
}
2870
2873
none. { // An object method
2871
2874
let of = trans_object_field ( bcx, base, ident) ;
@@ -2936,7 +2939,7 @@ fn maybe_add_env(bcx: @block_ctxt, c: lval_maybe_callee)
2936
2939
-> ( lval_kind , ValueRef ) {
2937
2940
alt c. env {
2938
2941
is_closure. { ( c. kind , c. val ) }
2939
- obj_env ( _) {
2942
+ obj_env ( _) | dict_env ( _ , _ ) {
2940
2943
fail "Taking the value of a method does not work yet (issue #435)" ;
2941
2944
}
2942
2945
null_env. {
@@ -3149,7 +3152,23 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef,
3149
3152
alt gen {
3150
3153
some ( g) {
3151
3154
lazily_emit_all_generic_info_tydesc_glues ( cx, g) ;
3152
- lltydescs = g. tydescs ;
3155
+ let i = 0 u, n_orig = 0 u;
3156
+ for param in * g. param_bounds {
3157
+ lltydescs += [ g. tydescs [ i] ] ;
3158
+ for bound in * param {
3159
+ alt bound {
3160
+ ty : : bound_iface ( _) {
3161
+ let res = trans_impl:: get_dict (
3162
+ bcx, option:: get ( g. origins ) [ n_orig] ) ;
3163
+ lltydescs += [ res. val ] ;
3164
+ bcx = res. bcx ;
3165
+ n_orig += 1 u;
3166
+ }
3167
+ _ { }
3168
+ }
3169
+ }
3170
+ i += 1 u;
3171
+ }
3153
3172
args = ty:: ty_fn_args ( tcx, g. item_type ) ;
3154
3173
retty = ty:: ty_fn_ret ( tcx, g. item_type ) ;
3155
3174
}
@@ -3220,12 +3239,13 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3220
3239
let bcx = f_res. bcx ;
3221
3240
3222
3241
let faddr = f_res. val ;
3223
- let llenv;
3242
+ let llenv, dict_param = none ;
3224
3243
alt f_res. env {
3225
3244
null_env. {
3226
3245
llenv = llvm:: LLVMGetUndef ( T_opaque_boxed_closure_ptr ( bcx_ccx ( cx) ) ) ;
3227
3246
}
3228
3247
obj_env ( e) { llenv = e; }
3248
+ dict_env ( dict, e) { llenv = e; dict_param = some ( dict) ; }
3229
3249
is_closure. {
3230
3250
// It's a closure. Have to fetch the elements
3231
3251
if f_res. kind == owned {
@@ -3244,6 +3264,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3244
3264
trans_args ( bcx, llenv, f_res. generic , args, fn_expr_ty, dest) ;
3245
3265
bcx = args_res. bcx ;
3246
3266
let llargs = args_res. args ;
3267
+ option:: may ( dict_param) { |dict| llargs = [ dict] + llargs}
3247
3268
let llretslot = args_res. retslot ;
3248
3269
3249
3270
/* If the block is terminated,
@@ -3306,8 +3327,7 @@ fn invoke_(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef],
3306
3327
// cleanups to run
3307
3328
if bcx. unreachable { ret bcx; }
3308
3329
let normal_bcx = new_sub_block_ctxt ( bcx, "normal return" ) ;
3309
- invoker ( bcx, llfn, llargs,
3310
- normal_bcx. llbb ,
3330
+ invoker ( bcx, llfn, llargs, normal_bcx. llbb ,
3311
3331
get_landing_pad ( bcx, to_zero, to_revoke) ) ;
3312
3332
ret normal_bcx;
3313
3333
}
@@ -4351,7 +4371,7 @@ fn new_fn_ctxt_w_id(cx: @local_ctxt, sp: span, llfndecl: ValueRef,
4351
4371
llobjfields : new_int_hash :: < ValueRef > ( ) ,
4352
4372
lllocals : new_int_hash :: < local_val > ( ) ,
4353
4373
llupvars : new_int_hash :: < ValueRef > ( ) ,
4354
- mutable lltydescs : [ ] ,
4374
+ mutable lltyparams : [ ] ,
4355
4375
derived_tydescs : ty:: new_ty_hash ( ) ,
4356
4376
id : id,
4357
4377
ret_style : rstyle,
@@ -4393,10 +4413,22 @@ fn create_llargs_for_fn_args(cx: @fn_ctxt, ty_self: self_arg,
4393
4413
obj_self( _) { }
4394
4414
_ {
4395
4415
for tp in ty_params {
4396
- let llarg = llvm:: LLVMGetParam ( cx. llfn , arg_n) ;
4397
- assert ( llarg as int != 0 ) ;
4398
- cx. lltydescs += [ llarg] ;
4416
+ let lltydesc = llvm:: LLVMGetParam ( cx. llfn , arg_n) , dicts = none;
4399
4417
arg_n += 1 u;
4418
+ for bound in * fcx_tcx ( cx) . ty_param_bounds . get ( tp. id ) {
4419
+ alt bound {
4420
+ ty : : bound_iface ( _) {
4421
+ let dict = llvm:: LLVMGetParam ( cx. llfn , arg_n) ;
4422
+ arg_n += 1 u;
4423
+ dicts = some ( alt dicts {
4424
+ none. { [ dict] }
4425
+ some ( ds) { ds + [ dict] }
4426
+ } ) ;
4427
+ }
4428
+ _ { }
4429
+ }
4430
+ }
4431
+ cx. lltyparams += [ { desc: lltydesc, dicts: dicts} ] ;
4400
4432
}
4401
4433
}
4402
4434
}
@@ -4485,7 +4517,7 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) {
4485
4517
let lltyparam: ValueRef =
4486
4518
GEPi ( bcx, obj_typarams, [ 0 , i] ) ;
4487
4519
lltyparam = Load ( bcx, lltyparam) ;
4488
- fcx. lltydescs += [ lltyparam] ;
4520
+ fcx. lltyparams += [ { desc : lltyparam, dicts : none } ] ;
4489
4521
i += 1 ;
4490
4522
}
4491
4523
i = 0 ;
@@ -5582,7 +5614,8 @@ fn write_abi_version(ccx: @crate_ctxt) {
5582
5614
fn trans_crate ( sess : session:: session , crate : @ast:: crate , tcx : ty:: ctxt ,
5583
5615
output : str , emap : resolve:: exp_map , amap : ast_map:: map ,
5584
5616
mut_map : mut:: mut_map , copy_map : alias:: copy_map ,
5585
- last_uses : last_use:: last_uses , method_map : typeck:: method_map )
5617
+ last_uses : last_use:: last_uses , method_map : typeck:: method_map ,
5618
+ dict_map : typeck:: dict_map )
5586
5619
-> ( ModuleRef , link:: link_meta ) {
5587
5620
let sha = std:: sha1:: mk_sha1 ( ) ;
5588
5621
let link_meta = link:: build_link_meta ( sess, * crate , output, sha) ;
@@ -5659,6 +5692,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
5659
5692
copy_map: copy_map,
5660
5693
last_uses: last_uses,
5661
5694
method_map: method_map,
5695
+ dict_map: dict_map,
5662
5696
stats :
5663
5697
{ mutable n_static_tydescs : 0 u,
5664
5698
mutable n_derived_tydescs : 0 u,
0 commit comments