@@ -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,15 +785,33 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
785785 let predicate = predicate. with_self_ty ( self . tcx , a) ;
786786 Obligation :: new ( 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 . cause . clone ( ) ,
792+ self . param_env ,
793+ ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives ( ty:: OutlivesPredicate (
794+ a, b_region,
795+ ) ) )
796+ . to_predicate ( self . tcx ) ,
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 . cause . clone ( ) ,
791806 self . param_env ,
792- self . tcx . mk_predicate ( ty:: Binder :: dummy ( ty:: PredicateKind :: TypeOutlives (
793- ty:: OutlivesPredicate ( a, b_region) ,
794- ) ) ) ,
795- ) ] )
796- . collect ( ) ;
807+ ty:: Binder :: dummy ( ty:: TraitRef :: new (
808+ self . tcx . require_lang_item ( hir:: LangItem :: PointerSized , Some ( self . cause . span ) ) ,
809+ self . tcx . mk_substs_trait ( a, & [ ] ) ,
810+ ) )
811+ . to_poly_trait_predicate ( )
812+ . to_predicate ( self . tcx ) ,
813+ ) ) ;
814+ }
797815
798816 Ok ( InferOk {
799817 value : ( vec ! [ Adjustment { kind: Adjust :: DynStar , target: b } ] , b) ,
0 commit comments