@@ -58,7 +58,7 @@ use rustc::infer::{Coercion, InferResult, InferOk};
58
58
use rustc:: infer:: type_variable:: TypeVariableOrigin ;
59
59
use rustc:: traits:: { self , ObligationCause , ObligationCauseCode } ;
60
60
use rustc:: ty:: adjustment:: { Adjustment , Adjust , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
61
- use rustc:: ty:: { self , TypeAndMut , Ty , ClosureSubsts } ;
61
+ use rustc:: ty:: { self , TypeAndMut , Ty , ClosureSubsts , Binder , List , ExistentialPredicate } ;
62
62
use rustc:: ty:: fold:: TypeFoldable ;
63
63
use rustc:: ty:: error:: TypeError ;
64
64
use rustc:: ty:: relate:: RelateResult ;
@@ -555,9 +555,19 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
555
555
ty:: Predicate :: Trait ( ref tr) if traits. contains ( & tr. def_id ( ) ) => {
556
556
if unsize_did == tr. def_id ( ) {
557
557
let sty = & tr. skip_binder ( ) . input_types ( ) . nth ( 1 ) . unwrap ( ) . sty ;
558
- if let ty:: Tuple ( ..) = sty {
559
- debug ! ( "coerce_unsized: found unsized tuple coercion" ) ;
560
- has_unsized_tuple_coercion = true ;
558
+ match sty {
559
+ ty:: Tuple ( ..) => {
560
+ debug ! ( "coerce_unsized: found unsized tuple coercion" ) ;
561
+ has_unsized_tuple_coercion = true ;
562
+ }
563
+ ty:: Dynamic ( data, _) => {
564
+ if self . tcx . features ( ) . object_safe_for_dispatch {
565
+ self . check_coercion_object_safe ( & mut selcx,
566
+ tr,
567
+ data) ?;
568
+ }
569
+ }
570
+ _ => { }
561
571
}
562
572
}
563
573
tr. clone ( )
@@ -626,6 +636,38 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
626
636
Ok ( coercion)
627
637
}
628
638
639
+ fn check_coercion_object_safe ( & self ,
640
+ selcx : & mut traits:: SelectionContext < ' f , ' gcx , ' tcx > ,
641
+ pred : & ty:: PolyTraitPredicate < ' tcx > ,
642
+ data : & Binder < & ' tcx List < ExistentialPredicate < ' tcx > > > )
643
+ -> Result < ( ) , TypeError < ' tcx > > {
644
+
645
+ let source = & pred. skip_binder ( ) . self_ty ( ) . sty ;
646
+ match source {
647
+ ty:: Dynamic ( ..) => Ok ( ( ) ) ,
648
+ _ => {
649
+ let cause = ObligationCause :: misc ( self . cause . span , self . body_id ) ;
650
+ let component_traits =
651
+ data. auto_traits ( ) . chain ( data. principal_def_id ( ) ) ;
652
+ for target_def_id in component_traits {
653
+ let obj_safe = traits:: Obligation :: new (
654
+ cause. clone ( ) ,
655
+ self . fcx . param_env ,
656
+ ty:: Predicate :: ObjectSafe ( target_def_id)
657
+ ) ;
658
+ match selcx. select ( & obj_safe. with ( pred. clone ( ) ) ) {
659
+ Ok ( _) => ( ) ,
660
+ Err ( err) => {
661
+ self . report_selection_error ( & obj_safe, & err, false ) ;
662
+ return Err ( TypeError :: Mismatch )
663
+ }
664
+ }
665
+ }
666
+ Ok ( ( ) )
667
+ }
668
+ }
669
+ }
670
+
629
671
fn coerce_from_safe_fn < F , G > ( & self ,
630
672
a : Ty < ' tcx > ,
631
673
fn_ty_a : ty:: PolyFnSig < ' tcx > ,
0 commit comments