@@ -2072,7 +2072,19 @@ fn node_type(cx: @crate_ctxt, sp: span, id: ast::node_id) -> TypeRef {
2072
2072
}
2073
2073
2074
2074
fn trans_unary ( bcx : @block_ctxt , op : ast:: unop , e : @ast:: expr ,
2075
- id : ast:: node_id , dest : dest ) -> @block_ctxt {
2075
+ un_expr : @ast:: expr , dest : dest ) -> @block_ctxt {
2076
+ // Check for user-defined method call
2077
+ alt bcx_ccx ( bcx) . method_map . find ( un_expr. id ) {
2078
+ some ( origin) {
2079
+ let callee_id = ast_util:: op_expr_callee_id ( un_expr) ;
2080
+ let fty = ty:: node_id_to_monotype ( bcx_tcx ( bcx) , callee_id) ;
2081
+ ret trans_call_inner ( bcx, fty, { |bcx|
2082
+ trans_impl:: trans_method_callee ( bcx, callee_id, e, origin)
2083
+ } , [ ] , un_expr. id , dest) ;
2084
+ }
2085
+ _ { }
2086
+ }
2087
+
2076
2088
if dest == ignore { ret trans_expr ( bcx, e, ignore) ; }
2077
2089
let e_ty = ty:: expr_ty ( bcx_tcx ( bcx) , e) ;
2078
2090
alt op {
@@ -2104,7 +2116,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
2104
2116
ret store_in_dest ( bcx, box, dest) ;
2105
2117
}
2106
2118
ast:: uniq ( _) {
2107
- ret trans_uniq:: trans_uniq ( bcx, e, id, dest) ;
2119
+ ret trans_uniq:: trans_uniq ( bcx, e, un_expr . id , dest) ;
2108
2120
}
2109
2121
ast:: deref {
2110
2122
bcx_ccx( bcx) . sess . bug ( "deref expressions should have been \
@@ -2193,12 +2205,26 @@ fn trans_eager_binop(cx: @block_ctxt, op: ast::binop, lhs: ValueRef,
2193
2205
ret store_in_dest ( cx, val, dest) ;
2194
2206
}
2195
2207
2196
- fn trans_assign_op ( bcx : @block_ctxt , op : ast:: binop , dst : @ ast:: expr ,
2197
- src : @ast:: expr ) -> @block_ctxt {
2208
+ fn trans_assign_op ( bcx : @block_ctxt , ex : @ ast:: expr , op : ast:: binop ,
2209
+ dst : @ast :: expr , src : @ast:: expr ) -> @block_ctxt {
2198
2210
let tcx = bcx_tcx ( bcx) ;
2199
2211
let t = ty:: expr_ty ( tcx, src) ;
2200
2212
let lhs_res = trans_lval ( bcx, dst) ;
2201
2213
assert ( lhs_res. kind == owned) ;
2214
+
2215
+ // A user-defined operator method
2216
+ alt bcx_ccx( bcx) . method_map . find ( ex. id ) {
2217
+ some ( origin) {
2218
+ let callee_id = ast_util:: op_expr_callee_id ( ex) ;
2219
+ let fty = ty:: node_id_to_monotype ( bcx_tcx ( bcx) , callee_id) ;
2220
+ ret trans_call_inner ( bcx, fty, { |bcx|
2221
+ // FIXME provide the already-computed address, not the expr
2222
+ trans_impl:: trans_method_callee ( bcx, callee_id, src, origin)
2223
+ } , [ dst] , ex. id , save_in ( lhs_res. val ) ) ;
2224
+ }
2225
+ _ { }
2226
+ }
2227
+
2202
2228
// Special case for `+= [x]`
2203
2229
alt ty:: struct ( tcx, t) {
2204
2230
ty:: ty_vec ( _) {
@@ -2305,20 +2331,34 @@ fn trans_lazy_binop(bcx: @block_ctxt, op: ast::binop, a: @ast::expr,
2305
2331
ret store_in_dest ( join_cx, phi, dest) ;
2306
2332
}
2307
2333
2308
- fn trans_binary ( cx : @block_ctxt , op : ast:: binop , a : @ast:: expr , b : @ast:: expr ,
2309
- dest : dest ) -> @block_ctxt {
2334
+
2335
+
2336
+ fn trans_binary ( bcx : @block_ctxt , op : ast:: binop , a : @ast:: expr ,
2337
+ b : @ast:: expr , dest : dest , ex : @ast:: expr ) -> @block_ctxt {
2338
+ // User-defined operators
2339
+ alt bcx_ccx ( bcx) . method_map . find ( ex. id ) {
2340
+ some ( origin) {
2341
+ let callee_id = ast_util:: op_expr_callee_id ( ex) ;
2342
+ let fty = ty:: node_id_to_monotype ( bcx_tcx ( bcx) , callee_id) ;
2343
+ ret trans_call_inner ( bcx, fty, { |bcx|
2344
+ trans_impl:: trans_method_callee ( bcx, callee_id, a, origin)
2345
+ } , [ b] , ex. id , dest) ;
2346
+ }
2347
+ _ { }
2348
+ }
2349
+
2310
2350
// First couple cases are lazy:
2311
2351
alt op {
2312
2352
ast : : and | ast:: or {
2313
- ret trans_lazy_binop( cx , op, a, b, dest) ;
2353
+ ret trans_lazy_binop( bcx , op, a, b, dest) ;
2314
2354
}
2315
2355
_ {
2316
2356
// Remaining cases are eager:
2317
- let lhs = trans_temp_expr ( cx , a) ;
2357
+ let lhs = trans_temp_expr ( bcx , a) ;
2318
2358
let rhs = trans_temp_expr ( lhs. bcx , b) ;
2319
2359
ret trans_eager_binop ( rhs. bcx , op, lhs. val ,
2320
- ty:: expr_ty ( bcx_tcx ( cx ) , a) , rhs. val ,
2321
- ty:: expr_ty ( bcx_tcx ( cx ) , b) , dest) ;
2360
+ ty:: expr_ty ( bcx_tcx ( bcx ) , a) , rhs. val ,
2361
+ ty:: expr_ty ( bcx_tcx ( bcx ) , b) , dest) ;
2322
2362
}
2323
2363
}
2324
2364
}
@@ -2746,15 +2786,8 @@ fn trans_callee(bcx: @block_ctxt, e: @ast::expr) -> lval_maybe_callee {
2746
2786
// Lval means this is a record field, so not a method
2747
2787
if !expr_is_lval ( bcx, e) {
2748
2788
alt bcx_ccx ( bcx) . method_map . find ( e. id ) {
2749
- some ( typeck:: method_static ( did) ) { // An impl method
2750
- ret trans_impl:: trans_static_callee ( bcx, e, base, did) ;
2751
- }
2752
- some ( typeck:: method_param ( iid, off, p, b) ) {
2753
- ret trans_impl:: trans_param_callee (
2754
- bcx, e, base, iid, off, p, b) ;
2755
- }
2756
- some ( typeck:: method_iface ( off) ) {
2757
- ret trans_impl:: trans_iface_callee ( bcx, e, base, off) ;
2789
+ some ( origin) { // An impl method
2790
+ ret trans_impl:: trans_method_callee ( bcx, e. id , base, origin) ;
2758
2791
}
2759
2792
}
2760
2793
}
@@ -3132,15 +3165,22 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef,
3132
3165
fn trans_call ( in_cx : @block_ctxt , f : @ast:: expr ,
3133
3166
args : [ @ast:: expr ] , id : ast:: node_id , dest : dest )
3134
3167
-> @block_ctxt {
3168
+ trans_call_inner ( in_cx, ty:: expr_ty ( bcx_tcx ( in_cx) , f) ,
3169
+ { |cx| trans_callee ( cx, f) } , args, id, dest)
3170
+ }
3171
+
3172
+ fn trans_call_inner ( in_cx : @block_ctxt , fn_expr_ty : ty:: t ,
3173
+ get_callee : fn ( @block_ctxt ) -> lval_maybe_callee ,
3174
+ args : [ @ast:: expr ] , id : ast:: node_id , dest : dest )
3175
+ -> @block_ctxt {
3135
3176
// NB: 'f' isn't necessarily a function; it might be an entire self-call
3136
3177
// expression because of the hack that allows us to process self-calls
3137
3178
// with trans_call.
3138
3179
let tcx = bcx_tcx ( in_cx) ;
3139
- let fn_expr_ty = ty:: expr_ty ( tcx, f) ;
3140
3180
3141
3181
let cx = new_scope_block_ctxt ( in_cx, "call" ) ;
3142
3182
Br ( in_cx, cx. llbb ) ;
3143
- let f_res = trans_callee ( cx, f ) ;
3183
+ let f_res = get_callee ( cx) ;
3144
3184
let bcx = f_res. bcx ;
3145
3185
3146
3186
let faddr = f_res. val ;
@@ -3478,10 +3518,12 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
3478
3518
ast:: expr_tup ( args) { ret trans_tup ( bcx, args, e. id , dest) ; }
3479
3519
ast:: expr_lit ( lit) { ret trans_lit ( bcx, * lit, dest) ; }
3480
3520
ast:: expr_vec ( args, _) { ret tvec:: trans_vec ( bcx, args, e. id , dest) ; }
3481
- ast:: expr_binary ( op, x, y) { ret trans_binary ( bcx, op, x, y, dest) ; }
3521
+ ast:: expr_binary ( op, x, y) {
3522
+ ret trans_binary ( bcx, op, x, y, dest, e) ;
3523
+ }
3482
3524
ast:: expr_unary ( op, x) {
3483
3525
assert op != ast:: deref; // lvals are handled above
3484
- ret trans_unary ( bcx, op, x, e. id , dest) ;
3526
+ ret trans_unary ( bcx, op, x, e, dest) ;
3485
3527
}
3486
3528
ast:: expr_fn ( proto, decl, body, cap_clause) {
3487
3529
ret trans_closure:: trans_expr_fn (
@@ -3620,7 +3662,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
3620
3662
}
3621
3663
ast:: expr_assign_op ( op, dst, src) {
3622
3664
assert dest == ignore;
3623
- ret trans_assign_op ( bcx, op, dst, src) ;
3665
+ ret trans_assign_op ( bcx, e , op, dst, src) ;
3624
3666
}
3625
3667
}
3626
3668
}
0 commit comments