Skip to content

Commit f20efc4

Browse files
committed
Handle UnsafePointer coercions in one place
1 parent c6c1796 commit f20efc4

File tree

1 file changed

+23
-37
lines changed

1 file changed

+23
-37
lines changed

Diff for: compiler/rustc_hir_typeck/src/coercion.rs

+23-37
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)