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

rustdoc: Refactor doctest collection and running code #125798

Merged
merged 17 commits into from
Jun 7, 2024

Conversation

camelid
Copy link
Member

@camelid camelid commented May 31, 2024

This code previously had a quite confusing structure, mixing the collection,
processing, and running of doctests with multiple layers of indirection. There
are also many cases where tons of parameters are passed to functions with little
typing information (e.g., booleans or strings are often used).

As a result, the source of bugs is obfuscated (e.g. #81070) and large changes
(e.g. #123974) become unnecessarily complicated. This PR is a first step to try
to simplify the code and make it easier to follow and less bug-prone.

r? @GuillaumeGomez

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels May 31, 2024
@camelid camelid marked this pull request as draft May 31, 2024 07:37
@GuillaumeGomez
Copy link
Member

Changes are pretty straight-forward, looks good to me. Please ping me once ready for a final review.

@rust-log-analyzer

This comment has been minimized.

Comment on lines +417 to +422
// FIXME: why does this code check if it *shouldn't* persist doctests
// -- shouldn't it be the negation?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was already there, but it's really weird. Changing it to is_some breaks a doctest in core (for MaybeUninit::uninit_array.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors

This comment was marked as resolved.

@camelid camelid marked this pull request as ready for review June 4, 2024 07:18
@camelid camelid changed the title [WIP] rustdoc: Refactor doctest collection and running code rustdoc: Refactor doctest collection and running code Jun 4, 2024
@camelid
Copy link
Member Author

camelid commented Jun 4, 2024

There's definitely more work to be done, but I think this is a good stopping point for this PR.

@GuillaumeGomez ready for review!

@camelid camelid added C-cleanup Category: PRs that clean code up or issues documenting cleanup. A-doctests Area: Documentation tests, run by rustdoc labels Jun 4, 2024
@camelid
Copy link
Member Author

camelid commented Jun 4, 2024

Also I should mention that a lot of the changes listed are just moving code into files. I made sure to put those in their own commits to aid in code review. In general this PR is best reviewed commit-by-commit.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jun 5, 2024

☔ The latest upstream changes (presumably #126016) made this pull request unmergeable. Please resolve the merge conflicts.

I moved some local arguments and options to either the local options
struct or, if it made sense, the global options struct.
This code turns the raw code given by the user into something actually
runnable, e.g. by adding a `main` function if it doesn't already exist.

I also made a couple other items private that didn't need to be
crate-public.
It doesn't really make sense to skip part of the source when we're
parsing it, so parse the whole doctest. This simplifies things too.
@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez
Copy link
Member

Thanks for the cleanup, it was very much needed! I'll give a higher priority to this PR as it is very merge conflict-prone.

@bors r+ p=1

@bors
Copy link
Contributor

bors commented Jun 7, 2024

📌 Commit 6aab04e has been approved by GuillaumeGomez

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 7, 2024
@bors
Copy link
Contributor

bors commented Jun 7, 2024

⌛ Testing commit 6aab04e with merge 4dc24ae...

@bors
Copy link
Contributor

bors commented Jun 7, 2024

☀️ Test successful - checks-actions
Approved by: GuillaumeGomez
Pushing 4dc24ae to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 7, 2024
@bors bors merged commit 4dc24ae into rust-lang:master Jun 7, 2024
7 checks passed
@rustbot rustbot added this to the 1.80.0 milestone Jun 7, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (4dc24ae): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

This benchmark run did not return any relevant results for this metric.

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: missing data
Artifact size: 319.46 MiB -> 319.56 MiB (0.03%)

@camelid camelid deleted the refactor-doctest branch August 4, 2024 00:29
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 7, 2024
…2, r=<try>

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Aug 12, 2024
…-v2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 12, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 12, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 13, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 13, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 13, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 13, 2024
…2, r=t-rustdoc

Greatly speed up doctests by compiling compatible doctests in one file

Fixes rust-lang#75341.

Take 2 at rust-lang#123974. It should now be much simpler to review since it's based on rust-lang#125798.

I split the changes as much as possible to make it as easy as possible to review (even though it's a huge lot of code changes...).

The following tests are not included into the combined doctests:
 * `compile_fail`
 * If there are crate attributes (`deny`/`allow`/`warn` are ok)
 * have invalid AST
 * `test_harness`
 * no capture
 * `--show-output` (because the output is nicer without the extra code surrounding it)

Everything else is merged into one file. If this one file fails to compile, we go back to the current strategy: compile each doctest separately.

Because of the `edition` codeblock attribute, I couldn't make them all into one file directly so I grouped them by edition, but it should be pretty anecdotic.

In case the users want a specific doctest to be opted-out from this doctest merge, I added the `standalone` codeblock attribute:

```rust
/// ```rust,standalone
/// // This doctest will be run in its own process!
/// ```
```

Now the interesting part, I ran it on a few crates and here are the results (with `cargo test --doc` to only include doctests):

| crate | nb doctests | before this PR | with this PR |
| - | - | - | - |
| sysinfo | 227 | 4.6s | 1.11s |
| geos | 157 | 3.95s | 0.45s |
| core | 4604 | 54.08s | 13.5s (merged: 0.9s, standalone: 12.6s) |
| std | 1147 | 12s | 3.56s (merged: 2.1s, standalone: 1.46s) |

r? `@camelid`

try-job: x86_64-msvc
try-job: aarch64-apple
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-doctests Area: Documentation tests, run by rustdoc C-cleanup Category: PRs that clean code up or issues documenting cleanup. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants