@@ -247,7 +247,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
247247 ty:: FnPtr ( a_sig_tys, a_hdr) => {
248248 // We permit coercion of fn pointers to drop the
249249 // unsafe qualifier.
250- self . coerce_from_fn_pointer ( a , a_sig_tys. with ( a_hdr) , b)
250+ self . coerce_from_fn_pointer ( a_sig_tys. with ( a_hdr) , b)
251251 }
252252 ty:: Closure ( closure_def_id_a, args_a) => {
253253 // Non-capturing closures are coercible to
@@ -813,18 +813,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
813813 } )
814814 }
815815
816- fn coerce_from_safe_fn < F , G > (
816+ fn coerce_from_safe_fn (
817817 & self ,
818- a : Ty < ' tcx > ,
819818 fn_ty_a : ty:: PolyFnSig < ' tcx > ,
820819 b : Ty < ' tcx > ,
821- to_unsafe : F ,
822- normal : G ,
823- ) -> CoerceResult < ' tcx >
824- where
825- F : FnOnce ( Ty < ' tcx > ) -> Vec < Adjustment < ' tcx > > ,
826- G : FnOnce ( Ty < ' tcx > ) -> Vec < Adjustment < ' tcx > > ,
827- {
820+ adjustment : Option < Adjust > ,
821+ ) -> CoerceResult < ' tcx > {
828822 self . commit_if_ok ( |snapshot| {
829823 let outer_universe = self . infcx . universe ( ) ;
830824
@@ -833,9 +827,22 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
833827 && hdr_b. safety . is_unsafe ( )
834828 {
835829 let unsafe_a = self . tcx . safe_to_unsafe_fn_ty ( fn_ty_a) ;
836- self . unify_and ( unsafe_a, b, to_unsafe)
830+ self . unify_and ( unsafe_a, b, |target| match adjustment {
831+ Some ( kind) => vec ! [
832+ Adjustment { kind, target: Ty :: new_fn_ptr( self . tcx, fn_ty_a) } ,
833+ Adjustment {
834+ kind: Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
835+ target,
836+ } ,
837+ ] ,
838+ None => simple ( Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ) ( target) ,
839+ } )
837840 } else {
838- self . unify_and ( a, b, normal)
841+ let a = Ty :: new_fn_ptr ( self . tcx , fn_ty_a) ;
842+ self . unify_and ( a, b, |target| match adjustment {
843+ None => vec ! [ ] ,
844+ Some ( kind) => vec ! [ Adjustment { kind, target } ] ,
845+ } )
839846 } ;
840847
841848 // FIXME(#73154): This is a hack. Currently LUB can generate
@@ -852,7 +859,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
852859
853860 fn coerce_from_fn_pointer (
854861 & self ,
855- a : Ty < ' tcx > ,
856862 fn_ty_a : ty:: PolyFnSig < ' tcx > ,
857863 b : Ty < ' tcx > ,
858864 ) -> CoerceResult < ' tcx > {
@@ -861,15 +867,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
861867 //!
862868
863869 let b = self . shallow_resolve ( b) ;
864- debug ! ( "coerce_from_fn_pointer(a={:?}, b={:?})" , a, b) ;
865-
866- self . coerce_from_safe_fn (
867- a,
868- fn_ty_a,
869- b,
870- simple ( Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ) ,
871- identity,
872- )
870+ debug ! ( ?fn_ty_a, ?b, "coerce_from_fn_pointer" ) ;
871+
872+ self . coerce_from_safe_fn ( fn_ty_a, b, None )
873873 }
874874
875875 fn coerce_from_fn_item ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
@@ -916,24 +916,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
916916 self . at ( & self . cause , self . param_env ) . normalize ( a_sig) ;
917917 obligations. extend ( o1) ;
918918
919- let a_fn_pointer = Ty :: new_fn_ptr ( self . tcx , a_sig) ;
920919 let InferOk { value, obligations : o2 } = self . coerce_from_safe_fn (
921- a_fn_pointer,
922920 a_sig,
923921 b,
924- |unsafe_ty| {
925- vec ! [
926- Adjustment {
927- kind: Adjust :: Pointer ( PointerCoercion :: ReifyFnPointer ) ,
928- target: a_fn_pointer,
929- } ,
930- Adjustment {
931- kind: Adjust :: Pointer ( PointerCoercion :: UnsafeFnPointer ) ,
932- target: unsafe_ty,
933- } ,
934- ]
935- } ,
936- simple ( Adjust :: Pointer ( PointerCoercion :: ReifyFnPointer ) ) ,
922+ Some ( Adjust :: Pointer ( PointerCoercion :: ReifyFnPointer ) ) ,
937923 ) ?;
938924
939925 obligations. extend ( o2) ;
0 commit comments