about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2024-10-24 15:53:36 -0700
committerGitHub <noreply@github.com>2024-10-24 15:53:36 -0700
commit3549dbb14969ed7e9ce5f92de1cfd02b961dcb7a (patch)
tree90a6783ca12f8a21ac82991dce18e93ca53b042e
parent96ae9d4703ed017c555b852cbd58efdf412fa805 (diff)
parent4e487689085ba8b490fbf735163250cc4edb05ae (diff)
downloadrust-3549dbb14969ed7e9ce5f92de1cfd02b961dcb7a.tar.gz
rust-3549dbb14969ed7e9ce5f92de1cfd02b961dcb7a.zip
Rollup merge of #132115 - bash:rustdoc-fake-variadic-wrapper, r=GuillaumeGomez,notriddle
rustdoc: Extend fake_variadic to "wrapped" tuples

This allows impls such as `impl QueryData for OneOf<(T,)>` to be displayed as variadic: `impl QueryData for OneOf<(T₁, T₂, …, Tₙ)>`.

See question on [zulip](https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/Make.20.60.23.5Bdoc.28fake_variadic.29.5D.60.20more.20useful).
-rw-r--r--compiler/rustc_passes/src/check_attr.rs24
-rw-r--r--src/librustdoc/html/format.rs18
-rw-r--r--tests/rustdoc/primitive-tuple-variadic.rs19
3 files changed, 55 insertions, 6 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 61e196bdebe..62c502f9524 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -918,12 +918,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         };
         match item_kind {
             Some(ItemKind::Impl(i)) => {
-                let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_]))
-                    || if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind {
-                        bare_fn_ty.decl.inputs.len() == 1
-                    } else {
-                        false
-                    }
+                let is_valid = doc_fake_variadic_is_allowed_self_ty(i.self_ty)
                     || if let Some(&[hir::GenericArg::Type(ty)]) = i
                         .of_trait
                         .as_ref()
@@ -2630,3 +2625,20 @@ fn check_duplicates(
         },
     }
 }
+
+fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool {
+    matches!(&self_ty.kind, hir::TyKind::Tup([_]))
+        || if let hir::TyKind::BareFn(bare_fn_ty) = &self_ty.kind {
+            bare_fn_ty.decl.inputs.len() == 1
+        } else {
+            false
+        }
+        || (if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &self_ty.kind
+            && let Some(&[hir::GenericArg::Type(ty)]) =
+                path.segments.last().map(|last| last.args().args)
+        {
+            doc_fake_variadic_is_allowed_self_ty(ty)
+        } else {
+            false
+        })
+}
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 5c599f20f9f..ea2f930ab83 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1368,6 +1368,24 @@ impl clean::Impl {
                 write!(f, " -> ")?;
                 fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
             }
+        } else if let clean::Type::Path { path } = type_
+            && let Some(generics) = path.generics()
+            && generics.len() == 1
+            && self.kind.is_fake_variadic()
+        {
+            let ty = generics[0];
+            let wrapper = anchor(path.def_id(), path.last(), cx);
+            if f.alternate() {
+                write!(f, "{wrapper:#}&lt;")?;
+            } else {
+                write!(f, "{wrapper}<")?;
+            }
+            self.print_type(ty, f, use_absolute, cx)?;
+            if f.alternate() {
+                write!(f, "&gt;")?;
+            } else {
+                write!(f, ">")?;
+            }
         } else {
             fmt_type(&type_, f, use_absolute, cx)?;
         }
diff --git a/tests/rustdoc/primitive-tuple-variadic.rs b/tests/rustdoc/primitive-tuple-variadic.rs
index b15e996f929..d142729d2a8 100644
--- a/tests/rustdoc/primitive-tuple-variadic.rs
+++ b/tests/rustdoc/primitive-tuple-variadic.rs
@@ -33,3 +33,22 @@ impl<T> Baz<[T; 1]> for (T,) {}
 //@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl<T> Baz<T> for (T₁, T₂, …, Tₙ)'
 #[doc(fake_variadic)]
 impl<T> Baz<T> for (T,) {}
+
+pub trait Qux {}
+
+pub struct NewType<T>(T);
+
+//@ has foo/trait.Qux.html
+//@ has - '//section[@id="impl-Qux-for-NewType%3C(T,)%3E"]/h3' 'impl<T> Qux for NewType<(T₁, T₂, …, Tₙ)>'
+#[doc(fake_variadic)]
+impl<T> Qux for NewType<(T,)> {}
+
+//@ has foo/trait.Qux.html
+//@ has - '//section[@id="impl-Qux-for-NewType%3CNewType%3C(T,)%3E%3E"]/h3' 'impl<T> Qux for NewType<NewType<(T₁, T₂, …, Tₙ)>>'
+#[doc(fake_variadic)]
+impl<T> Qux for NewType<NewType<(T,)>> {}
+
+//@ has foo/trait.Qux.html
+//@ has - '//section[@id="impl-Qux-for-NewType%3Cfn(T)+-%3E+Out%3E"]/h3' 'impl<T, Out> Qux for NewType<fn(T₁, T₂, …, Tₙ) -> Out>'
+#[doc(fake_variadic)]
+impl<T, Out> Qux for NewType<fn(T) -> Out> {}