Rollup merge of #129525 - notriddle:notriddle/fake-variadic-tuple-array, r=GuillaumeGomez

rustdoc: clean up tuple <-> primitive conversion docs

This adds a minor missing feature to `fake_variadic`, so that it can render `impl From<(T,)> for [T; 1]` correctly.
This commit is contained in:
Matthias Krüger 2024-08-26 01:49:02 +02:00 committed by GitHub
commit aa26e1ad97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 122 additions and 55 deletions

View File

@ -952,6 +952,16 @@ fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) {
bare_fn_ty.decl.inputs.len() == 1
} else {
false
}
|| if let Some(&[hir::GenericArg::Type(ty)]) = i
.of_trait
.as_ref()
.and_then(|trait_ref| trait_ref.path.segments.last())
.map(|last_segment| last_segment.args().args)
{
matches!(&ty.kind, hir::TyKind::Tup([_]))
} else {
false
};
if !is_valid {
self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() });

View File

@ -122,6 +122,8 @@ fn default() -> ($($T,)+) {
}
}
maybe_tuple_doc! {
$($T)+ @
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
#[inline]
@ -131,7 +133,10 @@ fn default() -> ($($T,)+) {
($($T,)+)
}
}
}
maybe_tuple_doc! {
$($T)+ @
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
#[inline]
@ -143,12 +148,13 @@ fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
}
}
}
}
// If this is a unary tuple, it adds a doc comment.
// Otherwise, it hides the docs entirely.
macro_rules! maybe_tuple_doc {
($a:ident @ #[$meta:meta] $item:item) => {
#[doc(fake_variadic)]
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
#[doc = "This trait is implemented for tuples up to twelve items long."]
#[$meta]
$item

View File

@ -1288,11 +1288,43 @@ pub(crate) fn print<'a, 'tcx: 'a>(
if self.is_negative_trait_impl() {
write!(f, "!")?;
}
if self.kind.is_fake_variadic()
&& let generics = ty.generics()
&& let &[inner_type] = generics.as_ref().map_or(&[][..], |v| &v[..])
{
let last = ty.last();
if f.alternate() {
write!(f, "{}<", last)?;
self.print_type(inner_type, f, use_absolute, cx)?;
write!(f, ">")?;
} else {
write!(f, "{}&lt;", anchor(ty.def_id(), last, cx).to_string())?;
self.print_type(inner_type, f, use_absolute, cx)?;
write!(f, "&gt;")?;
}
} else {
ty.print(cx).fmt(f)?;
}
write!(f, " for ")?;
}
if let clean::Type::Tuple(types) = &self.for_
if let Some(ty) = self.kind.as_blanket_ty() {
fmt_type(ty, f, use_absolute, cx)?;
} else {
self.print_type(&self.for_, f, use_absolute, cx)?;
}
print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f)
})
}
fn print_type<'a, 'tcx: 'a>(
&self,
type_: &clean::Type,
f: &mut fmt::Formatter<'_>,
use_absolute: bool,
cx: &'a Context<'tcx>,
) -> Result<(), fmt::Error> {
if let clean::Type::Tuple(types) = type_
&& let [clean::Type::Generic(name)] = &types[..]
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
{
@ -1305,7 +1337,13 @@ pub(crate) fn print<'a, 'tcx: 'a>(
"#trait-implementations-1",
cx,
)?;
} else if let clean::BareFunction(bare_fn) = &self.for_
} else if let clean::Type::Array(ty, len) = type_
&& let clean::Type::Generic(name) = &**ty
&& &len[..] == "1"
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
{
primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?;
} else if let clean::BareFunction(bare_fn) = &type_
&& let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
&bare_fn.decl.inputs.values[..]
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
@ -1329,14 +1367,10 @@ pub(crate) fn print<'a, 'tcx: 'a>(
write!(f, " -> ")?;
fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
}
} else if let Some(ty) = self.kind.as_blanket_ty() {
fmt_type(ty, f, use_absolute, cx)?;
} else {
fmt_type(&self.for_, f, use_absolute, cx)?;
fmt_type(&type_, f, use_absolute, cx)?;
}
print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f)
})
Ok(())
}
}

View File

@ -16,3 +16,20 @@ pub trait Bar {}
//@ has - '//section[@id="impl-Bar-for-(U,)"]/h3' 'impl<U: Foo> Bar for (U₁, U₂, …, Uₙ)'
#[doc(fake_variadic)]
impl<U: Foo> Bar for (U,) {}
pub trait Baz<T> { fn baz(&self) -> T { todo!() } }
//@ has foo/trait.Baz.html
//@ has - '//section[@id="impl-Baz%3C(T,)%3E-for-%5BT;+1%5D"]/h3' 'impl<T> Baz<(T₁, T₂, …, Tₙ)> for [T; N]'
#[doc(fake_variadic)]
impl<T> Baz<(T,)> for [T; 1] {}
//@ has foo/trait.Baz.html
//@ has - '//section[@id="impl-Baz%3C%5BT;+1%5D%3E-for-(T,)"]/h3' 'impl<T> Baz<[T; N]> for (T₁, T₂, …, Tₙ)'
#[doc(fake_variadic)]
impl<T> Baz<[T; 1]> for (T,) {}
//@ has foo/trait.Baz.html
//@ 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,) {}