Skip to content

Commit b5bab2b

Browse files
committed
implement and test fn ptr ABI compatibility rules
1 parent f993ddc commit b5bab2b

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, _)
@@ -366,6 +366,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
366366
return Ok(meta_ty(left) == meta_ty(right));
367367
}
368368

369+
// Compatible function pointer types.
370+
if let (ty::FnPtr(..), ty::FnPtr(..)) = (caller_ty.kind(), callee_ty.kind()) {
371+
return Ok(true);
372+
}
373+
369374
// Compatible integer types (in particular, usize vs ptr-sized-u32/u64).
370375
let int_ty = |ty: Ty<'tcx>| {
371376
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)