@@ -58,7 +58,7 @@ use rustc::infer::{Coercion, InferResult, InferOk};
5858use rustc:: infer:: type_variable:: TypeVariableOrigin ;
5959use rustc:: traits:: { self , ObligationCause , ObligationCauseCode } ;
6060use 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 } ;
6262use rustc:: ty:: fold:: TypeFoldable ;
6363use rustc:: ty:: error:: TypeError ;
6464use rustc:: ty:: relate:: RelateResult ;
@@ -555,9 +555,19 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
555555 ty:: Predicate :: Trait ( ref tr) if traits. contains ( & tr. def_id ( ) ) => {
556556 if unsize_did == tr. def_id ( ) {
557557 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+ _ => { }
561571 }
562572 }
563573 tr. clone ( )
@@ -626,6 +636,38 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
626636 Ok ( coercion)
627637 }
628638
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+
629671 fn coerce_from_safe_fn < F , G > ( & self ,
630672 a : Ty < ' tcx > ,
631673 fn_ty_a : ty:: PolyFnSig < ' tcx > ,
0 commit comments