Skip to content

Fix doc_cfg not working as expected on trait impls#153964

Merged
rust-bors[bot] merged 5 commits intorust-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 intorust-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/

Copy link
Copy Markdown
Contributor

@lolbinarycat lolbinarycat left a comment

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

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.


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?

Copy link
Copy Markdown
Member Author

@GuillaumeGomez GuillaumeGomez Mar 17, 2026

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.

@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.

Copy link
Copy Markdown
Contributor

@lolbinarycat lolbinarycat left a comment

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

@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 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

Copy link
Copy Markdown
Member Author

@GuillaumeGomez GuillaumeGomez Mar 18, 2026

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

Fixed merge conflict.

Copy link
Copy Markdown
Contributor

@lolbinarycat lolbinarycat left a comment

Choose a reason for hiding this comment

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

One last review pass, two points of substance and two very tiny nits about word choice in comments.

View changes since this review

// If `renamed` is some, then `impl_` is an inlined impl and it will be handled later on in the
// code. In here, we will generate a placeholder for it in order to be able to compute its
// `doc_cfg` info.
renamed: Option<Symbol>,
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.

After some reflection I think this should probably just be a boolean parameter called something like is_inlined. I feel like too often rustdoc just passes variables along as function parameters with the same name, even when they don't really make sense in that context. Although why are we saying "inlined" and not "trait" here? Is there some subtle difference I'm missing?

If this item is renamed, we can probably remove the comment, but we'll definitely need to make sure that the comment in clean_maybe_renamed_item is updated to still make sense.

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.

Fair enough.

cx: &'a mut DocContext<'tcx>,
cfg_info: CfgInfo,

/// To ensure the `doc_cfg` feature works with how `rustdoc` handles impl, we need to store
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.

Suggested change
/// To ensure the `doc_cfg` feature works with how `rustdoc` handles impl, we need to store
/// To ensure the `doc_cfg` feature works with how `rustdoc` handles impls, we need to store

nit: typo

Comment on lines +87 to +88
// If we have an impl, we check if it has an associated `cfg` "context", and if so we will
// use this context instead of the actual (wrong) one.
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.

Suggested change
// If we have an impl, we check if it has an associated `cfg` "context", and if so we will
// use this context instead of the actual (wrong) one.
// If we have an impl, we check if it has an associated `cfg` "context", and if so we will
// use that context instead of the actual (wrong) one.

very minor and somewhat subjective nit

// them up regardless of where they're located.
if !self.inlining && impl_.of_trait.is_none() {
self.add_to_current_mod(item, None, None);
if !self.inlining {
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.

Instead of copy-pasting this code, I'd like to see it refactored into a utility method add_impl_to_current_mod.

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.

Good idea.

@GuillaumeGomez GuillaumeGomez force-pushed the fix-trait-impl-doc-cfg branch from 2752dc5 to 19876d1 Compare March 23, 2026 20:47
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 23, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 23, 2026

⚠️ Warning ⚠️

  • There are issue links (such as #123) in the commit messages of the following commits.
    Please move them to the PR description, to avoid spamming the issues with references to the commit, and so this bot can automatically canonicalize them to avoid issues with subtree.

@GuillaumeGomez
Copy link
Copy Markdown
Member Author

Applied all suggestions!

@lolbinarycat
Copy link
Copy Markdown
Contributor

Thanks!

@bors r+

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 23, 2026

📌 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
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