@@ -329,6 +329,7 @@ type block_ctxt =
329
329
tag block_parent { parent_none; parent_some ( @block_ctxt) ; }
330
330
331
331
type result = rec ( @block_ctxt bcx , ValueRef val) ;
332
+ type result_t = rec ( @block_ctxt bcx , ValueRef val, ty:: t ty ) ;
332
333
333
334
fn extend_path ( @local_ctxt cx , & str name ) -> @local_ctxt {
334
335
ret @rec( path=cx. path + [ name] with * cx) ;
@@ -3320,18 +3321,16 @@ fn trans_unary(&@block_ctxt cx, ast::unop op, &@ast::expr e,
3320
3321
auto e_ty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ;
3321
3322
alt ( op) {
3322
3323
case ( ast:: not) {
3323
- sub =
3324
- autoderef( sub. bcx, sub. val,
3325
- ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ) ;
3326
- ret rslt( sub. bcx, sub. bcx. build. Not ( sub. val) ) ;
3324
+ auto dr = autoderef( sub. bcx, sub. val,
3325
+ ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ) ;
3326
+ ret rslt( dr. bcx, dr. bcx. build. Not ( dr. val) ) ;
3327
3327
}
3328
3328
case ( ast:: neg) {
3329
- sub =
3330
- autoderef( sub. bcx, sub. val,
3331
- ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ) ;
3329
+ auto dr = autoderef( sub. bcx, sub. val,
3330
+ ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ) ;
3332
3331
if ( ty:: struct ( cx. fcx. lcx. ccx. tcx, e_ty) == ty:: ty_float) {
3333
- ret rslt( sub . bcx, sub . bcx. build. FNeg ( sub . val) ) ;
3334
- } else { ret rslt( sub . bcx, sub. bcx. build. Neg ( sub . val) ) ; }
3332
+ ret rslt( dr . bcx, dr . bcx. build. FNeg ( dr . val) ) ;
3333
+ } else { ret rslt( dr . bcx, sub. bcx. build. Neg ( dr . val) ) ; }
3335
3334
}
3336
3335
case ( ast:: box( _) ) {
3337
3336
auto e_ty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, e) ;
@@ -3380,7 +3379,6 @@ fn trans_compare(&@block_ctxt cx0, ast::binop op, &ty::t t0, ValueRef lhs0,
3380
3379
auto rhs_r = autoderef( cx, rhs0, t0) ;
3381
3380
auto rhs = rhs_r. val;
3382
3381
cx = rhs_r. bcx;
3383
- auto t = ty:: type_autoderef( cx. fcx. lcx. ccx. tcx, t0) ;
3384
3382
// Determine the operation we need.
3385
3383
// FIXME: Use or-patterns when we have them.
3386
3384
@@ -3393,7 +3391,7 @@ fn trans_compare(&@block_ctxt cx0, ast::binop op, &ty::t t0, ValueRef lhs0,
3393
3391
case ( ast:: ge) { llop = C_u8 ( abi:: cmp_glue_op_lt) ; }
3394
3392
case ( ast:: gt) { llop = C_u8 ( abi:: cmp_glue_op_le) ; }
3395
3393
}
3396
- auto rs = compare( cx, lhs, rhs, t , llop) ;
3394
+ auto rs = compare( cx, lhs, rhs, rhs_r . ty , llop) ;
3397
3395
3398
3396
// Invert the result if necessary.
3399
3397
// FIXME: Use or-patterns when we have them.
@@ -4113,11 +4111,12 @@ fn trans_eager_binop(&@block_ctxt cx, ast::binop op, &ty::t intype,
4113
4111
}
4114
4112
4115
4113
fn autoderef_lval( & @block_ctxt cx, ValueRef v, & ty:: t t, bool is_lval)
4116
- -> result {
4114
+ -> result_t {
4117
4115
let ValueRef v1 = v;
4118
4116
let ty:: t t1 = t;
4117
+ auto ccx = cx. fcx. lcx. ccx;
4119
4118
while ( true) {
4120
- alt ( ty:: struct ( cx . fcx . lcx . ccx. tcx, t1) ) {
4119
+ alt ( ty:: struct ( ccx. tcx, t1) ) {
4121
4120
case ( ty:: ty_box( ?mt) ) {
4122
4121
// If we are working with an lval, we want to
4123
4122
// unconditionally load at the top of the loop
@@ -4132,24 +4131,41 @@ fn autoderef_lval(&@block_ctxt cx, ValueRef v, &ty::t t, bool is_lval)
4132
4131
// to cast this pointer, since statically-sized tag types have
4133
4132
// different types depending on whether they're behind a box
4134
4133
// or not.
4135
-
4136
- if ( !ty:: type_has_dynamic_size( cx. fcx. lcx. ccx. tcx, mt. ty) ) {
4137
- auto llty = type_of( cx. fcx. lcx. ccx, cx. sp, mt. ty) ;
4134
+ if ( !ty:: type_has_dynamic_size( ccx. tcx, mt. ty) ) {
4135
+ auto llty = type_of( ccx, cx. sp, mt. ty) ;
4138
4136
v1 = cx. build. PointerCast ( body, T_ptr ( llty) ) ;
4139
4137
} else { v1 = body; }
4140
-
4141
- // But if we aren't working with an lval, we get rid of
4142
- // a layer of indirection at the bottom of the loop so
4143
- // that it is gone when we return...
4144
- if ( !is_lval) { v1 = load_if_immediate( cx, v1, t1) ; }
4138
+ }
4139
+ case ( ty:: ty_res( ?did, ?inner, ?tps) ) {
4140
+ if ( is_lval) { v1 = cx. build. Load ( v1) ; }
4141
+ t1 = ty:: substitute_type_params( ccx. tcx, tps, inner) ;
4142
+ v1 = cx. build. GEP ( v1, [ C_int ( 0 ) , C_int ( 1 ) ] ) ;
4143
+ }
4144
+ case ( ty:: ty_tag( ?did, ?tps) ) {
4145
+ auto variants = ty:: tag_variants( ccx. tcx, did) ;
4146
+ if ( vec:: len( variants) != 1 u ||
4147
+ vec:: len( variants. ( 0 ) . args) != 1 u) {
4148
+ break ;
4149
+ }
4150
+ if ( is_lval) { v1 = cx. build. Load ( v1) ; }
4151
+ t1 = ty:: substitute_type_params
4152
+ ( ccx. tcx, tps, variants. ( 0 ) . args. ( 0 ) ) ;
4153
+ if ( !ty:: type_has_dynamic_size( ccx. tcx, t1) ) {
4154
+ v1 = cx. build. PointerCast
4155
+ ( v1, T_ptr ( type_of( ccx, cx. sp, t1) ) ) ;
4156
+ }
4145
4157
}
4146
4158
case ( _) { break ; }
4147
4159
}
4160
+ // But if we aren't working with an lval, we get rid of
4161
+ // a layer of indirection at the bottom of the loop so
4162
+ // that it is gone when we return...
4163
+ if ( !is_lval) { v1 = load_if_immediate( cx, v1, t1) ; }
4148
4164
}
4149
- ret rslt ( cx, v1 ) ;
4165
+ ret rec ( bcx= cx, val=v1 , ty=t1 ) ;
4150
4166
}
4151
4167
4152
- fn autoderef( & @block_ctxt cx, ValueRef v, & ty:: t t) -> result {
4168
+ fn autoderef( & @block_ctxt cx, ValueRef v, & ty:: t t) -> result_t {
4153
4169
ret autoderef_lval( cx, v, t, false) ;
4154
4170
}
4155
4171
@@ -4160,15 +4176,14 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, &@ast::expr a, &@ast::expr b)
4160
4176
alt ( op) {
4161
4177
case ( ast:: and) {
4162
4178
// Lazy-eval and
4163
-
4164
- auto lhs_res = trans_expr( cx, a) ;
4165
- lhs_res =
4166
- autoderef( lhs_res. bcx, lhs_res. val,
4179
+ auto lhs_expr = trans_expr( cx, a) ;
4180
+ auto lhs_res =
4181
+ autoderef( lhs_expr. bcx, lhs_expr. val,
4167
4182
ty:: expr_ty( cx. fcx. lcx. ccx. tcx, a) ) ;
4168
4183
auto rhs_cx = new_scope_block_ctxt( cx, "rhs") ;
4169
- auto rhs_res = trans_expr( rhs_cx, b) ;
4170
- rhs_res =
4171
- autoderef( rhs_res . bcx, rhs_res . val,
4184
+ auto rhs_expr = trans_expr( rhs_cx, b) ;
4185
+ auto rhs_res =
4186
+ autoderef( rhs_expr . bcx, rhs_expr . val,
4172
4187
ty:: expr_ty( cx. fcx. lcx. ccx. tcx, b) ) ;
4173
4188
auto lhs_false_cx = new_scope_block_ctxt( cx, "lhs false") ;
4174
4189
auto lhs_false_res = rslt( lhs_false_cx, C_bool ( false) ) ;
@@ -4181,20 +4196,18 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, &@ast::expr a, &@ast::expr b)
4181
4196
lhs_res. bcx. build. CondBr ( lhs_res. val, rhs_cx. llbb,
4182
4197
lhs_false_cx. llbb) ;
4183
4198
ret join_results( cx, T_bool ( ) ,
4184
- [ lhs_false_res, rec( bcx=rhs_bcx with rhs_res) ] ) ;
4199
+ [ lhs_false_res, rec( bcx=rhs_bcx,
4200
+ val=rhs_res. val) ] ) ;
4185
4201
}
4186
4202
case ( ast:: or) {
4187
4203
// Lazy-eval or
4188
-
4189
- auto lhs_res = trans_expr( cx, a) ;
4190
- lhs_res =
4191
- autoderef( lhs_res. bcx, lhs_res. val,
4192
- ty:: expr_ty( cx. fcx. lcx. ccx. tcx, a) ) ;
4204
+ auto lhs_expr = trans_expr( cx, a) ;
4205
+ auto lhs_res = autoderef( lhs_expr. bcx, lhs_expr. val,
4206
+ ty:: expr_ty( cx. fcx. lcx. ccx. tcx, a) ) ;
4193
4207
auto rhs_cx = new_scope_block_ctxt( cx, "rhs") ;
4194
- auto rhs_res = trans_expr( rhs_cx, b) ;
4195
- rhs_res =
4196
- autoderef( rhs_res. bcx, rhs_res. val,
4197
- ty:: expr_ty( cx. fcx. lcx. ccx. tcx, b) ) ;
4208
+ auto rhs_expr = trans_expr( rhs_cx, b) ;
4209
+ auto rhs_res = autoderef( rhs_expr. bcx, rhs_expr. val,
4210
+ ty:: expr_ty( cx. fcx. lcx. ccx. tcx, b) ) ;
4198
4211
auto lhs_true_cx = new_scope_block_ctxt( cx, "lhs true") ;
4199
4212
auto lhs_true_res = rslt( lhs_true_cx, C_bool ( true) ) ;
4200
4213
// see the and case for an explanation
@@ -4203,19 +4216,19 @@ fn trans_binary(&@block_ctxt cx, ast::binop op, &@ast::expr a, &@ast::expr b)
4203
4216
lhs_res. bcx. build. CondBr ( lhs_res. val, lhs_true_cx. llbb,
4204
4217
rhs_cx. llbb) ;
4205
4218
ret join_results( cx, T_bool ( ) ,
4206
- [ lhs_true_res, rec( bcx=rhs_bcx with rhs_res) ] ) ;
4219
+ [ lhs_true_res, rec( bcx=rhs_bcx,
4220
+ val=rhs_res. val) ] ) ;
4207
4221
}
4208
4222
case ( _) {
4209
4223
// Remaining cases are eager:
4210
4224
4211
- auto lhs = trans_expr( cx, a) ;
4225
+ auto lhs_expr = trans_expr( cx, a) ;
4212
4226
auto lhty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, a) ;
4213
- lhs = autoderef( lhs . bcx, lhs . val, lhty) ;
4214
- auto rhs = trans_expr( lhs. bcx, b) ;
4227
+ auto lhs = autoderef( lhs_expr . bcx, lhs_expr . val, lhty) ;
4228
+ auto rhs_expr = trans_expr( lhs. bcx, b) ;
4215
4229
auto rhty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, b) ;
4216
- rhs = autoderef( rhs. bcx, rhs. val, rhty) ;
4217
- ret trans_eager_binop( rhs. bcx, op,
4218
- ty:: type_autoderef( cx. fcx. lcx. ccx. tcx, lhty) ,
4230
+ auto rhs = autoderef( rhs_expr. bcx, rhs_expr. val, rhty) ;
4231
+ ret trans_eager_binop( rhs. bcx, op, lhs. ty,
4219
4232
lhs. val, rhs. val) ;
4220
4233
}
4221
4234
}
@@ -4931,7 +4944,7 @@ fn trans_path(&@block_ctxt cx, &ast::path p, ast::node_id id) -> lval_result {
4931
4944
fn trans_field( & @block_ctxt cx, & span sp, ValueRef v, & ty:: t t0,
4932
4945
& ast:: ident field, ast:: node_id id) -> lval_result {
4933
4946
auto r = autoderef( cx, v, t0) ;
4934
- auto t = ty :: type_autoderef ( cx . fcx . lcx . ccx . tcx , t0 ) ;
4947
+ auto t = r . ty ;
4935
4948
alt ( ty:: struct ( cx. fcx. lcx. ccx. tcx, t) ) {
4936
4949
case ( ty:: ty_tup( _) ) {
4937
4950
let uint ix = ty:: field_num( cx. fcx. lcx. ccx. sess, sp, field) ;
@@ -4971,11 +4984,11 @@ fn trans_index(&@block_ctxt cx, &span sp, &@ast::expr base, &@ast::expr idx,
4971
4984
// Is this an interior vector?
4972
4985
4973
4986
auto base_ty = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, base) ;
4974
- auto base_ty_no_boxes = ty:: strip_boxes( cx. fcx. lcx. ccx. tcx, base_ty) ;
4987
+ auto exp = trans_expr( cx, base) ;
4988
+ auto lv = autoderef( exp. bcx, exp. val, base_ty) ;
4989
+ auto base_ty_no_boxes = lv. ty;
4975
4990
auto is_interior =
4976
4991
ty:: sequence_is_interior( cx. fcx. lcx. ccx. tcx, base_ty_no_boxes) ;
4977
- auto lv = trans_expr( cx, base) ;
4978
- lv = autoderef( lv. bcx, lv. val, base_ty) ;
4979
4992
auto ix = trans_expr( lv. bcx, idx) ;
4980
4993
auto v = lv. val;
4981
4994
auto bcx = ix. bcx;
@@ -5056,14 +5069,29 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result {
5056
5069
ret trans_index( cx, e. span, base, idx, e. id) ;
5057
5070
}
5058
5071
case ( ast:: expr_unary( ?unop, ?base) ) {
5072
+ auto ccx = cx. fcx. lcx. ccx;
5059
5073
assert ( unop == ast:: deref) ;
5060
5074
auto sub = trans_expr( cx, base) ;
5061
- auto t = ty:: expr_ty( cx. fcx. lcx. ccx. tcx, base) ;
5062
- auto offset = alt ( ty:: struct ( cx. fcx. lcx. ccx. tcx, t) ) {
5063
- case ( ty:: ty_box( _) ) { abi:: box_rc_field_body }
5064
- case ( ty:: ty_res( _, _, _) ) { 1 }
5075
+ auto t = ty:: expr_ty( ccx. tcx, base) ;
5076
+ auto val = alt ( ty:: struct ( ccx. tcx, t) ) {
5077
+ case ( ty:: ty_box( _) ) {
5078
+ sub. bcx. build. GEP
5079
+ ( sub. val, [ C_int ( 0 ) , C_int ( abi:: box_rc_field_body) ] )
5080
+ }
5081
+ case ( ty:: ty_res( _, _, _) ) {
5082
+ sub. bcx. build. GEP ( sub. val, [ C_int ( 0 ) , C_int ( 1 ) ] )
5083
+ }
5084
+ case ( ty:: ty_tag( _, _) ) {
5085
+ auto ety = ty:: expr_ty( ccx. tcx, e) ;
5086
+ auto ellty;
5087
+ if ( ty:: type_has_dynamic_size( ccx. tcx, ety) ) {
5088
+ ellty = T_typaram_ptr ( ccx. tn) ;
5089
+ } else {
5090
+ ellty = T_ptr ( type_of( ccx, e. span, ety) ) ;
5091
+ } ;
5092
+ sub. bcx. build. PointerCast ( sub. val, ellty)
5093
+ }
5065
5094
} ;
5066
- auto val = sub. bcx. build. GEP ( sub. val, [ C_int ( 0 ) , C_int ( offset) ] ) ;
5067
5095
ret lval_mem( sub. bcx, val) ;
5068
5096
}
5069
5097
case ( ast:: expr_self_method( ?ident) ) {
@@ -5692,7 +5720,7 @@ fn trans_call(&@block_ctxt cx, &@ast::expr f, &option::t[ValueRef] lliterbody,
5692
5720
// It's a closure. We have to autoderef.
5693
5721
auto res = autoderef_lval( bcx, f_res. res. val, fn_ty, true) ;
5694
5722
bcx = res. bcx;
5695
- fn_ty = ty :: type_autoderef ( bcx . fcx . lcx . ccx . tcx , fn_ty ) ;
5723
+ fn_ty = res . ty ;
5696
5724
5697
5725
auto pair = res. val;
5698
5726
faddr =
0 commit comments