@@ -210,6 +210,7 @@ use trans::consts;
210
210
use trans:: datum:: * ;
211
211
use trans:: debuginfo:: { self , DebugLoc , ToDebugLoc } ;
212
212
use trans:: expr:: { self , Dest } ;
213
+ use trans:: monomorphize;
213
214
use trans:: tvec;
214
215
use trans:: type_of;
215
216
use middle:: ty:: { self , Ty } ;
@@ -1076,9 +1077,39 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
1076
1077
let adt_vals = if any_irrefutable_adt_pat ( bcx. tcx ( ) , m, col) {
1077
1078
let repr = adt:: represent_type ( bcx. ccx ( ) , left_ty) ;
1078
1079
let arg_count = adt:: num_args ( & * repr, 0 ) ;
1079
- let field_vals: Vec < ValueRef > = ( 0 ..arg_count) . map ( |ix|
1080
- adt:: trans_field_ptr ( bcx, & * repr, val, 0 , ix)
1080
+ let ( arg_count, struct_val) = if type_is_sized ( bcx. tcx ( ) , left_ty) {
1081
+ ( arg_count, val)
1082
+ } else {
1083
+ // For an unsized ADT (i.e. DST struct), we need to treat
1084
+ // the last field specially: instead of simply passing a
1085
+ // ValueRef pointing to that field, as with all the others,
1086
+ // we skip it and instead construct a 'fat ptr' below.
1087
+ ( arg_count - 1 , Load ( bcx, expr:: get_dataptr ( bcx, val) ) )
1088
+ } ;
1089
+ let mut field_vals: Vec < ValueRef > = ( 0 ..arg_count) . map ( |ix|
1090
+ adt:: trans_field_ptr ( bcx, & * repr, struct_val, 0 , ix)
1081
1091
) . collect ( ) ;
1092
+
1093
+ match left_ty. sty {
1094
+ ty:: ty_struct( def_id, substs) if !type_is_sized ( bcx. tcx ( ) , left_ty) => {
1095
+ // The last field is technically unsized but
1096
+ // since we can only ever match that field behind
1097
+ // a reference we construct a fat ptr here.
1098
+ let fields = ty:: lookup_struct_fields ( bcx. tcx ( ) , def_id) ;
1099
+ let unsized_ty = fields. iter ( ) . last ( ) . map ( |field| {
1100
+ let fty = ty:: lookup_field_type ( bcx. tcx ( ) , def_id, field. id , substs) ;
1101
+ monomorphize:: normalize_associated_type ( bcx. tcx ( ) , & fty)
1102
+ } ) . unwrap ( ) ;
1103
+ let llty = type_of:: type_of ( bcx. ccx ( ) , unsized_ty) ;
1104
+ let scratch = alloca_no_lifetime ( bcx, llty, "__struct_field_fat_ptr" ) ;
1105
+ let data = adt:: trans_field_ptr ( bcx, & * repr, struct_val, 0 , arg_count) ;
1106
+ let len = Load ( bcx, expr:: get_len ( bcx, val) ) ;
1107
+ Store ( bcx, data, expr:: get_dataptr ( bcx, scratch) ) ;
1108
+ Store ( bcx, len, expr:: get_len ( bcx, scratch) ) ;
1109
+ field_vals. push ( scratch) ;
1110
+ }
1111
+ _ => { }
1112
+ }
1082
1113
Some ( field_vals)
1083
1114
} else if any_uniq_pat ( m, col) || any_region_pat ( m, col) {
1084
1115
Some ( vec ! ( Load ( bcx, val) ) )
0 commit comments