Skip to content

Commit 6d94edd

Browse files
committed
implement and test fn ptr ABI compatibility rules
1 parent 5c579dd commit 6d94edd

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
298298
};
299299
// Check if the inner type is one of the NPO-guaranteed ones.
300300
Ok(match inner_ty.kind() {
301-
ty::Ref(..) => {
302-
// Option<&T> behaves like &T
301+
ty::Ref(..) | ty::FnPtr(..) => {
302+
// Option<&T> behaves like &T, and same for fn()
303303
inner_ty
304304
}
305305
ty::Adt(def, _)
@@ -368,6 +368,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
368368
return Ok(meta_ty(left) == meta_ty(right));
369369
}
370370

371+
// Compatible function pointer types.
372+
if let (ty::FnPtr(..), ty::FnPtr(..)) = (caller_ty.kind(), callee_ty.kind()) {
373+
return Ok(true);
374+
}
375+
371376
// Compatible integer types (in particular, usize vs ptr-sized-u32/u64).
372377
let int_ty = |ty: Ty<'tcx>| {
373378
Some(match ty.kind() {

src/tools/miri/tests/pass/function_calls/abi_compat.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::ptr;
55
#[derive(Copy, Clone, Default)]
66
struct Zst;
77

8+
fn id<T>(x: T) -> T { x }
9+
810
fn test_abi_compat<T: Clone, U: Clone>(t: T, u: U) {
911
fn id<T>(x: T) -> T {
1012
x
@@ -70,8 +72,11 @@ fn main() {
7072
test_abi_compat(&(), ptr::NonNull::<()>::dangling());
7173
// Reference/pointer types with different but sized pointees.
7274
test_abi_compat(&0u32, &([true; 4], [0u32; 0]));
75+
// `fn` types
76+
test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
7377
// Guaranteed null-pointer-optimizations.
7478
test_abi_compat(&0u32 as *const u32, Some(&0u32));
79+
test_abi_compat(main as fn(), Some(main as fn()));
7580
test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap());
7681
test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap()));
7782

0 commit comments

Comments
 (0)