@@ -58,7 +58,7 @@ use middle::check_const;
58
58
use middle:: def;
59
59
use middle:: lang_items:: CoerceUnsizedTraitLangItem ;
60
60
use middle:: mem_categorization:: Typer ;
61
- use middle:: subst:: { Subst , Substs , VecPerParamSpace } ;
61
+ use middle:: subst:: { Substs , VecPerParamSpace } ;
62
62
use middle:: traits;
63
63
use trans:: { _match, adt, asm, base, callee, closure, consts, controlflow} ;
64
64
use trans:: base:: * ;
@@ -471,8 +471,8 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
471
471
}
472
472
473
473
// This can be extended to enums and tuples in the future.
474
- // (&ty::ty_enum(def_id_a, substs_a ), &ty::ty_enum(def_id_b, substs_b )) |
475
- ( & ty:: ty_struct( def_id_a, substs_a ) , & ty:: ty_struct( def_id_b, substs_b ) ) => {
474
+ // (&ty::ty_enum(def_id_a, _ ), &ty::ty_enum(def_id_b, _ )) |
475
+ ( & ty:: ty_struct( def_id_a, _ ) , & ty:: ty_struct( def_id_b, _ ) ) => {
476
476
assert_eq ! ( def_id_a, def_id_b) ;
477
477
478
478
// The target is already by-ref because it's to be written to.
@@ -499,35 +499,41 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
499
499
} ;
500
500
501
501
let repr_source = adt:: represent_type ( bcx. ccx ( ) , source. ty ) ;
502
+ let src_fields = match & * repr_source {
503
+ & adt:: Repr :: Univariant ( ref s, _) => & s. fields ,
504
+ _ => bcx. sess ( ) . span_bug ( span,
505
+ & format ! ( "Non univariant struct? (repr_source: {:?})" ,
506
+ repr_source) ) ,
507
+ } ;
502
508
let repr_target = adt:: represent_type ( bcx. ccx ( ) , target. ty ) ;
503
- let fields = ty:: lookup_struct_fields ( bcx. tcx ( ) , def_id_a) ;
509
+ let target_fields = match & * repr_target {
510
+ & adt:: Repr :: Univariant ( ref s, _) => & s. fields ,
511
+ _ => bcx. sess ( ) . span_bug ( span,
512
+ & format ! ( "Non univariant struct? (repr_target: {:?})" ,
513
+ repr_target) ) ,
514
+ } ;
504
515
505
516
let coerce_index = match kind {
506
517
ty:: CustomCoerceUnsized :: Struct ( i) => i
507
518
} ;
508
- assert ! ( coerce_index < fields . len( ) ) ;
519
+ assert ! ( coerce_index < src_fields . len ( ) && src_fields . len ( ) == target_fields . len( ) ) ;
509
520
510
- for ( i, field) in fields. iter ( ) . enumerate ( ) {
521
+ let iter = src_fields. iter ( ) . zip ( target_fields. iter ( ) ) . enumerate ( ) ;
522
+ for ( i, ( src_ty, target_ty) ) in iter {
511
523
let ll_source = adt:: trans_field_ptr ( bcx, & repr_source, source. val , 0 , i) ;
512
524
let ll_target = adt:: trans_field_ptr ( bcx, & repr_target, target. val , 0 , i) ;
513
525
514
- let ty = ty:: lookup_field_type_unsubstituted ( bcx. tcx ( ) ,
515
- def_id_a,
516
- field. id ) ;
517
- let field_source = ty. subst ( bcx. tcx ( ) , substs_a) ;
518
- let field_target = ty. subst ( bcx. tcx ( ) , substs_b) ;
519
-
520
526
// If this is the field we need to coerce, recurse on it.
521
527
if i == coerce_index {
522
528
coerce_unsized ( bcx, span,
523
- Datum :: new ( ll_source, field_source ,
529
+ Datum :: new ( ll_source, src_ty ,
524
530
Rvalue :: new ( ByRef ) ) ,
525
- Datum :: new ( ll_target, field_target ,
531
+ Datum :: new ( ll_target, target_ty ,
526
532
Rvalue :: new ( ByRef ) ) ) ;
527
533
} else {
528
534
// Otherwise, simply copy the data from the source.
529
- assert_eq ! ( field_source , field_target ) ;
530
- memcpy_ty ( bcx, ll_target, ll_source, field_source ) ;
535
+ assert_eq ! ( src_ty , target_ty ) ;
536
+ memcpy_ty ( bcx, ll_target, ll_source, src_ty ) ;
531
537
}
532
538
}
533
539
}
@@ -2008,6 +2014,7 @@ fn float_cast(bcx: Block,
2008
2014
#[ derive( Copy , Clone , PartialEq , Debug ) ]
2009
2015
pub enum cast_kind {
2010
2016
cast_pointer,
2017
+ cast_fat_ptr,
2011
2018
cast_integral,
2012
2019
cast_float,
2013
2020
cast_enum,
@@ -2022,7 +2029,7 @@ pub fn cast_type_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> cast_kind {
2022
2029
if type_is_sized ( tcx, mt. ty ) {
2023
2030
cast_pointer
2024
2031
} else {
2025
- cast_other
2032
+ cast_fat_ptr
2026
2033
}
2027
2034
}
2028
2035
ty:: ty_bare_fn( ..) => cast_pointer,
@@ -2098,10 +2105,18 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
2098
2105
let llexpr = datum. to_llscalarish ( bcx) ;
2099
2106
PtrToInt ( bcx, llexpr, ll_t_out)
2100
2107
}
2108
+ ( cast_fat_ptr, cast_integral) => {
2109
+ let data_ptr = Load ( bcx, get_dataptr ( bcx, datum. val ) ) ;
2110
+ PtrToInt ( bcx, data_ptr, ll_t_out)
2111
+ }
2101
2112
( cast_pointer, cast_pointer) => {
2102
2113
let llexpr = datum. to_llscalarish ( bcx) ;
2103
2114
PointerCast ( bcx, llexpr, ll_t_out)
2104
2115
}
2116
+ ( cast_fat_ptr, cast_pointer) => {
2117
+ let data_ptr = Load ( bcx, get_dataptr ( bcx, datum. val ) ) ;
2118
+ PointerCast ( bcx, data_ptr, ll_t_out)
2119
+ }
2105
2120
( cast_enum, cast_integral) |
2106
2121
( cast_enum, cast_float) => {
2107
2122
let mut bcx = bcx;
0 commit comments