@@ -210,6 +210,7 @@ use trans::consts;
210210use trans:: datum:: * ;
211211use trans:: debuginfo:: { self , DebugLoc , ToDebugLoc } ;
212212use trans:: expr:: { self , Dest } ;
213+ use trans:: monomorphize;
213214use trans:: tvec;
214215use trans:: type_of;
215216use middle:: ty:: { self , Ty } ;
@@ -1076,9 +1077,39 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
10761077 let adt_vals = if any_irrefutable_adt_pat ( bcx. tcx ( ) , m, col) {
10771078 let repr = adt:: represent_type ( bcx. ccx ( ) , left_ty) ;
10781079 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)
10811091 ) . 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+ }
10821113 Some ( field_vals)
10831114 } else if any_uniq_pat ( m, col) || any_region_pat ( m, col) {
10841115 Some ( vec ! ( Load ( bcx, val) ) )
0 commit comments