@@ -775,7 +775,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
775775
776776 // Check the obligations of the cast -- for example, when casting
777777 // `usize` to `dyn* Clone + 'static`:
778- let obligations = predicates
778+ let mut obligations: Vec < _ > = predicates
779779 . iter ( )
780780 . map ( |predicate| {
781781 // For each existential predicate (e.g., `?Self: Clone`) substitute
@@ -785,16 +785,33 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
785785 let predicate = predicate. with_self_ty ( self . tcx , a) ;
786786 Obligation :: new ( self . tcx , self . cause . clone ( ) , self . param_env , predicate)
787787 } )
788- // Enforce the region bound (e.g., `usize: 'static`, in our example).
789- . chain ( [ Obligation :: new (
788+ . chain ( [
789+ // Enforce the region bound (e.g., `usize: 'static`, in our example).
790+ Obligation :: new (
791+ self . tcx ,
792+ self . cause . clone ( ) ,
793+ self . param_env ,
794+ ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives ( ty:: OutlivesPredicate (
795+ a, b_region,
796+ ) ) ) ,
797+ ) ,
798+ ] )
799+ . collect ( ) ;
800+
801+ // Enforce that the type is `usize`/pointer-sized. For now, only those
802+ // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts.
803+ if !a. is_dyn_star ( ) {
804+ obligations. push ( Obligation :: new (
790805 self . tcx ,
791806 self . cause . clone ( ) ,
792807 self . param_env ,
793- self . tcx . mk_predicate ( ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives (
794- ty:: OutlivesPredicate ( a, b_region) ,
795- ) ) ) ,
796- ) ] )
797- . collect ( ) ;
808+ ty:: Binder :: dummy ( ty:: TraitRef :: new (
809+ self . tcx . require_lang_item ( hir:: LangItem :: PointerSized , Some ( self . cause . span ) ) ,
810+ self . tcx . mk_substs_trait ( a, & [ ] ) ,
811+ ) )
812+ . to_poly_trait_predicate ( ) ,
813+ ) ) ;
814+ }
798815
799816 Ok ( InferOk {
800817 value : ( vec ! [ Adjustment { kind: Adjust :: DynStar , target: b } ] , b) ,
0 commit comments