@@ -2366,6 +2366,7 @@ fn trans_assign_op(bcx: @block_ctxt, op: ast::binop, dst: @ast::expr,
2366
2366
_ { }
2367
2367
}
2368
2368
}
2369
+
2369
2370
ret trans_eager_binop( bcx, op, Load ( bcx, lhs_res. val ) , t, rhs_val, t,
2370
2371
save_in ( lhs_res. val ) ) ;
2371
2372
}
@@ -3148,49 +3149,54 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
3148
3149
}
3149
3150
}
3150
3151
3151
- fn trans_object_field ( bcx : @block_ctxt , o : @ast :: expr , field : ast:: ident )
3152
- -> { bcx : @ block_ctxt , mthptr : ValueRef , objptr : ValueRef } {
3153
- let { bcx, val} = trans_expr ( bcx , o ) ;
3154
- let { bcx, val , ty } = autoderef ( bcx , val, ty:: expr_ty ( bcx_tcx ( bcx ) , o ) ) ;
3155
- ret trans_object_field_inner ( bcx , val , field , ty ) ;
3152
+ fn trans_field ( cx : @block_ctxt , sp : span , base : @ ast:: expr ,
3153
+ field : ast :: ident ) -> lval_maybe_callee {
3154
+ let { bcx, val} = trans_expr ( cx , base ) ;
3155
+ ret trans_field_inner ( bcx, sp , val, ty:: expr_ty ( bcx_tcx ( cx ) , base ) ,
3156
+ field ) ;
3156
3157
}
3157
3158
3158
- fn trans_object_field_inner ( bcx : @block_ctxt , o : ValueRef ,
3159
- field : ast:: ident , o_ty : ty:: t )
3160
- -> { bcx : @block_ctxt , mthptr : ValueRef , objptr : ValueRef } {
3161
- let ccx = bcx_ccx ( bcx) , tcx = ccx. tcx ;
3162
- let mths = alt ty:: struct ( tcx, o_ty) { ty:: ty_obj ( ms) { ms } } ;
3163
-
3164
- let ix = ty:: method_idx ( ccx. sess , bcx. sp , field, mths) ;
3165
- let vtbl = Load ( bcx, GEP ( bcx, o, [ C_int ( 0 ) , C_int ( abi:: obj_field_vtbl) ] ) ) ;
3166
- let vtbl_type = T_ptr ( T_array ( T_ptr ( T_nil ( ) ) , ix + 1 u) ) ;
3167
- vtbl = PointerCast ( bcx, vtbl, vtbl_type) ;
3159
+ fn trans_field_inner ( cx : @block_ctxt , sp : span , v : ValueRef , t0 : ty:: t ,
3160
+ field : ast:: ident ) -> lval_maybe_callee {
3161
+ let r = autoderef ( cx, v, t0) ;
3162
+ let t = r. ty ;
3163
+ alt ty:: struct ( bcx_tcx ( cx) , t) {
3164
+ ty:: ty_rec ( fields) {
3165
+ let ix: uint = ty:: field_idx ( bcx_ccx ( cx) . sess , sp, field, fields) ;
3166
+ let r_bcx = r. bcx ;
3167
+ // Silly check
3168
+ check type_is_tup_like ( r_bcx, t) ;
3169
+ let v = GEP_tup_like ( r_bcx, t, r. val , [ 0 , ix as int ] ) ;
3170
+ ret lval_no_env ( v. bcx , v. val , true ) ;
3171
+ }
3172
+ ty:: ty_obj ( methods) {
3173
+ let ix: uint = ty:: method_idx ( bcx_ccx ( cx) . sess , sp, field, methods) ;
3174
+ let vtbl = GEP ( r. bcx , r. val , [ C_int ( 0 ) , C_int ( abi:: obj_field_vtbl) ] ) ;
3175
+ vtbl = Load ( r. bcx , vtbl) ;
3168
3176
3169
- let v = GEP ( bcx, vtbl, [ C_int ( 0 ) , C_int ( ix as int ) ] ) ;
3170
- let fn_ty: ty:: t = ty:: method_ty_to_fn_ty ( tcx, mths[ ix] ) ;
3171
- let ret_ty = ty:: ty_fn_ret ( tcx, fn_ty) ;
3172
- let ret_ref = ast_util:: ret_by_ref ( ty:: ty_fn_ret_style ( tcx, fn_ty) ) ;
3173
- // FIXME: constrain ty_obj?
3174
- check non_ty_var( ccx, ret_ty) ;
3177
+ let vtbl_type = T_ptr ( T_array ( T_ptr ( T_nil ( ) ) , ix + 1 u) ) ;
3178
+ vtbl = PointerCast ( cx, vtbl, vtbl_type) ;
3175
3179
3176
- let ll_fn_ty = type_of_fn ( ccx, bcx. sp , ty:: ty_fn_proto ( tcx, fn_ty) ,
3177
- true , ret_ref, ty:: ty_fn_args ( tcx, fn_ty) ,
3178
- ret_ty, 0 u) ;
3179
- v = Load ( bcx, PointerCast ( bcx, v, T_ptr ( T_ptr ( ll_fn_ty) ) ) ) ;
3180
- ret { bcx : bcx, mthptr : v, objptr : o} ;
3181
- }
3180
+ let v = GEP ( r. bcx , vtbl, [ C_int ( 0 ) , C_int ( ix as int ) ] ) ;
3181
+ let tcx = bcx_tcx ( cx) ;
3182
+ let ccx = bcx_ccx ( cx) ;
3182
3183
3184
+ let fn_ty: ty:: t = ty:: method_ty_to_fn_ty ( tcx, methods[ ix] ) ;
3185
+ let ret_ty = ty:: ty_fn_ret ( tcx, fn_ty) ;
3186
+ let ret_ref = ast_util:: ret_by_ref ( ty:: ty_fn_ret_style ( tcx, fn_ty) ) ;
3187
+ // FIXME: constrain ty_obj?
3188
+ check non_ty_var( ccx, ret_ty) ;
3183
3189
3184
- fn trans_rec_field ( bcx : @ block_ctxt , base : @ast :: expr ,
3185
- field : ast :: ident ) -> lval_result {
3186
- let { bcx , val } = trans_expr ( bcx , base ) ;
3187
- let { bcx , val , ty } = autoderef ( bcx , val , ty :: expr_ty ( bcx_tcx ( bcx ) , base ) ) ;
3188
- let fields = alt ty :: struct ( bcx_tcx ( bcx) , ty ) { ty :: ty_rec ( fs ) { fs } } ;
3189
- let ix = ty :: field_idx ( bcx_ccx ( bcx ) . sess , bcx. sp , field , fields ) ;
3190
- // Silly check
3191
- check type_is_tup_like ( bcx , ty ) ;
3192
- let { bcx , val } = GEP_tup_like ( bcx , ty , val , [ 0 , ix as int ] ) ;
3193
- ret { bcx : bcx , val : val , is_mem : true } ;
3190
+ let ll_fn_ty =
3191
+ type_of_fn ( ccx , sp , ty :: ty_fn_proto ( tcx , fn_ty ) ,
3192
+ true , ret_ref , ty :: ty_fn_args ( tcx , fn_ty ) ,
3193
+ ret_ty , 0 u ) ;
3194
+ v = Load ( r . bcx , PointerCast ( r . bcx , v , T_ptr ( T_ptr ( ll_fn_ty ) ) ) ) ;
3195
+ ret { bcx : r . bcx , val : v , is_mem : true ,
3196
+ env : obj_env ( r . val ) , generic : none } ;
3197
+ }
3198
+ _ { bcx_ccx ( cx ) . sess . unimpl ( "field variant in trans_field" ) ; }
3199
+ }
3194
3200
}
3195
3201
3196
3202
fn trans_index ( cx : @block_ctxt , sp : span , base : @ast:: expr , idx : @ast:: expr ,
@@ -3242,30 +3248,24 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr,
3242
3248
ret lval_mem( next_cx, elt) ;
3243
3249
}
3244
3250
3245
- fn trans_callee ( bcx : @block_ctxt , e : @ast:: expr ) -> lval_maybe_callee {
3251
+ fn trans_callee ( cx : @block_ctxt , e : @ast:: expr ) -> lval_maybe_callee {
3246
3252
alt e. node {
3247
- ast:: expr_path ( p) { ret trans_path ( bcx , p, e. id ) ; }
3253
+ ast:: expr_path ( p) { ret trans_path ( cx , p, e. id ) ; }
3248
3254
ast:: expr_field ( base, ident) {
3249
- // Lval means record field, so not a method
3250
- if !expr_is_lval ( bcx_tcx ( bcx) , e) {
3251
- let of = trans_object_field ( bcx, base, ident) ;
3252
- ret { bcx : of. bcx , val : of. mthptr , is_mem : true ,
3253
- env : obj_env ( of. objptr ) , generic : none} ;
3254
- }
3255
+ ret trans_field ( cx, e. span , base, ident) ;
3255
3256
}
3256
3257
ast:: expr_self_method ( ident) {
3257
- alt bcx . fcx . llself {
3258
+ alt cx . fcx . llself {
3258
3259
some ( pair) {
3259
- let fld = trans_object_field_inner ( bcx, pair. v , ident, pair. t ) ;
3260
- ret { bcx : fld. bcx , val : fld. mthptr , is_mem : true ,
3261
- env : obj_env ( fld. objptr ) , generic : none} ;
3260
+ ret trans_field_inner ( cx, e. span , pair. v , pair. t , ident) ;
3262
3261
}
3263
3262
}
3264
3263
}
3265
- _ { }
3264
+ _ {
3265
+ let lv = trans_lval ( cx, e) ;
3266
+ ret lval_no_env ( lv. bcx , lv. val , lv. is_mem ) ;
3267
+ }
3266
3268
}
3267
- let lv = trans_lval ( bcx, e) ;
3268
- ret lval_no_env ( lv. bcx , lv. val , lv. is_mem ) ;
3269
3269
}
3270
3270
3271
3271
fn expr_is_lval ( tcx : ty:: ctxt , e : @ast:: expr ) -> bool {
@@ -3298,7 +3298,8 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
3298
3298
ret lval_maybe_callee_to_lval ( v, ty:: expr_ty ( bcx_tcx ( cx) , e) ) ;
3299
3299
}
3300
3300
ast:: expr_field ( base, ident) {
3301
- ret trans_rec_field ( cx, base, ident) ;
3301
+ let f = trans_field ( cx, e. span , base, ident) ;
3302
+ ret lval_maybe_callee_to_lval ( f, ty:: expr_ty ( bcx_tcx ( cx) , e) ) ;
3302
3303
}
3303
3304
ast:: expr_index ( base, idx) {
3304
3305
ret trans_index ( cx, e. span , base, idx, e. id ) ;
@@ -4324,8 +4325,9 @@ fn trans_expr_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest)
4324
4325
ast:: expr_call ( f, args) {
4325
4326
ret trans_call ( bcx, f, none, args, e. id , dest) ;
4326
4327
}
4328
+ // FIXME[DPS] untangle non-lval fields from trans_lval
4327
4329
ast:: expr_field ( _, _) {
4328
- fail "Taking the value of a method does not work yet (issue #435)" ;
4330
+ ret lval_to_dps ( bcx , e , dest ) ;
4329
4331
}
4330
4332
4331
4333
// These return nothing
0 commit comments