Skip to content

Commit 46133a8

Browse files
committed
Skip HR function pointers coercion fallback when neither side is HR
1 parent 7e439ab commit 46133a8

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
252252
})
253253
}
254254

255+
/// Whether a fn-pointer coercion involves a higher-ranked binder (source or
256+
/// target). If neither is higher-ranked, the `unify_hr_fn_ptr` fallback is a
257+
/// no-op re-relate of the same types.
258+
fn coercion_is_higher_ranked(&self, a_sig: ty::PolyFnSig<'tcx>, b: Ty<'tcx>) -> bool {
259+
a_sig.has_bound_regions()
260+
|| matches!(*b.kind(), ty::FnPtr(tys, hdr) if tys.with(hdr).has_bound_regions())
261+
}
262+
255263
/// Unify two types (using sub or lub).
256264
fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>, leak_check: ForceLeakCheck) -> CoerceResult<'tcx> {
257265
self.unify_raw(a, b, leak_check)
@@ -1075,7 +1083,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
10751083

10761084
match self.unify_and(a, b, [], adjust.clone(), ForceLeakCheck::Yes) {
10771085
ok @ Ok(_) => ok,
1078-
Err(_) => {
1086+
Err(_) if self.coercion_is_higher_ranked(a_sig, b) => {
10791087
let ty::FnPtr(b_sig_tys, b_hdr) = b.kind() else {
10801088
span_bug!(
10811089
self.cause.span,
@@ -1125,11 +1133,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
11251133
)
11261134
})
11271135
}
1136+
Err(err) => Err(err),
11281137
}
11291138
}
11301139
ty::FnPtr(_, _) => match self.unify(a, b, ForceLeakCheck::Yes) {
11311140
ok @ Ok(_) => ok,
1132-
Err(_) => self.unify_hr_fn_ptr(a_sig, b, Adjust::Subtype),
1141+
Err(_) if self.coercion_is_higher_ranked(a_sig, b) => {
1142+
self.unify_hr_fn_ptr(a_sig, b, Adjust::Subtype)
1143+
}
1144+
Err(err) => Err(err),
11331145
},
11341146
_ => self.unify(a, b, ForceLeakCheck::Yes),
11351147
}
@@ -1151,7 +1163,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
11511163
let adjust = Adjust::Pointer(PointerCoercion::ReifyFnPointer(b_hdr.safety()));
11521164
let infer = match self.unify_and(a, b, [], adjust.clone(), ForceLeakCheck::Yes) {
11531165
Ok(infer) => infer,
1154-
Err(_) => self.unify_hr_fn_ptr(a_sig, b, adjust)?,
1166+
Err(_) if self.coercion_is_higher_ranked(a_sig, b) => {
1167+
self.unify_hr_fn_ptr(a_sig, b, adjust)?
1168+
}
1169+
Err(err) => return Err(err),
11551170
};
11561171
obligations.extend(infer.obligations);
11571172
Ok(InferOk { value: infer.value, obligations })
@@ -1177,7 +1192,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
11771192
let adjust = Adjust::Pointer(PointerCoercion::ClosureFnPointer(safety));
11781193
match self.unify_and(pointer_ty, b, [], adjust.clone(), ForceLeakCheck::No) {
11791194
ok @ Ok(_) => ok,
1180-
Err(_) => self.unify_hr_fn_ptr(closure_sig, b, adjust),
1195+
Err(_) if self.coercion_is_higher_ranked(closure_sig, b) => {
1196+
self.unify_hr_fn_ptr(closure_sig, b, adjust)
1197+
}
1198+
Err(err) => Err(err),
11811199
}
11821200
}
11831201
_ => self.unify(a, b, ForceLeakCheck::No),

0 commit comments

Comments
 (0)