Skip to content

Commit bead8ee

Browse files
committed
Auto merge of rust-lang#98180 - notriddle:notriddle/rustdoc-fn, r=petrochenkov,GuillaumeGomez
Improve the function pointer docs This is rust-lang#97842 but for function pointers instead of tuples. The concept is basically the same. * Reduce duplicate impls; show `fn (T₁, T₂, …, Tₙ)` and include a sentence saying that there exists up to twelve of them. * Show `Copy` and `Clone`. * Show auto traits like `Send` and `Sync`, and blanket impls like `Any`. https://notriddle.com/notriddle-rustdoc-test/std/primitive.fn.html
2 parents 8fd963e + f598693 commit bead8ee

File tree

6 files changed

+179
-57
lines changed

6 files changed

+179
-57
lines changed

core/src/fmt/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2562,7 +2562,7 @@ macro_rules! tuple {
25622562

25632563
macro_rules! maybe_tuple_doc {
25642564
($a:ident @ #[$meta:meta] $item:item) => {
2565-
#[doc(tuple_variadic)]
2565+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
25662566
#[doc = "This trait is implemented for tuples up to twelve items long."]
25672567
#[$meta]
25682568
$item

core/src/hash/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ mod impls {
900900

901901
macro_rules! maybe_tuple_doc {
902902
($a:ident @ #[$meta:meta] $item:item) => {
903-
#[doc(tuple_variadic)]
903+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
904904
#[doc = "This trait is implemented for tuples up to twelve items long."]
905905
#[$meta]
906906
$item

core/src/primitive_docs.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ impl<T> (T,) {}
996996
// Fake impl that's only really used for docs.
997997
#[cfg(doc)]
998998
#[stable(feature = "rust1", since = "1.0.0")]
999-
#[doc(tuple_variadic)]
999+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
10001000
/// This trait is implemented on arbitrary-length tuples.
10011001
impl<T: Clone> Clone for (T,) {
10021002
fn clone(&self) -> Self {
@@ -1007,7 +1007,7 @@ impl<T: Clone> Clone for (T,) {
10071007
// Fake impl that's only really used for docs.
10081008
#[cfg(doc)]
10091009
#[stable(feature = "rust1", since = "1.0.0")]
1010-
#[doc(tuple_variadic)]
1010+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
10111011
/// This trait is implemented on arbitrary-length tuples.
10121012
impl<T: Copy> Copy for (T,) {
10131013
// empty
@@ -1441,11 +1441,16 @@ mod prim_ref {}
14411441
/// Note that all of this is not portable to platforms where function pointers and data pointers
14421442
/// have different sizes.
14431443
///
1444-
/// ### Traits
1444+
/// ### Trait implementations
14451445
///
1446-
/// Function pointers implement the following traits:
1446+
/// In this documentation the shorthand `fn (T₁, T₂, …, Tₙ)` is used to represent non-variadic
1447+
/// function pointers of varying length. Note that this is a convenience notation to avoid
1448+
/// repetitive documentation, not valid Rust syntax.
1449+
///
1450+
/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
1451+
/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
1452+
/// may change:
14471453
///
1448-
/// * [`Clone`]
14491454
/// * [`PartialEq`]
14501455
/// * [`Eq`]
14511456
/// * [`PartialOrd`]
@@ -1454,15 +1459,50 @@ mod prim_ref {}
14541459
/// * [`Pointer`]
14551460
/// * [`Debug`]
14561461
///
1462+
/// The following traits are implemented for function pointers with any number of arguments and
1463+
/// any ABI. These traits have implementations that are automatically generated by the compiler,
1464+
/// so are not limited by missing language features:
1465+
///
1466+
/// * [`Clone`]
1467+
/// * [`Copy`]
1468+
/// * [`Send`]
1469+
/// * [`Sync`]
1470+
/// * [`Unpin`]
1471+
/// * [`UnwindSafe`]
1472+
/// * [`RefUnwindSafe`]
1473+
///
14571474
/// [`Hash`]: hash::Hash
14581475
/// [`Pointer`]: fmt::Pointer
1476+
/// [`UnwindSafe`]: panic::UnwindSafe
1477+
/// [`RefUnwindSafe`]: panic::RefUnwindSafe
14591478
///
1460-
/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
1461-
/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
1462-
/// may change.
1463-
///
1464-
/// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe*
1465-
/// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits
1466-
/// are specially known to the compiler.
1479+
/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
1480+
/// these traits are specially known to the compiler.
14671481
#[stable(feature = "rust1", since = "1.0.0")]
14681482
mod prim_fn {}
1483+
1484+
// Required to make auto trait impls render.
1485+
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
1486+
#[doc(hidden)]
1487+
#[cfg(not(bootstrap))]
1488+
impl<Ret, T> fn(T) -> Ret {}
1489+
1490+
// Fake impl that's only really used for docs.
1491+
#[cfg(doc)]
1492+
#[stable(feature = "rust1", since = "1.0.0")]
1493+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1494+
/// This trait is implemented on function pointers with any number of arguments.
1495+
impl<Ret, T> Clone for fn(T) -> Ret {
1496+
fn clone(&self) -> Self {
1497+
loop {}
1498+
}
1499+
}
1500+
1501+
// Fake impl that's only really used for docs.
1502+
#[cfg(doc)]
1503+
#[stable(feature = "rust1", since = "1.0.0")]
1504+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1505+
/// This trait is implemented on function pointers with any number of arguments.
1506+
impl<Ret, T> Copy for fn(T) -> Ret {
1507+
// empty
1508+
}

core/src/ptr/mod.rs

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,27 @@ pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
18191819
hashee.hash(into);
18201820
}
18211821

1822+
// If this is a unary fn pointer, it adds a doc comment.
1823+
// Otherwise, it hides the docs entirely.
1824+
macro_rules! maybe_fnptr_doc {
1825+
(@ #[$meta:meta] $item:item) => {
1826+
#[doc(hidden)]
1827+
#[$meta]
1828+
$item
1829+
};
1830+
($a:ident @ #[$meta:meta] $item:item) => {
1831+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1832+
#[doc = "This trait is implemented for function pointers with up to twelve arguments."]
1833+
#[$meta]
1834+
$item
1835+
};
1836+
($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
1837+
#[doc(hidden)]
1838+
#[$meta]
1839+
$item
1840+
};
1841+
}
1842+
18221843
// FIXME(strict_provenance_magic): function pointers have buggy codegen that
18231844
// necessitates casting to a usize to get the backend to do the right thing.
18241845
// for now I will break AVR to silence *a billion* lints. We should probably
@@ -1827,51 +1848,72 @@ pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
18271848
// Impls for function pointers
18281849
macro_rules! fnptr_impls_safety_abi {
18291850
($FnTy: ty, $($Arg: ident),*) => {
1830-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1831-
impl<Ret, $($Arg),*> PartialEq for $FnTy {
1832-
#[inline]
1833-
fn eq(&self, other: &Self) -> bool {
1834-
*self as usize == *other as usize
1851+
maybe_fnptr_doc! {
1852+
$($Arg)* @
1853+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1854+
impl<Ret, $($Arg),*> PartialEq for $FnTy {
1855+
#[inline]
1856+
fn eq(&self, other: &Self) -> bool {
1857+
*self as usize == *other as usize
1858+
}
18351859
}
18361860
}
18371861

1838-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1839-
impl<Ret, $($Arg),*> Eq for $FnTy {}
1862+
maybe_fnptr_doc! {
1863+
$($Arg)* @
1864+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1865+
impl<Ret, $($Arg),*> Eq for $FnTy {}
1866+
}
18401867

1841-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1842-
impl<Ret, $($Arg),*> PartialOrd for $FnTy {
1843-
#[inline]
1844-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1845-
(*self as usize).partial_cmp(&(*other as usize))
1868+
maybe_fnptr_doc! {
1869+
$($Arg)* @
1870+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1871+
impl<Ret, $($Arg),*> PartialOrd for $FnTy {
1872+
#[inline]
1873+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1874+
(*self as usize).partial_cmp(&(*other as usize))
1875+
}
18461876
}
18471877
}
18481878

1849-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1850-
impl<Ret, $($Arg),*> Ord for $FnTy {
1851-
#[inline]
1852-
fn cmp(&self, other: &Self) -> Ordering {
1853-
(*self as usize).cmp(&(*other as usize))
1879+
maybe_fnptr_doc! {
1880+
$($Arg)* @
1881+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1882+
impl<Ret, $($Arg),*> Ord for $FnTy {
1883+
#[inline]
1884+
fn cmp(&self, other: &Self) -> Ordering {
1885+
(*self as usize).cmp(&(*other as usize))
1886+
}
18541887
}
18551888
}
18561889

1857-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1858-
impl<Ret, $($Arg),*> hash::Hash for $FnTy {
1859-
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
1860-
state.write_usize(*self as usize)
1890+
maybe_fnptr_doc! {
1891+
$($Arg)* @
1892+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1893+
impl<Ret, $($Arg),*> hash::Hash for $FnTy {
1894+
fn hash<HH: hash::Hasher>(&self, state: &mut HH) {
1895+
state.write_usize(*self as usize)
1896+
}
18611897
}
18621898
}
18631899

1864-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1865-
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
1866-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1867-
fmt::pointer_fmt_inner(*self as usize, f)
1900+
maybe_fnptr_doc! {
1901+
$($Arg)* @
1902+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1903+
impl<Ret, $($Arg),*> fmt::Pointer for $FnTy {
1904+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1905+
fmt::pointer_fmt_inner(*self as usize, f)
1906+
}
18681907
}
18691908
}
18701909

1871-
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1872-
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
1873-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1874-
fmt::pointer_fmt_inner(*self as usize, f)
1910+
maybe_fnptr_doc! {
1911+
$($Arg)* @
1912+
#[stable(feature = "fnptr_impls", since = "1.4.0")]
1913+
impl<Ret, $($Arg),*> fmt::Debug for $FnTy {
1914+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1915+
fmt::pointer_fmt_inner(*self as usize, f)
1916+
}
18751917
}
18761918
}
18771919
}
@@ -1896,7 +1938,7 @@ macro_rules! fnptr_impls_args {
18961938
}
18971939

18981940
fnptr_impls_args! {}
1899-
fnptr_impls_args! { A }
1941+
fnptr_impls_args! { T }
19001942
fnptr_impls_args! { A, B }
19011943
fnptr_impls_args! { A, B, C }
19021944
fnptr_impls_args! { A, B, C, D }

core/src/tuple.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ macro_rules! tuple_impls {
107107
// Otherwise, it hides the docs entirely.
108108
macro_rules! maybe_tuple_doc {
109109
($a:ident @ #[$meta:meta] $item:item) => {
110-
#[doc(tuple_variadic)]
110+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
111111
#[doc = "This trait is implemented for tuples up to twelve items long."]
112112
#[$meta]
113113
$item

std/src/primitive_docs.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ impl<T> (T,) {}
996996
// Fake impl that's only really used for docs.
997997
#[cfg(doc)]
998998
#[stable(feature = "rust1", since = "1.0.0")]
999-
#[doc(tuple_variadic)]
999+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
10001000
/// This trait is implemented on arbitrary-length tuples.
10011001
impl<T: Clone> Clone for (T,) {
10021002
fn clone(&self) -> Self {
@@ -1007,7 +1007,7 @@ impl<T: Clone> Clone for (T,) {
10071007
// Fake impl that's only really used for docs.
10081008
#[cfg(doc)]
10091009
#[stable(feature = "rust1", since = "1.0.0")]
1010-
#[doc(tuple_variadic)]
1010+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
10111011
/// This trait is implemented on arbitrary-length tuples.
10121012
impl<T: Copy> Copy for (T,) {
10131013
// empty
@@ -1441,11 +1441,16 @@ mod prim_ref {}
14411441
/// Note that all of this is not portable to platforms where function pointers and data pointers
14421442
/// have different sizes.
14431443
///
1444-
/// ### Traits
1444+
/// ### Trait implementations
14451445
///
1446-
/// Function pointers implement the following traits:
1446+
/// In this documentation the shorthand `fn (T₁, T₂, …, Tₙ)` is used to represent non-variadic
1447+
/// function pointers of varying length. Note that this is a convenience notation to avoid
1448+
/// repetitive documentation, not valid Rust syntax.
1449+
///
1450+
/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
1451+
/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
1452+
/// may change:
14471453
///
1448-
/// * [`Clone`]
14491454
/// * [`PartialEq`]
14501455
/// * [`Eq`]
14511456
/// * [`PartialOrd`]
@@ -1454,15 +1459,50 @@ mod prim_ref {}
14541459
/// * [`Pointer`]
14551460
/// * [`Debug`]
14561461
///
1462+
/// The following traits are implemented for function pointers with any number of arguments and
1463+
/// any ABI. These traits have implementations that are automatically generated by the compiler,
1464+
/// so are not limited by missing language features:
1465+
///
1466+
/// * [`Clone`]
1467+
/// * [`Copy`]
1468+
/// * [`Send`]
1469+
/// * [`Sync`]
1470+
/// * [`Unpin`]
1471+
/// * [`UnwindSafe`]
1472+
/// * [`RefUnwindSafe`]
1473+
///
14571474
/// [`Hash`]: hash::Hash
14581475
/// [`Pointer`]: fmt::Pointer
1476+
/// [`UnwindSafe`]: panic::UnwindSafe
1477+
/// [`RefUnwindSafe`]: panic::RefUnwindSafe
14591478
///
1460-
/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
1461-
/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
1462-
/// may change.
1463-
///
1464-
/// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe*
1465-
/// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits
1466-
/// are specially known to the compiler.
1479+
/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
1480+
/// these traits are specially known to the compiler.
14671481
#[stable(feature = "rust1", since = "1.0.0")]
14681482
mod prim_fn {}
1483+
1484+
// Required to make auto trait impls render.
1485+
// See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
1486+
#[doc(hidden)]
1487+
#[cfg(not(bootstrap))]
1488+
impl<Ret, T> fn(T) -> Ret {}
1489+
1490+
// Fake impl that's only really used for docs.
1491+
#[cfg(doc)]
1492+
#[stable(feature = "rust1", since = "1.0.0")]
1493+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1494+
/// This trait is implemented on function pointers with any number of arguments.
1495+
impl<Ret, T> Clone for fn(T) -> Ret {
1496+
fn clone(&self) -> Self {
1497+
loop {}
1498+
}
1499+
}
1500+
1501+
// Fake impl that's only really used for docs.
1502+
#[cfg(doc)]
1503+
#[stable(feature = "rust1", since = "1.0.0")]
1504+
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
1505+
/// This trait is implemented on function pointers with any number of arguments.
1506+
impl<Ret, T> Copy for fn(T) -> Ret {
1507+
// empty
1508+
}

0 commit comments

Comments
 (0)