diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index cfcc3ffb9c092..351d3d5101ba8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -159,11 +159,21 @@ #![feature(const_is_char_boundary)] // // Language features: +#![feature(abi_amdgpu_kernel)] +#![feature(abi_avr_interrupt)] +#![feature(abi_c_cmse_nonsecure_call)] +#![feature(abi_efiapi)] +#![feature(abi_msp430_interrupt)] +#![feature(abi_ptx)] +#![feature(abi_thiscall)] #![feature(abi_unadjusted)] +#![feature(abi_vectorcall)] +#![feature(abi_x86_interrupt)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] #![feature(associated_type_bounds)] #![feature(auto_traits)] +#![feature(c_unwind)] #![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(const_fn_floating_point_arithmetic)] @@ -206,6 +216,7 @@ #![feature(try_blocks)] #![feature(unboxed_closures)] #![feature(unsized_fn_params)] +#![feature(wasm_abi)] #![feature(asm_const)] // // Target features: diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 688ab63bf1366..d57524bb587be 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1394,8 +1394,9 @@ mod prim_ref {} /// [`Pointer`]: fmt::Pointer /// /// Due to a temporary restriction in Rust's type system, these traits are only implemented on -/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this -/// may change. +/// functions that take 12 arguments or less. In the future, this may change. +/// +/// These traits are implemented on all available ABIs, though the documentation hides them. /// /// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe* /// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index d2e680ecd20b5..d239ad790934c 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1839,7 +1839,8 @@ pub fn hash(hashee: *const T, into: &mut S) { // Impls for function pointers macro_rules! fnptr_impls_safety_abi { - ($FnTy: ty, $($Arg: ident),*) => { + ($(#[$Meta:meta])? $FnTy: ty, $($Arg: ident),*) => { + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl PartialEq for $FnTy { #[inline] @@ -1848,9 +1849,11 @@ macro_rules! fnptr_impls_safety_abi { } } + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl Eq for $FnTy {} + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl PartialOrd for $FnTy { #[inline] @@ -1859,6 +1862,7 @@ macro_rules! fnptr_impls_safety_abi { } } + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl Ord for $FnTy { #[inline] @@ -1867,6 +1871,7 @@ macro_rules! fnptr_impls_safety_abi { } } + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl hash::Hash for $FnTy { fn hash(&self, state: &mut HH) { @@ -1874,6 +1879,7 @@ macro_rules! fnptr_impls_safety_abi { } } + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Pointer for $FnTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1886,6 +1892,7 @@ macro_rules! fnptr_impls_safety_abi { } } + $(#[$Meta])? #[stable(feature = "fnptr_impls", since = "1.4.0")] impl fmt::Debug for $FnTy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1900,21 +1907,70 @@ macro_rules! fnptr_impls_safety_abi { } } -macro_rules! fnptr_impls_args { - ($($Arg: ident),+) => { - fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } +// #[doc(hidden)] is applied by default due to how many permutations are made. +// Without this, the documentation page for `fn` becomes 14 MB. +// In the future, this could be replaced by having rustdoc collapse repetitive ABI impls. +macro_rules! fnptr_impl_for_abi { + ($Abi:tt, $($Arg: ident),*) => { + fnptr_impls_safety_abi! { #[doc(hidden)] extern $Abi fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { #[doc(hidden)] unsafe extern $Abi fn($($Arg),*) -> Ret, $($Arg),* } + }; +} + +macro_rules! fnptr_impl_for_abi_with_docs { + ($Abi:tt, $($Arg: ident),*) => { + fnptr_impls_safety_abi! { extern $Abi fn($($Arg),*) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { unsafe extern $Abi fn($($Arg),*) -> Ret, $($Arg),* } }; - () => { +} + +macro_rules! fnptr_impl_for_abi_variadic_support { + ($Abi:tt, ) => { // No variadic functions with 0 parameters - fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, } - fnptr_impls_safety_abi! { extern "C" fn() -> Ret, } - fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, } - fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, } + fnptr_impls_safety_abi! { #[doc(hidden)] extern $Abi fn() -> Ret, } + fnptr_impls_safety_abi! { #[doc(hidden)] unsafe extern $Abi fn() -> Ret, } + }; + + ($Abi:tt, $($Arg: ident),*) => { + fnptr_impl_for_abi! { $Abi, $($Arg),* } + + fnptr_impls_safety_abi! { #[doc(hidden)] extern $Abi fn($($Arg),*, ...) -> Ret, $($Arg),* } + fnptr_impls_safety_abi! { #[doc(hidden)] unsafe extern $Abi fn($($Arg),*, ...) -> Ret, $($Arg),* } + } +} + +macro_rules! fnptr_impls_args { + ($($Arg: ident),*) => { + fnptr_impl_for_abi_with_docs! { "Rust", $($Arg),* } + + fnptr_impl_for_abi! { "C-cmse-nonsecure-call", $($Arg),* } + fnptr_impl_for_abi! { "C-unwind", $($Arg),* } + fnptr_impl_for_abi! { "aapcs", $($Arg),* } + fnptr_impl_for_abi! { "amdgpu-kernel", $($Arg),* } + fnptr_impl_for_abi! { "avr-interrupt", $($Arg),* } + fnptr_impl_for_abi! { "avr-non-blocking-interrupt", $($Arg),* } + fnptr_impl_for_abi! { "efiapi", $($Arg),* } + fnptr_impl_for_abi! { "fastcall", $($Arg),* } + fnptr_impl_for_abi! { "msp430-interrupt", $($Arg),* } + fnptr_impl_for_abi! { "platform-intrinsic", $($Arg),* } + fnptr_impl_for_abi! { "ptx-kernel", $($Arg),* } + fnptr_impl_for_abi! { "rust-call", $($Arg),* } + fnptr_impl_for_abi! { "rust-intrinsic", $($Arg),* } + fnptr_impl_for_abi! { "stdcall", $($Arg),* } + fnptr_impl_for_abi! { "stdcall-unwind", $($Arg),* } + fnptr_impl_for_abi! { "system", $($Arg),* } + fnptr_impl_for_abi! { "system-unwind", $($Arg),* } + fnptr_impl_for_abi! { "sysv64", $($Arg),* } + fnptr_impl_for_abi! { "thiscall", $($Arg),* } + fnptr_impl_for_abi! { "thiscall-unwind", $($Arg),* } + fnptr_impl_for_abi! { "unadjusted", $($Arg),* } + fnptr_impl_for_abi! { "vectorcall", $($Arg),* } + fnptr_impl_for_abi! { "wasm", $($Arg),* } + fnptr_impl_for_abi! { "win64", $($Arg),* } + fnptr_impl_for_abi! { "x86-interrupt", $($Arg),* } + + fnptr_impl_for_abi_variadic_support! { "C", $($Arg),* } + fnptr_impl_for_abi_variadic_support! { "cdecl", $($Arg),* } }; } diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 688ab63bf1366..d57524bb587be 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1394,8 +1394,9 @@ mod prim_ref {} /// [`Pointer`]: fmt::Pointer /// /// Due to a temporary restriction in Rust's type system, these traits are only implemented on -/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this -/// may change. +/// functions that take 12 arguments or less. In the future, this may change. +/// +/// These traits are implemented on all available ABIs, though the documentation hides them. /// /// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe* /// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits diff --git a/src/test/ui/function-pointer/function-pointer-impls.rs b/src/test/ui/function-pointer/function-pointer-impls.rs new file mode 100644 index 0000000000000..25ba4e7757cfa --- /dev/null +++ b/src/test/ui/function-pointer/function-pointer-impls.rs @@ -0,0 +1,11 @@ +// check-pass +fn assert_debug() {} + +fn main() { + assert_debug::(); + assert_debug::(); + assert_debug::(); + assert_debug::(); + assert_debug::(); + assert_debug::(); +} diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 76a47c49bbafb..a7863a89b2da5 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -103,7 +103,7 @@ LL | assert_eq!(Foo::Bar, i); extern "C" fn(A, B, C) -> Ret extern "C" fn(A, B, C, ...) -> Ret extern "C" fn(A, B, C, D) -> Ret - and 68 others + and 768 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 9 previous errors