@@ -3973,6 +3973,21 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
3973
3973
}
3974
3974
let ty_fields: [ ty:: field ] = [ ] ;
3975
3975
alt ty:: struct ( bcx_tcx ( cx) , t) { ty:: ty_rec ( flds) { ty_fields = flds; } }
3976
+
3977
+ tag fieldsrc {
3978
+ provided( lval_result) ;
3979
+ inherited ( ValueRef ) ;
3980
+ }
3981
+ type fieldval = {
3982
+ dst: ValueRef ,
3983
+ src: fieldsrc,
3984
+ ty: ty:: t
3985
+ } ;
3986
+ let fieldvals: [ fieldval ] = [ ] ;
3987
+
3988
+ // We build the record in two stages so that we don't have to clean up a
3989
+ // partial record if we fail: first collect all the values, then construct
3990
+ // the record.
3976
3991
for tf: ty:: field in ty_fields {
3977
3992
let e_ty = tf. mt . ty ;
3978
3993
// FIXME: constraint on argument?
@@ -3984,21 +3999,43 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
3984
3999
if str:: eq ( f. node . ident , tf. ident ) {
3985
4000
expr_provided = true ;
3986
4001
let lv = trans_lval ( bcx, f. node . expr ) ;
3987
- bcx =
3988
- move_val_if_temp ( lv. bcx , INIT , dst_res. val , lv, e_ty) ;
4002
+ bcx = lv. bcx ;
4003
+ fieldvals += [ {
4004
+ dst: dst_res. val ,
4005
+ src: provided ( lv) ,
4006
+ ty: e_ty
4007
+ } ] ;
3989
4008
break ;
3990
4009
}
3991
4010
}
3992
4011
if !expr_provided {
3993
4012
// FIXME: constraint on argument?
3994
4013
check type_is_tup_like ( bcx, t) ;
3995
4014
let src_res = GEP_tup_like ( bcx, t, base_val, [ 0 , i] ) ;
3996
- src_res =
3997
- rslt ( src_res. bcx , load_if_immediate ( bcx, src_res. val , e_ty) ) ;
3998
- bcx = copy_val ( src_res. bcx , INIT , dst_res. val , src_res. val , e_ty) ;
4015
+ bcx = src_res. bcx ;
4016
+ fieldvals += [ {
4017
+ dst: dst_res. val ,
4018
+ src: inherited ( src_res. val ) ,
4019
+ ty: e_ty
4020
+ } ] ;
3999
4021
}
4000
4022
i += 1 ;
4001
4023
}
4024
+
4025
+ // Now build the record
4026
+ for fieldval in fieldvals {
4027
+ alt fieldval. src {
4028
+ provided ( lv) {
4029
+ bcx = move_val_if_temp ( bcx, INIT , fieldval. dst ,
4030
+ lv, fieldval. ty ) ;
4031
+ }
4032
+ inherited ( val) {
4033
+ let val = load_if_immediate ( bcx, val, fieldval. ty ) ;
4034
+ bcx = copy_val ( bcx, INIT , fieldval. dst , val, fieldval. ty ) ;
4035
+ }
4036
+ }
4037
+ }
4038
+
4002
4039
add_clean_temp ( cx, rec_val, t) ;
4003
4040
ret rslt( bcx, rec_val) ;
4004
4041
}
0 commit comments