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

Commit 6950f14

Browse files
committed
rustdoc: show tuple impls as impl Trait for (T, ...)
This commit adds a new unstable attribute, `#[doc(tuple_varadic)]`, that shows a 1-tuple as `(T, ...)` instead of just `(T,)`, and links to a section in the tuple primitive docs that talks about these.
1 parent 7a93567 commit 6950f14

File tree

15 files changed

+111
-44
lines changed

15 files changed

+111
-44
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
401401
let msg = "`#[doc(keyword)]` is meant for internal use only";
402402
gate_feature_post!(self, rustdoc_internals, attr.span, msg);
403403
}
404+
405+
if nested_meta.has_name(sym::tuple_varadic) {
406+
let msg = "`#[doc(tuple_varadic)]` is meant for internal use only";
407+
gate_feature_post!(self, rustdoc_internals, attr.span, msg);
408+
}
404409
}
405410
}
406411

compiler/rustc_passes/src/check_attr.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,37 @@ impl CheckAttrVisitor<'_> {
804804
true
805805
}
806806

807+
fn check_doc_tuple_varadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
808+
match self.tcx.hir().find(hir_id).and_then(|node| match node {
809+
hir::Node::Item(item) => Some(&item.kind),
810+
_ => None,
811+
}) {
812+
Some(ItemKind::Impl(ref i)) => {
813+
if !matches!(&i.self_ty.kind, hir::TyKind::Tup([_])) {
814+
self.tcx
815+
.sess
816+
.struct_span_err(
817+
meta.span(),
818+
"`#[doc(tuple_varadic)]` can only be used on unary tuples",
819+
)
820+
.emit();
821+
return false;
822+
}
823+
}
824+
_ => {
825+
self.tcx
826+
.sess
827+
.struct_span_err(
828+
meta.span(),
829+
"`#[doc(keyword = \"...\")]` can only be used on impl blocks",
830+
)
831+
.emit();
832+
return false;
833+
}
834+
}
835+
true
836+
}
837+
807838
/// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes. Returns `true` if valid.
808839
///
809840
/// A doc inlining attribute is invalid if it is applied to a non-`use` item, or
@@ -1064,6 +1095,13 @@ impl CheckAttrVisitor<'_> {
10641095
is_valid = false
10651096
}
10661097

1098+
sym::tuple_varadic
1099+
if !self.check_attr_not_crate_level(meta, hir_id, "tuple_varadic")
1100+
|| !self.check_doc_tuple_varadic(meta, hir_id) =>
1101+
{
1102+
is_valid = false
1103+
}
1104+
10671105
sym::html_favicon_url
10681106
| sym::html_logo_url
10691107
| sym::html_playground_url
@@ -1117,7 +1155,8 @@ impl CheckAttrVisitor<'_> {
11171155
| sym::no_inline
11181156
| sym::notable_trait
11191157
| sym::passes
1120-
| sym::plugins => {}
1158+
| sym::plugins
1159+
| sym::tuple_varadic => {}
11211160

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

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,7 @@ symbols! {
14391439
tuple,
14401440
tuple_from_req,
14411441
tuple_indexing,
1442+
tuple_varadic,
14421443
two_phase,
14431444
ty,
14441445
type_alias_enum_variants,

library/core/src/fmt/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,7 @@ macro_rules! tuple {
23352335

23362336
macro_rules! maybe_tuple_doc {
23372337
($a:ident @ #[$meta:meta] $item:item) => {
2338+
#[cfg_attr(not(bootstrap), doc(tuple_varadic))]
23382339
#[doc = "This trait is implemented for tuples up to twelve items long."]
23392340
#[$meta]
23402341
$item

library/core/src/hash/mod.rs

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

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

library/core/src/primitive_docs.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -916,24 +916,11 @@ mod prim_str {}
916916
///
917917
/// # Trait implementations
918918
///
919-
/// If every type inside a tuple implements one of the following traits, then a
920-
/// tuple itself also implements it.
921-
///
922-
/// * [`Clone`]
923-
/// * [`Copy`]
924-
/// * [`PartialEq`]
925-
/// * [`Eq`]
926-
/// * [`PartialOrd`]
927-
/// * [`Ord`]
928-
/// * [`Debug`]
929-
/// * [`Default`]
930-
/// * [`Hash`]
931-
///
932-
/// [`Debug`]: fmt::Debug
933-
/// [`Hash`]: hash::Hash
934-
///
935-
/// Due to a temporary restriction in Rust's type system, these traits are only
936-
/// implemented on tuples of arity 12 or less. In the future, this may change.
919+
/// In this documentation the shorthand `(T, ...)` is used to represent all
920+
/// tuples up to length twelve. When that is used, any trait bounds expressed
921+
/// on `T` applies to each field of the tuple independently. Note that this is
922+
/// a convenience notation to avoid repetitive documentation, not valid
923+
/// Rust syntax.
937924
///
938925
/// # Examples
939926
///
@@ -978,6 +965,7 @@ impl<T, U> (T, U) {}
978965
// Fake impl that's only really used for docs.
979966
#[cfg(doc)]
980967
#[stable(feature = "rust1", since = "1.0.0")]
968+
#[doc(tuple_varadic)]
981969
/// This trait is implemented on arbitrary-length tuples.
982970
impl<T: Clone> Clone for (T,) {
983971
fn clone(&self) -> Self {
@@ -988,6 +976,7 @@ impl<T: Clone> Clone for (T,) {
988976
// Fake impl that's only really used for docs.
989977
#[cfg(doc)]
990978
#[stable(feature = "rust1", since = "1.0.0")]
979+
#[doc(tuple_varadic)]
991980
/// This trait is implemented on arbitrary-length tuples.
992981
impl<T: Copy> Copy for (T,) {
993982
// empty

library/core/src/tuple.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ macro_rules! tuple_impls {
105105

106106
macro_rules! maybe_tuple_doc {
107107
($a:ident @ #[$meta:meta] $item:item) => {
108+
#[cfg_attr(not(bootstrap), doc(tuple_varadic))]
108109
#[doc = "This trait is implemented for tuples up to twelve items long."]
109110
#[$meta]
110111
$item

library/std/src/primitive_docs.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -916,24 +916,11 @@ mod prim_str {}
916916
///
917917
/// # Trait implementations
918918
///
919-
/// If every type inside a tuple implements one of the following traits, then a
920-
/// tuple itself also implements it.
921-
///
922-
/// * [`Clone`]
923-
/// * [`Copy`]
924-
/// * [`PartialEq`]
925-
/// * [`Eq`]
926-
/// * [`PartialOrd`]
927-
/// * [`Ord`]
928-
/// * [`Debug`]
929-
/// * [`Default`]
930-
/// * [`Hash`]
931-
///
932-
/// [`Debug`]: fmt::Debug
933-
/// [`Hash`]: hash::Hash
934-
///
935-
/// Due to a temporary restriction in Rust's type system, these traits are only
936-
/// implemented on tuples of arity 12 or less. In the future, this may change.
919+
/// In this documentation the shorthand `(T, ...)` is used to represent all
920+
/// tuples up to length twelve. When that is used, any trait bounds expressed
921+
/// on `T` applies to each field of the tuple independently. Note that this is
922+
/// a convenience notation to avoid repetitive documentation, not valid
923+
/// Rust syntax.
937924
///
938925
/// # Examples
939926
///
@@ -978,6 +965,7 @@ impl<T, U> (T, U) {}
978965
// Fake impl that's only really used for docs.
979966
#[cfg(doc)]
980967
#[stable(feature = "rust1", since = "1.0.0")]
968+
#[doc(tuple_varadic)]
981969
/// This trait is implemented on arbitrary-length tuples.
982970
impl<T: Clone> Clone for (T,) {
983971
fn clone(&self) -> Self {
@@ -988,6 +976,7 @@ impl<T: Clone> Clone for (T,) {
988976
// Fake impl that's only really used for docs.
989977
#[cfg(doc)]
990978
#[stable(feature = "rust1", since = "1.0.0")]
979+
#[doc(tuple_varadic)]
991980
/// This trait is implemented on arbitrary-length tuples.
992981
impl<T: Copy> Copy for (T,) {
993982
// empty

src/librustdoc/clean/inline.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,11 @@ pub(crate) fn build_impl(
500500
for_,
501501
items: trait_items,
502502
polarity,
503-
kind: ImplKind::Normal,
503+
kind: if utils::has_doc_flag(tcx, did, sym::tuple_varadic) {
504+
ImplKind::TupleVaradic
505+
} else {
506+
ImplKind::Normal
507+
},
504508
}),
505509
box merged_attrs,
506510
cx,

src/librustdoc/clean/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,11 @@ fn clean_impl<'tcx>(
19991999
for_,
20002000
items,
20012001
polarity: tcx.impl_polarity(def_id),
2002-
kind: ImplKind::Normal,
2002+
kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::tuple_varadic) {
2003+
ImplKind::TupleVaradic
2004+
} else {
2005+
ImplKind::Normal
2006+
},
20032007
});
20042008
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
20052009
};

0 commit comments

Comments
 (0)