Skip to content

Fix doc_cfg not working as expected on trait impls - #153964

Merged
rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
GuillaumeGomez:fix-trait-impl-doc-cfg
Mar 24, 2026
Merged

Fix doc_cfg not working as expected on trait impls#153964
rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
GuillaumeGomez:fix-trait-impl-doc-cfg

Conversation

@GuillaumeGomez

Copy link
Copy Markdown
Member

Fixes #153655.

I spent waaaaay too much time on this fix. So the current issue is that rustdoc gets its items in two passes:

  1. All items
  2. Trait/blanket/auto impls

Because of that, the trait impls are not stored "correctly" in the rustdoc AST, meaning that the propagate_doc_cfg pass doesn't work correctly on them. So initially, I tried to "clean" the impls at the same time as the other items. However, it created a monstruous amount of bugs and issues and after two days, I decided to give up on this approach (might be worth fixing that in the future!). You can see what I tried here.

So instead, since the impls are stored at the end, I create placeholders for impls and in propagate_doc_cfg, I store the cfg "context" (more clear when reading the code 😛) and re-use it later on when the "real" impl comes up.

r? @lolbinarycat

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend 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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Mar 16, 2026
@rustbot

This comment has been minimized.

@GuillaumeGomez GuillaumeGomez changed the title Fix trait impl doc cfg Fix doc_cfg not working as expected on trait impls Mar 16, 2026
@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Not great that ImplItem and PlaceholderImplItem need to be handled in rustdoc lints. :-/

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

And CI passed. \o/

@lolbinarycat lolbinarycat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code looks good to me but I still need to do a more in-depth investigation of the logic. For now, here's some nits and clarifying questions.

View changes since this review

Comment thread src/librustdoc/clean/mod.rs Outdated
impl_: &hir::Impl<'tcx>,
def_id: LocalDefId,
cx: &mut DocContext<'tcx>,
// If `renamed` is some, then this is an inlined impl and it will be handled later on in the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: ambiguous pronoun, this would be less ambiguous if "this" was replaced with an actual name.

Comment thread src/librustdoc/json/conversions.rs
Comment thread src/librustdoc/passes/calculate_doc_coverage.rs
Comment thread src/librustdoc/passes/stripper.rs Outdated

clean::ImplItem(..) => {}

// They have no use anymore, so always remove them.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: great comments explain why code does something.

@@ -0,0 +1,59 @@
// This test ensures that `doc_cfg` feature is working as expected on trait impls.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just to be sure: we do have a test for non-trait impls, right? we definitely don't want to regress that.

also, do we have a test for non-auto doc(cfg(...)) on trait items?

@GuillaumeGomez GuillaumeGomez Mar 17, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Doesn't hurt to add one in the same test I guess. Gonna add a test for non-auto doc(cfg(...)) too.

Comment thread src/librustdoc/clean/mod.rs Outdated
@GuillaumeGomez
GuillaumeGomez force-pushed the fix-trait-impl-doc-cfg branch from ce71ac8 to 2dd7677 Compare March 17, 2026 11:47
@rustbot

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Added comments and greatly extended the tests.

@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Seems like a flaky failure. Restarted CI.

@lolbinarycat lolbinarycat left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I took a closer look at the actual logic this time and it seems solid and straightforwards, I can't come up with any edge cases that it would cause problems in.

My only issue of immediate relevance is rustc_span::symbol::kw::Impl and renamed being used in a somewhat unintuitive way, not sure what the best way to address that is but it definitely has an impact on code readability. I also found some missing test coverage but that's mostly unrelated so that can be handled in a followup PR if you want.

View changes since this review

Comment thread src/librustdoc/passes/check_doc_test_visibility.rs
Comment thread src/librustdoc/passes/calculate_doc_coverage.rs
Comment thread src/librustdoc/passes/propagate_doc_cfg.rs
Comment thread src/librustdoc/visit_ast.rs Outdated
@GuillaumeGomez
GuillaumeGomez force-pushed the fix-trait-impl-doc-cfg branch from 2dd7677 to 3f0f7d7 Compare March 18, 2026 15:49
@GuillaumeGomez

Copy link
Copy Markdown
Member Author

I added code comments to explain that the symbol is used as a sentinel value.

Comment thread src/librustdoc/visit_ast.rs Outdated
Comment on lines +436 to +440
if impl_.of_trait.is_none() {
None
} else {
Some(rustc_span::symbol::kw::Impl)
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would replacing parameter type Option<Symbol> with Option<BikeshedTy> be possible / much of a hassle where BikeshedTy is a new type that could be defined like enum BikeshedTy { BikeshedName(Symbol), BikeshedAnon }? I haven't read the rest of the diff, lol

@GuillaumeGomez GuillaumeGomez Mar 18, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Context: this argument is what an inlined item is renamed into. So no, I don't want to rename it. 😝

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 19, 2026
…amples-improvement, r=lolbinarycat

Don't emit rustdoc `missing_doc_code_examples` lint on impl items

@lolbinarycat realized in [this comment](rust-lang#153964 (comment)) that we weren't testing some cases for the `missing_doc_code_examples` lint. Turns out that it was not handling this case well. =D

So in short: `missing_doc_code_examples` lint should not be emitted on impl items and this PR fixes that.

r? @lolbinarycat
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 19, 2026
…amples-improvement, r=lolbinarycat

Don't emit rustdoc `missing_doc_code_examples` lint on impl items

@lolbinarycat realized in [this comment](rust-lang#153964 (comment)) that we weren't testing some cases for the `missing_doc_code_examples` lint. Turns out that it was not handling this case well. =D

So in short: `missing_doc_code_examples` lint should not be emitted on impl items and this PR fixes that.

r? @lolbinarycat
Zalathar added a commit to Zalathar/rust that referenced this pull request Mar 20, 2026
…amples-improvement, r=lolbinarycat

Don't emit rustdoc `missing_doc_code_examples` lint on impl items

@lolbinarycat realized in [this comment](rust-lang#153964 (comment)) that we weren't testing some cases for the `missing_doc_code_examples` lint. Turns out that it was not handling this case well. =D

So in short: `missing_doc_code_examples` lint should not be emitted on impl items and this PR fixes that.

r? @lolbinarycat
@rust-bors

This comment has been minimized.

@GuillaumeGomez
GuillaumeGomez force-pushed the fix-trait-impl-doc-cfg branch from 3f0f7d7 to 2752dc5 Compare March 20, 2026 16:49
@rustbot

This comment has been minimized.

@rustbot

This comment has been minimized.

@GuillaumeGomez

Copy link
Copy Markdown
Member Author

Applied all suggestions!

@lolbinarycat

Copy link
Copy Markdown
Contributor

Thanks!

@bors r+

@rust-bors

rust-bors Bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 19876d1 has been approved by lolbinarycat

It is now in the queue for this repository.

@rust-bors rust-bors Bot 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 Mar 23, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 23, 2026
…cfg, r=lolbinarycat

Fix `doc_cfg` not working as expected on trait impls

Fixes rust-lang#153655.

I spent waaaaay too much time on this fix. So the current issue is that rustdoc gets its items in two passes:
1. All items
2. Trait/blanket/auto impls

Because of that, the trait impls are not stored "correctly" in the rustdoc AST, meaning that the `propagate_doc_cfg` pass doesn't work correctly on them. So initially, I tried to "clean" the impls at the same time as the other items. However, it created a monstruous amount of bugs and issues and after two days, I decided to give up on this approach (might be worth fixing that in the future!). You can see what I tried [here](https://github.com/rust-lang/rust/compare/main...GuillaumeGomez:trait-impls-doc_cfg?expand=1).

So instead, since the impls are stored at the end, I create placeholders for impls and in `propagate_doc_cfg`, I store the `cfg` "context" (more clear when reading the code 😛) and re-use it later on when the "real" impl comes up.

r? @lolbinarycat
rust-bors Bot pushed a commit that referenced this pull request Mar 24, 2026
Rollup of 10 pull requests

Successful merges:

 - #153964 (Fix `doc_cfg` not working as expected on trait impls)
 - #153979 (Rename various query cycle things.)
 - #154132 (Add missing num_internals feature gate to coretests/benches)
 - #154153 (core: Implement `unchecked_funnel_{shl,shr}`)
 - #154236 (Clean up query-forcing functions)
 - #154252 (Don't store current-session side effects in `OnDiskCache`)
 - #154017 ( Fix invalid add of duplicated call locations for the rustdoc scraped examples feature)
 - #154163 (enzyme submodule update)
 - #154264 (Update books)
 - #154282 (rustc-dev-guide subtree update)
@rust-bors
rust-bors Bot merged commit 8a2bd0f into rust-lang:main Mar 24, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 24, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 24, 2026
…, r=eggyal,tgross35

[libcore] Disable `doc(auto_cfg)` for integers trait impls

Fixes rust-lang#153655.

Thanks to rust-lang#153964, `doc(auto_cfg)` finally works as expected on impls. So now this fix works:

<img width="1000" height="806" alt="image" src="https://github.com/user-attachments/assets/f37da375-c2eb-4a7b-abf2-1fdd3a73e2bb" />

cc @eggyal
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 24, 2026
…, r=eggyal,tgross35

[libcore] Disable `doc(auto_cfg)` for integers trait impls

Fixes rust-lang#153655.

Thanks to rust-lang#153964, `doc(auto_cfg)` finally works as expected on impls. So now this fix works:

<img width="1000" height="806" alt="image" src="https://github.com/user-attachments/assets/f37da375-c2eb-4a7b-abf2-1fdd3a73e2bb" />

cc @eggyal
github-actions Bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Apr 6, 2026
Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#153964 (Fix `doc_cfg` not working as expected on trait impls)
 - rust-lang/rust#153979 (Rename various query cycle things.)
 - rust-lang/rust#154132 (Add missing num_internals feature gate to coretests/benches)
 - rust-lang/rust#154153 (core: Implement `unchecked_funnel_{shl,shr}`)
 - rust-lang/rust#154236 (Clean up query-forcing functions)
 - rust-lang/rust#154252 (Don't store current-session side effects in `OnDiskCache`)
 - rust-lang/rust#154017 ( Fix invalid add of duplicated call locations for the rustdoc scraped examples feature)
 - rust-lang/rust#154163 (enzyme submodule update)
 - rust-lang/rust#154264 (Update books)
 - rust-lang/rust#154282 (rustc-dev-guide subtree update)
@GuillaumeGomez
GuillaumeGomez deleted the fix-trait-impl-doc-cfg branch July 7, 2026 15:01
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 24, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 24, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 25, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 26, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 26, 2026
…-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang#153964, rust-lang#154311, and rust-lang#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
rust-timer added a commit that referenced this pull request Jul 26, 2026
Rollup merge of #159819 - Vastargazing:fix/poison-error-auto-cfg-note, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in #153964, #154311, and #156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue #149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as #156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Jul 27, 2026
…, r=GuillaumeGomez

std::sync::poison: disable auto_cfg on PoisonError::new

`PoisonError::new` is defined twice, once for `#[cfg(panic = "unwind")]` and once for its negation. While exactly one definition survives expansion in any given build, the method itself is actually present in every configuration.

Currently, rustdoc's `auto_cfg` only looks at whichever `cfg` survived expansion and tags the method accordingly, generating a misleading "Available on panic=unwind only" portability badge in the docs.

This is the same `auto_cfg` limitation previously addressed in rust-lang/rust#153964, rust-lang/rust#154311, and rust-lang/rust#156426: when an item is split into mutually-exclusive `cfg` variants that collectively cover all builds, rustdoc incorrectly marks it as conditionally available. Issue rust-lang/rust#149786 pointed out `PoisonError::new` as another case of this pattern, but it hadn't been touched yet.

This PR applies the same fix as rust-lang/rust#156426 (adding `#[doc(auto_cfg = false)]` to both variants) and adds a regression test to cover this pattern going forward.

r? @GuillaumeGomez
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rustdoc-json Area: Rustdoc JSON backend 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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rustdoc reports wrong config conditions for impl LowerExp for integers

5 participants