@@ -775,7 +775,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
775
775
776
776
// Check the obligations of the cast -- for example, when casting
777
777
// `usize` to `dyn* Clone + 'static`:
778
- let obligations = predicates
778
+ let mut obligations: Vec < _ > = predicates
779
779
. iter ( )
780
780
. map ( |predicate| {
781
781
// For each existential predicate (e.g., `?Self: Clone`) substitute
@@ -785,15 +785,33 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
785
785
let predicate = predicate. with_self_ty ( self . tcx , a) ;
786
786
Obligation :: new ( self . cause . clone ( ) , self . param_env , predicate)
787
787
} )
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 (
790
805
self . cause . clone ( ) ,
791
806
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
+ }
797
815
798
816
Ok ( InferOk {
799
817
value : ( vec ! [ Adjustment { kind: Adjust :: DynStar , target: b } ] , b) ,
0 commit comments