mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
implement and test fn ptr ABI compatibility rules
This commit is contained in:
parent
f993ddc079
commit
b5bab2b1cc
@ -298,8 +298,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
};
|
||||
// Check if the inner type is one of the NPO-guaranteed ones.
|
||||
Ok(match inner_ty.kind() {
|
||||
ty::Ref(..) => {
|
||||
// Option<&T> behaves like &T
|
||||
ty::Ref(..) | ty::FnPtr(..) => {
|
||||
// Option<&T> behaves like &T, and same for fn()
|
||||
inner_ty
|
||||
}
|
||||
ty::Adt(def, _)
|
||||
@ -366,6 +366,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
return Ok(meta_ty(left) == meta_ty(right));
|
||||
}
|
||||
|
||||
// Compatible function pointer types.
|
||||
if let (ty::FnPtr(..), ty::FnPtr(..)) = (caller_ty.kind(), callee_ty.kind()) {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Compatible integer types (in particular, usize vs ptr-sized-u32/u64).
|
||||
let int_ty = |ty: Ty<'tcx>| {
|
||||
Some(match ty.kind() {
|
||||
|
@ -5,6 +5,8 @@ use std::ptr;
|
||||
#[derive(Copy, Clone, Default)]
|
||||
struct Zst;
|
||||
|
||||
fn id<T>(x: T) -> T { x }
|
||||
|
||||
fn test_abi_compat<T: Clone, U: Clone>(t: T, u: U) {
|
||||
fn id<T>(x: T) -> T {
|
||||
x
|
||||
@ -70,8 +72,11 @@ fn main() {
|
||||
test_abi_compat(&(), ptr::NonNull::<()>::dangling());
|
||||
// Reference/pointer types with different but sized pointees.
|
||||
test_abi_compat(&0u32, &([true; 4], [0u32; 0]));
|
||||
// `fn` types
|
||||
test_abi_compat(main as fn(), id::<i32> as fn(i32) -> i32);
|
||||
// Guaranteed null-pointer-optimizations.
|
||||
test_abi_compat(&0u32 as *const u32, Some(&0u32));
|
||||
test_abi_compat(main as fn(), Some(main as fn()));
|
||||
test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap());
|
||||
test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap()));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user