@@ -746,12 +746,12 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
746
746
controlflow:: trans_block ( bcx, & * * blk, dest)
747
747
}
748
748
ast:: ExprStruct ( _, ref fields, base) => {
749
- trans_rec_or_struct ( bcx,
750
- fields. as_slice ( ) ,
751
- base,
752
- expr. span ,
753
- expr. id ,
754
- dest)
749
+ trans_struct ( bcx,
750
+ fields. as_slice ( ) ,
751
+ base,
752
+ expr. span ,
753
+ expr. id ,
754
+ dest)
755
755
}
756
756
ast:: ExprTup ( ref args) => {
757
757
let repr = adt:: represent_type ( bcx. ccx ( ) , expr_ty ( bcx, expr) ) ;
@@ -1042,16 +1042,13 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
1042
1042
}
1043
1043
}
1044
1044
1045
- fn trans_rec_or_struct < ' a > (
1046
- bcx : & ' a Block < ' a > ,
1047
- fields : & [ ast:: Field ] ,
1048
- base : Option < Gc < ast:: Expr > > ,
1049
- expr_span : codemap:: Span ,
1050
- id : ast:: NodeId ,
1051
- dest : Dest )
1052
- -> & ' a Block < ' a > {
1045
+ fn trans_struct < ' a > ( bcx : & ' a Block < ' a > ,
1046
+ fields : & [ ast:: Field ] ,
1047
+ base : Option < Gc < ast:: Expr > > ,
1048
+ expr_span : codemap:: Span ,
1049
+ id : ast:: NodeId ,
1050
+ dest : Dest ) -> & ' a Block < ' a > {
1053
1051
let _icx = push_ctxt ( "trans_rec" ) ;
1054
- let bcx = bcx;
1055
1052
1056
1053
let ty = node_id_type ( bcx, id) ;
1057
1054
let tcx = bcx. tcx ( ) ;
@@ -1121,15 +1118,14 @@ pub struct StructBaseInfo {
1121
1118
* - `optbase` contains information on the base struct (if any) from
1122
1119
* which remaining fields are copied; see comments on `StructBaseInfo`.
1123
1120
*/
1124
- pub fn trans_adt < ' a > ( bcx : & ' a Block < ' a > ,
1121
+ pub fn trans_adt < ' a > ( mut bcx : & ' a Block < ' a > ,
1125
1122
repr : & adt:: Repr ,
1126
1123
discr : ty:: Disr ,
1127
1124
fields : & [ ( uint , Gc < ast:: Expr > ) ] ,
1128
1125
optbase : Option < StructBaseInfo > ,
1129
1126
dest : Dest ) -> & ' a Block < ' a > {
1130
1127
let _icx = push_ctxt ( "trans_adt" ) ;
1131
1128
let fcx = bcx. fcx ;
1132
- let mut bcx = bcx;
1133
1129
let addr = match dest {
1134
1130
Ignore => {
1135
1131
for & ( _i, ref e) in fields. iter ( ) {
@@ -1148,6 +1144,28 @@ pub fn trans_adt<'a>(bcx: &'a Block<'a>,
1148
1144
// failure occur before the ADT as a whole is ready.
1149
1145
let custom_cleanup_scope = fcx. push_custom_cleanup_scope ( ) ;
1150
1146
1147
+ // First we trans the base, if we have one, to the dest
1148
+ for base in optbase. iter ( ) {
1149
+ assert_eq ! ( discr, 0 ) ;
1150
+
1151
+ match ty:: expr_kind ( bcx. tcx ( ) , & * base. expr ) {
1152
+ ty:: LvalueExpr => {
1153
+ let base_datum = unpack_datum ! ( bcx, trans_to_lvalue( bcx, & * base. expr, "base" ) ) ;
1154
+ for & ( i, t) in base. fields . iter ( ) {
1155
+ let datum = base_datum. get_element (
1156
+ t, |srcval| adt:: trans_field_ptr ( bcx, repr, srcval, discr, i) ) ;
1157
+ let dest = adt:: trans_field_ptr ( bcx, repr, addr, discr, i) ;
1158
+ bcx = datum. store_to ( bcx, dest) ;
1159
+ }
1160
+ } ,
1161
+ ty:: RvalueDpsExpr | ty:: RvalueDatumExpr => {
1162
+ bcx = trans_into ( bcx, & * base. expr , SaveIn ( addr) ) ;
1163
+ } ,
1164
+ ty:: RvalueStmtExpr => bcx. tcx ( ) . sess . bug ( "unexpected expr kind for struct base expr" )
1165
+ }
1166
+ }
1167
+
1168
+ // Now, we just overwrite the fields we've explicity specified
1151
1169
for & ( i, ref e) in fields. iter ( ) {
1152
1170
let dest = adt:: trans_field_ptr ( bcx, repr, addr, discr, i) ;
1153
1171
let e_ty = expr_ty_adjusted ( bcx, & * * e) ;
@@ -1157,19 +1175,6 @@ pub fn trans_adt<'a>(bcx: &'a Block<'a>,
1157
1175
fcx. schedule_drop_mem ( scope, dest, e_ty) ;
1158
1176
}
1159
1177
1160
- for base in optbase. iter ( ) {
1161
- // FIXME #6573: is it sound to use the destination's repr on the base?
1162
- // And, would it ever be reasonable to be here with discr != 0?
1163
- let base_datum = unpack_datum ! ( bcx, trans_to_lvalue( bcx, & * base. expr, "base" ) ) ;
1164
- for & ( i, t) in base. fields . iter ( ) {
1165
- let datum = base_datum. get_element (
1166
- t,
1167
- |srcval| adt:: trans_field_ptr ( bcx, repr, srcval, discr, i) ) ;
1168
- let dest = adt:: trans_field_ptr ( bcx, repr, addr, discr, i) ;
1169
- bcx = datum. store_to ( bcx, dest) ;
1170
- }
1171
- }
1172
-
1173
1178
adt:: trans_set_discr ( bcx, repr, addr, discr) ;
1174
1179
1175
1180
fcx. pop_custom_cleanup_scope ( custom_cleanup_scope) ;
0 commit comments