@@ -58,7 +58,7 @@ use middle::check_const;
5858use middle:: def;
5959use middle:: lang_items:: CoerceUnsizedTraitLangItem ;
6060use middle:: mem_categorization:: Typer ;
61- use middle:: subst:: { Subst , Substs , VecPerParamSpace } ;
61+ use middle:: subst:: { Substs , VecPerParamSpace } ;
6262use middle:: traits;
6363use trans:: { _match, adt, asm, base, callee, closure, consts, controlflow} ;
6464use trans:: base:: * ;
@@ -476,8 +476,8 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
476476 }
477477
478478 // This can be extended to enums and tuples in the future.
479- // (&ty::ty_enum(def_id_a, substs_a ), &ty::ty_enum(def_id_b, substs_b )) |
480- ( & ty:: ty_struct( def_id_a, substs_a ) , & ty:: ty_struct( def_id_b, substs_b ) ) => {
479+ // (&ty::ty_enum(def_id_a, _ ), &ty::ty_enum(def_id_b, _ )) |
480+ ( & ty:: ty_struct( def_id_a, _ ) , & ty:: ty_struct( def_id_b, _ ) ) => {
481481 assert_eq ! ( def_id_a, def_id_b) ;
482482
483483 // The target is already by-ref because it's to be written to.
@@ -504,35 +504,41 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
504504 } ;
505505
506506 let repr_source = adt:: represent_type ( bcx. ccx ( ) , source. ty ) ;
507+ let src_fields = match & * repr_source {
508+ & adt:: Repr :: Univariant ( ref s, _) => & s. fields ,
509+ _ => bcx. sess ( ) . span_bug ( span,
510+ & format ! ( "Non univariant struct? (repr_source: {:?})" ,
511+ repr_source) ) ,
512+ } ;
507513 let repr_target = adt:: represent_type ( bcx. ccx ( ) , target. ty ) ;
508- let fields = ty:: lookup_struct_fields ( bcx. tcx ( ) , def_id_a) ;
514+ let target_fields = match & * repr_target {
515+ & adt:: Repr :: Univariant ( ref s, _) => & s. fields ,
516+ _ => bcx. sess ( ) . span_bug ( span,
517+ & format ! ( "Non univariant struct? (repr_target: {:?})" ,
518+ repr_target) ) ,
519+ } ;
509520
510521 let coerce_index = match kind {
511522 ty:: CustomCoerceUnsized :: Struct ( i) => i
512523 } ;
513- assert ! ( coerce_index < fields . len( ) ) ;
524+ assert ! ( coerce_index < src_fields . len ( ) && src_fields . len ( ) == target_fields . len( ) ) ;
514525
515- for ( i, field) in fields. iter ( ) . enumerate ( ) {
526+ let iter = src_fields. iter ( ) . zip ( target_fields. iter ( ) ) . enumerate ( ) ;
527+ for ( i, ( src_ty, target_ty) ) in iter {
516528 let ll_source = adt:: trans_field_ptr ( bcx, & repr_source, source. val , 0 , i) ;
517529 let ll_target = adt:: trans_field_ptr ( bcx, & repr_target, target. val , 0 , i) ;
518530
519- let ty = ty:: lookup_field_type_unsubstituted ( bcx. tcx ( ) ,
520- def_id_a,
521- field. id ) ;
522- let field_source = ty. subst ( bcx. tcx ( ) , substs_a) ;
523- let field_target = ty. subst ( bcx. tcx ( ) , substs_b) ;
524-
525531 // If this is the field we need to coerce, recurse on it.
526532 if i == coerce_index {
527533 coerce_unsized ( bcx, span,
528- Datum :: new ( ll_source, field_source ,
534+ Datum :: new ( ll_source, src_ty ,
529535 Rvalue :: new ( ByRef ) ) ,
530- Datum :: new ( ll_target, field_target ,
536+ Datum :: new ( ll_target, target_ty ,
531537 Rvalue :: new ( ByRef ) ) ) ;
532538 } else {
533539 // Otherwise, simply copy the data from the source.
534- assert_eq ! ( field_source , field_target ) ;
535- memcpy_ty ( bcx, ll_target, ll_source, field_source ) ;
540+ assert_eq ! ( src_ty , target_ty ) ;
541+ memcpy_ty ( bcx, ll_target, ll_source, src_ty ) ;
536542 }
537543 }
538544 }
@@ -2013,6 +2019,7 @@ fn float_cast(bcx: Block,
20132019#[ derive( Copy , Clone , PartialEq , Debug ) ]
20142020pub enum cast_kind {
20152021 cast_pointer,
2022+ cast_fat_ptr,
20162023 cast_integral,
20172024 cast_float,
20182025 cast_enum,
@@ -2027,7 +2034,7 @@ pub fn cast_type_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> cast_kind {
20272034 if type_is_sized ( tcx, mt. ty ) {
20282035 cast_pointer
20292036 } else {
2030- cast_other
2037+ cast_fat_ptr
20312038 }
20322039 }
20332040 ty:: ty_bare_fn( ..) => cast_pointer,
@@ -2103,10 +2110,18 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
21032110 let llexpr = datum. to_llscalarish ( bcx) ;
21042111 PtrToInt ( bcx, llexpr, ll_t_out)
21052112 }
2113+ ( cast_fat_ptr, cast_integral) => {
2114+ let data_ptr = Load ( bcx, get_dataptr ( bcx, datum. val ) ) ;
2115+ PtrToInt ( bcx, data_ptr, ll_t_out)
2116+ }
21062117 ( cast_pointer, cast_pointer) => {
21072118 let llexpr = datum. to_llscalarish ( bcx) ;
21082119 PointerCast ( bcx, llexpr, ll_t_out)
21092120 }
2121+ ( cast_fat_ptr, cast_pointer) => {
2122+ let data_ptr = Load ( bcx, get_dataptr ( bcx, datum. val ) ) ;
2123+ PointerCast ( bcx, data_ptr, ll_t_out)
2124+ }
21102125 ( cast_enum, cast_integral) |
21112126 ( cast_enum, cast_float) => {
21122127 let mut bcx = bcx;
0 commit comments