Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider using fake_variadic to improve docs #14697

Closed
janhohenheim opened this issue Aug 10, 2024 · 5 comments · Fixed by #14703
Closed

Consider using fake_variadic to improve docs #14697

janhohenheim opened this issue Aug 10, 2024 · 5 comments · Fixed by #14703
Labels
A-Cross-Cutting Impacts the entire engine C-Docs An addition or correction to our documentation D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! X-Contentious There are nontrivial implications that should be thought through
Milestone

Comments

@janhohenheim
Copy link
Member

janhohenheim commented Aug 10, 2024

How can Bevy's documentation be improved?

fake_variadic allows docs on docs.rs to pretend they use variadics to hide tuple implementation spam.
It requires #![cfg_attr(docsrs, feature(doc_cfg, rustdoc_internals))] on lib.rs.

This is an secret, undocumented internal feature for the standard library, as far as I know. Buuuuuut there is a precedent of popular crates using it... namely serde!

See https://docs.rs/serde/latest/src/serde/de/impls.rs.html#1480-1509 for a usage example and https://docs.rs/serde/latest/serde/trait.Deserialize.html#impl-Deserialize%3C'de%3E-for-(T,) for how it is rendered:

image

The exact usage is:

  • Use the following annotation for the first impl:
#[cfg_attr(docsrs, doc(fake_variadic))]
#[cfg_attr(
    docsrs,
    doc = "This trait is implemented for tuples up to 16 items long."
)]
  • use #[cfg_attr(docsrs, doc(hidden))] on the other impls
@janhohenheim janhohenheim added C-Docs An addition or correction to our documentation S-Needs-Triage This issue needs to be labelled A-Cross-Cutting Impacts the entire engine X-Contentious There are nontrivial implications that should be thought through S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! and removed S-Needs-Triage This issue needs to be labelled labels Aug 10, 2024
@alice-i-cecile alice-i-cecile added the D-Straightforward Simple bug fixes and API improvements, docs, test and examples label Aug 10, 2024
@alice-i-cecile
Copy link
Member

I love it we should do this.

@alice-i-cecile alice-i-cecile added this to the 0.15 milestone Aug 10, 2024
@bash
Copy link
Contributor

bash commented Aug 10, 2024

I'd be interested in working on this :)

Would adding an option to the all_tuples! macro be an acceptable solution?
Usage would look something like this:

all_tuples!(#[doc(fake_variadic)] impl_plugins_tuples, 0, 15, P, S);

Is bevy_utils intended for third-party use? If not then I could just do the fake variadic stuff unconditionally.

@alice-i-cecile
Copy link
Member

IMO we should just do this unconditionally there :)

@bash
Copy link
Contributor

bash commented Aug 10, 2024

Ah dang it. #[doc(fake_variadic)] only works on actual tuples and fn pointers.

For example this:

pub trait Example {}

macro_rules! impl_example {
    (($P:ident, $p:ident)) => {
        #[cfg_attr(docsrs, doc(fake_variadic))]
        #[cfg_attr(docsrs, doc = "This trait is implemented for tuples up to 16 items long.")]
        impl<P> Example for std::marker::PhantomData<(P,)> {}
    };
    ($(($P:ident, $p:ident)),*) => {
        #[cfg_attr(docsrs, doc(hidden))]
        impl<$($P,)*> Example for std::marker::PhantomData<($($P,)*)> {}
    };
}

bevy_utils::all_tuples!(impl_example, 0, 16, P, p);

fails with:

error: `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity

I guess this busts my dream of putting this in all_tuples! directly

@cart
Copy link
Member

cart commented Aug 10, 2024

I guess this busts my dream of putting this in all_tuples! directly

Could you add an additional parameter to it that adds it in an opt-in way?

github-merge-queue bot pushed a commit that referenced this issue Aug 12, 2024
# Objective

- Fixes #14697

## Solution

This PR modifies the existing `all_tuples!` macro to optionally accept a
`#[doc(fake_variadic)]` attribute in its input. If the attribute is
present, each invocation of the impl macro gets the correct attributes
(i.e. the first impl receives `#[doc(fake_variadic)]` while the other
impls are hidden using `#[doc(hidden)]`.
Impls for the empty tuple (unit type) are left untouched (that's what
the [standard
library](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html#impl-PartialEq-for-())
and
[serde](https://docs.rs/serde/latest/serde/trait.Serialize.html#impl-Serialize-for-())
do).

To work around rust-lang/cargo#8811 and to get
impls on re-exports to correctly show up as variadic, `--cfg docsrs_dep`
is passed when building the docs for the toplevel `bevy` crate.

`#[doc(fake_variadic)]` only works on tuples and fn pointers, so impls
for structs like `AnyOf<(T1, T2, ..., Tn)>` are unchanged.

## Testing

I built the docs locally using `RUSTDOCFLAGS='--cfg docsrs'
RUSTFLAGS='--cfg docsrs_dep' cargo +nightly doc --no-deps --workspace`
and checked the documentation page of a trait both in its original crate
and the re-exported version in `bevy`.
The description should correctly mention for how many tuple items the
trait is implemented.

I added `rustc-args` for docs.rs to the `bevy` crate, I hope there
aren't any other notable crates that re-export `#[doc(fake_variadic)]`
traits.

---

## Showcase

`bevy_ecs::query::QueryData`:
<img width="1015" alt="Screenshot 2024-08-12 at 16 41 28"
src="https://github.com/user-attachments/assets/d40136ed-6731-475f-91a0-9df255cd24e3">

`bevy::ecs::query::QueryData` (re-export):
<img width="1005" alt="Screenshot 2024-08-12 at 16 42 57"
src="https://github.com/user-attachments/assets/71d44cf0-0ab0-48b0-9a51-5ce332594e12">

## Original Description

<details>

Resolves #14697

Submitting as a draft for now, very WIP.

Unfortunately, the docs don't show the variadics nicely when looking at
reexported items.
For example:

`bevy_ecs::bundle::Bundle` correctly shows the variadic impl:

![image](https://github.com/user-attachments/assets/90bf8af1-1d1f-4714-9143-cdd3d0199998)

while `bevy::ecs::bundle::Bundle` (the reexport) shows all the impls
(not good):

![image](https://github.com/user-attachments/assets/439c428e-f712-465b-bec2-481f7bf5870b)

Built using `RUSTDOCFLAGS='--cfg docsrs' cargo +nightly doc --workspace
--no-deps` (`--no-deps` because of wgpu-core).

Maybe I missed something or this is a limitation in the *totally not
private* `#[doc(fake_variadic)]` thingy. In any case I desperately need
some sleep now :))

</details>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Cross-Cutting Impacts the entire engine C-Docs An addition or correction to our documentation D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants