Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 9a7b7d5

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 29c5a02 + ddb5a26 commit 9a7b7d5

File tree

29 files changed

+278
-106
lines changed

29 files changed

+278
-106
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
404404
gate_feature_post!(self, rustdoc_internals, attr.span, msg);
405405
}
406406

407-
if nested_meta.has_name(sym::tuple_variadic) {
408-
let msg = "`#[doc(tuple_variadic)]` is meant for internal use only";
407+
if nested_meta.has_name(sym::fake_variadic) {
408+
let msg = "`#[doc(fake_variadic)]` is meant for internal use only";
409409
gate_feature_post!(self, rustdoc_internals, attr.span, msg);
410410
}
411411
}

compiler/rustc_error_codes/src/error_codes/E0118.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ enum, union, or trait object.
44
Erroneous code example:
55

66
```compile_fail,E0118
7-
impl fn(u8) { // error: no nominal type found for inherent implementation
7+
impl<T> T { // error: no nominal type found for inherent implementation
88
fn get_state(&self) -> String {
99
// ...
1010
}
@@ -20,8 +20,8 @@ trait LiveLongAndProsper {
2020
fn get_state(&self) -> String;
2121
}
2222
23-
// and now you can implement it on fn(u8)
24-
impl LiveLongAndProsper for fn(u8) {
23+
// and now you can implement it on T
24+
impl<T> LiveLongAndProsper for T {
2525
fn get_state(&self) -> String {
2626
"He's dead, Jim!".to_owned()
2727
}
@@ -33,9 +33,9 @@ For example, `NewType` is a newtype over `Foo` in `struct NewType(Foo)`.
3333
Example:
3434

3535
```
36-
struct TypeWrapper(fn(u8));
36+
struct TypeWrapper<T>(T);
3737
38-
impl TypeWrapper {
38+
impl<T> TypeWrapper<T> {
3939
fn get_state(&self) -> String {
4040
"Fascinating!".to_owned()
4141
}

compiler/rustc_error_messages/locales/en-US/passes.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
8181
8282
passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
8383
84-
passes-doc-tuple-variadic-not-first =
85-
`#[doc(tuple_variadic)]` must be used on the first of a set of tuple trait impls with varying arity
84+
passes-doc-fake-variadic-not-valid =
85+
`#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity
8686
8787
passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
8888

compiler/rustc_passes/src/check_attr.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -706,14 +706,20 @@ impl CheckAttrVisitor<'_> {
706706
true
707707
}
708708

709-
fn check_doc_tuple_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
709+
fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
710710
match self.tcx.hir().find(hir_id).and_then(|node| match node {
711711
hir::Node::Item(item) => Some(&item.kind),
712712
_ => None,
713713
}) {
714714
Some(ItemKind::Impl(ref i)) => {
715-
if !matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) {
716-
self.tcx.sess.emit_err(errors::DocTupleVariadicNotFirst { span: meta.span() });
715+
let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_]))
716+
|| if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind {
717+
bare_fn_ty.decl.inputs.len() == 1
718+
} else {
719+
false
720+
};
721+
if !is_valid {
722+
self.tcx.sess.emit_err(errors::DocFakeVariadicNotValid { span: meta.span() });
717723
return false;
718724
}
719725
}
@@ -887,9 +893,9 @@ impl CheckAttrVisitor<'_> {
887893
is_valid = false
888894
}
889895

890-
sym::tuple_variadic
891-
if !self.check_attr_not_crate_level(meta, hir_id, "tuple_variadic")
892-
|| !self.check_doc_tuple_variadic(meta, hir_id) =>
896+
sym::fake_variadic
897+
if !self.check_attr_not_crate_level(meta, hir_id, "fake_variadic")
898+
|| !self.check_doc_fake_variadic(meta, hir_id) =>
893899
{
894900
is_valid = false
895901
}
@@ -939,7 +945,7 @@ impl CheckAttrVisitor<'_> {
939945
| sym::notable_trait
940946
| sym::passes
941947
| sym::plugins
942-
| sym::tuple_variadic => {}
948+
| sym::fake_variadic => {}
943949

944950
sym::test => {
945951
if !self.check_test_attr(meta, hir_id) {

compiler/rustc_passes/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ pub struct DocKeywordInvalidIdent {
212212
}
213213

214214
#[derive(SessionDiagnostic)]
215-
#[error(passes::doc_tuple_variadic_not_first)]
216-
pub struct DocTupleVariadicNotFirst {
215+
#[error(passes::doc_fake_variadic_not_valid)]
216+
pub struct DocFakeVariadicNotValid {
217217
#[primary_span]
218218
pub span: Span,
219219
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ symbols! {
696696
fabsf32,
697697
fabsf64,
698698
fadd_fast,
699+
fake_variadic,
699700
fdiv_fast,
700701
feature,
701702
fence,
@@ -1471,7 +1472,6 @@ symbols! {
14711472
tuple,
14721473
tuple_from_req,
14731474
tuple_indexing,
1474-
tuple_variadic,
14751475
two_phase,
14761476
ty,
14771477
type_alias_enum_variants,

compiler/rustc_typeck/src/coherence/inherent_impls.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ impl<'tcx> InherentCollect<'tcx> {
219219
| ty::RawPtr(_)
220220
| ty::Ref(..)
221221
| ty::Never
222+
| ty::FnPtr(_)
222223
| ty::Tuple(..) => self.check_primitive_impl(item.def_id, self_ty, items, ty.span),
223-
ty::FnPtr(_) | ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
224+
ty::Projection(..) | ty::Opaque(..) | ty::Param(_) => {
224225
let mut err = struct_span_err!(
225226
self.tcx.sess,
226227
ty.span,

library/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

library/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

library/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+
}

0 commit comments

Comments
 (0)