Skip to content

Commit 4e48768

Browse files
committed
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>
1 parent 8aca4ba commit 4e48768

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

compiler/rustc_passes/src/check_attr.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -918,12 +918,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
918918
};
919919
match item_kind {
920920
Some(ItemKind::Impl(i)) => {
921-
let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_]))
922-
|| if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind {
923-
bare_fn_ty.decl.inputs.len() == 1
924-
} else {
925-
false
926-
}
921+
let is_valid = doc_fake_variadic_is_allowed_self_ty(i.self_ty)
927922
|| if let Some(&[hir::GenericArg::Type(ty)]) = i
928923
.of_trait
929924
.as_ref()
@@ -2630,3 +2625,20 @@ fn check_duplicates(
26302625
},
26312626
}
26322627
}
2628+
2629+
fn doc_fake_variadic_is_allowed_self_ty(self_ty: &hir::Ty<'_>) -> bool {
2630+
matches!(&self_ty.kind, hir::TyKind::Tup([_]))
2631+
|| if let hir::TyKind::BareFn(bare_fn_ty) = &self_ty.kind {
2632+
bare_fn_ty.decl.inputs.len() == 1
2633+
} else {
2634+
false
2635+
}
2636+
|| (if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &self_ty.kind
2637+
&& let Some(&[hir::GenericArg::Type(ty)]) =
2638+
path.segments.last().map(|last| last.args().args)
2639+
{
2640+
doc_fake_variadic_is_allowed_self_ty(ty)
2641+
} else {
2642+
false
2643+
})
2644+
}

src/librustdoc/html/format.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,24 @@ impl clean::Impl {
13681368
write!(f, " -> ")?;
13691369
fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
13701370
}
1371+
} else if let clean::Type::Path { path } = type_
1372+
&& let Some(generics) = path.generics()
1373+
&& generics.len() == 1
1374+
&& self.kind.is_fake_variadic()
1375+
{
1376+
let ty = generics[0];
1377+
let wrapper = anchor(path.def_id(), path.last(), cx);
1378+
if f.alternate() {
1379+
write!(f, "{wrapper:#}&lt;")?;
1380+
} else {
1381+
write!(f, "{wrapper}<")?;
1382+
}
1383+
self.print_type(ty, f, use_absolute, cx)?;
1384+
if f.alternate() {
1385+
write!(f, "&gt;")?;
1386+
} else {
1387+
write!(f, ">")?;
1388+
}
13711389
} else {
13721390
fmt_type(&type_, f, use_absolute, cx)?;
13731391
}

tests/rustdoc/primitive-tuple-variadic.rs

+19
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,22 @@ impl<T> Baz<[T; 1]> for (T,) {}
3333
//@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl<T> Baz<T> for (T₁, T₂, …, Tₙ)'
3434
#[doc(fake_variadic)]
3535
impl<T> Baz<T> for (T,) {}
36+
37+
pub trait Qux {}
38+
39+
pub struct NewType<T>(T);
40+
41+
//@ has foo/trait.Qux.html
42+
//@ has - '//section[@id="impl-Qux-for-NewType%3C(T,)%3E"]/h3' 'impl<T> Qux for NewType<(T₁, T₂, …, Tₙ)>'
43+
#[doc(fake_variadic)]
44+
impl<T> Qux for NewType<(T,)> {}
45+
46+
//@ has foo/trait.Qux.html
47+
//@ has - '//section[@id="impl-Qux-for-NewType%3CNewType%3C(T,)%3E%3E"]/h3' 'impl<T> Qux for NewType<NewType<(T₁, T₂, …, Tₙ)>>'
48+
#[doc(fake_variadic)]
49+
impl<T> Qux for NewType<NewType<(T,)>> {}
50+
51+
//@ has foo/trait.Qux.html
52+
//@ has - '//section[@id="impl-Qux-for-NewType%3Cfn(T)+-%3E+Out%3E"]/h3' 'impl<T, Out> Qux for NewType<fn(T₁, T₂, …, Tₙ) -> Out>'
53+
#[doc(fake_variadic)]
54+
impl<T, Out> Qux for NewType<fn(T) -> Out> {}

0 commit comments

Comments
 (0)