13
13
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
14
14
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
15
15
16
- import core:: { either, str, uint, option, vec} ;
16
+ import core:: { either, str, int , uint, option, vec} ;
17
17
import std:: { map, time} ;
18
18
import std:: map:: hashmap;
19
19
import std:: map:: { new_int_hash, new_str_hash} ;
@@ -948,8 +948,6 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
948
948
& static_ti: option:: t < @tydesc_info > ) -> result {
949
949
alt cx. fcx . derived_tydescs . find ( t) {
950
950
some ( info) {
951
-
952
-
953
951
// If the tydesc escapes in this context, the cached derived
954
952
// tydesc also has to be one that was marked as escaping.
955
953
if !( escapes && !info. escapes ) && storage == tps_normal {
@@ -2606,8 +2604,9 @@ fn trans_external_path(cx: @block_ctxt, did: ast::def_id,
2606
2604
type_of_ty_param_kinds_and_ty ( lcx, cx. sp , tpt) ) ;
2607
2605
}
2608
2606
2609
- fn lval_static_fn ( bcx : @block_ctxt , tpt : ty:: ty_param_kinds_and_ty ,
2610
- fn_id : ast:: def_id , id : ast:: node_id ) -> lval_maybe_callee {
2607
+ fn lval_static_fn ( bcx : @block_ctxt , fn_id : ast:: def_id , id : ast:: node_id )
2608
+ -> lval_maybe_callee {
2609
+ let tpt = ty:: lookup_item_type ( bcx_tcx ( bcx) , fn_id) ;
2611
2610
let val = if fn_id. crate == ast:: local_crate {
2612
2611
// Internal reference.
2613
2612
assert ( bcx_ccx ( bcx) . item_ids . contains_key ( fn_id. node ) ) ;
@@ -2698,17 +2697,13 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
2698
2697
let ccx = bcx_ccx ( cx) ;
2699
2698
alt def {
2700
2699
ast : : def_fn ( did, _) | ast:: def_native_fn ( did, _) {
2701
- let tyt = ty:: lookup_item_type ( ccx. tcx , did) ;
2702
- ret lval_static_fn ( cx, tyt, did, id) ;
2700
+ ret lval_static_fn ( cx, did, id) ;
2703
2701
}
2704
2702
ast:: def_variant ( tid, vid) {
2705
- let v_tyt = ty:: lookup_item_type ( ccx. tcx , vid) ;
2706
- alt ty:: struct ( ccx. tcx , v_tyt. ty ) {
2707
- ty:: ty_fn ( _, _, _, _, _) {
2703
+ if vec:: len ( ty:: tag_variant_with_id ( ccx. tcx , tid, vid) . args ) > 0 u {
2708
2704
// N-ary variant.
2709
- ret lval_static_fn ( cx, v_tyt, vid, id) ;
2710
- }
2711
- _ {
2705
+ ret lval_static_fn ( cx, vid, id) ;
2706
+ } else {
2712
2707
// Nullary variant.
2713
2708
let tag_ty = node_id_type ( ccx, id) ;
2714
2709
let alloc_result = alloc_ty ( cx, tag_ty) ;
@@ -2724,7 +2719,6 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
2724
2719
} else { C_int ( ccx, 0 ) } ;
2725
2720
Store ( bcx, d, lldiscrimptr) ;
2726
2721
ret lval_no_env ( bcx, lltagptr, temporary) ;
2727
- }
2728
2722
}
2729
2723
}
2730
2724
ast:: def_const ( did) {
@@ -2838,15 +2832,30 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
2838
2832
ret lval_owned( next_cx, elt) ;
2839
2833
}
2840
2834
2835
+ // This is for impl methods, not obj methods.
2836
+ fn trans_method_callee ( bcx : @block_ctxt , e : @ast:: expr , base : @ast:: expr ,
2837
+ did : ast:: def_id ) -> lval_maybe_callee {
2838
+ let bcx = trans_expr ( bcx, base, ignore) ; // FIXME pass self
2839
+ lval_static_fn ( bcx, did, e. id )
2840
+ }
2841
+
2841
2842
fn trans_callee ( bcx : @block_ctxt , e : @ast:: expr ) -> lval_maybe_callee {
2842
2843
alt e. node {
2843
2844
ast:: expr_path ( p) { ret trans_path ( bcx, p, e. id ) ; }
2844
2845
ast:: expr_field ( base, ident) {
2846
+ let method_map = bcx_ccx ( bcx) . method_map ;
2845
2847
// Lval means this is a record field, so not a method
2846
- if !ty:: expr_is_lval ( bcx_tcx ( bcx) , e) {
2847
- let of = trans_object_field ( bcx, base, ident) ;
2848
- ret { bcx : of. bcx , val : of. mthptr , kind : owned,
2849
- env : obj_env ( of. objptr ) , generic : none} ;
2848
+ if !ty:: expr_is_lval ( method_map, bcx_tcx ( bcx) , e) {
2849
+ alt method_map. find ( e. id ) {
2850
+ some ( did) { // An impl method
2851
+ ret trans_method_callee ( bcx, e, base, did) ;
2852
+ }
2853
+ none. { // An object method
2854
+ let of = trans_object_field ( bcx, base, ident) ;
2855
+ ret { bcx : of. bcx , val : of. mthptr , kind : owned,
2856
+ env : obj_env ( of. objptr ) , generic : none} ;
2857
+ }
2858
+ }
2850
2859
}
2851
2860
}
2852
2861
ast:: expr_self_method ( ident) {
@@ -3466,7 +3475,7 @@ fn trans_expr_save_in(bcx: @block_ctxt, e: @ast::expr, dest: ValueRef)
3466
3475
// use trans_temp_expr.
3467
3476
fn trans_temp_lval ( bcx : @block_ctxt , e : @ast:: expr ) -> lval_result {
3468
3477
let bcx = bcx;
3469
- if ty:: expr_is_lval ( bcx_tcx ( bcx) , e) {
3478
+ if ty:: expr_is_lval ( bcx_ccx ( bcx ) . method_map , bcx_tcx ( bcx) , e) {
3470
3479
ret trans_lval ( bcx, e) ;
3471
3480
} else {
3472
3481
let tcx = bcx_tcx ( bcx) ;
@@ -3504,7 +3513,9 @@ fn trans_temp_expr(bcx: @block_ctxt, e: @ast::expr) -> result {
3504
3513
// - exprs with non-immediate type never get dest=by_val
3505
3514
fn trans_expr ( bcx : @block_ctxt , e : @ast:: expr , dest : dest ) -> @block_ctxt {
3506
3515
let tcx = bcx_tcx ( bcx) ;
3507
- if ty:: expr_is_lval ( tcx, e) { ret lval_to_dps ( bcx, e, dest) ; }
3516
+ if ty:: expr_is_lval ( bcx_ccx ( bcx) . method_map , tcx, e) {
3517
+ ret lval_to_dps ( bcx, e, dest) ;
3518
+ }
3508
3519
3509
3520
alt e. node {
3510
3521
ast:: expr_if ( cond, thn, els) | ast:: expr_if_check ( cond, thn, els) {
@@ -3544,7 +3555,9 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
3544
3555
ret trans_closure:: trans_bind ( bcx, f, args, e. id , dest) ;
3545
3556
}
3546
3557
ast:: expr_copy ( a) {
3547
- if !ty:: expr_is_lval ( tcx, a) { ret trans_expr ( bcx, a, dest) ; }
3558
+ if !ty:: expr_is_lval ( bcx_ccx ( bcx) . method_map , tcx, a) {
3559
+ ret trans_expr ( bcx, a, dest) ;
3560
+ }
3548
3561
else { ret lval_to_dps ( bcx, a, dest) ; }
3549
3562
}
3550
3563
ast:: expr_cast ( val, _) {
@@ -3945,7 +3958,8 @@ fn init_local(bcx: @block_ctxt, local: @ast::local) -> @block_ctxt {
3945
3958
alt local. node . init {
3946
3959
some ( init) {
3947
3960
if init. op == ast:: init_assign ||
3948
- !ty:: expr_is_lval ( bcx_tcx ( bcx) , init. expr ) {
3961
+ !ty:: expr_is_lval ( bcx_ccx ( bcx) . method_map , bcx_tcx ( bcx) ,
3962
+ init. expr ) {
3949
3963
bcx = trans_expr_save_in ( bcx, init. expr , llptr) ;
3950
3964
} else { // This is a move from an lval, must perform an actual move
3951
3965
let sub = trans_lval ( bcx, init. expr ) ;
@@ -4641,6 +4655,18 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
4641
4655
finish_fn ( fcx, lltop) ;
4642
4656
}
4643
4657
4658
+ fn trans_impl ( cx : @local_ctxt , name : ast:: ident , methods : [ @ast:: method ] ) {
4659
+ let sub_cx = extend_path ( cx, name) ;
4660
+ for m in methods {
4661
+ alt cx. ccx . item_ids . find ( m. node . id ) {
4662
+ some ( llfndecl) {
4663
+ trans_fn ( extend_path ( sub_cx, m. node . ident ) , m. span , m. node . meth ,
4664
+ llfndecl, none, [ ] , m. node . id ) ;
4665
+ }
4666
+ }
4667
+ }
4668
+ }
4669
+
4644
4670
4645
4671
// FIXME: this should do some structural hash-consing to avoid
4646
4672
// duplicate constants. I think. Maybe LLVM has a magical mode
@@ -4949,10 +4975,7 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
4949
4975
with * extend_path ( cx, item. ident ) } ;
4950
4976
trans_obj ( sub_cx, item. span , ob, ctor_id, tps) ;
4951
4977
}
4952
- ast:: item_impl ( _, _, _) {
4953
-
4954
- fail "FIXME[impl]" ;
4955
- }
4978
+ ast:: item_impl ( _, _, ms) { trans_impl ( cx, item. ident , ms) ; }
4956
4979
ast:: item_res ( dtor, dtor_id, tps, ctor_id) {
4957
4980
trans_res_ctor ( cx, item. span , dtor, ctor_id, tps) ;
4958
4981
@@ -5167,8 +5190,6 @@ fn raw_native_fn_type(ccx: @crate_ctxt, sp: span, args: [ty::arg],
5167
5190
ret T_fn ( type_of_explicit_args ( ccx, sp, args) , type_of ( ccx, sp, ret_ty) ) ;
5168
5191
}
5169
5192
5170
- fn item_path ( item : @ast:: item ) -> [ str ] { ret [ item. ident ] ; }
5171
-
5172
5193
fn link_name ( i : @ast:: native_item ) -> str {
5173
5194
alt attr:: get_meta_item_value_str_by_name ( i. attrs , "link_name" ) {
5174
5195
none. { ret i . ident ; }
@@ -5259,12 +5280,12 @@ fn collect_item_1(ccx: @crate_ctxt, abi: @mutable option::t<ast::native_abi>,
5259
5280
}
5260
5281
_ { }
5261
5282
}
5262
- visit:: visit_item ( i, pt + item_path ( i ) , v) ;
5283
+ visit:: visit_item ( i, pt + [ i . ident ] , v) ;
5263
5284
}
5264
5285
5265
5286
fn collect_item_2 ( ccx : @crate_ctxt , i : @ast:: item , & & pt: [ str ] ,
5266
5287
v : vt < [ str ] > ) {
5267
- let new_pt = pt + item_path ( i ) ;
5288
+ let new_pt = pt + [ i . ident ] ;
5268
5289
visit:: visit_item ( i, new_pt, v) ;
5269
5290
alt i. node {
5270
5291
ast:: item_fn ( f, tps) {
@@ -5278,6 +5299,13 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
5278
5299
ccx. obj_methods . insert ( m. node . id , ( ) ) ;
5279
5300
}
5280
5301
}
5302
+ ast:: item_impl ( _, _, methods) {
5303
+ let name = ccx. names . next ( i. ident ) ;
5304
+ for m in methods {
5305
+ register_fn ( ccx, i. span , pt + [ name, m. node . ident ] ,
5306
+ "impl_method" , [ ] , m. node . id ) ;
5307
+ }
5308
+ }
5281
5309
ast:: item_res ( _, dtor_id, tps, ctor_id) {
5282
5310
register_fn ( ccx, i. span , new_pt, "res_ctor" , tps, ctor_id) ;
5283
5311
// Note that the destructor is associated with the item's id, not
@@ -5307,7 +5335,7 @@ fn collect_items(ccx: @crate_ctxt, crate: @ast::crate) {
5307
5335
5308
5336
fn collect_tag_ctor ( ccx : @crate_ctxt , i : @ast:: item , & & pt: [ str ] ,
5309
5337
v : vt < [ str ] > ) {
5310
- let new_pt = pt + item_path ( i ) ;
5338
+ let new_pt = pt + [ i . ident ] ;
5311
5339
visit:: visit_item ( i, new_pt, v) ;
5312
5340
alt i. node {
5313
5341
ast:: item_tag ( variants, tps) {
@@ -5333,7 +5361,7 @@ fn collect_tag_ctors(ccx: @crate_ctxt, crate: @ast::crate) {
5333
5361
// The constant translation pass.
5334
5362
fn trans_constant ( ccx : @crate_ctxt , it : @ast:: item , & & pt: [ str ] ,
5335
5363
v : vt < [ str ] > ) {
5336
- let new_pt = pt + item_path ( it ) ;
5364
+ let new_pt = pt + [ it . ident ] ;
5337
5365
visit:: visit_item ( it, new_pt, v) ;
5338
5366
alt it. node {
5339
5367
ast:: item_tag ( variants, _) {
@@ -5520,7 +5548,7 @@ fn write_abi_version(ccx: @crate_ctxt) {
5520
5548
fn trans_crate ( sess : session:: session , crate : @ast:: crate , tcx : ty:: ctxt ,
5521
5549
output : str , emap : resolve:: exp_map , amap : ast_map:: map ,
5522
5550
mut_map : mut:: mut_map , copy_map : alias:: copy_map ,
5523
- last_uses : last_use:: last_uses )
5551
+ last_uses : last_use:: last_uses , method_map : typeck :: method_map )
5524
5552
-> ( ModuleRef , link:: link_meta ) {
5525
5553
let sha = std:: sha1:: mk_sha1 ( ) ;
5526
5554
let link_meta = link:: build_link_meta ( sess, * crate , output, sha) ;
@@ -5595,6 +5623,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
5595
5623
mut_map: mut_map,
5596
5624
copy_map: copy_map,
5597
5625
last_uses: last_uses,
5626
+ method_map: method_map,
5598
5627
stats :
5599
5628
{ mutable n_static_tydescs : 0 u,
5600
5629
mutable n_derived_tydescs : 0 u,
0 commit comments