Skip to content

Commit 7d71b34

Browse files
committed
coerce_from_safe_fn is just fnptr->fnptr coercion
1 parent ba8e3a7 commit 7d71b34

File tree

1 file changed

+29
-22
lines changed

1 file changed

+29
-22
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -797,34 +797,35 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
797797
self.unify_and(a, b, [], Adjust::ReborrowPin(mut_b))
798798
}
799799

800-
fn coerce_from_safe_fn(
800+
// Coerces an fnptr `a` to a fnptr `b`, this is only `fn(..)` to `unsafe fn(..)`.
801+
// Takes an `adjustment` used to get the `a` fnptr in the first place.
802+
fn coerce_fnptrs(
801803
&self,
802-
fn_ty_a: ty::PolyFnSig<'tcx>,
803-
b: Ty<'tcx>,
804+
a: ty::PolyFnSig<'tcx>,
805+
b: ty::PolyFnSig<'tcx>,
804806
adjustment: Option<Adjust>,
805807
) -> CoerceResult<'tcx> {
806-
debug_assert!(self.shallow_resolve(b) == b);
807-
808808
self.commit_if_ok(|snapshot| {
809809
let outer_universe = self.infcx.universe();
810810

811-
let result = if let ty::FnPtr(_, hdr_b) = b.kind()
812-
&& fn_ty_a.safety().is_safe()
813-
&& hdr_b.safety.is_unsafe()
814-
{
815-
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
811+
let a_ty = Ty::new_fn_ptr(self.tcx, a);
812+
let b_ty = Ty::new_fn_ptr(self.tcx, b);
813+
814+
// Handle coercing `fn(..)` to `unsafe fn(..)`
815+
let result = if a.safety().is_safe() && b.safety().is_unsafe() {
816+
let unsafe_a_ty = self.tcx.safe_to_unsafe_fn_ty(a);
817+
let adjustment = adjustment.map(|kind| Adjustment { kind, target: a_ty });
818+
816819
self.unify_and(
817-
unsafe_a,
818-
b,
819-
adjustment
820-
.map(|kind| Adjustment { kind, target: Ty::new_fn_ptr(self.tcx, fn_ty_a) }),
820+
unsafe_a_ty,
821+
b_ty,
822+
adjustment,
821823
Adjust::Pointer(PointerCoercion::UnsafeFnPointer),
822824
)
823825
} else {
824-
let a = Ty::new_fn_ptr(self.tcx, fn_ty_a);
825826
match adjustment {
826-
Some(adjust) => self.unify_and(a, b, [], adjust),
827-
None => self.unify(a, b),
827+
Some(adjust) => self.unify_and(a_ty, b_ty, [], adjust),
828+
None => self.unify(a_ty, b_ty),
828829
}
829830
};
830831

@@ -842,13 +843,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
842843

843844
fn coerce_from_fn_pointer(
844845
&self,
845-
fn_ty_a: ty::PolyFnSig<'tcx>,
846+
a_sig: ty::PolyFnSig<'tcx>,
846847
b: Ty<'tcx>,
847848
) -> CoerceResult<'tcx> {
848-
debug!(?fn_ty_a, ?b, "coerce_from_fn_pointer");
849+
debug!(?a_sig, ?b, "coerce_from_fn_pointer");
849850
debug_assert!(self.shallow_resolve(b) == b);
850851

851-
self.coerce_from_safe_fn(fn_ty_a, b, None)
852+
match b.kind() {
853+
ty::FnPtr(_, _) => self.coerce_fnptrs(a_sig, b.fn_sig(self.tcx), None),
854+
_ => self.unify(Ty::new_fn_ptr(self.tcx, a_sig), b),
855+
}
852856
}
853857

854858
fn coerce_from_fn_item(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
@@ -892,9 +896,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
892896
let InferOk { value: a_sig, mut obligations } =
893897
self.at(&self.cause, self.param_env).normalize(a_sig);
894898

895-
let InferOk { value, obligations: o2 } = self.coerce_from_safe_fn(
899+
let InferOk { value, obligations: o2 } = self.coerce_fnptrs(
896900
a_sig,
897-
b,
901+
b.fn_sig(self.tcx),
898902
Some(Adjust::Pointer(PointerCoercion::ReifyFnPointer)),
899903
)?;
900904

@@ -941,6 +945,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
941945
let pointer_ty =
942946
Ty::new_fn_ptr(self.tcx, self.tcx.signature_unclosure(closure_sig, safety));
943947
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
948+
949+
// We don't use `self.coerce_fnptrs` as handling `fn` to `unsafe fn`
950+
// was trivial to do so ourselves.
944951
self.unify_and(
945952
pointer_ty,
946953
b,

0 commit comments

Comments
 (0)