Skip to content

Conversation

@Muscraft
Copy link
Member

@Muscraft Muscraft commented Nov 11, 2025

@fmease's Deep analysis on the problem

Yeah, here's a deep analysis by me from a few weeks back of what's going on (#148101 (comment)):

[…]
However, since said PR (#147207: migrating coloring crates), HumanEmitter::supports_color() unconditionally(!) returns false (in fact, Emitter::supports_color is no longer used by anyone else and should be removed), so there's no reason to keep it. Rephrased, since that PR all compiler diagnostics for doctests are uncolored.
You could argue that I should keep it and patch supports_color in rustc to "work again". However, I'd rather rework our doctest coloring wholesale in a separate PR. At least before that migration PR, our setup was quite busted:

  1. First of all, it didn't query+set supports_color for syntactically invalid doctests, so syntax errors were always shown without color (contrary to e.g., name resolution errors).
  2. Second of all, calling supports_color() here was quite frankly wrong: Piping the output of rustdoc … --test into a file (or | cat or whatever) did not suppress colors. I'm not actually sure if we can ever address that nicely (without stripping ANSI codes after the fact) since we pass that diagnostic to libtest, right? I might very well be wrong here, maybe it's a non-issue.

/// ```
/// foo
/// ``` 
fn foo() {}
rustdoc --test lib.rs

Stable:
stable

Beta:
beta

Nightly:
nightly

After:
after

Note: This will need to be backported to beta

Fixes: #148749

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Nov 11, 2025
@rustbot

This comment was marked as outdated.

@fmease fmease assigned fmease and unassigned madsmtm Nov 11, 2025
Copy link
Member

@fmease fmease left a comment

Choose a reason for hiding this comment

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

Thanks, one small nit!

View changes since this review

info.supports_color =
HumanEmitter::new(stderr_destination(ColorConfig::Auto), translator.clone())
.supports_color();
let supports_color = match get_stderr_color_choice(ColorConfig::Auto, &std::io::stderr()) {
Copy link
Member

@fmease fmease Nov 11, 2025

Choose a reason for hiding this comment

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

I should've realized that much earlier: Obviously, like on stable, rustdoc bad-doctest.rs --test | cat / rustdoc bad-doctest.rs --test > file.txt still leads to colored output because libtest outputs this to stdout while we're querying stderr here.

I consider this a bug but I don't want it to be fixed in this PR since there are some subtleties. E.g., if you pass --no-capture (previously known as --nocapture) to rustdoc, then both output streams don't get captured meaning querying stderr would actually make sense in that specific case. There are probably some other things that need consideration.

}

pub fn get_stderr_color_choice(color: ColorConfig, stderr: &std::io::Stderr) -> ColorChoice {
let choice = color.to_color_choice();
Copy link
Member

@fmease fmease Nov 11, 2025

Choose a reason for hiding this comment

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

I'll provide some more context for other T-rustdoc members. In my opinion to_color_choice as used in both rustc & rustdoc is suboptimal as it doesn't harness the full power of crate anstyle-query due to the fact that it yields Never if the config is Auto and stderr is not a terminal meaning NO_COLOR=1 works but e.g., CLICOLOR_FORCE=1 doesn't.

That's a separate bug I or Muscraft will deal with in the future, hopefully.

I'm saying all that because I originally wanted to use CLICOLOR_FORCE=1 in a potential regression test for #148749 which requires --color=auto (not --color=always) which obviously never leads to colored output since it's captured by compiletest, not by the terminal. I wanted to use CLICOLOR_FORCE=1 to indirectly test --color=auto (and have the golden file be an SVG or ANSI codes if that doesn't work out).

That's the reason why there's no regression test. If you have any other ideas, please let me know.

@fmease
Copy link
Member

fmease commented Nov 11, 2025

While this does touch the compiler, the changes aren't behavioral. Therefore I'll now remove the T-compiler label and nominate it for T-rustdoc only.

@fmease fmease added beta-nominated Nominated for backporting to the compiler in the beta channel. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 11, 2025
@fmease
Copy link
Member

fmease commented Nov 11, 2025

@bors rollup

r=me with #148834 (comment) addressed in one way or another

@fmease fmease added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 11, 2025
@fmease
Copy link
Member

fmease commented Nov 12, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Nov 12, 2025

📌 Commit c523b65 has been approved by fmease

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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 12, 2025
bors added a commit that referenced this pull request Nov 12, 2025
Rollup of 16 pull requests

Successful merges:

 - #146627 (Simplify `jemalloc` setup)
 - #147753 (Suggest add bounding value for RangeTo)
 - #147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - #147974 (Improve diagnostics for buffer reuse with borrowed references)
 - #148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - #148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - #148500 (Update git index before running diff-index)
 - #148531 (rustc_target: introduce Abi, Env, Os)
 - #148536 (cmse: add test for `async` and `const` functions)
 - #148770 (implement `feature(c_variadic_naked_functions)`)
 - #148780 (fix filecheck typos in tests)
 - #148819 (Remove specialized warning for removed target)
 - #148830 (miri subtree update)
 - #148833 (Update rustbook dependencies)
 - #148834 (fix(rustdoc): Color doctest errors)
 - #148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 0675923 into rust-lang:main Nov 12, 2025
11 checks passed
@rustbot rustbot added this to the 1.93.0 milestone Nov 12, 2025
rust-timer added a commit that referenced this pull request Nov 12, 2025
Rollup merge of #148834 - Muscraft:fix-doctest-colors, r=fmease

fix(rustdoc): Color doctest errors

`@fmease's` [Deep analysis](#148749 (comment)) on the problem
> Yeah, here's a deep analysis by me from a few weeks back of what's going on ([#148101 (comment)](#148101 (comment))):
>
> > […]
> > However, since said PR ([#147207](#147207): migrating coloring crates), `HumanEmitter::supports_color()` unconditionally(!) returns `false` (in fact, `Emitter::supports_color` is no longer used by anyone else and should be removed), so there's no reason to keep it. Rephrased, since that PR all compiler diagnostics for doctests are uncolored.
> > You could argue that I should keep it and patch `supports_color` in rustc to "work again". However, I'd rather rework our doctest coloring wholesale in a separate PR. At least before that migration PR, our setup was quite busted:
> >
> > 1. First of all, it didn't query+set `supports_color` for syntactically invalid doctests, so syntax errors were always shown without color (contrary to e.g., name resolution errors).
> > 2. Second of all, calling `supports_color()` here was quite frankly wrong: Piping the output of `rustdoc … --test` into a file (or `| cat` or whatever) did **not** suppress colors. I'm not actually sure if we can ever address that nicely (without stripping ANSI codes after the fact) since we pass that diagnostic to `libtest`, right? I might very well be wrong here, maybe it's a non-issue.

<hr>

```rust
/// ```
/// foo
/// ```
fn foo() {}
```
```
rustdoc --test lib.rs
```

Stable:
<img width="377" height="290" alt="stable" src="https://github.com/user-attachments/assets/cd20f947-b58d-42db-8735-797613baa9cc" />

Beta:
<img width="377" height="290" alt="beta" src="https://github.com/user-attachments/assets/f02588fd-41d2-4642-b03a-5554a68671eb" />

Nightly:
<img width="377" height="290" alt="nightly" src="https://github.com/user-attachments/assets/871cb417-f47e-4058-8a76-3bcd538ce141" />

After:
<img width="377" height="290" alt="after" src="https://github.com/user-attachments/assets/5734c01f-3f1c-44bb-9404-628c0c33b440" />

Note: This will need to be backported to `beta`

Fixes: #148749
@Muscraft Muscraft deleted the fix-doctest-colors branch November 12, 2025 04:58
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Nov 12, 2025
Rollup of 16 pull requests

Successful merges:

 - rust-lang/rust#146627 (Simplify `jemalloc` setup)
 - rust-lang/rust#147753 (Suggest add bounding value for RangeTo)
 - rust-lang/rust#147832 (rustdoc: Don't pass `RenderOptions` to `DocContext`)
 - rust-lang/rust#147974 (Improve diagnostics for buffer reuse with borrowed references)
 - rust-lang/rust#148080 ([rustdoc] Fix invalid jump to def macro link generation)
 - rust-lang/rust#148465 (Adjust spans into the `for` loops context before creating the new desugaring spans.)
 - rust-lang/rust#148500 (Update git index before running diff-index)
 - rust-lang/rust#148531 (rustc_target: introduce Abi, Env, Os)
 - rust-lang/rust#148536 (cmse: add test for `async` and `const` functions)
 - rust-lang/rust#148770 (implement `feature(c_variadic_naked_functions)`)
 - rust-lang/rust#148780 (fix filecheck typos in tests)
 - rust-lang/rust#148819 (Remove specialized warning for removed target)
 - rust-lang/rust#148830 (miri subtree update)
 - rust-lang/rust#148833 (Update rustbook dependencies)
 - rust-lang/rust#148834 (fix(rustdoc): Color doctest errors)
 - rust-lang/rust#148841 (Remove more `#[must_use]` from portable-simd)

r? `@ghost`
`@rustbot` modify labels: rollup
@fmease
Copy link
Member

fmease commented Nov 12, 2025

Beta backport accepted as per #t-rustdoc > beta-nominated: #148834 @ 💬.

@fmease fmease added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

beta-accepted Accepted for backporting to the compiler in the beta channel. beta-nominated Nominated for backporting to the compiler in the beta channel. 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.

doctest errors are no longer colored

5 participants